今回は、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-Z19C | M5Stamp-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;
}
}
}
}
コメント