การสร้าง IoT sensor ด้วยบอร์ด Cucumber RS

Supachai Vorapojpisut
4 min readSep 22, 2021

--

ปีนี้จัดเป็นวิกฤติที่ต้องปรับการเรียนการสอนมาเป็นระบบออนไลน์แบบฉุกละหุกเนื่องจากปัญหาโควิด-19 เลยส่งผลกระทบกับวิชาแลปที่จะให้นักศึกษามาเรียนรู้การสร้างระบบการวัดตั้งแต่การต่อเซ็นเซอร์ไปจนถึงการวิเคราะห์ข้อมูล ช่วงนี้เลยต้องมองหาฮาร์ดแวร์สำหรับการทดลองที่เปิดให้นักศึกษาสามารถได้ไอเดียของความสัมพันธ์ระหว่าง กายภาพ — สัญญาณ — ข้อมูล ซึ่งจำเป็นมากสำหรับนักศึกษาส่วนใหญ่ที่หลักการยังไม่ค่อยแม่นแถมแนวคิดของนามธรรมก็ไม่ค่อยมี ตัวเลือกที่ price/performance ดีที่สุดในตลาดคือ บอร์ด Cucumber รุ่น RS ของ Gravitech ที่ตั้งราคาขายไว้แค่ 405 บาทไม่รวม VAT ซึ่งมีเซ็นเซอร์บนบอร์ดมาด้วยถึง 3 ตัวคือ

  • เซ็นเซอร์ HTS221 ของ ST Microelectronics สำหรับวัดอุณหภูมิ (-40 ~ 120 °C) และความชื้น (0 ~ 100 %RH) ซึ่งเป็นช่วงที่พอเหมาะกับการวัดสภาพแวดล้อมในชีวิตประจำวัน
  • เซ็นเซอร์ BMP280 ของ Bosch สำหรับวัดความดันอากาศแบบสัมบูรณ์ (300 ~ 1100 hPa) ซึ่งแม้จะไม่ละเอียดมากในการวัดความสูงแบบ altimeter (> 1 เมตร) แต่พอใช้ตรวจสอบสภาพแวดล้อมหรือตรวจจับความสูงของตึกได้
  • เซ็นเซอร์ MPU-6050 ของ TDK InvenSense ที่ภายในประกอบด้วยเซ็นเซอร์วัดความเร่งแบบ 3 แกน (ย่านสูงสุด ±16g) และไจโรสโคปแบบ 3 แกน (ย่านสูงสุด ±2000 องศา/วินาที) สำหรับตรวจจับการเคลื่อนไหว
บอร์ด Cucumber RS

หน่วยประมวลผลบนบอร์ด Cucumber RS คือ ESP32-S2 เพิ่งถูกรวมเข้าใน Arduino Core for ESP32 รุ่น 2.0.0 แบบ stable release เมื่อเดือนสิงหาคม 64 ที่ผ่านมาการเขียนโค้ดด้วย Arduino IDE จึงสะดวกมากขึ้น เพราะไม่ต้องมีขั้นตอนการติดตั้ง ESP-IDF toolchain รุ่นใหม่ ผมจึงอัพเดทบทความที่เคยโพสต์ที่ใช้ขั้นตอนติดตั้งพิเศษมาเป็น Arduino Core for ESP32 รุ่น 2.0.0 และแถมเนื้อหาในส่วน WiFi และ MQTT อีกหน่อย เพื่อให้สามารถส่งข้อมูลผ่านอินเตอร์เน็ตได้ด้วย

hello บนบอร์ด Cucumber RS

บอร์ด Cucumber ใช้โมดูล ESP32-S2-WROVER โดยมีหน่วยประมวลผล ESP32-S2 ที่มีจุดเด่นทั้งในแง่ประสิทธิภาพการประมวลผล (32bit/240MHz/4MB flash/2MB RAM) และการสื่อสารไร้สายผ่านโครงข่าย WiFi การเตรียมเครื่องมือพัฒนาสำหรับบอร์ด Cucumber RS จะเหมือนกับบอร์ด ESP32 ทั่วไปเมื่อใช้ Arduino Core for ESP32 รุ่น 2.0.0 ดังนี้

  1. ดาวน์โหลดและติดตั้ง Arduino IDE
  2. ติดตั้ง Arduino Core for ESP32 โดยเปิดเมนู File > Preferences แล้วกรอก URL ลงในช่อง Additional Board Manager URLs
    https://raw.githubusercontent.com/espressif/arduino-esp32/gh-pages/package_esp32_index.json
  3. ติดตั้ง ESP32 โดยเลือกเมนู Tools > Board > Boards Manager จากนั้นค้น esp32 แล้วติดตั้ง
  4. ติดตั้งไดรเวอร์ FTDI แล้วเสียบบอร์ด Cucumber RS กับคอมพิวเตอร์
