tinkering好きの素人

ものづくりの記録

M5Stack ディスプレイへのpythonシリアル通信で日本語全角表示と半角表示を切り替えられるようにした

pythonスクリプトからシリアル通信で文字列を送信し、全角日本語文字と半角英語を表示できるようにしたかった。(ここではM5Stackと同時にArduinoにもつないでいます)

python -> M5Stack のシリアル通信にはpyserialを使用。(pip install pyserial)

import serial, time

def main():
    #  COMポートを開く
    print("Open Port")
    ser =serial.Serial("/dev/cu.#シリアルポート", 115200)#M5Stackへ
    ser2 = serial.Serial("/dev/cu.#シリアルポート",9600)#Arduinoへ
    while True:
        
        ser.write('ありがとうございます\0。漢字もだせるのかな\0?カタカナはどうでしょ\0\1'.encode('utf-8'))#出したい文字列をバイト列にしてutf-8エンコード
        ser2.write(b'1')
        time.sleep(4)#4秒ごとにきりかえ
        
        ser.write("'age': 22.0\n'gender': 'female'\n'smile': 0.0\n'hair': 'brown'\n\2".encode('utf-8'))
        ser2.write(b'0')
        
        time.sleep(4)

    print("Close Port")
    ser.close()
    
    
main()


Arduino側のコードは
qiita.com
のライブラリを使わせていただき、

#include <M5Stack.h>
#include <sdfonts.h>

#define SD_PN 4

// フォントデータの表示
// buf(in) : フォント格納アドレス
// ビットパターン表示
// d: 8ビットパターンデータ
void fontDisp(uint16_t x, uint16_t y, uint8_t* buf) {
  uint32_t txt_color = TFT_WHITE;
  uint32_t bg_color = TFT_BLACK;

  uint8_t bn = SDfonts.getRowLength();               // 1行当たりのバイト数取得
//  Serial.print(SDfonts.getWidth(), DEC);            // フォントの幅の取得
//  Serial.print("x");
//  Serial.print(SDfonts.getHeight(), DEC);           // フォントの高さの取得
//  Serial.print(" ");
//  Serial.println((uint16_t)SDfonts.getCode(), HEX); // 直前し処理したフォントのUTF16コード表示

  for (uint8_t i = 0; i < SDfonts.getLength(); i += bn ) {
    for (uint8_t j = 0; j < bn; j++) {
      for (uint8_t k = 0; k < 8; k++) {
        if (buf[i + j] & 0x80 >> k) {
          M5.Lcd.drawPixel(x + 8 * j + k , y + i / bn, txt_color);
        } else {
          M5.Lcd.drawPixel(x + 8 * j + k , y + i / bn, bg_color);
        }
      }
    }
  }
}


// 指定した文字列を指定したサイズで表示する
// pUTF8(in) UTF8文字列
// sz(in)    フォントサイズ(8,10,12,14,16,20,24)
void fontDump(uint16_t x, uint16_t y, char* pUTF8, uint8_t sz) {
  uint8_t buf[MAXFONTLEN]; // フォントデータ格納アドレス(最大24x24/8 = 72バイト)
  SDfonts.open();                                   // フォントのオープン
  SDfonts.setFontSize(sz);                          // フォントサイズの設定
  uint16_t mojisu = 0;
  while ( pUTF8 = SDfonts.getFontData(buf, pUTF8) ) { // フォントの取得
    fontDisp(x + mojisu * sz, y, buf);                 // フォントパターンの表示
    ++mojisu;
  }

  SDfonts.close();                                  // フォントのクローズ
}

char printchar;


void setup() {
  Serial.begin(115200);

  M5.begin();

  M5.Lcd.setBrightness(100);
  M5.Lcd.fillScreen(TFT_BLACK);

  SDfonts.init(SD_PN);
}

char buff[255];
char kara[255];
int counter = 0;
int LED = 13;
int gyo = 0;
int flag = 0;

void loop() {
  // put your main code here, to run repeatedly:
  while(Serial.available()){
    if(gyo == 0){
      M5.Lcd.fillScreen(TFT_BLACK);
    }
    char inChar = char(Serial.read());
    buff[counter] = inChar;
    counter++;  
    if (inChar == '\0' && flag == 1){
      //全角
      fontDump(10, 10+gyo*30, buff, 24);
      gyo++;
      Serial.println(buff);
      counter = 0;
      digitalWrite(LED, HIGH);
      buff = '';
      memset(buff,'\0',sizeof(buff));
      
    }else if (inChar == '\n' && flag == 0){
      //半角
      M5.Lcd.setTextSize(2);
      M5.Lcd.drawString(buff,10,10+gyo*30);
      gyo++;
      Serial.println(buff);
      counter = 0;
      memset(buff,'\0',sizeof(buff));
          }else if(inChar == '\1'){
        flag=0;
        counter = 0;
        gyo = 0;
      }else if(inChar == '\2'){
        flag=1;
        counter = 0;
        gyo = 0;
      }
  }
}

f:id:minoritytech:20200818113203p:plain
f:id:minoritytech:20200818113550p:plain