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;
    }
}