目的
今回はRaspberryPiとM5StickCPlusでシリアル通信(M5StickCPlus→ラズパイ)を有線で行いたいと思います。
仕様したハード・ソフト
・MacBookPro(2016)
・RaspberryPi 4B
・M5 StickC Plus
・VSCode
・PlatformIO(VSCode拡張機能)
※PlatformIOの導入には以下の記事を参考にさせていただきました。
アジェンダ
- 
M5StickCPlusのコード - 
RaspberryPiのコード - シリアル通信
 
※以下に記載するコードは全てVSCode内拡張機能PlatformIOにて開発しています。
M5StickCPlusのコード
今回M5StickCPlusで行いたいのはシリアル通信にて送信するデータの取得とデータの送信になります。
送信するデータはM5StickCPlusに標準搭載されているIMU(複合センサ)MPU6886の値(Acceleration,Gyro,Pitch,Roll,Yaw)を仕様したいと思います。
使用するライブラリ
#include <M5StickCPlus.h>
今回はM5StickCPlusライブラリのみになります。
こちらのライブラリではM5StickCPlusのセンサやLCD等を利用するためのライブラリです。
変数宣言
//  加速度センサ、角速度センサの値
float accX = 0.0F;
float accY = 0.0F;
float accZ = 0.0F;
float gyroX = 0.0F;
float gyroY = 0.0F;
float gyroZ = 0.0F;
float pitch = 0.0F;
float roll  = 0.0F;
float yaw   = 0.0F;
//
bool isSend = false; // データ送信フラグ
送信するデータ(取得するデータ)は3軸加速度、3軸角速度、三次元ベクトルの回転の計九つになります。
isSendに関しては送信を行う際のフラグになるのでfalseを入れておきます。
セットアップ
void setup() {
  M5.begin();
  M5.IMU.Init();
  Serial.begin(9600);
  
  M5.Lcd.setRotation(3);
  M5.Lcd.setCursor(0,0,4);
  M5.Lcd.println("Not Send");
}
大まかに
- 
M5StickCPlusを使うための設定 - 
IMUを使うための設定 - シリアル通信速度の設定
 - 
LCDの設定 
になります。
ループ
void loop() {
  M5.update();
  if(M5.BtnA.wasPressed()){
    isSend = !isSend;
    if(isSend){
      M5.Lcd.fillScreen(BLACK);
      M5.Lcd.setCursor(0,0,4);
      M5.Lcd.println("Send");
    }
    else{
      M5.Lcd.fillScreen(BLACK);
      M5.Lcd.setCursor(0,0,4);
      M5.Lcd.println("Not Send");
    }
  }
  if(isSend){
    // 加速度データ取得
    M5.IMU.getAccelData(&accX, &accY, &accZ);
    // ジャイロデータ
    M5.IMU.getGyroData(&gyroX, &gyroY, &gyroZ);
    //角度データ
    M5.IMU.getAhrsData(&pitch, &roll, &yaw);
    
    // 加速度データを送信
    Serial.printf("%5.3f,%5.3f,%5.3f,%5.3f,%5.3f,%5.3f,%5.3f,%5.3f,%5.3f\n", accX,accY,accZ,gyroX,gyroY,gyroZ,pitch,roll,yaw);
  }
  delay(200);
}
行っていることは
- ボタンが押されたら処理を実行(
LCDniNot Send or Sendを表示) - 
isSendがTrueになったらデータを取得しシリアル通信を行う 
のみになっています。
コード全体
#include <M5StickCPlus.h>
//  加速度センサ、角速度センサの値
float accX = 0.0F;
float accY = 0.0F;
float accZ = 0.0F;
float gyroX = 0.0F;
float gyroY = 0.0F;
float gyroZ = 0.0F;
float pitch = 0.0F;
float roll  = 0.0F;
float yaw   = 0.0F;
//
bool isSend = false; // データ送信フラグ
void setup() {
  M5.begin();
  M5.IMU.Init();
  Serial.begin(9600);
  
  M5.Lcd.setRotation(3);
  M5.Lcd.setCursor(0,0,4);
  M5.Lcd.println("Not Send");
}
void loop() {
  M5.update();
  if(M5.BtnA.wasPressed()){
    isSend = !isSend;
    if(isSend){
      M5.Lcd.fillScreen(BLACK);
      M5.Lcd.setCursor(0,0,4);
      M5.Lcd.println("Send");
    }
    else{
      M5.Lcd.fillScreen(BLACK);
      M5.Lcd.setCursor(0,0,4);
      M5.Lcd.println("Not Send");
    }
  }
  if(isSend){
    // 加速度データ取得
    M5.IMU.getAccelData(&accX, &accY, &accZ);
    // ジャイロデータ
    M5.IMU.getGyroData(&gyroX, &gyroY, &gyroZ);
    //角度データ
    M5.IMU.getAhrsData(&pitch, &roll, &yaw);
    
    // 加速度データを送信
    Serial.printf("%5.3f,%5.3f,%5.3f,%5.3f,%5.3f,%5.3f,%5.3f,%5.3f,%5.3f\n", accX,accY,accZ,gyroX,gyroY,gyroZ,pitch,roll,yaw);
  }
  delay(200);
}
以上がM5StickCPlusのコードになります。
RaspberryPiのコード
使用するライブラリ
import serial
import time
serialとはpySerialライブラリのことであり、pip3でインストールする必要があります。
今回はこのライブラリを用いてシリアル通信を行なっていきます。
注意
serialでインポートできるライブラリとしてpySerialライブラリの他にserialライブラリも存在しています。
私はpipインストールの際に間違えて両方入れてしまいコードが動作しなかったため、uninstallしました。
デバイスのポート指定
ser = serial.Serial("/dev/ttyUSB0", 9600, timeout=0.1)
USBによるシリアル通信を行うためにどのポートで送受信を行うのかを指定する必要があります。
9600という数字はM5StickCPlusuの方でも指定したものと同じ通信速度にしてください。
"/dev/ttyUSB0"という箇所はご自分の機器にて接続した状態で以下のようなlsコマンドを入力して検出できたものにしてください。
ls /dev/ttyUSB*
このような表記が出ます。
コード全体
import serial
import time
ser = serial.Serial("/dev/ttyUSB0", 9600, timeout=0.1)
time.sleep(2) 
       
try:
    while True: 
        # print("test")    
        if ser.in_waiting > 0: # シリアル通信 受信待ち
            bytes = ser.readline()
            result, buf = bytes.decode('utf-8').split('\n')
            data = list(map(float, result.split(',')))
            print("AccX: {0}, AccY: {1}, AccZ: {2},GyroX: {3}, GyroY: {4}, GyroZ: {5},Pitch: {6}, Roll: {7}, Yaw: {8}".format(data[0], data[1], data[2], data[3],data[4],data[5],data[6],data[7],data[8]))
            
        time.sleep(0.2)
except KeyboardInterrupt:
    pass
print('program end')
ser.close()
短いので全体を載せてしまいます。
行なっていることは単純でシリアル通信にて受信したデータをlist型に格納しそれらをプリントしているのみです。
実行
ラズパイとM5StickCPlusをUSBケーブルにて接続しボタンを押すと...

値を取得することができました。
以上で目標達成です。
