M5StickCで速度と進行方向を表示する ~ ラズパイと連携

2021年3月7日

今までも、車載用の速度計をRaspberry Piを用いて作りました。しかし、表示器を設置する場所や、GPSセンサーを受信条件の良い場所に設置するなどの制約で、使い勝手が良くありませんでした。

また、スマートフォンを活用するなど、いろいろな方法も考えて試してみましたが、今のところ一番使い勝手が良いかなと思う方法を今回は紹介します。

それは、Raspberry PiGPSデータを受信し、M5StickCで表示させるというものです。Raspberry PiからUDPソケット通信でM5StickCにデータを送信します。Raspberry PiM5StickCは、条件の良い場所に設置します。

それでは、詳しく説明します。

Raspberry Pi側プログラム

これまで提供してきた「FormGPS」プログラムに、UDP送信ロジックを追加しました。提供記事からプログラムをダウンロードしてください。

起動すると、入力項目に送信先のIPアドレスがあります。送信先のIPアドレスが分かり次第、入力してください。入力後は「IP SET」ボタンを押すことでIPアドレスが有効になります。

なお、送信データは、"速度(3桁),進行方向(2文字)“のテキストデータですから、オリジナルのプログラムを作成してもらっても構いません。

M5StickC側プログラム

プログラムの仕組み自体は、今まで公開した高度表示などのプログラムと変わりません。UDPソケット通信で、速度と進行方向が渡ってくるので、それを表示します。

// Raspberry PiからGPS速度と方角を取得する
// UDP : speed,direction

#include <M5StickC.h>
#include <WiFi.h>
#include <WiFiUdp.h>
 
#define BUFSIZE 1024
 
const char* ssid     = "XXXXXXXX";
const char* password = "XXXXXXXX";
const int port = 60000;

WiFiUDP udp;

void print_wifi_state(){
  M5.Lcd.fillScreen(BLACK);
  M5.Lcd.setTextColor(YELLOW);
  M5.Lcd.setCursor(3, 3);
  M5.Lcd.println("WiFi connect");
  M5.Lcd.print("IP address: ");
  M5.Lcd.println(WiFi.localIP());
  M5.Lcd.print("Port: ");
  M5.Lcd.println(port);
  
}
 
void setup_wifi(){
 
  M5.Lcd.setTextColor(RED);
  M5.Lcd.setTextSize(2);
  M5.Lcd.setCursor(3, 3);
  M5.Lcd.print("Connecting to ");
  M5.Lcd.println(ssid);
 
  WiFi.mode(WIFI_STA);
  WiFi.begin(ssid, password);
 
  while (WiFi.status() != WL_CONNECTED) {
    delay(100);
    M5.Lcd.print(".");
  }
 
  print_wifi_state();
  
  udp.begin(port);
}


void setup() {
  M5.begin();

  M5.Lcd.setRotation(3);
  M5.Lcd.fillScreen(BLACK);
  
  setup_wifi();
}

void split(String data, String *lines){
  int count = 0;
  int datalength = data.length();
  for (int i = 0; i < datalength; i++) {
    char onec = data.charAt(i);
    if ( onec == ',' ) {
      count++;   
      if ( count == 2) {
        break ;
      }  
    }
    else {
      lines[count] += onec;
    }
  }
}

void loop() {
  char packetBuffer[BUFSIZE];
  String lines[2] ;

  // M5.update();

  int packetSize = udp.parsePacket();
 
  if (packetSize){

    int len = udp.read(packetBuffer, packetSize);
    if (len > 0){
      packetBuffer[len] = '\0';
    }
    split(packetBuffer, lines) ;

    M5.Lcd.fillScreen(BLACK);
    M5.Lcd.setTextSize(1);

    M5.Lcd.setTextColor(GREEN);
    M5.Lcd.setCursor(3, 10, 7);  //x,y,font 7:48ピクセル7セグ風フォント
    M5.Lcd.printf("%03d", lines[0].toInt()); // 速度を表示

    Serial.println("Speed=");
    Serial.println(lines[0]);

    float direction = lines[1].toInt() ;
    
    M5.Lcd.setTextColor(WHITE);
    M5.Lcd.setCursor(105, 34, 4);  //x,y,font 4:26ピクセルASCIIフォント

    if ((direction >=337.5 && direction <= 360) ||
        (direction >=0 && direction <= 22.5)) {
          // 北
          M5.Lcd.println("N");
    } else if (direction > 22.5 && direction < 67.5) {
          // 北東
          M5.Lcd.println("NE");
    } else if (direction >=67.5 && direction <= 112.5) {
          // 東
          M5.Lcd.println("E");
    } else if (direction >112.5 && direction < 157.5) {
          // 南東
          M5.Lcd.println("SE");
    } else if (direction >=157.5 && direction <= 202.5) {
          // 南
          M5.Lcd.println("S");
    } else if (direction >202.5 && direction < 247.5) {
          // 南西
          M5.Lcd.println("SW");
    } else if (direction >=247.5 && direction <= 292.5) {
          // 西
          M5.Lcd.println("W");
    } else if (direction >292.5 && direction < 337.5) {
          // 北西
          M5.Lcd.println("NW");
    } else {
          // ERROR
          M5.Lcd.println("XX");
    }
    
    // M5.Lcd.setTextColor(WHITE);
    // M5.Lcd.setCursor(25, 65, 1);  //x,y,font 1:Adafruit 8ピクセルASCIIフォント
    // M5.Lcd.println(lines[1]);   // 方角を表示
    
    Serial.println("Direction=");
    Serial.println(lines[1]);
  }

}

起動すると、Wi-Fiに接続が行われ、成功するとIPアドレスが表示されます。表示されたIPアドレスを、送信側で設定してください。

UDPソケット受信に成功すると、速度と進行方向(N,E,S,W,NE,SE,SW,NW)が表示されます。M5StickCの内部バッテリーだけなら、1時間位でバッテリー切れになるでしょう。外部のバッテリーを用意してください。

実際に動作させてみる

助手席に置いたラズパイ (座布団の柄が。。。)

Raspberry Pi助手席に、M5StickCダッシュボードに設置します。最初はM5StickCをメーター類の空いている場所に置こうと思ったのですが、今一つしっくりしません。結局、ダッシュボードの1Dinスペースに置きました(最初の写真)。

スマートフォンテザリングをしてWi-Fiを有効にします。Raspberry PiM5StickCは、どちらを先に起動しても構いません。起動後は、M5StickCIPアドレスRaspberry Piのアプリ「FormGPS」に設定してください。

Raspberry Piは、スマートフォンVNCクライアントを使って操作しました。

実際に使ってみて、M5StickCの液晶は、日が当たっても良く見えるところが良いです。速度と進行方向が良く見えて、キャラクタ表示液晶スマートフォンでの表示よりも見やすく感じます。

進行方向は、日本語か、矢印をビットマップで表示した方が良いと感じました。これは、いずれ改良したいです。

これからも試行錯誤してみます

今回は速度と進行方向でしたが、高度もそのうちに用意してみます。また、ヘッドアップディスプレイにしてみるなど、試行錯誤をしていきたいと思います。