在前幾篇文章中我們有嘗試使用 PixelBit 的 ESP32 以及 ATmega328p 互相通訊,但有些讀者認為有些複雜與凌亂,這次我們將會嘗試簡化 UART 之間的通訊方式,實作相關 Library,讓大家能更容易使用,在不降低效率前提下讓程式碼可讀性更高。
概念上如下
時常在做專案時會因為硬體限制,無法透過單一 MCU 操控所有硬體,例如:
PixelBit 就是屬於第一種情況,需要透過其他方式擴展 IO 數量,常用的擴展方式有幾種:
PixelBit 擴展 IO 方案選擇外掛一顆 MCU(ATmega328P),讓我們多了一般 IO 、PWM IO、I2C、SPI、ADC、Interrupt IO,算是一種”都來一點”的概念,優點是可以使用既有的 Library(ex: DHT11 22 Library) 透過各種通訊方式搭配其他感測器,在效率方面也會比較好,讓兩邊 MCU 能專心做各自的工作,缺點是使用者需要寫兩套程式(ESP32、ATmega328P),並透過 UART 互相溝通,當專案功能越多越複雜時對於時序觀念較不熟悉的開發者就會較為困難。
這次我們的目標就是要簡化 ESP32 與 ATmega328P 之間的各種通訊問題,解決問題大致如下:
基於以上情境範例程式碼如下:
#include "CircusUart.h"
CircusUart uart(Serial);
void setup()
{
Serial.begin(57600);
uart.on("Temp", ':', [](const char *temp) {
// temp = "24.6"
// TODO: upload temperature to cloud
});
uart.on("Humi", ':', [](const char *humi) {
// humi = "68.7"
// TODO: upload humidity to cloud
});
uart.on("SW_A", '\0', [](const char *data) {
// TODO: Get pictures from camera and upload to cloud
});
}
void loop()
{
uart.loop();
if (收到使用者輸入馬達速度) {
uart.send("Motor", ':', "128");
}
static uint32_t timer = 0;
if (millis() > timer) {
timer = millis() + 1000;
uart.send("Temp");
uart.send("Humi");
}
}
#include "CircusUart.h"
CircusUart uart(Serial);
void setup()
{
Serial.begin(57600);
uart.on("Temp", '\0', [](const char *temp) {
uart.send("Temp", ':', "24.6");
});
uart.on("Humi", ':', [](const char *humi) {
uart.send("Humi", ':', "68.7");
});
uart.on("Motor", ':', [](const char *speed) {
// speed = "128"
// TODO: Set Motor Speed 128
});
}
void loop()
{
uart.loop();
if (digitalRead(SWA_PIN)) {
uart.send("SW_A");
}
}
Library 內容也很簡單,我們明天再講,今天禮拜天好累明天見