การป้อน URL สำหรับติดตั้ง board manager
การเลือกติดตั้ง Arduino Core for ESP32

การเขียนโค้ดทดสอบเบื้องต้นใช้ Hello world แบบกระพริบ LED (ขา IO2) โดยใช้โค้ดตัวอย่าง เลือกบอร์ดเป็น ESP32S2 Dev Module และพอร์ตสื่อสาร จากนั้นกดปุ่ม Upload เพื่อ build และ deploy

void setup() {
Serial.begin(115200);
pinMode(2, OUTPUT);
}
void loop() {
Serial.println("Hello");
digitalWrite(2, !digitalRead(2)); // toggle LED
delay(1000);
}
ทดสอบโค้ด hello

การสร้าง IoT sensor

บอร์ด Cucumber รุ่น RS มาพร้อมเซ็นเซอร์ 3 ตัวคือ HTS221 สำหรับวัดอุณหภูมิ/ความชื้น BMP280 สำหรับวัดความดันอากาศ และ MPU-6050 สำหรับตรวจจับการเคลื่อนไหว ซึ่งทั้งสามเซ็นเซอร์จะเชื่อมต่อกับหน่วยประมวลผลทางพอร์ต I2C0 ทางขา IO12/IO13 การเขียนโค้ดสามารถเรียกใช้ไลบรารีของเซ็นเซอร์ที่พัฒนาโดย Adafruit ได้ ในขณะที่การสื่อสารแบบ IoT สามารถใช้ไลบรารี ESPAsync_WiFiManager เพื่อตั้งค่า SSID/passphrase สำหรับเชื่อมต่อโครงข่าย WiFi จากนั้นจึงใช้ไลบรารี PubSubClient เพื่อเชื่อมต่อ MQTT broker เช่น NETPIE

