มาเริ่มกันเลย!
รอบนี้พี่จะมาสอนวิธีอ่านข้อมูลจาก nodeMCU, WemOS หรือตัวอื่นๆ ผ่านเน็ตนะน้อง – ตัวอย่างแรกที่พี่จะใช้คือการอ่านอุณหภูมิจากเซ็นเซอร์ที่ต่อกับ ESP แบบเรียลไทม์ตามสั่งเลย – น้องกดรีเฟรชปุ๊บ อุณหภูมิ, ความชื้น, ความดัน อัพเดทสดๆ รัวๆ เลยบนเว็บ
ตัวอย่างที่สองคือการอ่านอุณหภูมิ, ความดัน, และความชื้นเป็นระยะๆ แล้วเก็บลงฐานข้อมูล จะได้เอาไปทำกราฟสวยๆ ดูแนวโน้มย้อนหลังได้อีกด้วย
สถานีตรวจอากาศยุคใหม่: ESP8266 + RemoteMe
บอกลาการเดินไปดูเทอร์โมมิเตอร์ที่ระเบียงบ้านได้เลย! โปรเจคนี้จะพาน้องสร้าง IoT Weather Station สุดเจ๋งโดยใช้ ESP8266 (จะเป็น NodeMCU หรือ Wemos D1 Mini ก็ได้) กับเซ็นเซอร์แม่นยำอย่าง BME280 แล้วเชื่อมต่อกับแพลตฟอร์ม RemoteMe.org น้องจะสามารถเช็คสภาพอากาศในบ้านจากที่ไหนบนโลกก็ได้ ไม่ว่าจะนั่งอยู่บนรถเมล์หรืออยู่คนละซีกโลกก็ตาม!
กลยุทธ์ข้อมูลแบบ Hybrid: เรียลไทม์ vs เก็บประวัติ
โปรเจคนี้จะโชว์แพทเทิร์นการสื่อสาร IoT สำคัญ 2 แบบ:
- ดึงข้อมูลตามสั่ง (On-Demand Syncing): ในโหมดนี้ ระบบจะใช้การสื่อสารแบบ synchronous พอน้องกดปุ่ม Refresh บนเว็บที่เราสร้างขึ้น สัญญาณจะถูกส่งไปหา ESP8266 ซึ่งจะอ่านค่าจากเซ็นเซอร์ทันทีและส่งค่าอุณหภูมิ, ความชื้น, ความดันล่าสุดกลับมาที่หน้าจอน้องแบบสดๆ
- บันทึกข้อมูลขึ้นคลาวด์อัตโนมัติ: สำหรับการวิเคราะห์ระยะยาว เราสามารถตั้งโปรแกรมให้ ESP8266 ตื่นขึ้นมาทำงานเป็นระยะๆ (เช่น ทุก 5 นาที), บันทึกข้อมูลลง RemoteMe Cloud Database แล้วกลับไป Deep Sleep อีกครั้ง วิธีนี้จะทำให้น้องสามารถสร้างกราฟสวยๆ ระดับโปรเพื่อติดตามแนวโน้มสภาพอากาศได้เป็นวัน เป็นสัปดาห์ หรือเป็นเดือนเลย
สถาปัตยกรรมซอฟต์แวร์และความปลอดภัยของข้อมูล
การขยายโปรเจค IoT แบบ DIY ต้องมากกว่าแค่ลอจิกง่ายๆ – มันต้องมีแบ็กเอนด์ที่แข็งแรง:
- ความปลอดภัยด้วยโทเคน: การโต้ตอบระหว่าง ESP8266 กับคลาวด์จะถูกป้องกันด้วย RemoteMe Tokens เพื่อให้แน่ใจว่าเฉพาะอุปกรณ์ที่น้องอนุญาตเท่านั้นที่สามารถโพสต์หรืออ่านข้อมูลได้
- การผสาน JSON และ JavaScript: ฝั่ง Frontend ใช้ JQuery และ Plotly ในการแยกวิเคราะห์สตรีมข้อมูล JSON ที่เข้ามา เพื่อเปลี่ยนค่าดิบจากเซ็นเซอร์ให้กลายเป็นกราฟที่สวยงามและโต้ตอบได้
- จุดเด่นของ BME280: ไม่เหมือนเซ็นเซอร์ตระกูล DHT นะตัวนี้ BME280 ให้ค่าความดันบรรยากาศมาด้วย ซึ่งสำคัญมากสำหรับการพยากรณ์การเปลี่ยนแปลงสภาพอากาศในพื้นที่และตรวจจับพายุที่กำลังมา
สร้างเพื่ออนาคต
ไม่ว่าน้องจะต้องการปรับปรุงระบบ HVAC ในบ้าน หรือแค่อยากมี "หน้าต่างอัจฉริยะ" ไว้ดูสภาพแวดล้อมรอบตัว โปรเจคนี้ก็เป็นเทมเพลตพื้นฐานที่เหมาะสำหรับ Smart Home Sensing มาก ด้วยดีไซน์แบบโมดูลาร์ น้องสามารถเพิ่มเซ็นเซอร์อื่นๆ (เช่น CO2 หรือ Dust modules) ได้ง่ายๆ เพื่อสร้างเครื่องตรวจสอบคุณภาพอากาศภายในอาคารที่ครบวงจรจริงๆ
ดูขั้นตอนทั้งหมดได้ในยูทูปเลยจ้า
อุณหภูมิ ความดัน และความชื้น แบบเรียกเมื่อต้องการ
สมมติฐานเบื้องต้น
เราจะเข้าถึงกลไกทั้งหมดจากภายนอกเครือข่ายท้องถิ่นนะ นั่นคือ เราจะสามารถอ่านอุณหภูมิจากมือถือบนรถเมล์ได้โดยไม่มีปัญหา
เพื่ออ่านอุณหภูมิ เราจะสร้างการสื่อสารแบบ synchronous หลังจากส่งข้อความไปหา ESP ของเราแล้ว เราจะได้รับอุณหภูมิ, ความชื้น และความดันกลับมาเป็นคำตอบ
โดยทั่วไปแล้ว การสร้างสถานการณ์แบบนี้ เราต้องสามารถเข้าถึง Arduino ของเราจากภายนอกเครือข่ายท้องถิ่นได้ – มีหลายวิธีให้เลือก พี่จะแสดงวิธีทำโดยใช้ remoteme.org ให้ดู
สิ่งที่เราอยากได้
เว็บไซต์ที่มีหน้าตาแบบนี้:

