2015/09/15
ESP-WROOM-02 Wi-Fiラジコンカー
安価なWi-Fiモジュールを使ってiPhoneから操作するラジコンカーを作りました。
リモコン受信側(ESP-WROOM-02)
受信側はAPモードで動作し、アクセスポイント無しでiPhoneと直接接続します。
左右にギアモータを取付けた台車(バッテリケース)に搭載し、iPhone上のiOSCアプリからのコマンドを受信して動作します。
コマンドは、左右のモータ回転速度、回転方向の制御、ヘッドライトの点灯、警笛の鳴動を用意しました。
*モーターの大きさに比べてフルブリッジが大きめですが、旧作の流用ですので・・
モーターギア:ちっちゃいものくらぶ-超小型ギアモーター
リモコン送信側(iPhone-iOSCアプリ)
Apple Store AppのiOSCを使用します。
iPhoneで操作するiOSCコントローラアプリです。
操作画面を用意されたテンプレートの中から選び、配置されたボタンやスライダを操作した際に送り出すデータ形式を設定するだけで使えます、操作データはUDPパケットとして送出されます。
iOSCから送出されるUDPパケットの内容
- ヘッドライト(ボタン、オルタネイト動作)
/osc/Fxx,ixx0123
0123は32bitバイナリ値、0:OFF、1:ON - 警笛(ボタン)
/osc/Cxx,ixx0123
0123は32bitバイナリ値、0:OFF、1:ON - 左(スライダ)
/osc/Lxx,ixx0123
0123は32bitバイナリ値、0~127:左スライダの位置 - 右(スライダ)
/osc/Rxx,ixx0123
0123は32bitバイナリ値、0~127:右スライダの位置
受信機側回路図
受信機側ソースコード
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 |
#include <ESP8266WiFi.h> #include <WiFiUdp.h> #define LED_Light 2 #define LED_Hone 15 #define PWM_LF 4 #define PWM_LR 12 #define PWM_RF 5 #define PWM_RR 13 const char ssid[] = "ESPCar"; const char pass[] = "ESP8266ap"; WiFiUDP udp; unsigned int localPort = 10000; const int OSC_PACKET_SIZE = 256; char packetBuffer[OSC_PACKET_SIZE]; void setup() { Serial.begin(115200); WiFi.softAP(ssid, pass); IPAddress myIP = WiFi.softAPIP(); Serial.print("AP IP address: "); Serial.println(myIP); Serial.println("Starting UDP"); udp.begin(localPort); Serial.print("Local port: "); Serial.println(udp.localPort()); pinMode(LED_Light, OUTPUT); pinMode(LED_Hone , OUTPUT); pinMode(PWM_LF , OUTPUT); pinMode(PWM_LR , OUTPUT); pinMode(PWM_RF , OUTPUT); pinMode(PWM_RR , OUTPUT); analogWrite(PWM_LF, 0); analogWrite(PWM_LR, 0); analogWrite(PWM_RF, 0); analogWrite(PWM_RR, 0); } void loop() { int rlen, NoData = 0; int Val_L = 0, Val_R = 0, Val_F = 0, Val_C = 0; while (1) { if (!(rlen = udp.parsePacket())) { if (++NoData > 50) { analogWrite(PWM_LF, 0); analogWrite(PWM_LR, 0); analogWrite(PWM_RF, 0); analogWrite(PWM_RR, 0); } delay(10); continue; } NoData = 0; udp.read(packetBuffer, (rlen > OSC_PACKET_SIZE) ? OSC_PACKET_SIZE : rlen); if (strncmp(&packetBuffer[0], "/osc/", 5) == 0) { switch (packetBuffer[5]) { case 'F': Val_F = packetBuffer[15]; digitalWrite(LED_Light, Val_F); break; case 'C': Val_C = packetBuffer[15]; analogWrite(LED_Hone, Val_C ? 512 : 0); break; case 'L': analogWrite(PWM_LF, 0); analogWrite(PWM_LR, 0); Val_L = packetBuffer[15]; if (Val_L >=(64 - 8) && Val_L <= (64 + 8)) { Val_L = 64; } if (Val_L >= 64) analogWrite(PWM_LF, (Val_L - 64) * 16); else analogWrite(PWM_LR, (63 - Val_L) * 16); break; case 'R': analogWrite(PWM_RF, 0); analogWrite(PWM_RR, 0); Val_R = packetBuffer[15]; if (Val_R >=(64 - 8) && Val_R <= (64 + 8)) { Val_R = 64; } if (Val_R >= 64) analogWrite(PWM_RF, (Val_R - 64) * 16); else analogWrite(PWM_RR, (63 - Val_R) * 16); break; } Serial.printf("F=%d, C=%d, L=%4d, R=%4d\n", Val_F, Val_C, Val_L, Val_R); } delay(10); } } |
この記事へのトラックバック URL :
Leave a comment