การเตรียมการสำหรับพัฒนาโค้ด IoT มีขั้นตอนดังนี้

  1. ลงทะเบียนใช้ NETPIE (https://netpie.io) แล้วล็อกอินเข้า NETPIE 2020
  2. กำหนดหัวข้อสื่อสาร โดยสร้าง project ใหม่ สร้าง Device จำนวน 2 ตัว (Cucumber และ PC) สร้าง Device Group แล้ว move อุปกรณ์เข้า group เดียวกัน
  3. ติดตั้งโปรแกรม MQTT Explorer จากนั้นสร้าง connection ใหม่ในการเชื่อมต่อกับ mqtt.netpie.io แล้วป้อน client ID, token, secret จาก Device ชื่อ PC
  4. เลือก subscribe ทาง topic ชื่อ @msg/sensors/cucumber
  5. ติดตั้งไลบรารีเพิ่มเติมใน Arduino IDE โดยเลือกเมนู Tools > Manage Libraries แล้วติดตั้ง Adafruit BMP280, Adafruit MPU6050, Adafruit HTS221, ESPAsync_WiFiManager, PubSubClient, littleFS_esp32
  6. เขียนโค้ดตัวอย่างใน Arduino IDE โดยป้อน client ID, token, secret จาก Device ชื่อ Cucumber
  7. กดปุ่ม Upload เพื่อ build และ deploy
  8. ใช้ MQTT Explorer เพื่อ monitor จากส่งค่าเซ็นเซอร์จากบอร์ด Cucumber RS
  9. ทดสอบ publish คำสั่ง on และ off ทาง topic ชื่อ @msg/leds/cucumber

โค้ดสำหรับเตรียมการเซ็นเซอร์

#include <Wire.h>
#include <Adafruit_BMP280.h>
#include <Adafruit_MPU6050.h>
#include <Adafruit_HTS221.h>
Adafruit_BMP280 bmp;
Adafruit_HTS221 hts;
Adafruit_MPU6050 mpu;
void setupHardware() {
Wire.begin(41, 40, 100000);
if (bmp.begin(0x76)) { // prepare BMP280 sensor
Serial.println("BMP280 sensor ready");
}
if (hts.begin_I2C()) { // prepare HTS221 sensor
Serial.println("HTS221 sensor ready");
}
if (mpu.begin()) { // prepare MPU6050 sensor
Serial.println("MPU6050 sensor ready");
}
pinMode(2, OUTPUT); // prepare LED
digitalWrite(2, HIGH);
}

โค้ดสำหรับเตรียมการ WiFi และ MQTT

#include <ESPAsync_WiFiManager.h>
#include <PubSubClient.h>
AsyncWebServer webServer(80);
WiFiClient esp32Client;
DNSServer dnsServer;
PubSubClient mqttClient(esp32Client);
IPAddress netpieBroker(35, 186, 155, 39);
const char NETPIE_CLIENT_ID[] = "";
const char NETPIE_TOKEN[] = "";
const char NETPIE_SECRET[] = "";
void callback(char* topic, byte* payload, unsigned int length) {
char cmd[100];
Serial.print("Message arrived [");
Serial.print(topic);
Serial.print("] ");
for (int i=0; i< length; i++) {
cmd[i] = (char)payload[i];
}
cmd[length] = 0;
Serial.println(cmd);
if (strcmp(cmd, "on") == 0) {
digitalWrite(2, LOW);
}
if (strcmp(cmd, "off") == 0) {
digitalWrite(2, HIGH);
}
}
void setupNetwork() {
// WiFi
ESPAsync_WiFiManager ESPAsync_wifiManager(&webServer, NULL, "Async_AutoConnect");
ESPAsync_wifiManager.resetSettings();
ESPAsync_wifiManager.setAPStaticIPConfig(IPAddress(192,168,132,1), IPAddress(192,168,132,1), IPAddress(255,255,255,0));
ESPAsync_wifiManager.autoConnect("Cucumber_AP");
if (WiFi.status() == WL_CONNECTED) {
Serial.print(F("Connected. Local IP: "));
Serial.println(WiFi.localIP());
} else {
Serial.println(ESPAsync_wifiManager.getStatus(WiFi.status()));
}
// NETPIE
mqttClient.setServer(netpieBroker, 1883);
mqttClient.setCallback(callback);
if (mqttClient.connect(NETPIE_CLIENT_ID, NETPIE_TOKEN, NETPIE_SECRET)) {
mqttClient.subscribe("@msg/leds/cucumber");
}
}

โค้ดสำหรับ main program

void setup() {
Serial.begin(115200);
setupHardware();
setupNetwork();
Serial.println("Starting");
}
void loop() {
static uint32_t prev_millis = 0;
char json_body[200];
const char json_tmpl[] = "{\"pressure\": %.2f,"
"\"temperature\": %.2f,"
"\"humidity\": %.2f,"
"\"acceleration\": [%.2f,%.2f,%.2f],"
"\"angular_velocity\":[%.2f,%.2f,%.2f]}";
sensors_event_t temp, humid;
sensors_event_t a, g;
if (millis() — prev_millis > 15000) {
prev_millis = millis();
float p = bmp.readPressure();
hts.getEvent(&humid, &temp);
float t = temp.temperature;
float h = humid.relative_humidity;
mpu.getEvent(&a, &g, &temp);
float ax = a.acceleration.x;
float ay = a.acceleration.y;
float az = a.acceleration.z;
float gx = g.gyro.x;
float gy = g.gyro.y;
float gz = g.gyro.z;
sprintf(json_body, json_tmpl, p, t, h, ax, ay, az, gx, gy, gz);
Serial.println(json_body);
mqttClient.publish("@msg/sensors/cucumber", json_body);
}
mqttClient.loop();
delay(100);
}
คลิปสาธิต IoT sensor

คลิปออนไลน์ดูได้จากลิงค์ https://1drv.ms/v/s!ArMKpoOdRO1NiPAifILX0jHzt_Dtyg?e=bw6c1B

終わりに (ในตอนท้าย)

การทดลองใช้บอร์ด Cucumber RS เพื่อรายงานค่าจากเซ็นเซอร์ไปยัง MQTT broker บน NETPIE ถือว่าง่ายขึ้นเยอะเมื่อ Arduino Core for ESP32 อัพเกรดเป็นรุ่น 2.0.0 ไลบรารีบน Arduino สำหรับเซ็นเซอร์ เช่น Adafruit ก็สามารถนำมาใช้ได้ โดยปรับแก้นิดหน่อยตรงการกำหนดขาของ I2C ผ่านทางไลบรารี Wire ในขณะที่การเชื่อมต่ออินเตอร์เน็ตด้วย WiFi และ MQTT ก็ทำได้ในรูปแบบเดียวกัน

เนื้อหาที่ advance ขึ้นคือการใช้ LINE เชื่อมกับอุปกรณ์ IoT ผ่านทาง MQTT ทำให้เราสามารถพัฒนา LINE bot ให้รับข้อมูลจากบอร์ด Cucumber แล้วไปติดต่อกับผู้ใช้ได้ ใครสนใจเนื้อหานี้ก็ติดต่อมาเพราะเป็นเนื้อหาที่จะไม่ได้เปิด public ครับ

--

--

Supachai Vorapojpisut
Supachai Vorapojpisut

Written by Supachai Vorapojpisut

Assistant Professor at Thammasat University

No responses yet