กลับไปหน้ารวมไฟล์
read-temperature-humidity-and-pressure-using-esp-wemo-0dcad0.md

มาเริ่มกันเลย!

รอบนี้พี่จะมาสอนวิธีอ่านข้อมูลจาก nodeMCU, WemOS หรือตัวอื่นๆ ผ่านเน็ตนะน้อง – ตัวอย่างแรกที่พี่จะใช้คือการอ่านอุณหภูมิจากเซ็นเซอร์ที่ต่อกับ ESP แบบเรียลไทม์ตามสั่งเลย – น้องกดรีเฟรชปุ๊บ อุณหภูมิ, ความชื้น, ความดัน อัพเดทสดๆ รัวๆ เลยบนเว็บ

ตัวอย่างที่สองคือการอ่านอุณหภูมิ, ความดัน, และความชื้นเป็นระยะๆ แล้วเก็บลงฐานข้อมูล จะได้เอาไปทำกราฟสวยๆ ดูแนวโน้มย้อนหลังได้อีกด้วย

สถานีตรวจอากาศยุคใหม่: ESP8266 + RemoteMe

บอกลาการเดินไปดูเทอร์โมมิเตอร์ที่ระเบียงบ้านได้เลย! โปรเจคนี้จะพาน้องสร้าง IoT Weather Station สุดเจ๋งโดยใช้ ESP8266 (จะเป็น NodeMCU หรือ Wemos D1 Mini ก็ได้) กับเซ็นเซอร์แม่นยำอย่าง BME280 แล้วเชื่อมต่อกับแพลตฟอร์ม RemoteMe.org น้องจะสามารถเช็คสภาพอากาศในบ้านจากที่ไหนบนโลกก็ได้ ไม่ว่าจะนั่งอยู่บนรถเมล์หรืออยู่คนละซีกโลกก็ตาม!

กลยุทธ์ข้อมูลแบบ Hybrid: เรียลไทม์ vs เก็บประวัติ

โปรเจคนี้จะโชว์แพทเทิร์นการสื่อสาร IoT สำคัญ 2 แบบ:

  1. ดึงข้อมูลตามสั่ง (On-Demand Syncing): ในโหมดนี้ ระบบจะใช้การสื่อสารแบบ synchronous พอน้องกดปุ่ม Refresh บนเว็บที่เราสร้างขึ้น สัญญาณจะถูกส่งไปหา ESP8266 ซึ่งจะอ่านค่าจากเซ็นเซอร์ทันทีและส่งค่าอุณหภูมิ, ความชื้น, ความดันล่าสุดกลับมาที่หน้าจอน้องแบบสดๆ
  2. บันทึกข้อมูลขึ้นคลาวด์อัตโนมัติ: สำหรับการวิเคราะห์ระยะยาว เราสามารถตั้งโปรแกรมให้ 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 นาที) ลงบนเซิร์ฟเวอร์

ข้อมูล Frontmatter ดั้งเดิม

title: "อ่านค่าอุณหภูมิ ความชื้น และความดันด้วย ESP / Wemo... งานง่ายแต่หล่อ!"
description: "โปรเจคนี้เราจะอ่านค่าจากเซนเซอร์ทั้งสามแบบตึงๆ ทั้งอุณหภูมิ ความดัน และความชื้น แล้วจะเอาไปแสดงผลบนเว็บเพจแบบวัยรุ่น หรือจะโยนข้อมูลขึ้น RemoteMe cloud เพื่อวาดเป็นกราฟเทพๆ ก็จัดไป!"
author: "remoteMe"
category: ""
tags:
  - "wifi"
  - "diy"
  - "home automation"
  - "nodemcu"
  - "wemos"
views: 2801
likes: 1
price: 1499
difficulty: "Easy"
components:
  - "1x NodeMCU ESP8266 Breakout Board"
  - "1x Wemos D1 Mini"
tools: []
apps:
  - "1x remoteMe.org"
downloadableFiles:
  - "https://projects.arduinocontent.cc/c46b75c7-a2b9-4df9-b1da-319e1815d43e.js"
  - "https://projects.arduinocontent.cc/db607fa2-4eed-46ae-a254-f9d0966a99ff.js"
  - "https://projects.arduinocontent.cc/3d7dd208-2218-4448-b405-211a601711bb.css"
  - "https://projects.arduinocontent.cc/c46b75c7-a2b9-4df9-b1da-319e1815d43e.js"
  - "https://projects.arduinocontent.cc/4513931a-afab-4088-9ac1-e4c5592f0b74.html"
  - "https://projects.arduinocontent.cc/628dc8fe-f9d1-4e5d-83ec-87cdf3c6477a.html"
  - "https://projects.arduinocontent.cc/4513931a-afab-4088-9ac1-e4c5592f0b74.html"
  - "https://projects.arduinocontent.cc/3d7dd208-2218-4448-b405-211a601711bb.css"
  - "https://projects.arduinocontent.cc/db607fa2-4eed-46ae-a254-f9d0966a99ff.js"
  - "https://projects.arduinocontent.cc/628dc8fe-f9d1-4e5d-83ec-87cdf3c6477a.html"
documentationLinks: []
passwordHash: "be3a79719bd5196d19fe59c040fa8304b9f1e0ff7fbc6cef85da4c69e764eb51"
encryptedPayload: "U2FsdGVkX18+lzQMrCKaa6ofuvrAcWJxW/9BLbz7q2Kje796RsimNO3oy9mu1sFgwDrjQXJdx691uX0EGSdDCEAsprqqAv3k+YDZSuFhAU8="
seoDescription: "Read temperature, humidity and pressure using ESP / Wemo. Display data on a WebPage or store in RemoteMe cloud as a chart."
videoLinks:
  - "https://www.youtube.com/embed/vBAPJe91ne8"
  - "https://www.youtube.com/embed/8M0--3vFK8o"
heroImage: "https://cdn.jsdelivr.net/gh/bigboxthailand/arduino-assets@main/images/projects/read-temperature-humidity-and-pressure-using-esp-wemo-0dcad0_cover.jpg"
lang: "en"