Simple WebSocket server to control a tank.
Dependencies: SNICInterface_mod WebSocketServer mbed-rtos mbed PowerControl C12832
au Firefox OS WoTハッカソン on ホワイトデーで使用した、タンクを動かすプログラムです。 ゲームパッドでタンクを操縦します。
ゲームパッドは PC に接続し、ブラウザ上の Web アプリから Gamepad API で入力を取得します。 取得した入力データは WebSocket で mbed 上の WebSocket サーバに送信します。
WebSocket サーバのコードはライブラリ化したので、他のプログラムでもインポートして使えます。
使用した機材
- LPC1768
- Murata TypeYD
- LPC1768 用アプリケーションボード
- TAMIYA トラック&ホイールセット
- TAMIYA ダブルキヤボックス(左右独立4速タイプ)
- TAMIYA ユニバーサルプレート
- TOSHIBA TA7291P x 2
- その他、モバイルバッテリー、電池ボックス等
左右のモータードライバにそれぞれ LPC1768 の p12, p13 と p14, p15 のピンを割り当てていますが、必要に応じてコードを変更してください。
コントローラー側(Webアプリ)
https://github.com/chikoski/wotxwot-control
Firefox ブラウザで動作確認しています(他のブラウザでは動かないかも)。 ゲームパッドの左右のスティックの前後の操作が左右それぞれのモータの前転・後転に対応しています。
動いているところの動画
https://www.facebook.com/video.php?v=456620974491805
ハッカソンでは ARM 賞をいただきました!
(参考) au Firefox OS WoTハッカソン on ホワイトデー
http://au-fx.kddi.com/event/20150314/wot_hackathon0314.html
main.cpp
- Committer:
- flatbird
- Date:
- 2015-03-16
- Revision:
- 10:578778037efb
- Parent:
- 9:774f408b9740
- Child:
- 11:a66b3b2aeb6c
File content as of revision 10:578778037efb:
#include <stdarg.h> #include <stdio.h> #include "mbed.h" #include "SNIC_WifiInterface.h" #include "SNIC_Core.h" #include "WebSocketServer.h" #if defined(TARGET_LPC1768) #include "PowerControl/EthernetPowerControl.h" #endif #include "C12832.h" #define SSID "your_wifi_ssid" #define SEC_TYPE e_SEC_WPA2_AES #define SEC_KEY "your_wifi_password" #if defined(TARGET_LPC1768) C12832 lcd(p5, p7, p6, p8, p11); #endif DigitalOut l1(p12); DigitalOut l2(p13); DigitalOut r1(p14); DigitalOut r2(p15); class WSHandler: public WebSocketHandler { public: virtual void onMessage(char* text); virtual void onMessage(char* data, size_t size); virtual void onOpen(); virtual void onClose(); }; static bool connectWiFi(); static void lcd_printf( const char* fmt, ... ); // tx, rx, cts, rts, reset, alarm=NC, baud=115200 C_SNIC_WifiInterface wifi(p9, p10, NC, NC, p30); int main() { #if defined(TARGET_LPC1768) PHY_PowerDown(); #endif while (true) { if (!connectWiFi()) { wait(3); continue; } WebSocketServer server; WSHandler handler; if (!server.init(80)) { printf("Failed to init server\r\n"); wait(3); continue; } server.setHandler("/ws/", &handler); server.run(); } } bool connectWiFi() { printf("connecting wifi\r\n"); lcd_printf("connecting wifi\r\n"); int ret = wifi.init(); if (ret != 0) { printf("ERROR: Failed to init wifi %d\r\n", ret); return false; } wait(0.5); ret = wifi.disconnect(); if (ret != 0) { printf("ERROR: Failed to disconnect wifi %d\r\n", ret); return false; } wait(0.3); wifi.connect(SSID, strlen(SSID), SEC_TYPE, SEC_KEY, strlen(SEC_KEY)); if (ret != 0) { printf("ERROR: Failed to connect wifi %d\r\n", ret); return false; } wait(0.5); wifi.setIPConfig(true); wait(0.5); printf("WiFi connected: %s\r\n", wifi.getIPAddress()); lcd_printf("connected: %s\r\n", wifi.getIPAddress()); return true; } void lcd_printf( const char* fmt, ... ) { char buffer[ 64 ]; va_list ap; va_start( ap, fmt ); vsnprintf( buffer, 64, fmt, ap ); va_end( ap ); lcd.cls(); lcd.locate( 0, 3 ); lcd.printf( buffer ); } void WSHandler::onMessage(char* text) { printf("TEXT: [%s]\r\n", text); } void WSHandler::onOpen() { lcd_printf("websocket opened\r\n"); } void WSHandler::onClose() { lcd_printf("websocket closed\r\n"); } #define THRESHOLD 20 void WSHandler::onMessage(char* data, size_t size) { int8_t lv = data[0]; int8_t rv = data[1]; printf("[%d/%d]\r\n", lv, rv); // 0 0 free // 0 1 normal rotation // 1 0 reverse rotation // 1 1 brake if (lv <= -THRESHOLD) { // normal l1 = 0; l2 = 1; } else if (lv >= THRESHOLD) { // reverse l1 = 1; l2 = 0; } else { // free l1 = 0; l2 = 0; } if (rv <= -THRESHOLD) { // normal r1 = 0; r2 = 1; } else if (rv >= THRESHOLD) { // reverse r1 = 1; r2 = 0; } else { // free r1 = 0; r2 = 0; } }