TerraControl – With NodeMCU Webserver

UPDATE 3: Version 1.3

I’m working on making the code as user friendly as possible but it’s going to be a long run. I’d like to have separate html and css files but I’m still figuring it out. For now, few changes…:

  • ! ! ! included mDNS protocol, so from now on you don’t need IP address to connect to your NodeMCU, simply put terracontrol.local in your browser and you are done (you have to be on the same network, of course)
  • separate file for setting up the variables (setting.h). Unzip the file to your Projects folder, when you open the *.ino file, setting.h should be opened as well.

UPDATE 2: Version 1.2

  • improved graph displaying range
  • new values in graphs are moved to the end of array, not starting from the beginning again
  • improved light setting – it is now unlimited (ON time can now be later than OFF time)
  • code for manual defining your own server is in one place and commented by default (i.e. it is on automatic setting)
  • clearer information in serial monitor
  • unified function for min/max values in array
  • new function for printing out minute values

UPDATE 1: Please see the version 1.1 I got the graphs and statistics working! Well, sort of…the range is still not as I want it to be, but at least now it is correctly displaying min and max. Plus new mouseover feature for the individual values in the graph.

After my first attempt to create controlled terrarium using Arduino board I got my hands on NodeMCU 12E board and I knew it was going to be a big step up!

I took me a few days before I began to understand how this board works (thanks to a lot of instructables here and google of course) and the possibilities it had. It think I’m on the right path to create exactly what I was dreaming about for several years…

So what is TerraControl v1.2 capable of?

  1. 2 automatically controlled relays (light timer and heating)
  2. 2 manually controlled relays (fan, second heating)
  3. GMT time change
  4. Simple graphs with highest/lowest temperature/humidity over the last 24 hours
  5. Monitoring temperature and humidity in terrarium
  6. All accessible and adjustable through webserver using HTML and CSS

What is necessary:

  • given the nature of NodeMCU board (its output is only 3.3v) you will either have to buy 3.3V relay board, or modify 5v board, or buy I2C logic converter module – for example – $0.9
  • 5V source (I’m using older usb charger)
  • wires
  • solder
  • case/box
  • Arduino IDE

Step 1: Getting the Parts Together

Connecting these parts is easy, just look at the source code and keep in mind that GPIO’s of the NodeMCU board is different from the actual boards description (as seen on the trird picture):

//Define sensor pins
#define SENSOR_IN 15 //D8
#define SENSOR_IN_Type DHT22

//Define Relay pins
#define relayLight 5 //D1
#define relayHeat 4 //D2
#define relayFan 12 //D6
#define relayHeat2 14 //D5

i.e. DHT sensor pin goes to D8 (board’s D3, D4, D8 can’t be used as output but can be used as input), and the relay pins accordingly to the code. Remember, if you are using 5V relay, you need to modify the relay board or use I2C logic converter.

! ! ! IMPORTANT! When uploading the code to the board, you have to disconnect the DHT sensor, otherwise you will get an error when attempting to upload ! ! !

All parts can be powered with 5v power adapter

Step 2: Setup and Customization

Before we upload the code, there are few things that needs to be set up in setting.h:

//You WiFi AP
const char ssid[] = “SSID Name”; // insert your WiFi AP name
const char pass[] = “password”; // insert your WiFi password

// T E R R A R I U M S E T T I N G
float tempMin = 24; // temperature in Celsius for switching the heating ON
float tempMax = 30; // temperature in Celsius for switching the heating OFF

int humMin = 50; // minimum humidity in %
int humMax = 70; // maximum humidity in %

// hour and minute for light to go ON
int lightOn_hour = 7;
int lightOn_min = 0;

// hour and minute for light to go OFF
int lightOff_hour = 20;
int lightOff_min = 30;

// Central European Time (1 for winter time)
int timeZone = 2;

Uncomment the following part of the code if you know how to define your server manually or just run the code and get addresses from the serial monitor.

/*— UNCOMMENT THIS FOR MANUAL SETTING —
IPAddress ip(192, 168, 0, 111); //Node static IP
IPAddress gateway(192, 168, 0, 1);
IPAddress subnet(255, 255, 255, 0);
WiFi.config(ip, gateway, subnet);
*/

All done? Great, let’s move on…

Step 3: Alwas ON/OFF Relay Connection

One thing I wanted was the relay board to be used as little as possible. As you probably know, relays have two possible ways of connection: ON when not used and ON when used. So I connected the light and heating to “ON when not used” (heating is almost always ON and lights are ON for about 13-14 hours every day) and fan and heating 2 to “ON when used” (I barely need to use one of them).

That is why the code for the same function is using different values:

if (heatVal == 1) {
client.println(“ON”);
} else {
client.println(“OFF”); }

AND

if (heat2Val == 1) {
client.println(“OFF”);
} else {
client.println(“ON”); }

You can of course modify the code according to your needs.

Now just connect the DHT sensor and let’s look at the result!

Step 4: Webserver

When you open the webserver you will see simple page with all information about your terrarium and some features:

  • Light ON/OFF time can be adjusted (step are: 1 hour for hour setting and 5 min for minute setting). At the moment ON time has to be earlier that OFF time (ON 22:30 and OFF 0:30 will not work – yet) – fixed in version 1.2
  • Temperature setting (steps are 0.5 degree Celsius)
  • Manualy turn ON/OFF other two relays – Fan and Heat 2 and adjust timezone when the time changes

if needed, change your timezones in following part of the code:

if (request.indexOf(“/TIMEZONE_SWITCH”) != -1) {
if (timeZone == 1) {
timeZone = 2;
setSyncProvider(getNtpTime);
} else {
timeZone = 1;
setSyncProvider(getNtpTime);
} }

  • Webserver is using automatic time synchronization

Step 5: Disclosure

I know that the HTML and CSS code could be much more simple and the coding is not really user friendly but for the moment it works as it is supposed to (only the graphs are not very accurate but I’m still working on them) and I will get to these points when I start working on version number two. I have already decided to use external power supply (in this version I just stripped the 5v adapter and soldered it inside the box) and I also want the power cables to be more accessible and easier to connect/disconnect. I hope you guys (and your pets) will appreciate this instructable, if you do, please leave a short comment. And of course, suggestions are more than welcome! Thank you

ESPway | 로봇 제어 세그웨이 스타일 와이파이 ESP8266 구축

내가 아두 이노와 임베디드 시스템 땜질 시작 이후로, 나는 자기 밸런싱, 세그웨이 같은 로봇을 구축하는 방법에 대해 매우 흥분했습니다. 인터넷의 주위에 유사한 프로젝트 및 리소스는 매우 풍부하다.

첫 번째 프로토 타입은 플라스틱 도시락 상자 안에 지어졌습니다. 그것은 아두 이노 나노 사용 원격 제어를 적외선. 그것은 사용 MPU6050 로봇의 방향을 검출하기위한 관성 측정 유닛. 균형은 매우 잘 작동하지만, 적외선 원격 제어는 매우 비실용적이고 신뢰할 수 있었다.

내가 대해 알게되었을 때이 프로젝트는 부활 ESP8266 , 매우 강력한 코어의 저렴한, 와이파이 활성화 마이크로 컨트롤러. 웹 개발에 대한 배경을 갖는, 와이파이 연결이 나에게 가능성의 세계처럼 보였다.

전통적 아두 이노 커뮤니티 원격 제어 로봇은 블루투스 통신을 이용하여 구현되어왔다. 그러나, 이것은 실질적으로 컨트롤러 소프트웨어를 각 플랫폼에 개별적으로 구현되어야한다는 것을 의미한다 (안드로이드, 아이폰 OS, PC 등)

HTML과 자바 스크립트로 구현 웹 애플리케이션은 점점 더 인기를 끌고있다. 이유 중 하나는 휴대 성이다. 웹 응용 프로그램을 한 번 작성되면, 그것은 충분히 좋은 웹 브라우저가있는 모든 플랫폼에서 실행할 수 있습니다.

ESP8266은 WiFi 액세스 포인트로 구성 될 수있다. 하나는 웹 응용 프로그램 서비스를 제공하기 ESP8266이 가능하고, 정적 페이지를 제공하는 HTTP 서버를 설정할 수 있습니다. 로봇 제어 소프트웨어는 웹 응용 프로그램으로 구현 된 경우 이제 상상! 그건 내 프로젝트 ESPway 뒤에 키 생각이다.

이 작은 로봇에 대한 코드와 회로도를 찾을 수 있습니다 GitHub의에 . 구축 개발 및 소프트웨어 사용에 대한 사전 설명이 있습니다. 또한이 사용자 설명서의 어떤 종류를 짓고 있어요. 이 프로젝트는 또한 한 레딧에 논의 나는 비디오를 게시 할 때 얼마 전에.

안전 제일

깊은 기술적 인 세부 사항에 다이빙하기 전에, 그래도 난 당신이 스스로를 구축하려고하는 경우 안전에 대해 경고한다.

전자 및 소프트웨어는이 글을 쓰는 현재의 (저전압 차단 제외) 안전 기능이 포함되어 있지 않습니다. ESP8266의 펌웨어 (이것은 아마도 수 / 노점을 충돌하는 경우  일), 회전에서 모터를 중지 아무것도 없다. 이 로봇은 작은 및 그 주변을 손상하지 충분히 빛이 내 경우에는 특별한 문제가되지 않습니다. 그러나,이 로봇의 크고 무거운 버전을 제작하기 전에 안전을 고려하시기 바랍니다. 하나는 아마도 소프트웨어 오류의 경우에 모터를 차단 할 몇 가지 안전 장치 시스템을 구현할 수 있습니다.

전자 및 기계

이 로봇 부품의 대부분은 이베이 나 AliExpress에서 공급된다. 전체 회로도는 GitHub의에서 찾을 수 있습니다. 이 프로젝트의 목표 중 하나는 가능한 한 간단하고 저렴한 전자를 유지했다.

로봇의 핵심은 ESP8266 마이크로 컨트롤러가있다. 그것은 독립 구성 요소로 사용되지하지만 거기 WEMOS D1 미니보드. 그것은 USB 커넥터와 펌웨어를 업로드하기위한 USB-에-UART 컨버터를 가지고있다.

MPU6050는 방위 센서로서 사용된다. 그것은 I2C를 통해 통신, 사용 가능한 저렴한 브레이크 아웃 보드의 많음이있다. 나는 GY-521라는 하나를 데 사용합니다.

모터는 통합 금속 기어 박스와 평범한 오래된 DC 모터입니다. 공칭 회전 속도는 300 rpm으로, 그리고 그들은 6V에 대한 평가된다. 하나는 “N20의 300RPM”또는 “12ga의 300RPM”를 검색하여 이러한 모터를 찾을 수 있습니다.

모터가 구동되어 L293D 듀얼 H 브리지 모터 드라이버 IC. 그 로봇을 구축 할 때 내가 손에 가지고 무엇 때문에이 IC는 주로 선택되었다. 바이폴라 트랜지스터의 출력은 다리를 건너 큰 전압 강하를 생산 이제 나는 배웠다. 결국 내가 가진 드라이버 교체 할 수 있습니다 DRV8833 MOSFET 출력을 가지고있다.

나는 로봇에 전력을 공급하기 위해 2 셀 리튬 폴리머 배터리를 사용하고 있습니다. 완전히 충전 된 때 ~ 8.4 볼트를 제공합니다. 전지 전압은 ESP8266의 아날로그 입력을 통해 모니터되고, 배터리 전압이 소정의 임계 값 아래로 떨어질 때, 모터를 차단하는 선택적인 특징이있다. 즉 리튬 폴리머 배터리를 사용하는 것이 일반적이다. 아날로그 입력 범위는 0-1 볼트이다. 3.3 다음 D1 미니 보드, 이미 1의 비율로 분압기있다. 따라서 I은 아날로그 입력 범위에 적합하도록 배터리 전압 스케일링 1:10 비율로 수정 한 저항을 추가했다.

마지막으로,이 WS2812B의 NeoPixels은 로봇의 “눈”으로 추가됩니다. 그들은 (OTA 업데이트 등을 진행있을 경우이 떨어진 경우) 로봇의 현재 상태를보고 매우 유용 증명

크기와 무게의 최적화를 설계 목표로 설정 한 것을 다른 역학에 대해 말을 많이가 아니다. 프로토 타입 몸은 4mm 합판의 일부 조각의 내장 및 에폭시와 함께 붙어있다.

로봇의 일반보기

소프트웨어 플랫폼

현재 자원과 ESP8266에 소프트웨어를 개발하기위한 지원의 재산이있다. 제조업체 Espressif하는 RTOS없이 운영 체제와 다른 하나 하나가 제공하는 두 개의 SDK가 있습니다. 도있다 아두 이노 코어 의 심바 크로스 플랫폼 RTOS 프레임 워크와 MicroPython은 . 새로운 언어와 프레임 워크가 큰 인 지금 가끔씩 튀어 나올 것 같다!

이 로봇에 대한 몇 가지 프로토 타입을 사용하여 아두 이노 코어에서 수행 된 PlatformIO를 빌드 시스템으로. 프로토 타입 작업은에서 찾을 수 있습니다 해당 지점 GitHub의의 REPO의.

그러나 최대의 유연성과 제어를 위해, 나는 제조업체의 “비 OS”SDK로 전환. 하나는이 마이크로 컨트롤러와 함께 얻을 수있는 즉 약으로 기본입니다. 나는 특히,이 SDK에 사용할 멋진 도서관이 있었다 찾을 수 기쁘게 생각 libesphttpd 간단한 HTTP 서버와 파일 시스템을 구현한다. 그것은 또한 웹 소켓 통신 시설을 갖추고으로이 프로젝트를위한 안성맞춤이었다.

모바일 웹 UI

로봇에 전원을 공급하고, WiFi 액세스 포인트에 클라이언트 장치를 연결 한 후, 하나는 기본 IP 주소에서 웹 브라우저 사용자 인터페이스를 열 수 있습니다 192.168.4.1.

나는 가능한 한 간단하게 UI를 유지하기 위해 노력했다. 그것은 본질적으로 HTML5 캔버스에 그려진 가상 “조이스틱”로 구성되어 있습니다. 터치 디바이스에서 휴대 전화 등, 꽤 직관적 인 느낌.

조정에 사용되는 사용자 인터페이스.

의 URL에서 로봇의 PID 매개 변수의 온라인 튜닝을위한 UI도 있습니다 /pid. 그것은 진행중인 작품이지만, 반 사용 가능한 상태에서 이미. 그것은 본질적으로 펌웨어를 매개 변수가 변경 될 때마다 다시 깜박하지 않고 한 번에 로봇을 조정 할 수 있습니다. 하나는 UI를 통해 플래시 메모리에 조정 매개 변수를 저장할 수 있습니다.

초기 PID 튜닝 사용자 인터페이스를 제공합니다.

웹 소켓을 통해 대기 시간이 짧은 통신

아마이 프로젝트의 가장 흥미로운 부분은 낮은 지연 시간 원격 제어를 달성하는 방법이다.

전통적으로 사람들은 ESP8266에 HTTP API가 어떤 종류의를 구현하고있다. 그것은 각 명령에 대해 별도의 URL가 있다는 것을 의미한다. 예는 로봇 차, 같은 URL이있을 것 /forward/backward/stop/turn-left/turn-right등 다음 만들 것 클라이언트 응용 프로그램 AJAX의 로봇을 제어하는 요청을. 그러나, TCP 연결을 열고 모든 명령에 구문 분석 HTTP 헤더가있을 것입니다 의미합니다. 즉, 불필요한 오버 헤드 및 지연을 도입한다. 이 컨트롤은 그런 식으로 매우 부드러운 없을 것이다.

더 나은 대안은 열려있는 TCP 소켓을 유지하고 두 방향으로 그것을 통해 정보를 전송하는 것입니다. ESP8266 원시 TCP 통신을위한 일류 지원을하고 있지만, 자바 스크립트 하나는 원시 TCP 소켓을 열 수 없습니다. 대신있다 WebSockets를 정의 된 핸드 쉐이킹 프로토콜 및 데이터 프레임 포맷 첨가 TCP 소켓이다. 때문에 libesphttpd웹 소켓 구현을 가지고, 나는이 세부 사항에 대해 걱정하지 않았지만, 단지 데이터 패킷을 교환한다.

데이터 패킷의 첫 번째 바이트에 해당되는 명령을 표시하고, 이후의 추가 바이트 데이터이다 : 거기 로봇와 UI 사이에 통신하는 매우 단순한 프로토콜이다. 부가 데이터의 길이는 각각의 명령에 대한 알려진 고정된다. 예를 들어, 클라이언트에 의해 전송 된 “스티어링”데이터 패킷은 3 바이트로 구성 첫 번째 바이트 (즉, 같은 코드로 정의되어 제로 STEERING). 두번째 바이트는 원하는 속도를 나타내고, 세 번째는 회전 속도를 나타내는 (네거티브 = 좌, 포지티브 = 우측). 이 경우, 두 번째 및 세 번째 바이트는 8 비트 부호있는 정수로 해석된다. 데이터 바이트의 해석은 문제의 명령에 따라 달라집니다.

부드러운 양방향 통신을 감안할 때, 하나는 멋진 모든 종류의 것들을 구현할 수 있습니다. 예를 들어, 로봇은 클라이언트 웹 응용 프로그램에서 배터리 모니터링을 허용, 연결된 모든 클라이언트에 현재 배터리 독서를 보낼 수 있습니다. 또한, 가장 실용적인 것들 중 하나는 PID 컨트롤러 매개 변수의 온라인 튜닝이다.

데이터 바이트의 C 코드, 조작 및 천연 재 해석된다. 자바 스크립트에서는, 이진 데이터는로 표현되는 ArrayBuffer원시 이진 데이터의 블록의 표현은 본질적이다. 액세스 및 수정하려면, 하나는 사용할 수 있습니다 DataView기본 바이너리 버퍼에 바이트 수준의 액세스를 제공한다. 하나는 예를 들어 “바이트의 16 비트 부호없는 정수 (리틀 엔디안)로 13 쓰기 버퍼의 처음부터 오프셋 2″라고 할 수있다. 나는 자바 스크립트 API를 제공 낮은 수준의 제어가 찾을 수 놀랐다.

고정 소수점 센서 퓨전

I2C를 통해 MPU6050와 통신하는 것은 쉽다. 하나는 1 kHz에서 업데이트되는 세 축의 가속도와 자이로 측정치를 포함하는 하드웨어 레지스터를 판독 할 수있다. 배향으로이 값을 변환하는 과정은 “센서 퓨전”라고한다. 거기를 수행하는데 사용될 수 센서 자체로 신호 처리 코어이고,이 우수한 I2Cdevlib것을 구현한다. 그러나, 내가하고 싶지 않은 무언가 센서에 바이너리 펌웨어 덩어리를 업로드해야합니다. 또한, 그 알고리즘은 미가공 데이터는 1 kHz에서 사용할 경우에도 200 Hz의 샘플링 레이트만을 할 수있다.

