
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
Revision 8:6635ca3b5a5c, committed 2015-03-14
- Comitter:
- flatbird
- Date:
- Sat Mar 14 07:52:50 2015 +0000
- Parent:
- 7:6cfe0638b957
- Child:
- 9:774f408b9740
- Commit message:
- fixed
Changed in this revision
--- a/WebSocketServer.cpp Sat Mar 14 00:14:40 2015 +0900 +++ b/WebSocketServer.cpp Sat Mar 14 07:52:50 2015 +0000 @@ -30,6 +30,7 @@ while (true) { bool isWebSocket = false; + printf("accepting\r\n"); int ret = mTCPSocketServer.accept(mConnection); if (ret != 0) { continue; @@ -56,6 +57,7 @@ } } else { if (!this->handleWebSocket(buf, ret)) { + printf("websocket closed\r\n"); break; } } @@ -86,23 +88,23 @@ if (strlen(buf) <= 0) { break; } - printf("%s\r\n", line); + printf("[%s]\r\n", line); if (line == &buf[0]) { char* method = strtok(buf, " "); char* path = strtok(NULL, " "); char* version = strtok(NULL, " "); - printf("[%s] [%s] [%s]\r\n", method, path, version); +// printf("[%s] [%s] [%s]\r\n", method, path, version); } else if (strncmp(line, UPGRADE_WEBSOCKET, strlen(UPGRADE_WEBSOCKET)) == 0) { isUpgradeWebSocket = true; - printf("%s found\r\n", UPGRADE_WEBSOCKET); + printf("*** %s found\r\n", UPGRADE_WEBSOCKET); } else if (strncmp(line, SEC_WEBSOCKET_KEY, strlen(SEC_WEBSOCKET_KEY)) == 0) { - printf("%s found\r\n", SEC_WEBSOCKET_KEY); + printf("*** %s found\r\n", SEC_WEBSOCKET_KEY); isSecWebSocketKeyFound = true; char* ptr = line + strlen(SEC_WEBSOCKET_KEY); while (*ptr == ' ') ++ptr; strcpy(key, ptr); - printf("key=%s\r\n", key); + printf("*** key=%s\r\n", key); } i += 2; line = &buf[i]; @@ -111,6 +113,7 @@ if (isUpgradeWebSocket && isSecWebSocketKeyFound) { this->sendUpgradeResponse(key); + mPrevFin = true; return true; } @@ -129,8 +132,11 @@ bool fin = (*ptr & 0x80) == 0x80; uint8_t opcode = *ptr & 0xF; +// printf("Byte1: %02X\r\n", *ptr); +// printf("fin=%d\r\n", fin); printf("opcode=%d\r\n", opcode); + if (opcode == OP_PING) { *ptr = ((*ptr & 0xF0) | OP_PONG); mConnection.send_all(buf, size); @@ -140,17 +146,22 @@ return false; } ptr++; +// printf("Byte2: %02X\r\n", *ptr); - mPrevFin = fin; - if (!fin || !mPrevFin) { + if (!fin || !mPrevFin) { printf("WARN: Data consists of multiple frame not supported\r\n"); + mPrevFin = fin; return true; // not an error, just discard it } + mPrevFin = fin; - bool mask = (*ptr & 0x80) == 1; + bool mask = (*ptr & 0x80) == 0x80; uint8_t len = *ptr & 0x7F; ptr++; - + +// printf("mask=%d\r\n", mask); +// printf("length=%d\r\n", len); + if (len > 125) { printf("WARN: Extended payload lenght not supported\r\n"); return true; // not an error, just discard it @@ -168,12 +179,15 @@ } if (mHandler) { if (opcode == OP_TEXT) { +// printf("OP_TEXT\r\n"); data[len] = '\0'; mHandler->onMessage(data); } else if (opcode == OP_BINARY) { +// printf("OP_BINARY %d\r\n", len); mHandler->onMessage(data, len); } } +// printf("return true\r\n"); return true; }
--- a/WebSocketServer.h Sat Mar 14 00:14:40 2015 +0900 +++ b/WebSocketServer.h Sat Mar 14 07:52:50 2015 +0000 @@ -6,11 +6,11 @@ class WebSocketHandler { public: - virtual void onOpen() = 0; - virtual void onClose() = 0; - virtual void onMessage(char* text) = 0; - virtual void onMessage(char* data, size_t size) = 0; - virtual void onError() = 0; + virtual void onOpen() {}; + virtual void onClose() {}; + virtual void onMessage(char* text) {}; + virtual void onMessage(char* data, size_t size) {}; + virtual void onError() {}; }; class WebSocketServer
--- a/main.cpp Sat Mar 14 00:14:40 2015 +0900 +++ b/main.cpp Sat Mar 14 07:52:50 2015 +0000 @@ -6,9 +6,22 @@ #include "PowerControl/EthernetPowerControl.h" #endif -#define SSID "wotxwot" +#define SSID "KDDI_hackathon05" #define SEC_TYPE e_SEC_WPA2_AES -#define SEC_KEY "wotpasswd" +#define SEC_KEY "123456789" + +DigitalOut l1(p5); +DigitalOut l2(p6); + +DigitalOut r1(p7); +DigitalOut r2(p8); + +class WSHandler: public WebSocketHandler +{ +public: + virtual void onMessage(char* text); + virtual void onMessage(char* data, size_t size); +}; static bool connectWiFi(); @@ -19,20 +32,24 @@ #if defined(TARGET_LPC1768) PHY_PowerDown(); #endif - while (!connectWiFi()) { - wait(3); - } - - printf("WiFi connected: %s\r\n", wifi.getIPAddress()); + while (true) { + if (!connectWiFi()) { + wait(3); + continue; + } + WebSocketServer server; + WSHandler handler; - WebSocketServer server; + if (!server.init(80)) { + printf("Failed to init server\r\n"); + wait(3); + continue; + } + printf("WiFi connected: %s\r\n", wifi.getIPAddress()); - if (!server.init(80)) { - printf("Failed to init server\r\n"); - return 1; + server.setHandler("/ws", &handler); + server.run(); } - - server.run(); } bool connectWiFi() { @@ -65,3 +82,42 @@ return true; } +void WSHandler::onMessage(char* text) { + printf("TEXT: [%s]\r\n", text); +} + +#define THRESHOLD 30 + +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; + } +} +