หลังจากโหลดหน้าเว็บเสร็จ เราก็จะแสดงค่าอุณหภูมิ ความดัน และความชื้นปัจจุบันให้เห็นกันชัดๆ และแน่นอนว่าข้อมูลจะรีเฟรชใหม่ทุกครั้งที่กดปุ่ม Refresh นะจ๊ะ
อุปกรณ์ที่ต้องใช้
GY-BME280 – ตัวเดียวจบ ทั้งเทอร์โมมิเตอร์ ไฮโกรมิเตอร์ และบารอมิเตอร์

- nodeMCU หรือ WemOS
การต่อสาย

ตั้งค่า app.remoteme.org
ก่อนจะกลับไปเล่นกับ Arduino ของเรา มาลงทะเบียนบัญชีและสร้างโทเคนกันก่อน ตามขั้นตอนด้านล่างเลย
สมัครสมาชิก

- เปิดแอป remoteme.org
- ไปที่แท็บ Sign Up
- ระบบไม่ขออีเมล ดังนั้นถ้าลืมรหัสผ่านจะกู้คืนไม่ได้ ต้องจำให้ดีนะ!
- กด SignUp ระบบจะล็อกอินให้เราโดยอัตโนมัติ
สร้างโทเคน
โทเคนนี้แหละที่เราจะเอาไปใส่ในโค้ด Arduino เพื่อให้บอร์ดของเราต่อเข้ากับบัญชีเราได้


- ไปที่แท็บ Tokens ทางซ้ายมือ
- กด New Token ตั้งชื่อโทเคน (ตั้งอะไรก็ได้) แล้วกด OK
- [3] นี่คือช่องเดียวที่ต้องกรอก – ชื่อโทเคนมีไว้ให้เราจำง่ายๆ ไม่ได้เอาไปใช้ที่ไหนนอกจากแสดงในรายการโทเคน
- ระบบจะสร้างโทเคนให้:
- ตัวอย่างโทเคนของพี่คือ “~267_ZxoWtJ)0ph&2c” สามารถก๊อปปี้ได้โดยคลิกที่ไอคอนสีฟ้า
โปรแกรมสำหรับ Arduino
ขั้นแรก ต้องติดตั้งไลบรารี่เพิ่มเติมก่อน
ดาวน์โหลดไลบรารี่ RemoteMe แล้วเพิ่มไลบรารี่ในรูปแบบ zip
เพิ่มไฟล์ zip ที่ดาวน์โหลดมาเข้าไปในไลบรารี่