주어진 ESP8266가 가진 32 비트 코어를 가지고 16 * 16 -> 32 비트 곱셈 확대, I 센서 융합하는 대신에 구현 될 수 있다고 생각. 가장 특히, 선택할 수있는 많은 알고리즘이 있습니다 보완 필터 , 칼만 필터 와 Madgwick 필터 . 후자는 독창적으로 작동 최첨단 신규 알고리즘 쿼터니온 방향의 표현. 또한이 시작하는 데 사용할 수 몇 가지 예제 코드이었다, 그래서 Madgwick 알고리즘이 선택되었다.

ESP8266는 부동 소수점 유닛이 골대를 벗어났습니다하고, 부동 소수점 연산은 소프트웨어로 구현해야합니다. 즉, 복잡한 비즈니스 컴파일러 지원 라이브러리에서 수행되었지만, 그것은 아주 느리다. 따라서, 나는 완전히 알고리즘의 부동 소수점 숫자의 사용을 방지하기 위해 원했다. 따라서 나는 Q16.16에 샘플 코드를 번역하기로 결정했습니다 고정 소수점 숫자 표현을 . 고정 점은 우리가 기본적으로 정수를 위해 노력하고 있지만, 16 최하위 바이트가 소수 부분으로 촬영 한 것을 의미한다.

구현에 대한 하나 개의 좋은 실용적인 세부 다음 Madgwick 알고리즘에, 하나는 어떤 경우에 벡터와 사원 수를 정상화해야한다. 이 경우 정규화는 제곱근으로 나눈 것을 의미한다. ESP8266의 핵심은 하드웨어 부문을 가지고 있지 않기 때문에이 소프트웨어에서 구현 될 필요가 있습니다. 동일은 제곱근에 적용됩니다. 우리는 어떻게 든 그것을 피할 수있는 경우에 따라서는 개별적으로 두 작업을 수행하는 것이 훨씬 이해가되지 않습니다. 반면에, 곱셈 연산의 측면에서 상대적으로 저렴합니다. 제곱근 나누면 제곱근의 역수를 곱한 것과 같다. 즉 여기에서 이루어졌다 무슨 – 상호 제곱근 함수의 라인을 따라 구현 이 StackOverflow의 대답 .

캐스케이드 PID 제어

어떻게 로봇이 실제로 균형을 유지합니까? 지금까지 우리는 로봇의 방향의 좋은 평가가 있습니다. 어떻게 든 적합한 모터 출력 신호로 변환되어야한다.

대답 할 두 가지 질문이 있습니다 :

  1. 로봇의 기울기 각도는 균형을 유지하기 위해 무엇을해야 하는가?
  2. 어떤 모터 출력 전력은 소정 경사각을 달성해야 하는가?

캐스 캐 이드 :이 자연스럽게 종종 자기 밸런싱 로봇에 구현 된 제어 전략에 이르게 PID 컨트롤러 . PID 제어에 대한 소개, 나는 기사 추천 박사 학위없이 PID를 팀 웨스콧에 의해. 본질적으로, 제 제어부는 입력으로서 원하는 속도를 취득하는 속도를 달성하기 위해 경사 각도를 제어한다. 바람직한 경사각은 그 각도를 달성하기 위해 모터 출력을 조정하는 제 제어기에 공급된다.

물론, 상기 제 2 제어부는 MPU6050 관성 측정 유닛을 통해 피드백을 얻는다. 한편, 현재 속도의 피드백을 얻는 것은 사소한 일이 아니다. 하나는 모터 샤프트에 회전 인코더를 설치하여 그것을 달성 할 수있다. 비용을 최소화하고 회로를 단순화하기 위해, 나는 그것을 밖으로 떠났다. 대신에, 내 코드에 사용되는 조 근사있다 : 속도 피드백이 단기 변동을 취소하기 위해 평활화 모터 구동 신호로부터 취해진 다. 이 사실은 놀라 울 정도로 잘 작동합니다!

또한, 단순한 형태의 게인 스케줄링은 로봇이 낙하하려고하는 상황에서 사용된다. 높은 비례 이득 PID 계수들의 상이한 세트는 다시 안정성을 달성하기 위해로드된다. 아래의 비디오 (일부 fallovers와 함께) 당신은 행동에서 볼 수 있습니다.

여기에 설명 된 제어 방식은 자기 밸런싱 로봇을 구현하는 유일한 방법은 아니다. 참고 이 문서 로봇의 동적 모델을 기반으로 제어 방식과 비교합니다.

소프트웨어 드라이버

마지막으로을의이 ESP8266 프로그래밍의 일부 실용성을 논의하자.

이 마이크로 컨트롤러에 하나의 문제는 하드웨어 주변의 부족이다. 특히, 칩상의 I2C 또는 PWM 어떠한 하드웨어 구현은 없다. 그들은 소프트웨어로 구현되어야한다. 문제는 매우 동일한 프로세서 코어 끊임없이 무선 통신을 처리하는 것으로한다. 그래서, 다른 소프트웨어 루틴은 와이파이 인터럽트에 의해 중단 얻을 수 있습니다. I2C 및 PWM 모두 타이밍에 대한 중요하기 때문에 그것은 약간의 문제입니다.

PWM 및 I2C의 소프트웨어 구현은 Espressif SDK와 함께 번들로 제공됩니다. 그러나 글을 쓰는, 그들은 어떤 식 으로든하거나 비효율적에 결함이 있습니다. 다행히, 지역 사회에서 어떤 똑똑한 사람들은 자신의 드라이버를 출시했다. I 사용하여 결국 ESP8266_new_pwm정확한 타이밍 안정된 PWM 신호를 실현할 NMI 인터럽트를 사용 스테판 브루엔스 의해. 모터는 2 kHz에서 PWM으로 공급된다.

I2C를 들어,라는 빠른 조립 구현 brzo_i2c파스칼 커턴스키으로 사용 하였다. 나는 I2C 거래 중에 완전히 비활성화 인터럽트 때문에 처음에는 I2C 드라이버에 약간의 문제가 있었다. 이는 결국 일부 WiFi를 발사 할 수없는 방해 아마도에, 펌웨어 충돌로했다. 즉, 쉽게 인터럽트를 비활성화 명령을 주석에 의해 수정되었습니다. 즉, I2C 타이밍을 타협하지만, 실제로는 모든 것이 매우 잘 작동하고있다.

피드백

이 문서에서 설명하는 무언가의 더 정교한 설명을 좋아하거나 해결하기 위해 발견 뭔가를했을 경우,이 사이트에 문제를 제기하십시오 GitHub의의의 repo . 당신은 또한에 연락처 찾을 수 있습니다 이 페이지를 . 모든 의견은 매우 환영하고 감사합니다.

ESPway | A Segway-style WiFi controlled robot built on ESP8266

Ever since I started tinkering with Arduino and embedded systems, I’ve been pretty excited about building a self-balancing, Segway-like robot. There’s a wealth of similar projects and resources around the Internet.

The first prototype was built inside a plastic lunch box. It used an Arduino Nano and infrared remote control. It used the MPU6050 inertial measurement unit for detecting the orientation of the robot. The balancing worked very well, but the infrared remote control was quite impractical and unreliable.

The project was revived when I learned about ESP8266, a cheap, WiFi enabled microcontroller with a pretty powerful core. Having some background in web development, the WiFi connectivity looked like a world of possibilities to me.

Traditionally in the Arduino community, remote controlled robots have been implemented using Bluetooth for the communication. However, this practically means that the controller software has to be implemented separately on each platform (Android, iOS, PC, etc.)

Web applications implemented with HTML and JavaScript are becoming more and more popular. One of the reasons is the portability. When the web app has been written once, it can be run on any platform which has a good enough web browser.

The ESP8266 can be configured as a WiFi access point. One can set up a HTTP server serving static pages, making the ESP8266 able to serve web apps. Now imagine if the robot control software was implemented as a web application! That is the key idea behind my project ESPway.

The code and schematics for this little robot can be found on GitHub. There are preliminary instructions on building, developing and using the software. I’m also building some kind of a user manual there. The project was also discussed on Reddit a while ago when I posted the video.

Safety first

Before diving deeper in the technical details, I though I should warn you about safety in case you are going to build this yourself.

The electronics and software don’t contain any safety features (except low voltage cutoff) as of writing this. If the firmware on the ESP8266 crashes / stalls (it can and probably will happen), there’s nothing stopping the motors from spinning. This is not a particular issue in my case where the robot is small and light enough to not damage its surroundings. However, please consider the safety before building a larger and heavier version of this robot. One could probably implement some failsafe system which would shut off the motors in case of a software failure.

Electronics and mechanics

Most of the parts for this robot are sourced from eBay or AliExpress. The complete schematic can be found on GitHub. One of the goals of this project was to keep the electronics as simple and cheap as possible.

At the core of the robot there is the ESP8266 microcontroller. It is not used as a standalone component but there’s a WEMOS D1 mini board. It has a USB connector and a USB-to-UART converter for uploading the firmware.

The MPU6050 is used as the orientation sensor. It communicates via I2C, and there’s a plenty of affordable breakout boards available. I used one called GY-521.

The motors are plain old DC motors with an integrated metal gearbox. The nominal revolution rate is 300 rpm, and they are rated for 6V. One can find these motors by searching for “n20 300rpm” or “12ga 300rpm”.

The motors are driven by the L293D dual H-bridge motor driver IC. This IC was chosen mostly because that’s what I had at hand when building the robot. Now I’ve learned that the bipolar transistor outputs produce a significant voltage drop across the bridge. Eventually I’ll replace the driver with a DRV8833 which has MOSFET outputs.

I’m using a 2-cell LiPo battery for powering the robot. It gives ~8.4 volts when fully charged. The battery voltage is monitored via the analog input of the ESP8266, and there’s an optional feature to cut off the motors when the battery voltage falls under a certain threshold. That’s common practice used with LiPo batteries. The analog input range is 0-1 volts. On the D1 mini board, there already is a voltage divider with a ratio of 1:3.3. Hence I only had to add one resistor to modify the ratio to 1:10, which scales the battery voltage to fit the analog input range.

Finally, two WS2812B NeoPixels are added as the “eyes” of the robot. They have proven quite useful for reporting the current state of the robot (if it has fallen, if there’s OTA update in progress etc.)

There’s not much to say about the mechanics, other that that optimization of size and weight were set as design goals. The prototype body was built out of some pieces of 4mm plywood and glued together with epoxy.

A general view of the robot

Software platform

Nowadays there is a wealth of resources and support for developing software on the ESP8266. There are two SDKs offered by the manufacturer Espressif, one with a RTOS and the other one with no operating system. There is also an Arduino core, the Simba cross-platform RTOS framework and MicroPython. New languages and frameworks seem to pop out every now and then, which is great!

Some prototyping for this robot was done on the Arduino core, using PlatformIO as the build system. The prototyping work can be found in the corresponding branch of the GitHub repo.

However, for maximum flexibility and control, I switched to the manufacturer’s “non-OS” SDK. That is about as native as one can get with this microcontroller. I was pleased to find there were some great libraries available for this SDK, particularly libesphttpd which implements a simple HTTP server and a filesystem. It was a great fit for this project as it also features WebSocket communication facilities.

Mobile web UI

After powering on the robot and connecting a client device to the WiFi access point, one can open the user interface with a web browser at the default IP address 192.168.4.1.

I tried to keep the UI as simple as possible. It essentially consists of a virtual “joystick” drawn on a HTML5 canvas. On a touch device such as a mobile phone, it feels quite intuitive.

The user interface used for steering.

There is also a UI for on-line tuning of the robot’s PID parameters at the url /pid. It is a work in progress, but it’s already in a semi-usable state. It essentially allows tuning the robot in one pass without re-flashing the firmware every time the parameters are changed. One can save the tuned parameters to the flash memory via the UI.

The initial PID tuning user interface.

Low latency communications via a WebSocket

Probably the most interesting part of this project is the method of achieving low latency remote control.

Traditionally people have been implementing some kind of HTTP APIs on the ESP8266. It means that there’s a separate URL for each command. E.g. for a robot car, there would be URLs like /forward/backward/stop/turn-left/turn-right etc. The client application would then make AJAX requests to control the robot. However, that means there would be a TCP connection opened and a HTTP header parsed on every command. That introduces unnecessary overhead and latency. The control would not be very smooth that way.

A better alternative is to keep the TCP socket open and send information over it in two directions. While the ESP8266 has first-class support for raw TCP communication, in JavaScript one can’t open raw TCP sockets. Instead there are WebSockets which are TCP sockets added with a defined handshaking protocol and a data frame format. Because libesphttpd has a WebSocket implementation, I didn’t have to care about these details but just exchange data packets.

There’s a very simple protocol in the communication between the robot and the UI: the first byte of a data packet indicates which command is in question, and the subsequent bytes are additional data. The length of the additional data is known and fixed for each command. For example, a “steering” data packet sent by the client consists of three bytes: the first byte is zero (that’s defined in the code as STEERING). The second byte indicates the desired speed and the third one indicates turning rate (negative = left, positive = right). In this case the second and third byte are interpreted as 8-bit signed integers. The interpretation of the data bytes depends on the command in question.

Given smooth two-way communication, one can implement all kinds of cool things. For example, the robot can send the current battery reading to all connected clients, allowing battery monitoring in the client web app. Also, one of the most practical things is on-line tuning of the PID controller parameters.

In the C code, manipulation and reinterpretation of the data bytes is natural. In JavaScript, binary data is represented as an ArrayBuffer which is essentially a representation of a block of raw binary data. To access and modify it, one can use a DataView, which gives byte level access to the underlying binary buffer. One can e.g. say “write 13 as a 16-bit unsigned integer (little Endian) at byte offset 2 from the beginning of the buffer”. I was actually surprised to find there is such low level control available in the JavaScript APIs.

Fixed-point sensor fusion

Communicating with the MPU6050 via I2C is easy. One can read the hardware registers which contain acceleration and gyro readings on three axes that are updated at 1 kHz. The process of translating these values into an orientation is called “sensor fusion”. There is a signal processing core in the sensor itself that could be used to do that, and the excellent I2Cdevlib implements that. However, that requires uploading a binary firmware blob on the sensor, which is something I did not want to do. In addition, that algorithm is only capable of 200 Hz sample rate even though the raw data is available at 1 kHz.

Given that the ESP8266 has a 32-bit core with 16*16 -> 32-bit widening multiplication, I thought the sensor fusion could be implemented on that instead. There are many algorithms to choose from, most notably the complementary filterKalman filter and Madgwick filter. The latter is a state-of-the-art novel algorithm which works cleverly with the quaternion representation of the orientation. Additionally there was some sample code available to get started with, so the Madgwick algorithm was chosen.

The ESP8266 misses a floating point unit, and the floating point operations must be implemented in software. That complex business has been done in the compiler support libraries, but it is quite slow. Hence, I wanted to entirely avoid the usage of floating point numbers in the algorithm. Therefore I chose to translate the sample code to the Q16.16 fixed point number representation. Fixed point means that we’re essentially working integers but the 16 least significant bytes are taken to be the fractional part.

One nice practical detail about the implementation: in the Madgwick algorithm, one has to normalize vectors and quaternions on some occasions. Normalization in this case means dividing by a square root. ESP8266’s core doesn’t have hardware division, so it has to be implemented in the software. The same applies for the square root. Thus it doesn’t make much sense to do both operations individually if we could avoid it somehow. On the other hand, multiplication is relatively cheap in terms of operations. Dividing by the square root is equivalent to multiplying by the reciprocal of the square root. That’s what was done here – a reciprocal square root function was implemented along the lines of this StackOverflow answer.

Cascade PID control

How does the robot actually maintain the balance? So far we have a nice estimate of the orientation of the robot. It has to be somehow translated to a suitable motor output signal.

There are two questions to answer:

  1. What should the tilt angle of the robot be in order to stay balanced?
  2. What should the motor output power be to achieve the desired tilt angle?

This naturally leads to a control strategy that is often implemented in self-balancing robots: a cascaded PID controller. For an introduction on PID control, I recommend the article PID without a PhD by Tim Wescott. Essentially, the first controller gets the desired velocity as an input and controls the inclination angle to achieve that velocity. The desired inclination angle is fed to a second controller which regulates the motor output power to achieve that angle.

Naturally, the second controller gets feedback via the MPU6050 inertial measurement unit. On the other hand, getting feedback of the current velocity is not a trivial task. One could achieve that by installing rotation encoders on the motor shafts. In order to minimize the cost and simplify the circuitry, I left that out. Instead, there’s a crude approximation used in my code: the velocity feedback is taken from the motor drive signal which is smoothed in order to cancel short-term variations. This actually works surprisingly well!

