M5Stamp-C3でUARTを使う

電子工作
M5Stamp-C3

今回は、M5Stamp-C3に二酸化炭素センサ(MH-Z19C)を接続して、UARTの実験を行ってみました。

ピン配置を見ると、Tx㉑、Rx⑳の表示があります。このピンは、プログラムの書込みを行うUSBと共通で使われているようです。”Serial.begin(9600)”で定義し”Serial”に対して”print”を行うと、ArduinoIDEのシリアルモニタ上に表示されます。このピンを使ってUART接続を行うこともできますが、何かと不便な事もあるので別のピンを使った接続を探りました。

ピン配置を示したシールを見ると、”PORT U”の文字と、D-⑱、D-⑲があります。USB接続に使うピンと思いますが、このピンに”Serial1”の定義を行ってみることにしました。

int RX_PIN = 18;
int TX_PIN = 19;
Serial1.begin(9600, SERIAL_8N1, RX_PIN, TX_PIN);

シリアル-USB変換モジュールを使い、”Serial1″に対して”print”した内容をPC上のシリアルモニタで確認すると、問題なく通信できていることが確認できました。

早速、手元にあった二酸化炭素センサ(MH-Z19C)を繋いで動作確認を行いました。前回のTFT液晶との接続を活かして、測定結果はTFT液晶モジュールに表示します。
(配線が、ぐちゃぐちゃです ^^;;;)
図のとおり、問題なく動作しているのが確認できました。

前回のTFT液晶モジュールとの接続に⑱、⑲ピンを使っていたので、これを⑥、⑦に変更しています。

TFT液晶モジュールM5Stamp-C3
GND(1) ⇔ GND
VCC(2) ⇔ 3.3V
A0(8) ⇔ 4
SDA(9) ⇔ 7
SCK(10) ⇔ 6
CS(15) ⇔ 10
REST(17) ⇔ 5
LED-A(19) ⇔ 3.3V

二酸化炭素センサ(MH-Z19C)との接続は、以下のとおりです。

MH-Z19CM5Stamp-C3
Rx  ⇔ 19
Tx  ⇔ 18
Vin  ⇔ 5V
GND  ⇔ GND

M5Stamp-C3のこの場所は”PORT U”と表示されており、付属の”Grove”コネクタが取付けられるようになっています。”Grove”系のセンサを接続するのには便利ですね。

この状態で、I2C接続に使う⑧、⑨は空けてありますので、さらにBME280などのI2Cインターフェイスを持つセンサを接続することも可能です。 M5Stamp-C3は、ESP32-DevKitC等と比べると非常に小型化されていますので、色々なところに組込んで便利に使えると思います。

一応、MH-Z19Cからデータを取得し、TFT液晶に表示するプログラムソースを載せておきます。(このプログラムで、動作を保証するものではありません。また、フォントのファイルは添付していません。)

#include <Adafruit_GFX.h>
#include <Adafruit_ST7735.h>
#include "Serif_plain_14.h"
#include "DSEG7_Classic_Mini_Regular_30.h"

#define TFT_CS    10
#define TFT_RST    5
#define TFT_DC     4
#define TFT_SCLK   6
#define TFT_MOSI   7
#define BLACK   0x0000
#define BLUE    0x001F
#define RED     0xF800
#define GREEN   0x07E0
#define CYAN    0x07FF
#define MAGENTA 0xF81F
#define YELLOW  0xFFE0
#define WHITE   0xFFFF
Adafruit_ST7735 tft = Adafruit_ST7735(TFT_CS, TFT_DC, TFT_MOSI, TFT_SCLK, TFT_RST);

byte ReadCO2[9] = {0xFF, 0x01, 0x86, 0x00, 0x00, 0x00, 0x00, 0x00, 0x79};
byte SelfCalOn[9]  = {0xFF, 0x01, 0x79, 0xA0, 0x00, 0x00, 0x00, 0x00, 0xE6};
byte SelfCalOff[9] = {0xFF, 0x01, 0x79, 0x00, 0x00, 0x00, 0x00, 0x00, 0x86};
byte retval[9];

int RX_PIN = 18;
int TX_PIN = 19;

void setup() {
  Serial.begin(9600);
  Serial1.begin(9600, SERIAL_8N1, RX_PIN, TX_PIN);
  
  Serial1.write(SelfCalOn, sizeof SelfCalOn);
  delay(5000);
  tft.initR(INITR_GREENTAB);
  tft.fillScreen(BLUE);
  tft.setRotation(3);

  tft.setFont(&Serif_plain_14);
  tft.setTextSize(1);
  tft.setCursor(30, 15);
  tft.setTextColor(WHITE, BLUE);
  tft.print("CO2 Monitor");
}

void loop() {
  uint16_t co2;
  uint16_t old_co2;
  int i;
  char dummy_CO2[10];
  char old_CO2[10];
  bool FLG;
  unsigned long time;

  time = millis();
  for ( i = 0 ; i < 10 ; i++ ) {
    dummy_CO2[i] = 0;
    old_CO2[i] = 0;
  }
  old_co2 = 0;
  
  while (1) {
    Serial1.write(ReadCO2, sizeof ReadCO2);
    Serial1.readBytes((char *)retval, sizeof retval);

    co2 = retval[2] * 256 + retval[3];
    if ( co2 > 20000 ) ESP.restart();
    sprintf(dummy_CO2, "%04d", co2);
    sprintf(old_CO2, "%04d", old_co2);
    tft.setFont(&DSEG7_Classic_Mini_Regular_30);
    tft.setTextSize(1);
    tft.setCursor(40, 70);
    tft.setTextColor(BLUE);
    tft.print(old_CO2);
    tft.setCursor(40, 70);
    tft.setTextColor(WHITE);
    if ( co2 > 1000 ) tft.setTextColor(RED);
    tft.print(dummy_CO2);
    tft.setFont(&Serif_plain_14);
    tft.setTextSize(1);
    tft.setTextColor(WHITE);
    tft.setCursor(120, 100);
    tft.print("ppm");
    old_co2 = co2;
    FLG = true;
    while (FLG) {
      if ( millis() - time >= 5000 ) {
        time = millis();
        FLG = false;
      }
    }
  }
}

コメント

PAGE TOP