แล้วตรวจสอบให้แน่ใจว่าติดตั้งถูกต้องทุกอย่าง

ไลบรารี่อื่นๆ ที่ต้องใช้
- WebSockets by Markus Sattler
- ArduinoHttpClient by Arduino
- ESP8266WiFi by Iven Grokhotkov
- SparkFun BME280 by SparkFun Electronics
โค้ดโปรแกรมสำหรับ Arduino สามารถนำไปใช้ได้เลย
พี่ว่าโค้ดโปรแกรมอ่านเข้าใจไม่ยากนะ ส่วนฟังก์ชันสำคัญอย่าง `onUserSyncMessage` พี่อธิบายไว้ด้านล่างแล้ว อย่าลืมเติมค่าคงที่ของเราให้ครบด้วยล่ะ:
#define WIFI_NAME ""
#define WIFI_PASSWORD ""
#define DEVICE_ID 204
#define DEVICE_NAME "temperatureOnRequest"
#define TOKEN ""
นอกจากนี้ มีคำอธิบายการทำงานเพิ่มเติมท้ายบทความด้วย
อัพโหลดโปรแกรม Arduino ลงบอร์ดได้เลย หลังจาก Arduino เริ่มทำงาน ในแท็บ Devices จะปรากฏ ESP ของเรา:

เว็บเพจ
ถึงเวลาสร้างเว็บไซต์ที่จะเชื่อมต่อกับ ESP ของเราและแสดงข้อมูลแล้ววว!
ในแท็บ “Devices” เลือกปุ่ม New แล้วเลือก “New WebPage”