In addition, a simple form of gain scheduling is used in situations where the robot is about to fall. A different set of PID coefficients with higher proportional gain is loaded in order to reach stability again. You can see this in action (along with some fallovers 😉 in the video below.

The control scheme described here is not the only way to implement self-balancing robots. See this articlefor comparison with a control scheme based on a dynamic model of the robot.

Software drivers

Last but not least, let’s discuss some practicalities of programming the ESP8266.

One problem with this microcontroller is the lack of hardware peripherals. In particular, there are no hardware implementations of I2C or PWM on the chip. They have to be implemented in software. The problem is that the very same processor core has constantly handle the WiFi communication. So, any other software routine might get interrupted by the WiFi interrupts. That’s a bit of a problem since both I2C and PWM are critical about timing.

Software implementations of PWM and I2C are bundled with the Espressif SDK. However, as of writing, they are flawed in some way or just inefficient. Luckily, some smart people in the community have rolled their own drivers. I ended up using ESP8266_new_pwm by Stefan Bruens, which uses NMI interrupts to realize a stable PWM signal with correct timing. The motors are fed with 2 kHz PWM.

For I2C, a fast assembly implementation called brzo_i2c by Pascal Kurtansky was used. I had some problems with the I2C driver at first since it completely disabled interrupts during I2C transactions. That eventually led to the firmware crashing, probably due to some WiFi interrupt not being able to fire. That was easily fixed by commenting out the instruction that disabled the interrupts. That compromises the I2C timing, but in practice everything has been working very well.

Feedback

If you would like a more elaborate description of something described in this article or have found something to fix, please file an issue on this site’s GitHub repo. You can also find contact details on this page. Any feedback is very welcome and appreciated.

LED Matrix Bar Weather Station V1

Features:
– ESP8266 WeMos Dq mini module which I finally found good application for (now you can buy better cheap ESPs)
– 6 x LEDMatrix module with MAX7219 driver
– supplied directly from USB port with USB plug
– all data are synchronized every 7-8 minutes
– time and date are taken from google.com
– weather informations are grabbed from openweather.org JSON api
– in the future also other news and infos grabbing can be possible
– no hardware RTC clock is necessary
– responsive web(UI) design

+ internal temperature, humidity sensor (options – DS18B20, DHT22, DHT12)
+ ESP8266 setup as a Wi-Fi Web Server (WiFiManager, OTA, mDNS)
+ receives a message input from a User Input page, then displays the message on a scrolling LED matrix display.

– 6 x MAX7219 8 x 8 LED Matrix module
– 1 x WeMos D1 mini
– 1 x Interface Shield

Source code is available here:
The code is being cleaned up. Please wait… I’ll share it soon.

3D Parts:
https://www.thingiverse.com/thing:2650808

 

NOTE: Recently added support for rotated LED Matrices

Inspired by and source code from:
https://www.youtube.com/watch?v=2I_us…

저장저장

저장저장

Polargraph Drawing Machine

This machine, a variation on the hanging-pen plotter is a conspicuous and wilfully naive attempt to break out of the pristine, pixel perfect, colour-corrected space that exists inside our computers. It’s a drawing machine, that takes a pen (a human tool) and uses it to draw in a singularly robotic way, with some grand results.

It doesn’t draw at all like we would (though it could), and we would struggle to draw exactly as it does (though we could).

It can draw on things bigger than itself – the question is really “how long is a piece of string?” when it comes to working out it’s maximum area.

It’s easier to look at what it does, than to explain it, so just have a look.

Step 1: History

Well there have been lots of new drawing machines doing the rounds lately, there’s a real thirst to see devices that leap out of the virtual into the
physical. For me, it’s all too easy to produce digital things which are interesting – programming or mash-ups or virtual experiments are devalued because they are intangible, you can run a hundred, a thousand, a million variations in a day – it’s the proverbial roomful of monkeys with typewriters. The output becomes disposable, it get’s hard to see the value, the craft.

So 3D printers and other desktop manufacturing tools and technologies (laser cutters etc) have got more and more popular, it’s hard to overestimate how much hunger there is for a tangible, physical, touchable, smellable product of all this clever-clever digital work.

So this isn’t wholly original, check out this prior art for more inspiration:

Hektor – the daddy of all hanging drawing machines
Der Kritzler – the smartest one yet
AS220 Drawbot – the basis for mine
SADBot – Instructable for an automatic drawing machine on the same pattern by Dustyn Roberts

But this is the original Polargraph! The term is a portmanteau word invented for this instructable, and it has caught on. People who don’t know their drawbot history often use the word to describe any hanging-v plotter, but it is actually means something very specific: A machine that runs the Polargraph software.

Mostly based on the success of this instructable, I started a little workshop making Polargraph parts, and the next-generation Polargraph gear (PolargraphSD). Couple of links below:

Polargraph website
Polargraph wiki and code
Flickr stuff

Step 2: Parts

There’s a hundred different ways of making a machine like this, but I’m going to show you how I make mine, as a jumping off point. I hope you’ll see some places it can be improved.

Electronics.

  • Microcontroller – Arduino Uno or compatible. I’ve used a Seeeduino here. (from coolcomponents). Be aware that some “arduino compatible” boards that use FTDI chips are only really Arduino Duemilanove compatible – they have very slightly less memory, so the Polargraph code no longer fits on it.
  • Motor drivers – Adafruit’s Motoshield v1. A modern classic. It can drive two stepper motors each drawing up to 600mA and has pinouts for a servo too, so is perfect for this project. This is now discontinued by Adafruit, but boards like them are widely available on ebay (search for “L293D motor shield arduino”). Adafruit _do_ make a new motorshield that is even better, but I haven’t got one to test one.
  • Motors – Look for motors with a current rating of around 600mA (0.6A).  Mine were 400 steps per revolution (0.9 degree per step), NEMA 16 stepper motors, with a 5mm diameter shaft off ebay, but something like this NEMA-17 with a 0.4A current rating would do nicely, as would this one from Adafruit.Power supply. 1 amp (1000mA) Variable voltage AC/DC power supply. Set the voltage as high as you dare. If things start getting hot, just turn it down a bit. 9v will be fine, 12 may be pushing it, but it depends on your motors really. At peak, the machine might be drawing 1.2 amps (2x 600mA), so you might benefit from a beefier-than-average power supply. That said, it ran for months on a 600mA supply before I did something silly and it stopped. (expro.)

Gondola.

  • This is the pen holder. I am from the “heavy and stable” school of thought. I think it makes for a more definitive impression, and a cleaner line.
  • 3x 6003Z deep groove bearings. (simplybearings.co.uk)
  • 50mm length of K&S stock #144 brass tubing (21/32″, 16.66mm dia). (hobbies)
  • Laser cut acrylic parts.  The original is made of corrugated cardboard and a blank CD, just glued on, so this is by no means necessary. (Ponoko)

Running gear.

  • Beaded cord.  This is used in roller blinds.  (ebay – a shade better).  You could use metal ball chain if it matches the pitch.
  • Sprockets. Don’t seem to exist off-the-shelf, so I made these 3D printed ones (shapeways).
  • Counterweights.  I used a bolt with a stack of washers hung on it.

Hardware.

  • Surface – big flat surface to base your machine on.  Discussed in the next step.
  • Brackets – laser cut plywood to allow the motors to be fastened to a flat wall.  If you are mounting on a board, you might be able to just simply stick the motors directly on the top edge of the board. (Ponoko)

Step 3: Sprocket up!

I couldn’t find a source for these beaded cord sprockets.  Roller blind mechanisms have them in, but not in an easily usable form.  I made my own and had them printed through Shapeways.  John Abella has made a parametric sprocket suitable for other bead spacings that can be 3d printed at home if you have access to something like a makerbot or a reprap.

Push-fit a sprocket onto the 5mm shaft of the motor.

Step 4: Prepare your motors

Strip the ends of the motor wires and tin them. Unless you have very long wires already on them, you’ll be extending them, and use whatever is to hand to do it – in my case, I used plain screw terminals.  Make sure you label your extension cable too.

Step 5: The drawing surface

Find a big board or something to use as your surface.  Your board should be at least 150mm bigger on each side than the largest sheet of paper you want to draw on.

You can use a wall if you have some motor mounting brackets, but I was always terrified about it going wrong and scrawling marker pen over my wall.  My landlady would be unimpressed, I feel.

Using a board means you can tilt it slightly too just by leaning it against the wall, and that’s a good thing because the weight of the gondola presses the pen to the page.  When the surface is perfectly vertical, it’s hard to get any pressure against the page – the lines tend to come out a pretty woolly.

I went down the local DIY shed and scavenged in the offcuts bin for the biggest bit of chipboard I could fit in my little car, but I’ve also had good success with building a machine based on the biggest IKEA Ribba picture frame.  This has the added feature that you can use it as a picture frame afterwards, amazingly.  A whiteboard is a good alternative too, because you can test quickly, but any kind of flat surface will do.  My first one was only big enough for A3, and worked fine, so don’t feel it has to be massive.

Step 6: Mount your motors – edge style

Your motors should be mounted so that the sprockets are as close as possible to the drawing surface.  If you have a thick surface, you can get away with just sticking your motors to the top edge of the board with double-sided foam tape.  This is actually a nice way of doing it because it cushions the vibration too.  The motors do tend to twist a bit, because their little foam rafts have some stretch in them, but on mine it wasn’t really a problem unless I left the gondola hanging for days.

This arrangement is much neater when it comes to cabling and things too.  It all hangs down the back.

If you have access to a 3d printer, there is a neat stepper motor mount available at http://softsolder.com/2011/08/23/nema-17-stepper-motor-mount/.

Step 7: Mount your motors – front style

This is way I’ve come to mount the motors, and it looks a bit untidy, but it is less dependant on the type of your drawing surface – it can be stuck onto anything basically, including walls and other enormous surfaces.

I have attached plans for a motor mount to be lasercut from 3mm thick plywood, but there’s nothing clever about it except that it only slots together, so the motory bits can be removed easily, leaving the main mount plates in place.  I have got it on a Ponoko P1 sized piece of board, and you will need two of these cut.The plans for Der Kritzler include window-mountable servo holders that use suction cups.  That bracket is probably stronger than mine too, but it needs more parts to build it.

Fasten the big plates onto your surface in the top corners.  They should be exactly level.  I use double sided sticky foam tape for more or less everything, but make sure you use plenty because they are fairly heavy, and there is some vibration.

Step 8: Electronics – Arduino

You need an Arduino UNO board, I used a Seeeduino v2.21 here – it did the job very nicely back in the day, but a couple of new features have been added to the code and so it doesn’t fit on anymore. Genuine UNOs have very slightly more space for programs.

Upload the source code to the arduino. Seriously. Actually do this. Nothing will work until you do this. Do it.

Look at this fine guide courtesy of Adafruit for help. Or anywhere on Instructables, or one of the hundreds of Arduino tutorials on the web.

Because it changes regularly, I have not attached a copy of the code itself to this step, but the very most recent version can be downloaded in a bundle from the polargraph code repository. Download the file called Polargraph.___.zip.

Unzip the bundle. Inside it is a folder called arduino-source which contains (you guessed it), the source code for the arduino part of the project.

Inside arduino-source there is a folder called libraries. It contains the libraries you need (

Adafruit’s AFMotor and Mike McCauley’s Accelstepper)

It also contains a folder called polargraph_server_a1. This is the polargraph firmware source code.

Copy the contents of arduino-source/libraries into your Arduino/libraries/folder.

Copy arduino-source/polargraph_server_a1 into your Arduino/ folder.

You should have created three new folders on your disk:

  • Arduino/polargraph_server_a1/
  • Arduino/libraries/Accelstepper/
  • Arduino/libraries/AFMotor/

Start Arduino IDE.

Go to File->Sketchbook->polargraph_server_a1

Fourteen files will open up and be displayed as tabs in the IDE. This is the source code of the firmware.

Press the “verify” button in the toolbar to try and compile it.

If it compiles, press the “upload” button in the toolbar to upload it.

Of course the source code is also available in the code repository – https://github.com/euphy/polargraph_server_a1 – should you want the very most recent version, but you’ll have to figure that one out yourself.

Once you do that, you should confirm that it is working properly – use the serial monitor on the board, set to 57600 baud to make sure that it is issuing “READY” every couple of seconds (see the last image).

Step 9: Electronics – Motorshield

The motorshield is usually supplied as a kit, it’s easy to solder up, follow the instructions on the Adafruit site. It’s brilliant. I am an Adafruit fanboy, so sue me. Not much more to say about it. Adafruit discontinued the v1 motorshield in 2013. Lots of people are still selling clones of the v1 design on ebay, just search for “L293D arduino motor shield”.

(The firmware can be compiled to use the Adafruit Motorshield v2, but it’s not as good. There are instructions in the source code that show you what you need to change.)

The motorshield has two stepper motor ports, one on either side. It takes it’s power from the host arduino, but has a separate connector that you can use to connect an external power supply. If you have a power supply that has bare leads, you can screw them in here (make sure you get the polarity right) use this and remove the power jumper from beside it. I’m going to stress that the power connector is wires up properly – +V on the left hand wire, GND on the right. There is no reverse polarity protection on this board, so if you do it wrong it’s likely you’ll damage the board, and maybe your arduino too.

If you don’t use it, you should plug your external power supply directly into your arduino, and leave the power jumper ON. I am wiring directly, because it’s better practice to have entirely separate supplies for motor and logic.

I also added little heat sinks to the driver chips (L293Ds) on the motorshield. They get hot, and you can use a fan to cool them if you have one spare, and really, I don’t know if they every really get dangerous, but with heatsinks on I feel a more comfortable letting them run for hours and hours.

Step 10: Electronics – Wiring

Each motor has two circuits, or coils in it, and a bipolar stepper has four wires coming out of it, two for each circuit. Most steppers will have a datasheet that will let you know which colour wires lead to which coil. Find out, either using your datasheet, or a multimeter (a bit more about steppers, and how to figure them out on adafruit and this article helped me figure it all out.).

Mine have the red and the blue wire attached to one coil, and the white and the yellow wire on the other coil.

The two motors should be wired up with their coloured wires matching left and right. So on the left hand side, you should have wire pair 1 (red/blue) in the top two terminals, and wire pair 2 (yellow/white) in the bottom two terminals. And on the right, it’ll be exactly the same: pair 1 in the top, pair 2 in the bottom.

I stuck my arduino to a bit of foamcore board stuck on the back of my drawing surface. Just makes it a bit easier to deal with.

Push the motorshield into the arduino, and fire it up!

Step 11: Controller software – install

The setup is ready to test! The software you use to control it is a little application written in Processing. You can run this from the source code, but it’s probably easier to use one of the pre-compiled binaries that I’ve made. The most recent code bundle has the latest versions for Mac, Windows or linux. Download the file called Polargraph.*.zip (rather than the “source code” files).

(That bundle also includes all the source for the controller, and the firmware, and all the Processing and Arduino libraries you need to run from source.)

Download it, unzip it, and run the executable in the controller folder. It’ll open up very small, but maximise the window to see more. It will automatically create a default configuration file in the same folder as it runs in, and you should then click “save properties” in the top-left corner to save the new window size as the default.

Compile from source

If you’re curious about Processing, you’re right to be: It’s ace. There are useful tutorials on processing.org, and of course here on Instructables too. It’s basically java, but optimised to run little stand alone programs with graphics. If you’re interested in keeping on the leading edge of the controller development, you might like to check out the code directly from the repository and compile it yourself. Another reason: The precompiled binaries that I distribute are a little idiosyncratic, and sometimes refuse to work on some people’s machines. If you compile from source, then it’ll work at least.

Couple of notes – The controller is getting a bit long-in-the-tooth now, and I haven’t updated it to use Processing 3 yet. So in the meantime, it will only compile in Processing 2.x. Additionally, the libraries have also since moved on since it was written, and it’ll only work with the versions in the zip file (referred to above). I’m working on an update, but it’s not ready yet.

  1. Install Processing 2.2.1 (From https://processing.org/download/?processing)
  2. Run Processing, find where your sketchbook folder is: (File->Preferences, sketchbook location).
  3. Install libaries: Unzip the code bundle, and copy the contents of the processing-source/Processing libraries into sketchbook/libraries.
  4. Install project: In the code bundle, copy the whole processing-source/polargraphcontroller folder into your sketchbook folder.
  5. Restart Processing, and open the controller with File->Sketchbook->polargraphcontroller.
  6. Run: When some files have opened up and you can see some code, hit the play button in the toolbar (or use Ctrl-R) and you should see the controller spring into live.

It’ll only be a small window, so go ahead and stretch it so you can see everything. If it worked, then well done. NEXT!

Step 12: Controller software – Primer

Ok, in the controller window there are three main elements.

  1. The control panel with all the buttons down the far-left,
  2. The grey rectangle in the middle that represents the machine itself,
  3. The command queue down the right-hand side of the machine.

Some of the controls are just to do with the controller (like load image), but some (like set home or render pixel) send commands to the machine itself. Some of the controls are number spinners, click and drag up and down on them to change their value.

Move the mouse over the machine and you’ll see some lines overlaid that represent the hanging cords. You can zoom in and out from the machine using the mouse scroll wheel, and “grab” it and move it around using the middle mouse button drag.

If a command is issued to the machine, it’s held in a queue until the machine signals to say it’s ready to do something. The command queue is shown on the far right of the app window. When you first start it up, it’s in paused mode, and is pre-loaded with a couple of default settings. You can start it and stop it by clicking on the queue header (where it says COMMAND QUEUE: Paused – click to start). The queue can be emptied with the reset queue button. While the queue is paused, individual commands can be removed from it by clicking on them.

The interface is separated into three tabs, switch between them using the labels at the very top. Each tab has a different set of buttons in it’s panel.

  1. Input. Used for loading images, moving, resizing, selecting an area to draw, as well as issuing the drawing commands. Click on load image and browse to an image, (png or jpg), then move image and resize image to place it on the page.
  2. Setup. Used for defining the machine hardware. Change the machine size, the page size and position and the home point position. Also change the motor speeds and pen size. Once you’ve changed the machine on-screen to reflect the real size of your own machine, press upload machine spec to send it to the machine.
  3. Queue. Used for exporting and importing the queue to and from a text file. They are in plain text, so it’s easy enough to hack them.

Next let’s connect it up.

Step 13: Controller software – introduce it to your hardware

To get the controller to talk to the machine, change to the setup tab and then click on the serial button. This will pop up a little window with a list of the available serial ports in it. If you know which one to try, click it. If not, just go through them, waiting for a couple of seconds between each one until you see the top line of the main window turn green and show Polargraph READY!

The hardware broadcasts that it’s ready every couple of seconds, which is why you might need to wait. If you don’t want to connect it (because you haven’t got a machine yet) just choose no serial connection.

Job done! Close the serial port window and then click save properties in the control panel, so the controller remembers it for next time.

Step 14: Controller software – make it move!

Confirm you have set the right serial port, and that it’s communicating with the arduino by looking for a Polargraph READY! at the top of the window. This line will be red if it’s not connected. If you connect the machine after starting the controller, then you’ll probably need to close and restart the controller too.

If you’re running from Processing, then you should also be seeing incoming: READY in the Processing console every couple of seconds, in the background.

That’s great! Unpause the command queue, and you’ll see the first couple of commands get gobbled up by the machine, one after another. Click Set home.You’ll see a command appear in the the command queue, and then it’ll get sent to the machine right away. You will see the big purple dot that signals the location of the pen will move to the be in the middle of the top edge of the machine on-screen. The motors themselves will also give a little wriggle, and you’ll find they’re locked – they’re now under power!

Ok, now click the Move pen to point button, which is as close to a manual move command as you have, and click somewhere right down at the bottom of the machine. With luck, you will hear and see the motors whirr into life, accelerate and then decelerate back down again.

The purple spot will move too. This is where the machine thinks the pen is.

Try this again, and make sure the sprockets are moving in the right direction. When the machine is moving the pen down the page, the left-hand motor will be spinning clockwise, and the right-hand motor will be spinning anti-clockwise. When the machine is moving up the page, it’ll be the other way around.

If one, or both of your motors are going in the wrong direction, you might have got your datasheet wrong, or made an error when labelling them up or something. You just need to swap your two pairs of wires around. To be honest, trial and error is as good a way of working out the correct circuits as anything else, but it’s hard to do until you’re absolutely sure all the rest of it is working right.

Good work! I recommend a cup of tea! There’s no part of a project quite so rewarding as that first moment when it moves, or makes a noise, or electrocutes you, I think you’ll agree.

Step 15: Assemble the gondola

The gondola is the pen holder. There’s a few alternative designs out there for them, including this 3D printable one that seems to do the business nicely. My design is much heavier, and has a hollow centre so that the pen can always be in the exact point where the cords converge. In practice, I’m unclear about how much difference this makes, but it makes me feel good.

I made the first one from corrugated cardboard, and a blank CD, stuck to some ball bearings (see the last picture on this step). Later I graduated onto some fancy-dan laser cut parts (available through ponoko, or you can grab the source from the github repo), but the principle is the same. I’ve attached the design in an EPS on a ponoko P1 sized board.

The parts just slide together, and then onto a length of brass tube (see parts list). The laser cut parts have nodes in them that will need a little filing to get them on. Just be careful because the acrylic is pretty brittle. It should all push-fit together, but if it gets too loose, a few dabs of glue will keep it together. I usually put a bead of glue around the hole in the stabiliser, and then another couple of dots around the hole in the final spacer ring.

The sequence is, from bottom to top:

  1. Big stabiliser
  2. Empty bearing
  3. Spacer ring
  4. Bearing with straight cord hanger arm
  5. Spacer ring
  6. Bearing with offset cord hanger arm
  7. Spacer ring (this is the one I glue)
  8. And a plywood ring as a decorative touch

Step 16: Add cord and counterweights

The length of the cord will obviously dictate the size of your drawing. Make your cords long enough to stretch at least from your sprocket to the opposite corner of your biggest drawing paper sheet, when it’s mounted. Don’t forget to leave a couple of inches to tie/clip your counterweights on with. Just push one end into the clips on the gondola.

I use some bolts with washers on them as counterweights, but you can use anything – bags of change are a good alternative. The exact weight isn’t critical at all – this is not a finely balanced machine. The object is to have the gondola hang naturally in the upper-middle of the machine’s drawing area. My weights are around 150 grams each.

After this, you may even wear your gondola with beaded cord as if it is a steampunk arc reactor medallion. I often do, and feel very powerful at it. POW! TAKE THAT, BAD GUYS!

Ahem… Or you can just put it on the machine, draping the cords over the sprockets. You’ll need to figure out a neat way of avoiding the cables if you have front-mounted motors like me.

Step 17: Back to the drawing board

Ok, the last bits of configuration then:

  1. Measure your machine size
  2. Find your home point

Use the diagram attached to this step, and draw lines on your drawing surface in the places marked.

It’s important that the lines are all square and parallel, and your measurements are accurate. You can’t hope to get good results if you don’t have it marked out properly. As they say: Proper Preparation Prevents Poor Polargraphs. Don’t they?

Ok, so measure your machine width, in mm. This is the distance between the closest points of your sprockets. Measure from the teeth rather than from the rim. It should really be from the point where the cord hangs, but that changes all the time, so this’ll do.

Now draw a line for the top edge of your machine. It should run exactly in between your sprockets, between the two motor shafts.

Draw another horizontal line, exactly 120mm lower than your top edge you just drew. This is where you’ll put the top edge of your page. You can’t expect to draw much higher than this.

Draw a vertical line down the exact centre of your machine. Where this vertical line crosses your top edge of page line is your home point. The machine knows where it is, you know where it is. You both agree, and it’s where everything starts from.

Step 18: Finish configuring your controller

Start the controller again, and change to the setup tab.

Set:
machine width
machine height

entering the values you just measured, in millimetres. Height isn’t actually that important since it doesn’t affect the geometry, but it does affect how big it appears on your screen, so make it accurate if you can. You will be able to see the machine changing size on screen as you adjust these values.

You can also change the page width here, and the page position. Unless you have a much wider machine than this, leave page pos y as 120 though.

Other than that, page size and position is a purely visual aid to let you size your drawing properly. You can centre the page horizontally with the centre pagebutton.

The home point has a default position that is where you marked it on your board in the last step, that is, halfway across the top edge of your machine. Click centre homepoint to reset if it goes astray, and you can set it to anywhere you like if you don’t want it there (for whatever reason).

Now save properties again so you don’t have to enter this again!

Advanced editing
If you are using different motors, or different sprockets, change:

  • stepsPerRev: This is how many steps your motors have per revolution. Well, it’s actually _double_ that, because I’m using an interleaved step style in the software – it creates kind of intermediate steps. My stepper motors have 400 steps per rev, so I enter 800. Yours are probably 200, so you should enter 400.
  • mmPerRev: This is how much cord is extended per revolution. It is essentially the circumference of the sprockets, though with these beaded cords, it’s actually the length of 8 bead sections.
  • step multiplier: (not shown on the pic…) This is how many microsteps the machine can make between your big steps. For this machine, set to 1.

If you are changing these settings, you are best off restarting the app afterwards. There’s a lot of other calculations based on these figures, so a fresh start is safer.

Step 19: Upload your measurements to the machine

So now you should see the size has changed on-screen so the controller knows what the real size of your machine is. But the machine itself doesn’t!

You need to upload it by going on the setup tab, you might already be there, and clickking Upload machine spec. This saves the new size into EEPROM on the arduino, so it’ll stay there even when the power is lost. Unless you change the sizes, this is the only time you have to do that. Page size isn’t relevant here, only machine size.

If you’re curious (and why wouldn’t you be?) Download machine spec does the opposite – it set’s the machine size in the controller to be whatever the hardware has saved. This might be useful if you delete your configuration file sizes and don’t want to measure it all again.

But remember that the configuration file doesn’t ever get updated until you click save properties. So remember that if you make changes you want to keep.

Step 20: Now really make it move!

You need to calibrate the machine before each drawing session. This involves telling it where the pen is. You do this by clicking Set home on the Input tab and then physically moving the gondola so that it directly over the home point that you worked out earlier.

Clicking Set home locks the motors, it applies power, so they will hold the gondola there for as long as you want.

AND THAT’S IT!

Use Move pen to point to move the gondola around the drawing surface. The noise should be smooth, and the motion also. If you find your motors slip – most likely near the extremes of the the surface, or when you’re moving fast – you’ll need to recalibrate. As soon as the actual position of the gondola gets out of sync with where the machine thinks it is, then your geometry is all off and your drawings will be distorted.

The standard maximum speed is 600 steps per second, and the acceleration is 700 steps per second (per second). Change these values by using the number spinners on the setup tab, and then clicking send speed. These speed change commands also skip right to the front of the queue too – they’re priority, you can see them in cyan in the queue.

Step 21: Work with images

So that’s the hard bit done – now load a drawing, select an area to draw, and choose a drawing style.

  • On Input tab, click load image and browse to an image to try. Some work better than others, but it’s all to taste, so just experiment.
  • If your image doesn’t show up right away, it might be off the screen somewhere, or too small. Click move image and you should see a ghost version of your image hovering under your mouse. Click in the centre of your machine to place it there, and click move image again to move out of that mode.
  • Drag resize image to control how big the image is.
  • Click Select Area and drag a box around the area you want to draw.
  • Once you’ve selected an area, the view will automatically switch to hiding the image, and showing the density preview. Use the smaller view buttons in the bottom of the control panel to show the image or hide the density preview.
  • The density preview is designed to show what detail is being captured. The circles are not representative of the shapes that will be drawn, but are representative of their intended position, size and brightness.
  • Drag the number spinner for grid size to change the size of the “pixels”, bearing in mind that smaller ones take longer to draw (actually they are faster individually, but there are more of them).
  • Drag the number spinner for sample area to change the contrast of your image. This is the size of the area that is sampled when choosing the density (pixel sample area). I find I get the best results with a sample area just bigger than my grid size.

Remember, that once you’ve found a setting you like, you can save it to the properties configuration file by clicking save properties. If you don’t, it’ll all disappear when you restart and you will burst into tears.

Step 22: Choose a pixel style

Currently there are four pixel styles.

  • Shade Square wave – the standard. Pixel density is translated into a square wave pattern. Darker pixel = more waves = more ink.
  • Shade Scaled square wave – the half-tone effect. Instead of changing the number of waves, this one changes the size of the square that gets drawn. Darker pixel = big pixel = more ink.
  • Shade Solid – used for multi-layer chroma keying effects. This shades every pixel at maximum density, no variation.
  • Shade scribble – noisy effect. This is like a randomised pixel – a number of lines are drawn, but their direction and length are random (within the boundary of the pixel). Darker pixel = more lines = more ink.

Step 23: Load it up and get scribbling!

Load a pen in the gondola just by sticking it in with a bit of blu-tack, so the tip peeps out just a bit.

Stick a piece of paper onto the surface.

Home your gondola.

Click the “render” button for the kind of pixel you want.  Watch in amazement!

I’ve had best success with non-bleeding pens and paper.  I like using a very smooth paper like bristol board, along with hard-tipped fineliner pens.  Here in the UK I can buy these ZIG Millennium pens quite easily, and they’re really good. Pigma MICRON seems to be a popular US pen in the same kind of vein.

For coarser drawings, a thicker tip is good, I’ve used regular sharpies regularly, and though they bleed badly, they are vibrant and solid.

Step 24: Pen lift servo

If you fasten a little servo motor to the gondola, you can use it to lift the pen off the page.  There are two servo connectors on the motorshield, if you connect up SER1, then this will respond to commands sent to the machine.  I just use the control horn to poke through the gondola and lever against the surface.

The commands can be issued manually by using # or ~ to raise or lower the pen.  This is not very subtle, but it works well enough to prevent the pen from leaving a big bleedy mark at the end of the drawing. These commands are automatically added to the beginning and the end of the queue when you do a drawings.

Step 25: Pen thickness

The size of the pen tip controls how many waves the machine can fit into one pixel.  If you have a pixel that is 20mm square, and you have a 1mm pen tip, then you can only fit a maximum of 20 lines in before it’s at it’s maximum density.  Adding more ink then won’t make it any darker.

If you then swap out the pen and put in one with a 0.5mm tip, 20 lines will no longer completely fill in the pixel, now it will require 40 lines to fill it.  The machine works out the maximum possible density based on what sized pen you tell it you’ve installed.

You can change the pen width on the setup tab, by changing the value of pen tip size and clicking send pen tip size.  The tip size is not saved in the machine, it needs to be resent every time the machine is restarted, which is why the value is pre-loaded in the queue when you restart the controller.

Test pen widths
Rather than rely on manufacturers descriptions of pen tip width, there is a kind of calibration function to test pen widths too, this draws a sequence of pixels at maximum density, but it increments the pen width setting between each one, so you can try to narrow down what pen tip thickness gives you the deepest density you want.

There are three settings on that setup tab that control the size of the test swatch:

Pen test start tip – this is the tip size for the very first square and should be low.
Pen test end tip – this is the biggest tip size the machine will try.
Pen test inc size – this is the size of the increments that the machine will make to get from the start tip size to the end tip size.

If it was set to start:0.6, end: 2.0 and increment: 0.1, the machine will draw the first pixel as if it has a 0.6mm sized pen, then draw more, each time incrementing by 0.1mm, until it is 2mm.

Once you’ve decided which square you want to be your darkest, set the pen tip width to the setting required and save properties.

Step 26: Vector graphics drawing

With the new software (controller v1+ and server_a1), came vector drawing capabilities that make this machine even more useful.

Using Inkscape
All the paths need to be separate in the SVG file.  Text needs to be converted into paths.  You can do this by selecting everything and going to Path->Object To Path (this will convert any shapes like letters into outlines), and then select them all again and do Path->Break Apart (this breaks up any letters that have more than one outline in them).  You might find it useful after that to change the fill colour to empty (click on the empty swatch at the bottom), and set the outline to be black (shift-click on the black swatch at the bottom).  Save it.

Click load vector from the input control panel, and choose your SVG file.  If you can’t see your vector, click “move vector” and you should see it floating under your mouse as you move it.  Click again to place the SVG.  You can resize by dragging the “resize vector” number spinner.  Here 100 represents full size, that is 1px in inkscape equals 1mm on the machine.

Only lines that are entirely within the page area will be processed by the controller.

Now click render vector to convert the line art into polargraph commands and load them all into the command queue.  For vector work, the move direct command is used to tell the machine where to move, and it will always draw in a straight line on the board. The down side is that it’s a lot slower because it basically chops the line into dozens of smaller lines, and has to do a lot more calculations continuously.

If you hide the vector lines (show vector) you can see the actual lines that are stored up in the command queue previewed (show queue preview).

28BYJ-48 Stepper Motor

Stepper Motor  is a motor controlled by a series of electromagnetic coils. The center shaft has a series of magnets mounted on it, and the coils surrounding the shaft are alternately given current or not, creating magnetic fields which repulse or attract the magnets on the shaft, causing the motor to rotate.

This design allows for very precious control of the motor,There are two basic types of stepper motors, unipolar steppers and bipolar steppers .

In This instructable , I will talk about an Unipolar Stepper Motor 28-BYJ48 .

The unipolar stepper motor has five or six wires and four coils (actually two coils divided by center connections on each coil). The center connections of the coils are tied together and used as the power connection. They are called unipolar steppers because power always comes in on this one pole.

Step 1: Specification , Motor Driver

There are many Types of Drivers , L293 , ULN2003 , A3967SLB , And More ,
The 28-BYJ48 Even comes with Breakout using ULN2003 As a Motor driver chip .
Specification for this Motor  ” And you can download datasheet from the attachment “Rated voltage : 5VDC
Number of Phase 4
Speed Variation Ratio 1/64
Stride Angle 5.625° /64
Frequency 100Hz
DC resistance 50Ω±7%(25℃)
Idle In-traction Frequency > 600Hz
Idle Out-traction Frequency > 1000Hz
In-traction Torque >34.3mN.m(120Hz)
Self-positioning Torque >34.3mN.m
Friction torque 600-1200 gf.cm
Pull in torque 300 gf.cm
Insulation grade Aand the schematics of  This breakout shown like the Pictures on the attachment
Note that if you want to use L293 Instead of ULN2003 , You will need to leave Red wire No connection.

Materials :

you will need :

1) Arduino Board .
2) BYJ48 Stepper Motor 5v
3) ULN2003 Moror driver Module
4) Jumper .
5) 5v voltage source  “Optional” .