เอาล่ะวัยรุ่น มาอัพโหลดไฟล์ 3 ไฟล์ขึ้นเว็บไซต์ของเรากันดีกว่า
- ไฟล์ที่ต้องอัพโหลดคือ index.html, script.js และ styles.css อยู่ตรงนี้เลย (จัดไปจาก GitHub)
- วิธีที่ง่ายสุดคือลากไฟล์จาก GitHub มาปล่อยบนเว็บไซต์ของเราเลย ตามที่เห็นในคลิปวีดีโอด้านล่าง
- เรากรอกข้อมูลลงในช่องต่างๆ ตามในภาพหน้าจอ ส่วนความหมายของแต่ละช่อง อ่านต่อได้ที่นี่เลย
- การเปิดเว็บไซต์: ให้คลิกที่ไฟล์ index.html แล้วเลือก "Open in New Tab" ในแท็บใหม่ที่เปิดขึ้นมา นั่นคือเว็บไซต์ของเราแล้ว พอกด Refresh ค่าอุณหภูมิ ความดัน และความชื้นก็จะอัพเดทเป็นค่าปัจจุบันเลย
แล้วมันทำงานยังไงล่ะ?
ส่วนสำคัญของโค้ดอยู่ที่ไฟล์ script.js และโปรแกรมบน Arduino มาดูกันทีละส่วนเลย
script.js
function setup(){
\tremoteme = new RemoteMe({
\t\tautomaticlyConnectWS: true,
\t\tautomaticlyConnectWebRTC:false,
\t\twebSocketConnectionChange: webSocketConnectionChange,
\t\twebRTCConnectionChange: undefined,
\t\tmediaConstraints: {'mandatory': {'OfferToReceiveAudio': false, 'OfferToReceiveVideo': false}}
\t});
}
นี่คือการตั้งค่ามาตรฐาน โปรแกรมจะต่อและลงทะเบียนกับแอปพลิเคชัน remoteme.org ทันที
การอ้างอิงไปยังฟังก์ชัน
webSocketConnectionChange: webSocketConnectionChange,
ฟังก์ชันจริงๆ มีหน้าตาแบบนี้:
function webSocketConnectionChange(state){
\tif (state==WebsocketConnectingStatusEnum.CONNECTED){
\t\treadDataNow();
\t}
}
แปลว่าพอต่อกับ remoteme.org สำเร็จ โปรแกรมก็จะอ่านข้อมูลเลย ฟังก์ชัน readDataNow() ตัวเดียวกันนี้ก็ถูกเรียกตอนเรากดปุ่ม "Refresh" ด้วย
มาดูกันว่า readDataNow() ทำอะไรบ้าง:
function readDataNow(){
\tremoteme.sendUserSyncMessageWebSocket(temperatureArduinoDeviceId,[],onResponse);
}
มันส่งข้อมูลไปหา ESP ของเรา (นี่แหละที่ต้องใช้ temperatureArduinoDeviceId ซึ่งคือ ID หรือที่อยู่ของ ESP ในตัวอย่างนี้คือ 204) ส่วนข้อมูลที่ส่งไปคืออาร์เรย์ว่างๆ: [] และพอมีคำตอบกลับมา ฟังก์ชัน onResponse ก็จะถูกเรียก
ทีนี้มาดูฝั่งโปรแกรมบน ESP กันบ้าง ว่าเราจัดการข้อความแบบ synchronous ที่เข้ามายังไง
arduino.ino:
void onUserSyncMessage(uint16_t senderDeviceId, uint16_t dataSize, uint8_t* data, uint16_t &returnDataSize, uint8_t *&returnData)
{
\tuint16_t pos = 0;
\treturnDataSize = sizeOf(float32)*3;
\treturnData = (uint8_t*)malloc(returnDataSize);
\t
\tRemoteMeMessagesUtils::putFloat(returnData,pos, (mySensor.readTempC()));
\tRemoteMeMessagesUtils::putFloat(returnData, pos, (mySensor.readFloatPressure() ));
\tRemoteMeMessagesUtils::putFloat(returnData, pos, (mySensor.readFloatHumidity() ));
\t
}
ฟังก์ชันด้านบนจะถูกเรียกใช้เมื่อมีข้อความส่งมาจาก script.js พารามิเตอร์มีดังนี้:
returnData = (uint8_t*)malloc(returnDataSize);
\t
\tRemoteMeMessagesUtils::putFloat(returnData,pos, (mySensor.readTempC()));
\tRemoteMeMessagesUtils::putFloat(returnData, pos, (mySensor.readFloatPressure() ));
\tRemoteMeMessagesUtils::putFloat(returnData, pos, (mySensor.readFloatHumidity() ));
โดยใช้ฟังก์ชัน putFloat เราจะใส่ค่าที่อ่านได้ทั้งสามค่าเข้าไปในตาราง output ทีละตัว หลังจากออกจากฟังก์ชัน เราก็จะได้อาร์เรย์ของไบต์ที่เขียนค่าต่อไปนี้ไว้แล้ว: อุณหภูมิ, ความดัน และความชื้น
- senderDeviceId – ไอดีของเว็บไซต์เรา
- dataSize – ขนาดของข้อมูล (ในกรณีเราคือ 0 เพราะเราส่งอาร์เรย์ว่างมาจาก script.js)
- data - ข้อมูลจากเว็บไซต์ (ในกรณีเราไม่มีอะไรในนี้)
- returnDataSize – ตรงนี้เราจะใส่จำนวนไบต์ที่เราจะส่งกลับไปเป็นคำตอบ – เราส่ง 12 เพราะเรามีค่าที่อ่านได้ 3 ค่า และแต่ละค่าเป็น float ที่มีขนาด 4 ไบต์
- returnData – ตรงนี้เราจะเขียนข้อมูลที่จะส่งกลับ
กลับไปที่ไฟล์ script.js เพื่ออ่านค่าเหล่านี้กัน:
script.js
function onResponse(output){
\tvar data = new RemoteMeData(output);
\tvar temp = data.popFloat32();
\tvar pressure = data.popFloat32();
\tvar humm = data.popFloat32();
\t$("#tempOut").html(temp.toFixed(2)+" C");
\t$("#pressOut").html((pressure/100).toFixed(2)+" hPa");
\t$("#hummOut").html(humm.toFixed(2)+" %");
}
ด้วยฟังก์ชัน popFloat32 เราจะดึงค่า float ทั้งสามค่าออกมาทีละตัว หลังจากจัดรูปแบบให้สวยงามแล้ว ก็ใช้ jquery แสดงผลไปยัง element ที่เหมาะสม
บันทึกอุณหภูมิ ความดัน และความชื้นไว้บนเซิร์ฟเวอร์ และแสดงผลบนกราฟ
คราวนี้เราไม่อยากอ่านค่าอุณหภูมิแบบเรียกเมื่อต้องการแล้ว แต่เราจะบันทึกค่าที่อ่านได้เป็นระยะๆ (ในตัวอย่างนี้คือทุก 5 นาที) ลงบนเซิร์ฟเวอร์