Step 2: Arduino Code .

\

The Arduino IDE Support a Library for Stepper Motor , Very Easy to use , After Connect Motor with arduino You can Upload the Sketch on to the arduino .

But …

You must take something  in consider :

This Motor has a Gear ratio of 64 , and Stride Angle 5.625°  so this motor has a 4096 Steps .

 steps = Number of steps in One Revolution  * Gear ratio   .

steps= (360°/5.625°)*64″Gear ratio” = 64 * 64 =4096 . this value will substitute it on The arduino Sketch

For adafruit Stepper Motor , the Stride Angle 7.5° and Gear ratio is 16 , So number of steps in 1 Revolution is :

steps in One Revolution  = 360 / 7.5 = 48   .

steps= 48 * 16 = 768

That’s will be different depend on what motor you are using , So check The Datasheet for Your stepper Motor to calibrate this values

28-BYJ48 Motor Datasheet .

Motor Driver ULN2003 BreakOut Connected To Arduino From IN1 – IN4 To D8 – D11 Respectively

To Power you Motor ,  Recommanded to use external Power Supply with 5V-500mA  at least , Don’t power it directly from arduino Board 5V .

Step 3: Library Direction Issue … And how to fix it .

When You Upload the sketch to the arduino , The Motor will Be rotate in  one direction By type the command :

step(steps);

So you must Put the Number of step to turn the motor .

The reference  said You can put the positive value to turn one direction, negative to turn the other.

If that’s  OK With Your stepper Motor , You  don’t need to read the following .

If Not , Your Motor turn to same direction even you Put the steps Positive Value or negative , What is the issue ?

This Motor need to operate as the Table on the attachment .

the arduino Stepper Library need to modify to match this requirement .

I wrote a code which is allow to this motor to Move clockwise and counter clock wise

Code in the next step :

Step 4: Modify Code

the final code for this Stepper motor :

/*
BYJ48 Stepper motor code
Connect :
IN1 >> D8
IN2 >> D9
IN3 >> D10
IN4 >> D11
VCC … 5V Prefer to use external 5V Source
Gnd
written By :Mohannad Rawashdeh
http://www.instructables.com/member/Mohannad+Rawashdeh/
28/9/2013
*/

#define IN1  8
#define IN2  9
#define IN3  10
#define IN4  11
int Steps = 0;
boolean Direction = true;// gre
unsigned long last_time;
unsigned long currentMillis ;
int steps_left=4095;
long time;
void setup()
{
Serial.begin(115200);
pinMode(IN1, OUTPUT);
pinMode(IN2, OUTPUT);
pinMode(IN3, OUTPUT);
pinMode(IN4, OUTPUT);
// delay(1000);

}
void loop()
{
while(steps_left>0){
currentMillis = micros();
if(currentMillis-last_time>=1000){
stepper(1);
time=time+micros()-last_time;
last_time=micros();
steps_left–;
}
}
Serial.println(time);
Serial.println(“Wait…!”);
delay(2000);
Direction=!Direction;
steps_left=4095;
}

void stepper(int xw){
for (int x=0;x<xw;x++){
switch(Steps){
case 0:
digitalWrite(IN1, LOW);
digitalWrite(IN2, LOW);
digitalWrite(IN3, LOW);
digitalWrite(IN4, HIGH);
break;
case 1:
digitalWrite(IN1, LOW);
digitalWrite(IN2, LOW);
digitalWrite(IN3, HIGH);
digitalWrite(IN4, HIGH);
break;
case 2:
digitalWrite(IN1, LOW);
digitalWrite(IN2, LOW);
digitalWrite(IN3, HIGH);
digitalWrite(IN4, LOW);
break;
case 3:
digitalWrite(IN1, LOW);
digitalWrite(IN2, HIGH);
digitalWrite(IN3, HIGH);
digitalWrite(IN4, LOW);
break;
case 4:
digitalWrite(IN1, LOW);
digitalWrite(IN2, HIGH);
digitalWrite(IN3, LOW);
digitalWrite(IN4, LOW);
break;
case 5:
digitalWrite(IN1, HIGH);
digitalWrite(IN2, HIGH);
digitalWrite(IN3, LOW);
digitalWrite(IN4, LOW);
break;
case 6:
digitalWrite(IN1, HIGH);
digitalWrite(IN2, LOW);
digitalWrite(IN3, LOW);
digitalWrite(IN4, LOW);
break;
case 7:
digitalWrite(IN1, HIGH);
digitalWrite(IN2, LOW);
digitalWrite(IN3, LOW);
digitalWrite(IN4, HIGH);
break;
default:
digitalWrite(IN1, LOW);
digitalWrite(IN2, LOW);
digitalWrite(IN3, LOW);
digitalWrite(IN4, LOW);
break;
}
SetDirection();
}
}
void SetDirection(){
if(Direction==1){ Steps++;}
if(Direction==0){ Steps–; }
if(Steps>7){Steps=0;}
if(Steps<0){Steps=7; }
}

Low-Cost, Arduino-Compatible Drawing Robot

I designed this project for a 10-hour workshop for ChickTech.org whose goal is to introduce teenage women to STEM topics. The goals for this project were:

  • Easy to build.
  • Easy to program.
  • Did something interesting.
  • Low-cost so participants could take it home and continue to learn.

With those goals in mind, here were a couple of the design choices:

  • Arduino compatible for ease of programming.
  • 4xAA battery power for cost and availability.
  • Stepper motors for accurate motion.
  • 3D Printed for ease of customization.
  • Pen plotting with Turtle graphics for interesting output.
  • Open Source so you could make one of your own!

Here is the robot that came closest to what I wanted to do: http://mirobot.io. I don’t have a laser cutter and shipping from England was prohibitive. I do have a 3D printer, so I guess you can see where this is going . . .

Don’t let the lack of a 3D printer deter you. You can locate local hobbyists willing to help you out at https://www.3dhubs.com/.

It took a lot of work, but I’m please with how it turned out. And, I learned quite a bit in the process. Let me know what you think!

Step 1: Parts

There are a number of ways to power, drive, and control robots. You may have different parts on hand that will work, but these are the ones I’ve tried and found to work well:

Electronics:

*Note: See the last step for a discussion on using regular Arduino or Raspberry Pi boards.

Hardware:

3D-Printed Parts (check out www.3dhubs.com if you don’t have access to a printer):

Tools and Supplies:

  • Phillips screw driver
  • Hot glue gun
  • Digital multi-meter
  • Sharp knife
  • Crayola colored markers

Step 2: Flash the Firmware

Before we get too far into construction, lets load the test firmware on to the microcontroller. The test program just draws for boxes so we can check for proper direction and dimension.

To talk to the Trinket Pro, you are going to need:

  1. Driver from https://learn.adafruit.com/introducing-pro-trinket…
  2. Arduino software from https://learn.adafruit.com/introducing-pro-trinket…

Lady Ada and the Adafruit team have created a far better set of instructions in the links above than I can provide. Please use them if you are stuck.

Note: The one trick that makes the Trinket different from regular Arduino is that you have to reset the board before uploading the sketch.

Step 3: Pen Holder and Battery Holders

  1. Install the Pen Holder with the Servo Bracket on the shorter side of the chassis (Image 1).
  2. Insert the nuts on the top side of the chassis (Image 2)
  3. Attach the battery holders on the bottom of the chassis using 3Mx6mm flat-head screws (Images 3 & 4).
  4. Thread the battery leads through the rectangular cable runs (Image 4 & 5).
  5. Repeat for the other battery holder.

Note: Unless specified, the remainder of the screws are 3Mx8mm pan head srews.

Step 4: Wheels

  1. Test fit your wheel to the stepper shaft (Image 1).
    1. If it is too tight, you can heat the wheel hub with a hair drier or hot air gun and then insert the shaft.
    2. If it is too loose, you can use a 3Mx8mm screw to hold it against the flat of the shaft (Image 2).
    3. If you are a perfectionist, you can calibrate your printer and get it just right.
  2. Place the o-ring around the rim of the wheel (Image 3 & 4).
  3. Repeat for the other wheel.

Step 5: Stepper Brackets

  1. Insert a nut into the stepper bracket and attach them to the top of the chassis with a screw (Image 1).
  2. Insert the stepper into the bracket and attach with screws and nuts.
  3. Repeat for the other bracket.

Step 6: Caster

  1. Insert the ball bearing into the caster.
    • Do not force it in or it will break. Use a hair-drier or hot air gun to soften the material if needed.
  2. Attach the caster to the bottom side of the chassis in front of the battery holder.

Step 7: Breadboard

  1. Remove one of the power rails using a sharp knife, cutting through the bottom adhesive (Image 1).
  2. Holding the breadboard over the chassis rails, mark where they intersect the edge (Image 2).
  3. Using a straight edge (like the removed power rail), mark the lines and cut through the backing (Image 3).
  4. Place the breadboard on the chassis with the rails touching the exposed adhesive (Image 4).

Step 8: Power

  1. Place the microcontroller, darlington driver, and power switch on to the bread board (Image 1).
    • I’ve added orange dots for visibility to mark the following:
      • Pin 1 of the darlington driver.
      • The battery pin of the microtroller.
      • The power switch “on” position.
  2. With the right-hand battery leads:
    1. Connect the red line to the first pin of the power switch (Image 2).
    2. Connect the black lead to an empty row between the microcontroller and the darlington chip (Image 2).
  3. With the left-hand battery leads:
    1. Connect the red line to the same row as the black lead of the other battery (Image 3).
    2. Connect the black line to the negative rail of the breadboard (Image 3).
  4. Connect power to the microcontroller:
    1. Red jumper from positive rail to the battery pin (orange dot, Image 4).
    2. Black jumper from the negative rail to the pin marked “G” (Image 4).
  5. Install batteries and switch the power on. You should see the green and red lights of the controller come on (Image 5).

Troubleshooting: If the microcontroller lights do not come on, immediately turn the power off and troubleshoot:

  1. Batteries installed in the correct orientation?
  2. Double check battery leads positioning.
  3. Double check switch leads positioning.
  4. Use a multi-meter to check voltages of batteries.
  5. Use multi-meter to check power rail voltages.

Step 9: Headers and Servo wiring

Male header pins allow us to connect the 5-pin servo JST connectors to power and the darlington driver (Image 1):

  1. The first 5-pin header starts one row in front of the darlington driver.
  2. The second servo header should then line up with the end of the darlington driver.

Before the wiring gets to complicated, lets get the servo wired up:

  1. Add a 3-pin header for the servo on the right edge of the forward section of the breadboard( Image 2).
  2. Add a red jumper from the center pin to the positive side of the power rail.
  3. Add a black or brown jumper from the outer pin to the negative side of the power rail.
  4. Add a colored jumper from the inner pin to Pin 8 of the microcontroller.
  5. Install the servo horn with the shaft to the full clock-wise position and the arm extending to the right-side wheel (Image 3)
  6. Install the servo in the pen holder using the servo’s screws (Image 3).
  7. Connect the servo connector aligning the colors (Image 4).

Step 10: Stepper Control

Time to wire power for the darlington driver and steppers, which will be driven directly from the battery:

  1. Connect a black or brown jumper from the lower right darlington pin to the negative side of the power rail (Image 1).
  2. Connect a red jumper from the upper right darlington pin to the positive side of the power rail.
  3. Connect a red jumper from the upper left pin header to the positive side of the power rail (Image 2).
  4. Connect the left stepper connector to the left side pin header with the red lead on the right side (Image 3).
  5. Connect the right stepper connector to the right side pin header with the read lead on the left side.

Note: The red lead of the stepper connector is the power and should match the red leads on the breadboard.

Step 11: Stepper Control (Continued)

Now we will connect the stepper signal wires from the microcontroller to the input side of the darlington driver:

  1. Starting with Pin 6 of the microcontroller, connect the leads for four control jumpers for the left stepper motor (Image 1).
  2. Match these jumpers to the input side of the darlington on the right. All colors should match with the exception of green, which matches the pink wire of the stepper (Image 2).
  3. Starting with Pin 13 of the microcontroller, connect the leads for the four control jumpers for the right stepper motor (Image (3).
  4. Match these jumpers to the input side of the darlington on the left. All colors should match with the exception of green, which matches the pink wire of the stepper (Image 3).

Step 12: Testing and Calibration

Hopefully you already uploaded the firmware in Step 2. If not, do it now.

The test firmware just draws a square repeatedly so we can check direction and accuracy.

  1. Place your robot on a smooth, flat, open surface.
  2. Turn the power on.
  3. Watch your robot draw squares.

If you are not seeing lights on the microcontroller, go back and troublshoot power as in Step 8.

If your robot is not moving, double check the power connections to the darlington driver in Step 9.

If your robot is moving erratically, double check the pin connections for the microcontroller and darlington driver in Step 10.

If your robot is moving in an approximate square, it is time to put some paper down and put a pen in it (Image 1).

Your calibration points are:

float wheel_dia=66.25;  // mm (increase = spiral out)
float wheel_base=112;   // mm (increase = spiral in)
int steps_rev=128;      // 128 for 16x gearbox, 512 for 64x gearbox

I started with a measured wheel diameter of 65 mm and you can see the boxes rotating inward (Image 2).

I increased the diameter to 67, and you can see it was rotating outward (Image 3).

I eventually arrived at a value of 66.25 mm (Image 4). You can see that there is still some inherent error due to gear lash and such. Close enough to do something interesting!

Step 13: Raising and lowering the pen

We’ve added a servo, but haven’t done anything with it. It allows you to raise and lower the pen so the robot can move without drawing.

  1. Place the pen collar on the pen (Image 1).
  2. If it is loose, tape it in place.
  3. Check that it will touch the paper when the servo arm is lowered.
  4. Check that it will not touch the paper when raised (Image 2).

The servo angles can be adjusted either by removing the horn and re-positioning it, or through the software:

int PEN_DOWN = 170; // angle of servo when pen is down
int PEN_UP = 80;    // angle of servo when pen is up

The pen commands are:

penup();
pendown();

Step 14: Have Fun!

I hope you made is this far without too many curse words. Let me know what you struggled with so I can improve the instructions.

Now it is time to explore. If you look at the test sketch, you will see I have provided you some standard “Turtle” commands:

forward(distance);   // millimeters
backward(distance);
left(angle);         // degrees
right(angle);
penup();
pendown();
done();              // release stepper to save battery

Using these commands, you should be able to do just about anything, from drawing snow flakes or writing your name. If you need some help getting started, check out:

Step 15: Other Platforms

Could this robot be done with a regular Arduino? Yes! I went with the Trinket because of the low cost and small size. If you increase the chassis length, you can fit a regular Arduino on one side and the breadboard on the other (Image 1). It should work pin-for-pin with the test sketch, plus, you now can get to the serial console for debugging!

Could this robot be done with a Rasberry Pi? Yes! This was my first line of investigation because I wanted to program in Python, and be able to control it over the web. Like the full size Arduino above, you just place the Pi on one side, and the breadboard on the other (Image 2). Power becomes the primary concern because four AA is not going to cut it. You need to provide about 1A of current at a stable 5V, otherwise your WiFi module will stop communicating. I’ve found the Model A is much better on power consumption, but I’m still working out how to supply reliable power. If you figure it out, let me know!

ESP8266 and Visuino: Control Servo Remotely over Wi-Fi with Rotary Encoder

ESP8266 modules are great low cost stand alone controllers with built in Wi-Fi. In this Instructable I will show you how you can control a Servo remotely over Wi-Fi with a Rotary Encoder. The Instructable is a similar but more advanced version of the “Arduino Nano and Visuino: Control Servo with Rotary Encoder” Instructable.

In the Instructable, I will use 2 NodeMCUmodules. One version 0.9, and the other 1.0. The NodeMCU are the easiest way to program and experiment with ESP8266controllers. This Instructable however can easily be done with other modules, and the Servo module can even use ESP-01 module as it needs only one GPIO pin to connect to the Servo.

Step 1: Components

  1. NodeMCU ESP8266 boards (I used both NodeMCU 0.9, and NodeMCU 1.0 versions, but any other combination, or even stand alone ESP-12 will work)
  2. One Rotary Encoder module I got from this cheap 37 sensors set.
  3. 1 Small Servo
  4. 8 Female-Female jumper wires
  5. 3 Male-Female jumper wires

Step 3: Connect the Servo to the second NodeMCU ESP8266 Module

Connect the Servo to the second NodeMCU ESP8266 Module
56ac0dec15be4d97d90007e9.jpeg 56ac0e234fbadef83c00027d.jpeg 56ac14164936d4a6440009e1.jpeg

To simplify this Instructable, we will connect the Power from the NodeMCU to the Servo, In real projects, you will need to have a dedicated power supply for the servo! Please look at this Instructable to see how you can connect the Servo to external power.

  1. Connect Ground(Black wire),Power(Red wire), and Control(Orange wire) to the Servo (Picture 1)
  2. Connect the other end of the Power wire(Red wire) to the 5V(Called “Vin” in NodeMCU version 1.0) Power pin of the ESP8266 NodeMCU module (Picture 2)
  3. Connect the other end of the Ground wire(Black wire) to the Ground pin of the ESP8266 NodeMCU module (Picture 2)
  4. Connect the other end of the Control wire(Orange wire) to the Digital pin 2of the ESP8266 NodeMCU module (Picture 3)
  5. Picture 4 shows where are the Ground, 5V(Vin) Power, and Digital 2 pins of the NodeMCU 0.9

Step 4: Start Visuino, and select the ESP8266 Board type

Start Visuino, and select the ESP8266 Board type
ESP8266.png

To start programming the Arduino, you will need to have the Arduino IDEinstalled from here: http://www.arduino.cc.

Make sure that you install 1.6.7 or higher, otherwise this Instructable will not work!

If you have not done follow the steps in this Instructable to setup the Arduino IDE to program ESP 8266!

The Visuinohttps://www.visuino.com also needs to be installed.

  1. Start Visuinoas shown in the first picture
  2. Click on the “Tools” button on the Arduino component (Picture 1) in Visuino
  3. When the dialog appears, select “NodeMCU ESP-12” as shown on Picture 2

Step 5: In Visuino: Setup the module as Access Point

In Visuino: Setup the module as Access Point
AccessPointConfigEnable.png AccessPointConfigIP.png
  1. In the Object Inspector, expand the “Modules” property, then the “WiFi” sub property, then the “AccessPoint: sub property (Picture 1)
  2. Set the value of the “SSID” sub property of the “AccessPoint”, to “ServoRemote” (Picture 1)

To make sure the Access Point will be on the 200.200.200.X subnet, we need to assign a fixed address.

  1. In the Object Inspector, expand the “Config” sub property of the “AccessPoint” property (Picture 2)
  2. Set the value of the “Enabled” sub property of the Config to “True” (Picture 2)
  3. Set the value of the “IP” sub property to “200.200.200.100” (Picture 3)

Step 6: In Visuino: Add an UDP Socket for the communication

In Visuino: Add an UDP Socket for the communication
SocketsAddUDP.png SocketsRemoteIP.png SocketsRemotePort.png

Next we need to add an UDP socket for the communication.

  1. In the Object Inspector, click on the “…” button next to the value of the “Sockets” sub property of the “WiFi” property (Picture 1)
  2. In the Sockets editor select “UDP Socket”, and then click on the “+” button (Picture 2)
  3. In the Object Inspector, set the value “RemoteIPAddress” property to “200.200.200.200” (Picture 3) – this is the fixed IP address that we will assign to the other module later on
  4. In the Object Inspector set the value of the “RemotePort” to “8888” (Picture 4)
  5. Close the “Sockets” editor.

Step 7: In Visuino: Add and connect Rotary Encoder component

In Visuino: Add and connect Rotary Encoder component
ComponentRotaryConnect1.png
ComponentRotaryConnect2.png
  1. Type “rotar” in the Filter box of the Component Toolbox then select the “Rotary Encoder Sensor” component (Picture 1), and drop it in the design area
  2. Connect the “Out” pin of the Digital[ 2 ] channel of the “NodeMCU ESP-12″component to the “Clock(A)” pin of the RotaryEncoderSensor1(Picture 2)
  3. Connect the “Out” pin of the Digital[ 3 ] channel of the”NodeMCU ESP-12″

    component to the “Direction(B)” pin of the RotaryEncoderSensor1(Picture 3)

Step 8: In Visuino: Add and connect Up/Down Counter component

In Visuino: Add and connect Up/Down Counter component
ComponentCounterInitialValue.png
ComponentCounterMinRollOver.png
ComponentCounterMinValue.png
ComponentCounterMaxRollOver.png
ComponentCounterMaxValue.png

We need a counter to count the Up/Down rotations from 0 to 100, and we need to set in in the middle/neutral 50:

  1. Type “count” in the Filter box of the Component Toolbox then select the “Up/Down Counter” component (Picture 1), and drop it in the design area
  2. In the Object Inspector set the value of the InitialValue property to 50(Picture 2)
  3. In the Object Inspector expand the Counter’s Min property
  4. In the Object Inspector set the value of the RollOver sub property to False(Picture 3)
  5. In the Object Inspector set the

    value of theValue sub property to 0 (Picture 3)

  6. In the Object Inspector expand the Counter’s Max property(Picture 5)
  7. In the Object Inspector set the

    value of theRollOver sub property to False(Picture 5)

  8. In the Object Inspector set the value of the Value sub property to 100(Picture 6)

Step 9: In Visuino: Connect the Up/Down Counter component

In Visuino: Connect the Up/Down Counter component
ComponentCounterConnect2.png
ComponentCounterConnect3.png
PullUp.png
  1. Connect the “Down” pin of the RotaryEncoderSensor1 component to the “Down” pin of the UpDownCounter1 component (Picture 1)
  2. Connect the “Up” pin of the RotaryEncoderSensor1 component to the “Up” pin of the UpDownCounter1 component (Picture 2)
  3. Connect the “Out” pin of the” Digital[ 4 ]” channel of the “NodeMCU ESP-12” component to the “Reset” pin of the UpDownCounter1 (Picture 3)

The Rotary encoder module switch that I have does not have pull up resistor. The ESP8266 however has built-in optional pull-up resistors for the pins. To enable the pull-up resistor for the Digital pin 4:

  1. In the Object Inspector expand the “Digital” property, then the “Digital[ 4 ]” sub property (Picture 4)
  2. In the Object Inspector set the value of the IsPullUp sub property to True(Picture 4)

Step 10: In Visuino: Add and connect Integer To Analog component

In Visuino: Add and connect Integer To Analog component
ComponentIntToAnalogScale.png
ComponentIntToAnalogConnect.png

The servo needs analog value in the range between 0 and 1.0, so we need to convert the count to Analog and multiply it by 0.01 to convert the 0 to 100 range into Analog 0 to 1.0:

  1. Type “To Analo” in the Filter box of the Component Toolbox then select the “Integer To Analog” component (Picture 1), and drop it in the design area
  2. In the Object Inspector set the Scale property to 0.01 (Picture 2) . This will convert the counter values from the integer range of 0 to 100, to the analog range of 0.0 to 1.0.
  3. Connect the “Out” pin of the UpDownCounter1 to the “In” pin of the IntegerToAnalog1 component (Picture 3)

Step 11: In Visuino: Add and Make Structure component, and add Analog channel to it

In Visuino: Add and Make Structure component, and add Analog channel to it
ComponentMakeStructTools.png
ComponentSplitAddChannel1.png
ComponentSplitAddChannel2.png

We need to send the analog value over the UDP. To do that we will make a structure with analog value and will send it over the UDP socket.

  1. Type “make” in the Filter box of the Component Toolbox then select the “Make Structure” component (Picture 1), and drop it in the design area
  2. Click on the “Tools” button (Picture 2) to open the “Elements” editor (Picture 3)
  3. In the “Elements” editor select the “Analog” element, and then clickon the “+” button (Picture 3) to add an Analog element (Picture 4)
  4. Close the “Elements” editor.

Step 12: In Visuino: Connect the Make Structure component

In Visuino: Connect the Make Structure component
ComponentMakeStructConnect2.png
ComponentMakeStructConnect3.png
  1. Connect the “Out” pin of the MakeStructure1 component to the “In” pin of the “Modules.WiFi.Sockets.UDPSocket1” of the “NodeMCU ESP-12” component (Picture 3)
  2. Connect the the “In” pin of the “Elements.Analog1” element of the MakeStructure1 component to the “Out” pin of the IntegerToAnalog1component (Picture 3)

Step 13: Generate, Compile, and Upload the ESP8266 code for the Rotary Encoder Module

Generate, Compile, and Upload the ESP8266 code for the Rotary Encoder Module
Arduino IDE.png
  1. In Visuino, Press F9 or click on the button shown on Picture 1 to generate the Arduino code, and open the Arduino IDE
  2. Connect the first NodeMCU module (The one with the Rotary Encoder) with USB cable to the computer
  3. Select the board type and serial port as I have shown you in this Inctructable
  4. Make sure you have installed the latest staging version of the ESP support! The stable release does not have some of the latest features, and you will have errors when you try to compile!
  5. In the Arduino IDE, click on the Upload button, to compile and upload the code (Picture 2)

Step 14: In Visuino: Select the ESP8266 Board type, and configure it to connect to the Access Point

 In Visuino: Select the ESP8266 Board type, and configure it to connect to the Access Point
AccessPointsAdd.png
AccessPointsSSID.png
AccessPointsConfigEnable.png
AccessPointsConfigIP.png

Now lets program the Servo module.

  1. Start new project.
  2. Click on the “Tools” button on the Arduino component, and when the dialog appears, select “NodeMCU ESP-12” as you did in Step 4 for the Rotary Encoder module

Next we need to configure the module to connect to the Access Point of the Thermometer module, and use a fixed IP Address of 200.200.200.200

  1. In the Object Inspector, expand the “Modules” property, then the “WiFi” sub property, then the “AccessPoints” sub property, and click on the “…” button next to its value (Picture 1)
  2. In the “AccessPoins” editor, select “WiFi Access Point”, and then click on the “+” button to add the access point (Picture 2)
  3. In the Object Inspector, set the value of the “SSID” property to “ServoRemote” (Picture 3)
  4. In the Object Inspector, expand the “Config” property, and set the value of the “Enabled” sub property to “True” (Picture 4)
  5. In the Object Inspector, set the value of the “IP” sub property to “200.200.200.200” (Picture 5)

Step 15: In Visuino: Add an UDP Socket for the communication

In Visuino: Add an UDP Socket for the communication
SocketsAddUDP.png
SocketsAddUDPPort.png

Next we need to add an UDP socket for the communication.

  1. In the Object Inspector, click on the “…” button next to the value of the Sockets sub property of the WiFi (Picture 1)
  2. In the Sockets editor select “UDP Socket”, and then click on the “+” button (Picture 2)
  3. In the Object Inspector, set the value “RemoteIPAddress” property to “200.200.200.200” (Picture 3)
  4. In the Object Inspector set the value of the “Port” to “8888” (Picture 4)

Step 16: In Visuino: Add Split Structure component, and add Analog channel to it

In Visuino: Add Split Structure component, and add Analog channel to it
ComponentSplitAddChannel.png
ComponentSplitAddChannel1.png
ComponentSplitAddChannel2.png

The Remote Control module sends the servo position in binary floating point form as a packet. We need to decode it properly. For this we need a “Split Structure” component with “Analog” element in it.

  1. Type “struct” in the Filter box of the Component Toolbox then select the “Split Structure” component (Picture 1), and drop it in the design area
  2. Click on the “Tools” button (Picture 2) to open the Elements editor (Picture 3)
  3. In the “Elements” editor select the “Analog” element, and then click on the “+” button (Picture 3) to add an Analog element (Picture 4)
  4. Close the Elements editor.

Step 17: In Visuino: Add and connect Servo component

In Visuino: Add and connect Servo component
Connect1.png
Connect2.png
Connect3.png
  1. Type “servo” in the Filter box of the Component Toolbox then select the “Servo” component (Picture 1), and drop it in the design area
  2. Connect the “Out” pin of the Servo1 component to the “Digital” input pin of Digital[ 2 ] channel of the Arduino component (Picture 2)
  3. Connect the “In” pin of the Servo1 component (Picture 3) to the “Out” pin of the “Elements.Analog1” of the SplitStructure1 component (Picture 4)

Step 18: Generate, Compile, and Upload the ESP8266 code for the Servo

Generate, Compile, and Upload the ESP8266 code for the Servo
Arduino IDE.png
  1. In Visuino, Press F9 or click on the button shown on Picture 1 to generate the Arduino code, and open the Arduino IDE
  2. Connect the second NodeMCU module (The one with the Servo) with USB cable to the computer
  3. Select the board type and serial port as I have shown you in this Inctructable
  4. In the Arduino IDE, click on the Upload button, to compile and upload the code (Picture 2)

Step 19: And play…

And play...
VisuinoDiagramCrop.png
VisuinoDiagramCrop.png

Congratulations! You have completed the project.

Picture 1 shows the connected and powered up project.

If you rotate the Rotary Encoder back and forth, the Servo will move in the same direction, as you can see in the video. If you press the Rotary Encoder shaft down, the Servo will move to neutral center position.

On Picture 2 you can see the complete Visuino diagram for the Rotary Encoder Remote Control module.

On Picture 3 you can see the complete Visuino diagram for the Servo module.

Also attached are the Visuino projects, that I created for this Instructable. You can download and open them in Visuinohttps://www.visuino.com

Wii 리모컨(Wiimote)으로 RC Car 조종하기 – 2WS (Tamiya M-03)

이젠 벽돌이 되어버린 니텐도 Wii를 되살리기 차원에서 Wii 리모컨을 사용하여 RC Car를 조종하는 프로젝트를 시작해봅니다.

Source를 수정하여 Tamiya M-03 샤시에 적용해 보기로 했습니다.

Circuit@Home에서 소개 받았습니다!

RC car controlled by Wii Remote on Arduino http://www.circuitsathome.com/mcu/rc-car-controlled-by-wii-remote-on-arduino

USB Host를 적용하여 Bluetooth로 직접 연결하는 방식이기 때문에 구성은 매우 간단합니다.

Arduino는 Nano를 사용하였고 USB Host Shield와 연결하기 위해 Mother Board를 하나 꾸며보았습니다.

기능도 조금 추가했습니다.

바나나를 던지거나 하지는 못하지만 “A” 버튼을 누르면 레이저가 발사되듯이 Fire LED가 켜지도록 하였고 “+” 버튼은 Head Light, “-” 버튼은 Back Light로 사용할 수 있도록 하였습니다.

그리고 좌우방향 버튼으로도 Steering이 가능하도록 하였습니다.

 Arrow Up  Left steering
 Arrow Down  Right steering
 Arrow Left  Gear Down
 Arrow Right  Gear Up
 A  Fire & Shutting
 B  –
 +  Head Light
 –  Back Light
 1  Backward
 2  Forward
 Home  Throttle mode change

하드웨어 (Hardware)

송신기 (Transmitter)

  • Wii 리모컨 (Wiimote)

수신기 (Reciver)

  • Arduino Nano

  • USB Host Shield
  • Bluetooth USB 어댑터 (Dongle)

  • DIY Mother Board
 
 

통신 거리는 Bluetooth 특성상 대략 10m 정도 밖에 안될 거라고 예상합니다만 그 이상도 충분합니다.

 

RC Car

  • Tamiya M-03

소프트웨어 (Software)

Arduino 용 라이브러리와 스케치를 포함한 파일은 github 에 있습니다.
이 라이브러리는 Richard Ibbotson이 만든 코드 wiiblue.pde 을 기반으로하고 있습니다.

샘플 스케치 (Sketch)

TwoWheelSterringWii.ino

#include “WiiRemote.h”

#include <MemoryFree.h>

#include <Servo.h>

#define PIN_STEERING_SIGNAL        2

#define PIN_ESC_SIGNAL             4

#define PIN_HEAD_LIGHT_SIGNAL     14

#define PIN_BACK_LIGHT_SIGNAL     15

#define PIN_FIRE_SIGNAL           17

#define PIN_STEERING_SELECT       16

#define SERIAL_DEBUG               0    // 0: active mode, 1: serial debug mode

enum eAngle

{

STEERING_ANGLE_MAX           = 165,   // to right

STEERING_ANGLE_CENTER        = 90,

STEERING_ANGLE_MIN           = 15,    // to left

STEERING_ANGLE_STEP          = 5,

STEERING_ANGLE_MAX_INVERT    = 165,   // to right

STEERING_ANGLE_CENTER_INVERT = 90,

STEERING_ANGLE_MIN_INVERT    = 15,    // to left

THROTTLE_ANGLE_MAX           = 160,   // 80,

THROTTLE_ANGLE_CENTER        = 90,

THROTTLE_ANGLE_MIN           = 10,

};

enum eServoPulse

{

SERVO_PULSE_MAX              = 2400,  // to left

SERVO_PULSE_NEUTRAL          = 1550,  // 1500 Futaba compatible, 1.55msec

SERVO_PULSE_MIN              = 600,   // to right

SERVO_PULSE_MAX_INVERT       = 600,   // to right

SERVO_PULSE_NEUTRAL_INVERT   = 1450,  // 1460 Futaba compatible, 1.55msec

SERVO_PULSE_MIN_INVERT       = 2400,  // to left

};

enum eESCPulse

{

/*

*  Futaba timing

*

*  0us     1072us         1522us          1922us

*   +———*————+-*-+————-*

*   |   n/a   |   forwad   |d|d|   Reverse   |

*   +———*————+-*-+————-*

*          Max Forwad     Neutral         Max Reverse

*

*   d: dead zone, +10us and -10us

*/

ESC_PULSE_NEUTRAL     = 1522,

ESC_PULSE_BRAKE       = 1600,

ESC_PULSE_FWD_MAX     = 800,   //1200, // 1072

ESC_PULSE_FWD_MIN     = 1510,

ESC_PULSE_FWD_3RD     = (ESC_PULSE_FWD_MIN – 240),

ESC_PULSE_FWD_2ND     = (ESC_PULSE_FWD_MIN – 160),

ESC_PULSE_FWD_1ST     = (ESC_PULSE_FWD_MIN – 80),

ESC_PULSE_REV_MAX     = 1700,  // 1922

ESC_PULSE_REV_FIX     = 1650,

ESC_PULSE_REV_MIN     = 1600,

};

enum eGear

{

GEAR_1ST = 1,

GEAR_2ND = 2,

GEAR_3RD = 3,

};

WiiRemote wiiremote;

Servo SteeringServo;

Servo ESC;

void setup()

{

#if SERIAL_DEBUG

Serial.begin(115200);

Serial.print(“\r\nfreeMemory() reports: “);

Serial.print(freeMemory(), DEC);

Serial.println(“Serial connect…”);

#endif

SteeringServo.attach(PIN_STEERING_SIGNAL);

SteeringServo.writeMicroseconds(SERVO_PULSE_NEUTRAL);

ESC.attach(PIN_ESC_SIGNAL);

ESC.writeMicroseconds(ESC_PULSE_NEUTRAL);

pinMode(PIN_HEAD_LIGHT_SIGNAL, OUTPUT);

pinMode(PIN_BACK_LIGHT_SIGNAL, OUTPUT);

digitalWrite(PIN_HEAD_LIGHT_SIGNAL, LOW);

digitalWrite(PIN_BACK_LIGHT_SIGNAL, LOW);

pinMode(PIN_FIRE_SIGNAL, OUTPUT);

digitalWrite(PIN_FIRE_SIGNAL, LOW);

pinMode(PIN_STEERING_SELECT, INPUT);

digitalWrite(PIN_STEERING_SELECT, LOW);

wiiremote.init();

/*

unsigned char wiiremote_bdaddr[6] = {0x00, 0x1e, 0x35, 0xda, 0x48, 0xbc};

wiiremote.setBDAddress(wiiremote_bdaddr, 6);

wiiremote.setBDAddressMode(BD_ADDR_FIXED);

*/

#if SERIAL_DEBUG

Serial.println(“Wiimote connecting…”);

Serial.println(“Please press 1 button and 2 button simultaneously”);

#endif

}

void loop()

{

wiiremote.task(&myapp);

}

int steering_angle          = STEERING_ANGLE_CENTER;

int steering_angle_invert   = STEERING_ANGLE_CENTER_INVERT;

int old_steering_angle      = STEERING_ANGLE_CENTER;

bool analog_throttle        = false;  // false = use “One” button as throttle

int throttle_angle          = THROTTLE_ANGLE_CENTER;

int gear                    = GEAR_1ST;

int pulse_steering;

int pulse_esc;

bool fire                   = false;                  // fire

bool head_light             = false;                  // head light

bool back_light             = false;                  // back light

void myapp(void)

{

#if SERIAL_DEBUG

Serial.print(“\r\n”);

#endif

/* Steering */

steering_angle = getSteeringAngle();

steering_angle_invert = getSteeringAngleInvert();

if (digitalRead(PIN_STEERING_SELECT) == HIGH) {

pulse_steering = map(steering_angle,

STEERING_ANGLE_MIN, STEERING_ANGLE_MAX,

SERVO_PULSE_MAX, SERVO_PULSE_MIN);

SteeringServo.writeMicroseconds(pulse_steering);

} else {

pulse_steering = map(steering_angle_invert,

STEERING_ANGLE_MIN_INVERT, STEERING_ANGLE_MAX_INVERT,

SERVO_PULSE_MAX_INVERT, SERVO_PULSE_MIN_INVERT);

SteeringServo.writeMicroseconds(pulse_steering);

}

if (wiiremote.buttonPressed(WIIREMOTE_UP)) {

steering_angle = STEERING_ANGLE_MIN;

steering_angle_invert = STEERING_ANGLE_MIN_INVERT;

if (digitalRead(PIN_STEERING_SELECT) == HIGH) {

pulse_steering = map(steering_angle, STEERING_ANGLE_MIN, STEERING_ANGLE_MAX, SERVO_PULSE_MAX, SERVO_PULSE_MIN);

SteeringServo.writeMicroseconds(pulse_steering);

} else {

pulse_steering = map(steering_angle_invert, STEERING_ANGLE_MIN_INVERT, STEERING_ANGLE_MAX_INVERT, SERVO_PULSE_MAX_INVERT, SERVO_PULSE_MIN_INVERT);

SteeringServo.writeMicroseconds(pulse_steering);

}

} else if (wiiremote.buttonPressed(WIIREMOTE_DOWN)) {

steering_angle = STEERING_ANGLE_MAX;

steering_angle_invert = STEERING_ANGLE_MAX_INVERT;

if (digitalRead(PIN_STEERING_SELECT) == HIGH) {

pulse_steering = map(steering_angle, STEERING_ANGLE_MIN, STEERING_ANGLE_MAX, SERVO_PULSE_MAX, SERVO_PULSE_MIN);

SteeringServo.writeMicroseconds(pulse_steering);

} else {

pulse_steering = map(steering_angle_invert, STEERING_ANGLE_MIN_INVERT, STEERING_ANGLE_MAX_INVERT, SERVO_PULSE_MAX_INVERT, SERVO_PULSE_MIN_INVERT);

SteeringServo.writeMicroseconds(pulse_steering);

}

}

#if SERIAL_DEBUG

Serial.print(“\tServo=”);

Serial.print(pulse_steering);

#endif

/* Brake and Throttle */

if (wiiremote.buttonPressed(WIIREMOTE_ONE)) {

if (pulse_esc < ESC_PULSE_NEUTRAL) {

// moving forward before press “One”

brake();

pulse_esc = ESC_PULSE_NEUTRAL;

} else {

// while stopping or moving backward, keep moving backward

pulse_esc = ESC_PULSE_REV_FIX;

}

} else {

if (analog_throttle) {

throttle_angle = getThrottleAngle();

pulse_esc = map(throttle_angle,

THROTTLE_ANGLE_MIN, THROTTLE_ANGLE_MAX,

ESC_PULSE_FWD_MIN, ESC_PULSE_FWD_MAX);

} else if (wiiremote.buttonPressed(WIIREMOTE_TWO)) {

switch (gear) {

case GEAR_1ST:

pulse_esc = ESC_PULSE_FWD_1ST;

break;

case GEAR_2ND:

pulse_esc = ESC_PULSE_FWD_2ND;

break;

case GEAR_3RD:

pulse_esc = ESC_PULSE_FWD_3RD;

break;

default:

pulse_esc = ESC_PULSE_NEUTRAL;

break;

}

} else {

pulse_esc = ESC_PULSE_NEUTRAL;

}

}

ESC.writeMicroseconds(pulse_esc);

//delay(15);

#if SERIAL_DEBUG

Serial.print(“\tESC=”);

Serial.print(pulse_esc);

#endif

/* Throttle mode */

if (wiiremote.buttonClicked(WIIREMOTE_HOME)) {

analog_throttle = !analog_throttle;

if (analog_throttle) {

wiiremote.setLED(WIIREMOTE_LED4); // analog mode

} else {

wiiremote.setLED(WIIREMOTE_LED1); // fixed mode, 1st gear

gear = GEAR_1ST;

}

}

/* Shift up or down */

if (!analog_throttle) {

if (wiiremote.buttonClicked(WIIREMOTE_RIGHT)) {

shiftUp();

} else if (wiiremote.buttonClicked(WIIREMOTE_LEFT)) {

shiftDown();

}

}

/* Fire */

if (wiiremote.buttonPressed(WIIREMOTE_A)) {

digitalWrite(PIN_FIRE_SIGNAL, HIGH);

} else {

digitalWrite(PIN_FIRE_SIGNAL, LOW);

}

/* Head light LED */

if (wiiremote.buttonClicked(WIIREMOTE_PLUS)) {

head_light = !head_light;

if (head_light) {

digitalWrite(PIN_HEAD_LIGHT_SIGNAL, HIGH);

} else {

digitalWrite(PIN_HEAD_LIGHT_SIGNAL, LOW);

}

}

/* Back light LED */

if (wiiremote.buttonClicked(WIIREMOTE_MINUS)) {

back_light = !back_light;

if (back_light) {

digitalWrite(PIN_BACK_LIGHT_SIGNAL, HIGH);

} else {

digitalWrite(PIN_BACK_LIGHT_SIGNAL, LOW);

}

}

} // myapp

int getSteeringAngle(void)

{

double rad;

int deg;

rad = acos((double) wiiremote.Report.Accel.Y);

deg = (int) (rad * 180.0 / PI);

/* clipping */

if (deg > STEERING_ANGLE_MAX) { deg = STEERING_ANGLE_MAX; }

if (deg < STEERING_ANGLE_MIN) { deg = STEERING_ANGLE_MIN; }

return deg;

}

int getSteeringAngleInvert(void)

{

double rad;

int deg;

rad = acos((double) wiiremote.Report.Accel.Y);

deg = (int) (rad * 180.0 / PI);

/* clipping */

if (deg > STEERING_ANGLE_MAX_INVERT) { deg = STEERING_ANGLE_MAX_INVERT; }

if (deg < STEERING_ANGLE_MIN_INVERT) { deg = STEERING_ANGLE_MIN_INVERT; }

return deg;

}

int getThrottleAngle(void)

{

double rad;

double compensate_z;

int deg;

rad = asin((double) wiiremote.Report.Accel.Y);

compensate_z = (double) wiiremote.Report.Accel.Z / cos(rad);

rad = asin(compensate_z);

deg = (int) (rad * 180.0 / PI);

/* clipping */

if (deg > THROTTLE_ANGLE_MAX) { deg = THROTTLE_ANGLE_MAX; }

if (deg < THROTTLE_ANGLE_MIN) { deg = THROTTLE_ANGLE_MIN; }

return deg;

}

inline void brake(void)

{

ESC.writeMicroseconds(ESC_PULSE_BRAKE);

delay(15);

ESC.writeMicroseconds(ESC_PULSE_NEUTRAL);

delay(15);

}

inline void shiftUp(void)

{

if (gear < GEAR_3RD) {

gear++;

wiiremote.setLED( (WIIREMOTE_LED1 << (gear – GEAR_1ST)) );

}

}

inline void shiftDown(void)

{

if (gear > GEAR_1ST) {

gear–;

wiiremote.setLED( (WIIREMOTE_LED1 << (gear – GEAR_1ST)) );

}

}

Internet 제어 Raspberry Pi Camera Rover (Robot)

소개

이 프로젝트의 아이디어는 상기 프로세서로 라즈베리 파이를 사용하여 인터넷을 통해 완전히 제어 로봇을 생성하는 것이다. 로봇은 HTML로 작성된 웹 페이지에 의해 직접 제어 턴에있는 쉘 스크립트 작성 저수준의 명령을 사용하여 제어된다. 우리는 예를 들면 파이썬 같은 고급 언어를 사용하는 사실은, 로봇이 페이지 (인터넷 속도가 느린 경우에도)에 의해 수신 된 명령에 빠르게 반응하도록 야기된다.

아래 링크에서는 어떻게 완성 된 프로젝트를 볼 수 있습니다

이 프로젝트는 두 부분으로 분할하고, 배울 것 1 부에서한다 :

설치 및 GPIO가 RPI를 제어하는 라이브러리 WiringPi를 사용

는 H-Bridge를 사용하여 제어 모터

웹 서버의 RPI 변형

인터넷을 통해 상기 로봇을 제어하기 위해 HTML (자바 스크립트)에 페이지를 만들기

더 나아가 로봇이 현실 세계의 “비전”을 가지고 있는지 확인하기 위해, 당신은 당신이 배울이 튜토리얼의 두 번째 부분에 갈 수 있습니다 :

물어와 비디오 스트림을 생성하는 방법

설치 및 라이브러리 ServoBlaster를 사용하는 방법

서보 모터를 제어하고, 카메라의 수직 및 수평 위치 (WFP / 틸트기구) 메커니즘을 구축하는 방법

인터넷을 통해 카메라의 위치를 제어하기 위하여 HTML 페이지를 작성

 

블록 다이어그램은 아래 날개 프로젝트의 두 부분에 대한 일반적인 생각을 보여줍니다

부 : 인터넷을 통해 조명 및 모터 제어

RPI는 웹 서버로 정의하고 HTML 페이지로부터 명령을 수신한다. 이러한 명령은 RPI 로봇 (방향과 속도)의 모터를 제어 일으키는 개의 GPIO의 상태를 변경 및 / 떨어져 LED에 (시뮬레이션 디지털 제어 시스템을 더)한다. 당신이 볼 수 있듯이, 로봇은 실제로 만약 IoT 프로젝트의 특별한 경우이다. 당신은 실제로 당신이 원하는 것을 제어 할 수 있으며,이 튜토리얼은 새로운 아이디어가 미래에 구현 될위한 출발점이 될하기위한 것입니다.

아래의 그림, 우리는이 첫 번째 부분에서 개발되는의 개요에서 :

자료의 목록

라즈베리 파이 모델 2 또는 3

H 브리지 L293-D

DC 모터 (2 배)

드라이버 9V 배터리

RPI에 배터리 5V

LED와 30 옴의 저항

브레드 보드 및 전선

아크릴 엔진 / 전자 제품에 대한 지원 (키트, CD를, 등을 할 수 있습니다)

도서관 WIRINGPI의 설치

WiringPi는 C로 작성된 라이브러리가 GPIO가의 RPI에 직접 액세스하는 데 사용됩니다. 매우 쉽게 쓸 수 있으며 크게 ( “embebeda 시스템”) RPI 및 전자 관련된 모든 프로젝트를 단순화합니다.

라이브러리 WiringPi는 “GPIO”프로그램 및 GPIO 핀을 구성 할 수 있습니다 (wiringpi.com/the-gpio-utility)라는 유틸리티가 포함되어 있습니다. 당신은 읽기 및 / 또는 쉘 스크립트와 같은 명령의 RPI의 핀에 직접 작성하는 유틸리티를 사용할 수 있습니다. 당신은 GPIO 쉘 스크립트에 명령 정수를 사용하여 프로그램을 작성할 수 있습니다.

WiringPi를 설치하려면 :

git clone git://git.drogon.net/wiringPi

cd wiringPi

./build

유틸리티의 화면 버전을 표시하려면 다음 명령을 사용합니다 :

gpio -v

일반적으로 액세스 모든 핀을 읽고 그 모드를 상호 참조 표를 작성하는 다른 포맷 (wiringPi, BCM_GPIO 핀 및 물리적)의 핀의 상태가 “GPIO의 ReadAll 메쏘드를”명령어를 사용할 수있는 테이블을 제시 현재 값을 표시합니다. 이 명령은 RPI와 파이에 적합한 인쇄도 소나무의 버전 / 모델을 감지합니다.

gpio readall

모니터 화면 아래 위의 두 명령의 항목의 결과를 나타낸다.

예를 들면, 출력으로서 BCM_GPIO 방식을 사용하여 하나의 GPIO를 설정하는 명령을 사용하는 것 :

gpio mode -g 10 out

가능 GPIO 핀이 정의 모드가되면, 당신은 동일한의 논리 상태를 정의 할 수 있습니다. 예에서, 핀은 논리 하이 상태로 이동한다 :

gpio write -g 10 1

그 양극과 GND 사이에 330ohm 저항을 부가 LED GPIO.10 핀의 음극을 설치 테스트합니다. 확실히 모든 것이 작동하는지 확인하기 위해 몇 가지 검사를 수행합니다.

출력 또는 입력으로 핀을 설정할 수있는 것 외에도 PWM 형식의 출력으로서 그 중 일부를 설정할 수있다. 이것은 물리적 핀 12 GPIO.18의 경우이다.

핀을 설정하려면 :

gpio -g mode 18 pwm

또는

gpio mode 1 pwm     참고 : ( “1”) GPIO.18에 WPI ID입니다

PWM 값을 설정합니다 :

gpio pwm 1 XXX     참고 : [XXX 0 사이의 값입니다 -> 1023]

예. :

gpio pwm 1 512       참고 : (50 % 듀티 cicle)

이 핀 particularmante의 구성을 제거하려면 :

gpio unexport 1

모든 핀 구성을 제거하려면 :

gpio unexportall

라즈베리 PI 및 LIBRARY WIRINGPI WITH 제어 모터

이 시점에서, WiringPi 라이브러리가 설치되어 있고 당신은 당신의 RPI의 모니터에 명령 줄에서 직접 GPIO를 제어 할 수 있습니다. 다음 단계는 모터를 제어하기위한 로직을 생성하는 것이다. 이를 위해, 우리는 H-다리의 L-293-D를 사용합니다. 이 H- 브리지는 2 개의 모터를 제어 할 수 있고, 모터의 각각에 대해 입력 3 필수 :

왼쪽 엔진 : “활성화”; “모터 +”와 “모터 -”

모터 오른쪽 : “활성화”; “모터 +”와 “모터 -”

항목에서 두 엔진은 서로 연결되어 “사용”GPIO.18에 의해 제어된다. 이 핀은 속도 제어에 대한 책임이 있습니다. 만약, 속도를 제어하는 “1”로 핀을하게 할 필요가없는 경우, 예를 들어 (+ 5V에 연결).

우리는 왼쪽 엔진이 “앞으로”이동하려는 경우, 우리는 + 모터 (M의 +)를 설정해야합니다, 협약 “1”과 모터 – (M-) “0”. 모터가 반대 방향으로 회전되도록 우리가 대향 할 것이다 : 엔진 + (M +)을 “0”으로 모터 – (M-) “1”이다. 실제로, 엔진의 방향을 정확하게 제어 입력을 정의하는 가장 좋은 방법은 동일한 조립하여 테스트하는 것이다.

우리는 항목의 다리에 개의 GPIO를 할당합니다 :

왼쪽 엔진 + : GPIO.5

왼쪽 모터 : GPIO.6

오른쪽 엔진 + : GPIO.13

오른쪽 엔진 – : GPIO.19

위의 가정에 기초하여, 논리는 GPIO를 테이블에 할당 될 수 수준 (표 화상을 참조)로 구축 할 수있다.

다음 단계는 엔진을 구동하기 위해 쉘 스크립트를 생성하는 것이다.

각 스크립트는 기본적으로 단순 텍스트 파일 형식이다. 텍스트 파일을 실행하려고하면, 운영 체제는 스크립트인지 아닌지를 결정하는 단서를 검색하며, 어떻게 적절하게 처리. 이 때문에, 당신이 알아야 할 몇 가지 지침이있다.

각 스크립트로 시작해야합니다 “#!/bin/bash”(해쉬 – 뱅 해킹}

각각의 새로운 라인은 새로운 명령입니다

주석 행은 #로 시작

명령은 ()에 의해 둘러싸여있다

운영체제 (쉘)은 텍스트 파일을 분석하면 스크립트의 첫 줄이 제작 될 때, 가장 직접적인 방법은 파일을 식별하기 #! / 빈이 / 떠들썩한 파티! 주석 행은 해시 (#)로 시작하지만 다음 OS를 강제 뱅 (!)와 쉘 경로를 추가하는 스크립트를 실행합니다.

예를 들어, “앞으로”이동합니다 모터를 제어하는​​ 쉘 스크립트를 작성하고, 위의 테이블을 기반으로, 우리는 텍스트 편집기를 수행해야하고 I를 사용하고 당신을 위해 가장 적합한 편집기를 사용하여 (아래의 파일을 생성 이것에 대한 NANO) :

sudo nano forward.cgi

#!/bin/bash

gpio -g write 5 1

gpio -g write 6 0

gpio -g write 13 1

gpio -g write 19 0

스크립트가 생성되면, 우리는 당신에게 실행할 수있는 권한을 부여해야합니다 :

sudo chmod 755 forward.cgi

이제 스크립트를 실행합니다 :

sudo ./forward.cgi

LED가 스크립트를 테스트하는 데 사용하고, 실제 엔진은 이후의 단계에서 첨가 될 것이다.

파일 확장자와 같은 것을 사용 .cgi로 참고. CGI는 “공용 게이트웨이 인터페이스”를 의미합니다. 이 웹 서버는 동적 웹 페이지를 생성하는 서버에 설치 실행 프로그램과 상호 작용하는 표준 방법입니다. 이러한 프로그램은 CGI하거나 CGI를 스크립트로 알려져 있습니다; 그들은 일반적으로 스크립팅 언어로 기술되지만, 임의의 프로그래밍 언어로 기록 될 수있다.

계속해서, 같은 아이디어는 상기 테이블의 다른 조합에 적용한다 :

sudo nano stop.cgi

#!/bin/bash

gpio -g write 5 0

gpio -g write 6 0

gpio -g write 13 0

gpio -g write 19 0

sudo nano reverse.cgi

#!/bin/bash

gpio -g write 5 0

gpio -g write 6 1

gpio -g write 13 0

gpio -g write 19 1

sudo nano left.cgi

#!/bin/bash

gpio -g write 5 0

gpio -g write 6 1

gpio -g write 13 1

gpio -g write 19 0

sudo nano right.cgi

#!/bin/bash

gpio -g write 5 1

gpio -g write 6 0

gpio -g write 13 0

gpio -g write 19 1

스크립트를 작성하면 forward.cgi으로 수행되었을 때, 당신은 그들에게 동일하게 실행할 수있는 권한을 부여해야합니다

    sudo chmod 755 stop.cgi

sudo chmod 755 reverse.cgi

sudo chmod 755 left.cgi

sudo chmod 755 right.cgi

이제 모든 것이 작동하는지 확인하기 위해 몇 가지 테스트를 실행합니다 :

./forward.cgi

./left.cgi

./reverse.cgi

./right.cgi

./stop.cgi

좋은 방법은 자주 사용하는 프로그램에 대한 특정 디렉토리가 있고 “빈”을 호출하는 것입니다. 그래서, 우리는 프로젝트에서 사용하는 스크립트를 저장하려면, 우리는 예를 들어, 모든 실행 스크립트를 포함하는 CGI-빈 (또는 바이너리 파일)에 대해 디렉토리를 작성해야합니다.

우리가 우리의 웹 사이트가 위치하며 “VAR”에서 “WWW”디렉토리를 만들어 보자 그 아래, 스크립트 디렉토리 “CGI – bin에”

sudo mkdir /var/www

sudo mkdir /var/www/cgi-bin

이제, 우리는 새로운 디렉토리에있는 모든 파일을 이동 :

sudo mv /*.sgi /var/www/cgi-bin

cd /var/www/cgi-bin

ls 명령을 사용하여 만든 파일을 볼 수 있습니다 :

/ 오프 LED 및 제어 엔진 속도 ON (선택 사항)

우리는 H 브리지 모터 제어를위한 oL293-D로 사용하기 때문에, 우리는 방향을 넘어, 우리는 또한 속도를 제어 할 것인지 여부를 결정해야합니다.

두 가지 가능성이 여기에 :

고정 속도 : 두 개의 저항으로 전압 분배기를 사용하여 연결 핀 1과 + 5V (최대 속도) 또는 다른 비례 값의 다리 (활성화) 9

나무 딸기 파이 GPIO.18에 연결 핀 1과 9 (PWM 출력)

우리는 우리가 조향 제어를 설정했던 것과 같은 방식으로 스크립트의 그룹을 생성합니다 :

sudo nano nospeed.cgi

#!/bin/bash

gpio pwm 1 0

sudo nano lowspeed.cgi

#!/bin/bash

gpio pwm 1 250

sudo nano regularspeed.cgi

#!/bin/bash

gpio pwm 1 512

sudo noano highspeed.cgi

#!/bin/bash

gpio pwm 1 1023

스크립트가 생성되면, 당신은 그들에게 실행할 수있는 권한을 부여해야합니다 :

sudo chmod 755 nospeed.cgi

sudo chmod 755 lowspeed.cgi

sudo chmod 755 regularspeed.cgi

sudo chmod 755 highspeed.cgi

자, 그냥 모든 것이 작동하는지 확인하기 위해 몇 가지 테스트를 실행합니다 :

./lowspeedcgi

./regularspeed.cgi

./highspeed.cgi

./nospeedcgi

테스트를 위해, 우리는 그의 섬광의 강도는 명령이 작동 볼 수 GPIO.18에 LED를 연결합니다.

마지막으로, 우리는 예를 들어, 나 램프를 끄려면 사용되는 디지털 출력을 제어하는​​ 별도의 스크립트를 생성합니다. 우리는이에 대한 GPIO.10을 사용합니다 :

sudo nano llighton.cgi

#!/bin/bash

gpio -g write 10 1

sudo nano llightoff.cgi

#!/bin/bash

gpio -g write 10 0

sudo chmod 755 lighton.cgi

sudo chmod 755 lightoff.cgi

마지막 한가지 다른 단계로 이동하기 전에. 당신이 RPI를 다시 시작하면 개의 GPIO는 입력 기본 상태로 돌아갑니다. 그래서 우리는 모든 부팅의 시작 부분에 실행을 /etc/rc.local 스크립트를 변경해야합니다.

그냥 스크립트의 마지막 명령 (종료 0) 전에 GPIO가 모드 설정 명령을 포함합니다 :

sudo nano /etc/rc.local

gpio -g mode 5 out

gpio -g mode 6 out

gpio -g mode 13 out

gpio -g mode 19 out

gpio -g mode 10 out

gpio mode 1 pwm

exit 0

“출구 0″직전의 커맨드 라인으로서 PWM 명령을 갖는 것이 좋다.

RPI를 시작할 때마다 이제 영사 출력을 제어 할 준비가 될 것이다.

즐길 이제 시스템을 다시 부팅합니다

sudo reboot

설치하기 WEBSERVER

매우 가볍고 빠른 웹 서버입니다 lighttpd를 설치합니다 (예를 들어 대신 아파치 사용할 수 있습니다). 그 위키 페이지에 기재된 바와 같이 “이 Lighttpd 고성능 환경에 최적화 빠르고 유연한 보안 웹 서버가있다. 그것은 다른 웹 서버에 비해 낮은 메모리 풋 프린트를 가지고 있으며, 너무 CPU를로드 할주의하십시오.

이제이 Lighttpd 및 해당 구성 요소를 설치하자 :

sudo apt-get -y install lighttpd

sudo lighttpd-enable-mod cgi

sudo lighttpd-enable-mod fastcgi

기본적으로,이 Lighttpd 디렉토리에 index.html 페이지를 찾을 경우 : / var / www /에서 HTML을. index.html을이 폴더에 직접 저장할 수 있도록하자,이를 변경하자의 경우 : / var / www가. 이를 위해, 당신은이 Lighttpd 구성 파일을 편집해야합니다 :

sudo nano /etc/lighttpd/lighttpd.conf

변경:

server.document-root =“/var/www/html”

으로:

server.document-root =“/var/www”

이 변경 사항을 적용하기 위해 중지하고 웹 서버를 다시 시작해야합니다 :

sudo /etc/init.d/lighttpd stop

sudo /etc/init.d/lighttpd start

이때, 웹 서버가 실행되고 index.html 페이지는 단지 IP 어드레스를 입력 RPI,은 / var / www가, 우리는 브라우저로부터 액세스 할 수 있습니다.

우리는 테스트 목적으로 간단한 페이지를 작성합니다.

첫째, 우리는 페이지 이미지를 저장하는 디렉토리를 작성 :

mkdir /var/www/images

(시험, 난 이미 디렉토리 (/images/robot52.png)에 나에게 .PNG 파일을 보낸 있습니다 :

cd / var / www

sudo index.html nano

<html>

<head>

</head>

<style>

body {background-color: lightyellow}

h1 {color:blue}

</style>

<body>

<div style=”text-align:center”>

<h1>MJRoBot RPi Web Robot Control</h1>

<br><br>

<img src=”/images/robot52.png”>

</body>

</html>

페이지를 편집 완료 후, 저장 및 사용 권한을 변경 :

sudo chmod 755 index.html

지금 내 경우 예를 들어, IP 주소 라즈베리 파이를 브라우저를 열고 입력 : 10.0.0.31을

최종 결과는 아래에 볼 수있다 :

로봇을 제어하기 ONE PAGE의 HTML을 생성하기

의 우리의 웹 사이트를위한 심플한 디자인을 생각하자. 무엇을 할 수 명령?

lighton.cgi 및 lighoff.cgi : 두 개의 버튼은 ==> 스크립트로 작동 켜고 불을 끕니다

모터 제어 방향 다섯 버튼 ==> 스크립트로 작동합니다 forward.cgi, stop.cgi, left.cgi, right.cgi 및 reverse.cgi

모터 속도 제어를위한 네 개의 버튼 ==> escripts 작동합니다 : nospeed.cgi, lowspeed.cgi, regularspeed.cgi 및 highspeed.cgi

우리가 마지막 단계에서 생성 된 HTML의 index.html 파일을 사용하여, 우리는 자신의 스크립트 구현을위한 통화 기능을 설정 버튼이 포함됩니다.

예를 들어,이 LED (GPIO.10)을 점등하는 버튼을 만들 수 있습니다 :

button {

color: blue;

background:lightgrey;

border: 1px solid #000;

border-radius: 8px;

position: center;

}

<button style=”height: 50.0px;width: 100.0px;”><img src=”/images/lighton.png” style=”height: 40.0px;”></button>

HTML 코드는 위의와 둥근 버튼을 만들 것 “밝은 빛.”

버튼을 누를 때, 명령 “의 onclick = LIGHTON는 ()”은 “LIGHTON는 ()”함수를 호출하기 때문에 :

function lighton()

{

xmlhttp.open(“GET”,”cgi-bin/lighton.cgi”,true

xmlhttp.send();

}

LIGHTON () 함수가 호출되기 때문에 그리고, 스크립트가 lighton.cgi와 “짜잔는”LED가 켜집니다 실행됩니다.

동일한 절차가 다른 버튼을 사용한다. 외관을 구성하고 페이지를 작성하는 데 사용되는 다른 HTML 태그가있다.

HTML 소스 파일 (이전 단계에서 사용되는 LED의 구성의 테스트 페이지)에서 볼 수있다 :

HTML 페이지에 링크

ROBOT BODY ASSEMBLY

우선 플랫폼을 찾는 것입니다. 나는 4 DC 모터와 4WD 키트를하기로 결정했다. 이동성 분석은 4WD가 (코너링을 위해) 여기에서 생각하기 때문에 제어가 용이 아니라고하지 않습니다 실현, 우리는 완전한 로봇을 설정하지만, 실제 테스트는 나는 “코스터”를 추가하여 후륜을 사용 just’ll 전면에 ( “rolon”와 같은 탈취제 남아).

몸과 엔진이 제자리에 후에는, 브레드 보드를 포함 모터 연결하고 테스트하는 시간이다. 각각의 모터를 테스트하기 위해 외부 배터리를 사용합니다.

아래 그림과 같이 엔진은 H 브리지 D-L293에 의해 제어됩니다

이 시점에서, 당신은 또한 RPI의 GPIO가 시뮬레이션, 다리의 입력에 + 5V와 GND를 사용하여 모터를 제어, 테스트를 수행 할 수 있습니다.

RPI 설치

모든 corretamante 작동되면, 그것은 라즈베리 파이를 추가하는 시간이다. 전체 회로는 다음과 같습니다 :

작은 섀시와 엔진 사이의 RPI 5V 배터리를 설치합니다. RPI는 상단에 있습니다.

은 RPI를 켜기 전에 모든 케이블 연결을 확인합니다.

이전의 모든 단계가 OK 인 경우에, 당신은 IP 주소 RPI를 사용하여 로봇을 제어 할 수 있습니다.

당신의 마음에 드는 웹 브라우저와 안전한 여행을 엽니 다!

이하, 로봇이 웹 페이지를 사용하여 테스트가 비디오 :

파트 2 : 인터넷 카메라의 비디오 스트리밍 및 원격 제어 (팬 / 틸트)

도입에서 설명하고있는 바와 같이, 로봇은 사물의 인터넷 사업을 개발하는 변명은 거의이다. 우리가 여기 짓을하면 거기에서, 우리는 거의 모든 것을 제어 할 수 있습니다 Internet.The를 통해 GPIO가 RPI를 제어하는 것입니다!

이 두 번째 부분에서, 우리는 고통을 탐구 비디오를 스트리밍하는 방법도 서보 모터를 사용하여 카메라의 위치를 제어하는 방법을 찾을 수 있습니다. 인터넷을 통해 카메라를 제어하는 것은 보안에 사용하기 위해 포함, 여러 용도를 가질 수 있습니다.

궁극적 인 목적은 상기 프로젝트의 두 부분을 결합 만이 인터넷을 통해 제어 할 수없는 로봇을 만들뿐만 아니라, 스트리밍 비디오를 전송하는 것이다.

블록 다이어그램은이 프로젝트의 두 번째 부분의 개념을 도시한다.

RPI는 웹 서버로 프로그래밍 및 HTML 페이지로부터 명령을 수신한다. 이 명령은 위치는 서보 모터 (팬 / 틸트와 수평 / 수직)를 통해 파고, GPIO가 RPI를 제어합니다.

자료리스트

이전 재료의 목록, 우리는 고통과 두 개의 미니 서보 180도를 추가합니다. 그것은 Voltagen 6V 레귤레이터 (7806)는 엔진 전원 같은 이미 설치된 9V 배터리를 사용할 수있게하는 것이 필요하다.

스트리밍 비디오

튜토리얼을 기반으로 비디오 트리머 물기를 설치합니다 :

엘 모타 (업데이트 2014년 1월 19일)가 개발 라즈베리 파이 보드 카메라 비디오 스트리밍.

먼저, 운영 체제를 업데이트 할 수 있도록 :

    sudo apt-get update
    sudo apt-get upgrade
버전 dev에 libjpeg를 설치합니다 :
     sudo apt-get install libjpeg62-turbo-dev
 참고 : libjpeg62-DEV는 현재 무효이며,)이로 대체되었습니다
cmake를 설치합니다 :
    sudo apt-get install cmake
플러그인 raspicam와 MJPG – 유영 다운로드 :
    git clone https://github.com/jacksonliam/mjpg-streamer.git ~/mjpg-streamer
디렉토리를 변경 :
    make clean all
이전  jpg-streamer를 장착합니다 :
    sudo rm -rf /opt/mjpg-streamer
    sudo mv ~/mjpg-streamer/mjpg-streamer-experimental /opt/mjpg-streamer
    sudo rm -rf ~/mjpg-streamer
전송을 시작합니다
    LD_LIBRARY_PATH=/opt/mjpg-streamer/ /opt/mjpg-streamer/mjpg_streamer -i “input_raspicam.so -fps 15 -q 50 -x 640 -y 480” -o “output_http.so -p 9000 -w /opt/mjpg-streamer/www” &
모니터에서는 스트리밍에 대한 정보를 볼 수 있습니다
MJPG Streamer Version.: 2.0
i: fps………….: 15
i: resolution……..: 640 x 480
i: camera parameters…………..:
Sharpness 0, Contrast 0, Brightness 50, Saturation 0,
ISO 400, Video Stabilisation No, Exposure compensation 0
Exposure Mode ‘auto’, AWB Mode ‘auto’,
Image Effect ‘none’, Metering Mode ‘average’,
Colour Effect Enabled No with U = 128, V = 128
Rotation 0, hflip No, flip No
www-folder-path…: /opt/mjpg-streamer/www/
HTTP TCP port…..: 9000
username:password.: disabled
commands……….: enabled
Starting Camera
Encoder Buffer Size 81920
카메라가 작동되어야한다. 브라우저 및 유형으로 이동
    http : // 당신의 IP 주소 : 9000 / stream.html
것과 같은 테스트 페이지 아래 (카메라에 의해 촬영 된 이미지) 표시됩니다.

참고 당신은 당신을 위해 가장 적합한 하나, 통신 포트를 변경하면 RPI 모니터를 입력 한 명령 줄에서 매개 변수 “9000”를 변경하려는 경우. 우리 15 초당 프레임 수 (fps) 640 × 480의 해상도로 작업합니다. 또한 명령 행에 이러한 매개 변수를 변경할 수 있습니다.

당신은 당신이하는 /etc/rc.local 스크립트에 명령을 포함하지 않으면 다음과 같이 드라이브를 시스템이 다시 시작할 때마다 (재부팅)을 시작하려면 위의 명령 줄을 다시 입력해야합니다 :

sudo nano /etc/rc.local

LD_LIBRARY_PATH=/opt/mjpg-streamer/ /opt/mjpg-streamer/mjpg_streamer -i “input_raspicam.so -fps 15 -q 50 -x 640 -y 480” -o “output_http.so -p 9000 -w /opt/mjpg-streamer/www” &

웹 서버가 이미 설치되어있는 반면, 우리는 우리의 페이지에 표시하는 비디오를 스트리밍 다음 줄을 입력해야합니다 :

<iframe src=”http://Your IP Adress:9000/javascript_simple.html” frameborder=”0″ align=”middle” width=”640″ height=”480″ align=”middle” scrolling=”no”>$

위의 라인을 포함하여 아래, 우리는 간단한 HTML 페이지를 볼 수 있습니다

<html>

<head>

</head>

<style>

body {background-color: lightyellow}

h1 {color:blue}

</style>

<body>

<div style=”text-align:center”>

<h1> MJRoBot RPi Web Robot Control   <img style=”height: 100px”src=”/images/robot52.png”> </h1>

<br><br>

<iframe src=”http://10.0.1.31:9000/javascript_simple.html” frameborder=”0″ align=”middle” width=”640″ height=”480″ align=”middle” scrolling=”no”>$

</body>

</html>

브라우저에서 RPI IP를 입력, 우리는 결과 아래에 도달 :

SERVOBLASTER 라이브러리 설치

큰 라이브러리가 서보 모터를 제어하기 위해 사용될 수있다 ServoBlaster

이는 GPIO 핀을 통해 복수의 서보 모터를 제어하기위한 인터페이스를 제공 라즈베리 파이위한 특정 소프트웨어이다. 사용자는, 출력의 펄스 폭을 변경 명령​​을 전송하여 종의 위치를​​ 제어한다. GPIO는 이전 값을 변경하는 새로운 명령을 전달하는 당신에게 펄스 폭을 유지합니다.

기본적으로 ServoBlaster 8 서보 모터를 제어하도록 구성되어 있지만 21 서보로 설정 일반적으로 펄스 폭의 위치를​​ 제어 0.5 밀리 초 2.5 밀리 초 사이 어딘가에 활성 펄스를 필요로 할 수 있습니다 종. 주파수가 중요하지는 않지만 펄스는 약 20 밀리 초마다 반복한다. 펄스는이 서보 위치로 직접 번역이기 네, 그것은 중요 폭.

서보 제어에 더하여, ServoBlaster은 적합한 예를 들면 최대 21 개의 LED의 밝기를 제어하게 0 ~ 100 % (듀티) 사이의 펄스 폭을 생성하도록 구성 될 수있다.

ServoBlaster 당신이 명령을 보낼 수있는 장치 파일은 / dev / servoblaster을 만듭니다. 이 명령의 형식은 다음과 같습니다

[서보 번호] = [서보 위치]

(Ex .: echo P1-11 = 80% >/dev/servoblaster)

또는

P [header] – [pin] = [servo-position]

(Ex: echo P0 = 80% >/dev/servoblaster)

첫째, clonemos는 GitHub의 프로젝트를 Richardghirst :

cd /

sudo git clone https://github.com/richardghirst/PiBits

디렉토리를 변경 :

cd PiBits

cd ServoBlaster

cd user

내용을 나열하고 디렉토리 파일 “servod.c”를 포함하는지 확인

ls

컴파일하고 servod.c 파일을 설치합니다 :

sudo make servod

sudo make install

이 때, servod 프로그램이 설치됩니다. 권한을 변경하고 테스트 할 수 있도록 프로그램을 실행합니다 :

sudo chmod 755 servod

sudo ./servod

모든 것이 OK 경우, 모니터, 다음의 정보에 표시되어야합니다 :

Board model:                     2

GPIO configuration:            P1 (40 pins)

Using hardware:                PWM

Using DMA channel:              14

Idle timeout:             Disabled

Number of servos:                8

Servo cycle time:            20000us

Pulse increment step size:      10us

Minimum width value:            50 (500us)

Maximum width value:           250 (2500us)

Output levels:              Normal

Using P1 pins:               7,11,12,13,15,16,18,22

Servo mapping:

0 on P1-7           GPIO-4

1 on P1-11          GPIO-17

2 on P1-12          GPIO-18

3 on P1-13          GPIO-27

4 on P1-15          GPIO-22

5 on P1-16          GPIO-23

6 on P1-18          GPIO-24

7 on P1-22          GPIO-25

위의 종의 매핑을합니다. 우리는 기본 서보 모터에 의해 구성되어 있지만 카메라 제어의 경우, 예를 들어 단지 우리가에 사용되는 핀을 제한해야하며, (2) 필요 8. 그냥 생각 :

GPIO.17 (P1-11)이 TILT에 사용되는 (수직 제어)

GPIO.23 (P1-16)는 PAN에 사용되는 (수평 제어)

구성 할 핀을 설정하려면 다음 매개 변수를 입력 :

sudo ./servod –p1pins = 11,16

위의 명령을 실행하면, 모니터는 이제 하단에 표시한다 :

사용 P1 핀 : 11.16

서보 매핑 :

0 on P1-11 GPIO-17

1 on P1-16 GPIO-23

또한 당신은 RPI를 다시 시작하면, 설정이 손실 될 수 있습니다, 그래서 /etc/rc.local에의 마지막 명령을 포함하는 것이 중요하다

sudo nano /etc/rc.local

cd /PiBits/ServoBlaster/user

sudo ./servod –p1pins=11,16

cd

아래의 스크립트를 변경하는 것도 중요하다 :

sudo nano /etc/init.d/servoblaster

case “$1” in

start)

/usr/local/sbin/servod $OPTS >/dev/null

change to:

/usr/local/sbin/servod –p1pins=11,16 $OPTS >/dev/null

참조에 대한 전체 스크립트 아래 :

#!/bin/sh

### BEGIN INIT INFO

# Provides:          servoblaster

# Required-Start:    hostname $local_fs

# Required-Stop:

# Should-Start:

# Default-Start:     2 3 4 5

# Default-Stop:      0 1 6

# Short-Description: Start/stop servod.

# Description:       This script starts/stops servod.

### END INIT INFO

PATH=/sbin:/usr/sbin:/bin:/usr/bin

. /lib/init/vars.sh

OPTS=”–idle-timeout=2000″

STATUSFILE=”/tmp/servoblaster-status”

if [ $( id -u ) != 0 ]; then

echo “ERROR: Must be run as root”

exit 1

fi

case “$1” in

start)

/usr/local/sbin/servod –p1pins=11,16 $OPTS >/dev/null<br>        ;;

restart|reload|force-reload)

killall servod

/usr/local/sbin/servod $OPTS >/dev/null

;;

stop)

killall servod

;;

status)

if [ ! -e /dev/servoblaster ]; then

echo “ERROR: /dev/servoblaster does not exist”

exit 2

fi

rm -f $STATUSFILE

echo “status $STATUSFILE” > /dev/servoblaster

sleep 0.2

if [ ! -e $STATUSFILE ]; then

echo “ERROR: servod not responding”

exit 3

elif grep -q “^OK” $STATUSFILE; then

echo “OK”

exit 0

elif grep “^ERROR:” $STATUSFILE; then

exit 4

else

echo “ERROR: No status from servod”

exit 5

fi

;;

*)

echo “Usage: servoblaster [start|stop|status]” >&2

exit 6

;;

esac

exit 0

변경 사항을 영구적 될 수 있도록 지금 시스템을 다시 시작

sudo reboot

이게 다예요. 서보 블래스터가 설치됩니다. 이 순간부터, ServoBlaster이 두 종을 인식 할 수 있습니다 :

servo 0 ==> p1-11

servo 1 ==> p1-16

에코 명령은 동일한 결과로, 위의 형식 중 하나로 실행할 수 있습니다 :

echo P1-11=40% >/dev/servoblaster

echo P1-16=60% >/dev/servoblaster

or

echo 0=40% >/dev/servoblaster

echo 1=60% >/dev/servoblaster

기구 조립 PAN / TILT

이 시장에 여러 팬 / 틸트 메커니즘이 있지만, 난 그냥 종을 묶는 당신이 아래의 사진에서 볼 수 있듯이 물린 함께 매우 간단한을 넣어하기로 결정했다 :

서보를 RPI에 설치하기

위와 같이, RPI에 종의 데이터 케이블을 연결합니다.

은 RPI에 별도의 전압 소스에 + V 두 종을 연결합니다 (물론, GNDS이 연결되어 있어야합니다). 당신이 로봇의 팬 / 틸트 메커니즘을 설치합니다 후에는 DC 모터에 사용 된 것과 동일한 배터리 (9V)를 사용할 수 있습니다. 이 경우에있어서, 6V의 전압 레귤레이터가 요구된다.

서보을 테스트하려면, Servoblaster의 명령 “에코”를 사용합니다. 당신은 백분율로 어느 각도 값을 사용할 수 있습니다. 당신의 팬 / 틸트 메커니즘 최선의 범위를 테스트 :

TILT Servo:

echo P1-11=20% >/dev/servoblaster (looking down)

echo P1-11=60% >/dev/servoblaster (looking front)

echo P1-11=90% >/dev/servoblaster (looking up)

PAN Servo:

echo P1-16=30% >/dev/servoblaster

echo P1-16=62% >/dev/servoblaster

echo P1-16=90% >/dev/servoblaster

우리는 쉽게 스크립트는 종의 위치를​​ 제어 할 수 있습니다. 예를 들어, 우리는 아래의 파일을 작성해야합니다 발견 된 값을 기준으로 카메라 “기대”를 위치 쉘 스크립트를 만들 수 있습니다 :

sudo nano cam_view_front.cgi

#!/bin/bash

echo P1-11=60% >/dev/servoblaster

echo P1-16=62% >/dev/servoblaster

스크립트가 생성되면, 우리는 당신에게 실행할 수있는 권한을 부여해야합니다 :

sudo chmod 755 cam_view_front.cgi

이제 스크립트를 실행합니다 :

./cam_view_front.cgi

에코 명령을 사용하여 임의의 위치에 카메라를 이동 한 다음 새 스크립트를 실행합니다. 당신은 카메라가 자동으로 위치 “정면”으로 돌아갑니다 것을 볼 수 있습니다.

계속해서, 같은 아이디어는 다른 가능한 카메라 위치에 도포한다.

내 페이지를 생성하기 위해, 나는 TILT 5 중간 위치 및 이동하려면 5 중간 위치를 만들하기로 결정했습니다. 당신은 또한 더 단단한 위치의 변화에​​ 대해 “슬라이더”를 사용하도록 선택할 수 있습니다. 당신이 결정한다.

스크립트 “cam_view_front.cgi”에 기재 한 바와 같이 10 개의 새로운 스크립트를 작성, 같은 원리를합니다 사용 :

leftpan.cgi                 ==> 90%

leftcenterpan.cgi     ==> 76%

centerpan.cgi            ==> 62%

rightcenterpan.cgi  ==> 46%

rightpan.cgi               ==> 30%

downtilt.cgi               ==> 20%

downcentertilt.cgi   ==> 40%

centertilt.cgi              ==> 60%

upcentertilt.cgi         ==> 75%

uptilt.cgi                     ==> 90%

카메라를 제어 ONE PAGE의 HTML을 생성하기

우리는 카메라의 스트리밍 만든 index.html을 사용, 우리가 이전에 만든 스크립트를 실행하는 함수를 호출 10 버튼이 포함됩니다.

이하, 전체 HTML 코드 페이지를 만들 수 있습니다 :

index.html을 페이지에 HTML 코드

로봇에 카메라와 종들을 포용.

이제 우리는 우리의 RPI 스트리밍 비디오가 인터넷을 통해 카메라를 배치 할 수 있습니다, 우리는 첫 번째 부분에서 만든 로봇 프로젝트의 두 번째 부분을 통합 할 것이다.

포스트의 선두의 블록도, 프로젝트가 통합 될 수있는 방법을 설명하고 아래 회로 접속 방법을 보여

이어서 두 번째 부분 및 부분의 추가 버튼 및 모터의 제어를위한 제 1 생성 함수로 개발 된 웹 페이지를 가지고.

최종 HTML 페이지로 링크

ROBOT FULL은 생명을 걸립니다!

마지막 단계는 통합기구가 PAN / 로봇의베이스를 기울이다 :

아래 동영상은 어떻게 완전한 로봇을 설명합니다.