ESP32 อ่านค่า ADC และแสดงกราฟแบบเรียลไทม์ด้วย WebSocket + Chart.js

บทนำ

การเก็บและแสดงผลข้อมูลแบบเรียลไทม์ในยุคปัจจุบันมีความสำคัญอย่างยิ่งในหลากหลายด้าน ไม่ว่าจะเป็นการตรวจสอบสถานะของระบบในอุตสาหกรรม การเฝ้าระวังสุขภาพ หรือการเรียนรู้และพัฒนาโปรเจคในด้าน Internet of Things (IoT) หนึ่งในอุปกรณ์ที่มีความสามารถสูงในการเชื่อมต่อและประมวลผลข้อมูลในลักษณะนี้คือ ESP32 ซึ่งเป็นไมโครคอนโทรลเลอร์ที่มาพร้อมกับ WiFi และ Bluetooth ในตัว ในบทความนี้ เราจะสร้างระบบที่สามารถอ่านค่าแรงดันไฟฟ้าจาก ADC ของ ESP32 และส่งข้อมูลผ่านโปรโตคอล WebSocket ไปยังเว็บเพจที่แสดงผลเป็นกราฟแบบเรียลไทม์ด้วยการใช้ไลบรารี Chart.js บทความนี้จะอธิบายขั้นตอนต่าง ๆ อย่างละเอียด เพื่อให้ผู้อ่านสามารถทำตามและสร้างระบบของตัวเองได้อย่างง่ายดาย

อุปกรณ์ที่ต้องใช้

ก่อนที่เราจะเริ่มต้นลงมือทำโปรเจคนี้ มาเตรียมอุปกรณ์กันก่อน:

  1. ESP32 Development Board: เป็นไมโครคอนโทรลเลอร์ที่มี WiFi และ Bluetooth ในตัว ซึ่งจะใช้สำหรับการอ่านค่าแรงดันไฟฟ้าจาก ADC และส่งข้อมูลผ่าน WebSocket
  2. สาย USB: สำหรับเชื่อมต่อ ESP32 กับคอมพิวเตอร์เพื่ออัปโหลดโค้ด
  3. แหล่งจ่ายไฟและวงจรที่ต้องการตรวจวัดแรงดันไฟฟ้า: เช่น แบตเตอรี่หรือวงจรที่มีสัญญาณแรงดันไฟฟ้าเพื่อทดสอบการอ่านค่า ADC

รายละเอียดพื้นฐานของ ESP32 คืออะไร พร้อมจุดเด่นและวิธีเริ่มต้นใช้งาน

การตั้งค่าเบื้องต้น

1. การติดตั้ง Arduino IDE และไลบรารีที่จำเป็น

หากคุณยังไม่มี Arduino IDE สามารถดาวน์โหลดและติดตั้งได้จาก เว็บไซต์ Arduino หลังจากติดตั้ง Arduino IDE แล้ว ให้เพิ่มบอร์ด ESP32 โดยทำตามขั้นตอนต่อไปนี้:

  1. เปิด Arduino IDE แล้วไปที่ File > Preferences
  2. ที่ช่อง Additional Boards Manager URLs ให้ใส่ URL นี้: https://dl.espressif.com/dl/package_esp32_index.json
  3. ไปที่ Tools > Board > Boards Manager ค้นหา ESP32 และติดตั้ง

จากนั้นติดตั้งไลบรารีที่จำเป็น:

  1. ไปที่ Sketch > Include Library > Manage Libraries
  2. ค้นหาและติดตั้งไลบรารี ESPAsyncWebServer และ AsyncTCP

ยังไม่รู้ว่าจะดาวน์โหลด Arduino IDE ที่ไหน? คลิกเลยที่ Arduino IDE Download & Install เพื่อเริ่มต้นใช้งานได้ทันที!

2. การเชื่อมต่อ WiFi

ขั้นตอนแรกคือการเชื่อมต่อ ESP32 กับเครือข่าย WiFi ของคุณเพื่อให้สามารถส่งข้อมูลไปยังเว็บเพจได้ เราจะใช้ไลบรารี WiFi.h สำหรับการเชื่อมต่อ WiFi และ ESPAsyncWebServer.h สำหรับการตั้งค่าเซิร์ฟเวอร์ WebSocket

#include <WiFi.h>
#include <ESPAsyncWebServer.h>
#include <AsyncTCP.h>
#include "index.h"

const char* ssid = "Your_SSID"; // เปลี่ยนเป็น SSID ของคุณ
const char* password = "Your_PASSWORD"; // เปลี่ยนเป็น Password ของคุณ

const int potPin = 34; // Pin ADC 

AsyncWebServer server(80);
AsyncWebSocket ws("/ws");

void handleWebSocketMessage(void *arg, uint8_t *data, size_t len) {
  AwsFrameInfo *info = (AwsFrameInfo*)arg;
  if(info->final && info->index == 0 && info->len == len && info->opcode == WS_TEXT) {
    data[len] = 0;
    Serial.printf("Received message: %s\n", data);
  }
}

void onEvent(AsyncWebSocket *server, AsyncWebSocketClient *client, AwsEventType type, void *arg, uint8_t *data, size_t len) {
  switch (type) {
    case WS_EVT_CONNECT:
      Serial.println("WebSocket client connected");
      break;
    case WS_EVT_DISCONNECT:
      Serial.println("WebSocket client disconnected");
      break;
    case WS_EVT_DATA:
      handleWebSocketMessage(arg, data, len);
      break;
    case WS_EVT_PONG:
    case WS_EVT_ERROR:
      break;
  }
}

void setup() {
  Serial.begin(115200);
  WiFi.begin(ssid, password);

  while (WiFi.status() != WL_CONNECTED) {
    delay(1000);
    Serial.println("Connecting to WiFi...");
  }
  Serial.println("Connected to WiFi");
  Serial.print("Local ESP32 IP: ");
  Serial.println(WiFi.localIP());

  ws.onEvent(onEvent);
  server.addHandler(&ws);

  // ส่งไฟล์ HTML ที่มี Chart.js
  server.on("/", HTTP_GET, [](AsyncWebServerRequest *request){
    request->send_P(200, "text/html", index_html);
  });

  server.begin();
}

เพิ่งเริ่มต้นกับ ESP32? ไม่แน่ใจว่าไลบรารี WiFi มีฟังก์ชันอะไรให้ใช้บ้าง — คลิกอ่าน ESP32 WiFi Library Functions เพิ่มเติมได้เลย

ในโค้ดนี้ เราใช้ไลบรารี WiFi.h เพื่อเชื่อมต่อกับ WiFi โดยกำหนด SSID และรหัสผ่านของเครือข่ายที่คุณต้องการเชื่อมต่อ หลังจากเชื่อมต่อสำเร็จ จะมีการตั้งค่า WebSocket โดยใช้ ESPAsyncWebServer.h และ AsyncTCP.h และสร้างเว็บเซิร์ฟเวอร์ที่พอร์ต 80

3. การอ่านค่า ADC และส่งข้อมูลผ่าน WebSocket

ในส่วนนี้ ESP32 จะอ่านค่า ADC จากขาที่กำหนดและแปลงค่าเป็นแรงดันไฟฟ้า จากนั้นส่งข้อมูลผ่าน WebSocket ไปยังเว็บเพจ


void loop() {
// อ่านค่า ADC
int adcValue = analogRead(potPin); // เปลี่ยนหมายเลขขา ADC ตามที่คุณใช้งาน
Serial.println(adcValue);
float voltage = adcValue * (3.3 / 4095.0); // แปลงค่า ADC เป็นแรงดันไฟฟ้า

// ส่งค่าแรงดันผ่าน WebSocket
String voltageStr = String(voltage, 2);
Serial.println(voltageStr);
ws.textAll(voltageStr);

delay(1500); // ส่งข้อมูลทุก ๆ 1.5 วินาที
}

เรียนรู้การอ่านค่าอนาล็อกจากเซนเซอร์ด้วย ESP32 ได้ที่ ESP32 Analog Read

ในฟังก์ชัน loop() จะทำการอ่านค่า ADC จากขาที่กำหนด (ในที่นี้คือขา 34) และแปลงค่า ADC เป็นแรงดันไฟฟ้า โดยใช้สูตร voltage = adcValue * (3.3 / 4095.0) จากนั้นส่งข้อมูลแรงดันไฟฟ้าผ่าน WebSocket ไปยังทุก ๆ client ที่เชื่อมต่ออยู่

4. สร้างเว็บเพจเพื่อแสดงกราฟด้วย Chart.js

เราจะใช้ Chart.js เพื่อสร้างกราฟที่จะแสดงค่าแรงดันไฟฟ้าแบบเรียลไทม์ โดยสร้างเว็บเพจ HTML ที่มี JavaScript สำหรับการเชื่อมต่อ WebSocket และการอัปเดตกราฟ

const char index_html[] PROGMEM = R"rawliteral(
<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <title>ESP32 ADC Plotter</title>
</head>
<body>
  <h1>ESP32 ADC Plotter</h1>
  <canvas id="myChart" style="height:55vh; width:80vw"></canvas>

  <script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
  <script src="https://cdn.jsdelivr.net/npm/chartjs-plugin-datalabels@2.0.0"></script>
  
  <script>

      const ctx = document.getElementById('myChart').getContext('2d');
      var chart = new Chart(ctx, {
      type: 'line',
      data: {
        labels: [],
        datasets: [{
          label: 'Voltage (V)',
          data: [],
          borderColor: 'rgba(75, 192, 192, 1)',
          fill: false,
          borderWidth: 2
        }]
      },
      options: {
        tension: 0.4,
        scales: {
          y: {
            beginAtZero: true,
            max: 4
          }
        },
        plugins: {
          datalabels: {
            display: true,
            align: 'top',
            color: 'black',
            formatter: function(value) {
              return value.toFixed(2) + ' V';
            }
          }
        }
      },
      plugins: [ChartDataLabels]
    });
    
    var gateway = `ws://${window.location.hostname}/ws`;
    var websocket;

    window.addEventListener('load', onLoad);

    function onLoad(event) {
        initWebSocket();
    }

    function initWebSocket() {
        websocket = new WebSocket(gateway);
        websocket.onopen = onOpen;
        websocket.onclose = onClose;
        websocket.onmessage = onMessage;
    }

    function onOpen(event) {
        console.log('Connection opened');
    }

    function onClose(event) {
        console.log('Connection closed');
    }

    function onMessage(event) {
        let date = new Date().toLocaleTimeString();
        chart.data.labels.push(date);
        
        var dataVolt = parseFloat(event.data);
        chart.data.datasets[0].data.push(dataVolt);
        
        // ลบข้อมูลใน array data เมื่อเกิน 20 ค่า
        if (chart.data.datasets[0].data.length > 20) {
          chart.data.datasets[0].data.shift();
          chart.data.labels.shift();
        }            
        
        // อัพเดท chart
        chart.update();
    }
  </script>
</body>
</html>


)rawliteral";

ในโค้ด HTML นี้ เราใช้ Chart.js เพื่อสร้างกราฟแบบเส้น โดยเชื่อมต่อกับ WebSocket ที่ ws://[ESP32_IP_ADDRESS]/ws และรับค่าข้อมูลแรงดันไฟฟ้าแบบเรียลไทม์ เมื่อได้รับข้อมูลใหม่ กราฟจะอัปเดตโดยการเพิ่มข้อมูลใหม่และลบข้อมูลเก่าออกเมื่อเกิน 20 ค่า

กรุณา เข้าสู่ระบบ เพื่อดาวน์โหลด

ผลลัพธ์

ภาพแสดงกราฟแรงดันไฟฟ้า0-3.3โวลล์ จากการอ่านค่า analog to digital จาก esp32 แล้วใช้ esp32 web server แสดงผลบนจอโทรศัพท์

สรุป

โปรเจคนี้เป็นตัวอย่างที่ดีในการใช้งาน ESP32 สำหรับการอ่านค่าแรงดันไฟฟ้า (ADC) และส่งข้อมูลแบบเรียลไทม์ผ่าน WebSocket ไปยังเว็บเพจที่แสดงผลด้วยกราฟจาก Chart.js นี่เป็นวิธีที่มีประสิทธิภาพและง่ายต่อการใช้งานสำหรับโปรเจค IoT หวังว่าบทความนี้จะเป็นประโยชน์และช่วยให้คุณสร้างโปรเจคของคุณได้ง่ายขึ้น!

คำถามที่พบบ่อย

1. ทำไมถึงต้องใช้ WebSocket? 

WebSocket เป็นโปรโตคอลที่ช่วยให้สามารถส่งข้อมูลแบบเรียลไทม์ได้อย่างมีประสิทธิภาพโดยไม่ต้องรีเฟรชหน้าเว็บ ซึ่งแตกต่างจาก HTTP ที่ต้องมีการร้องขอและตอบกลับทุกครั้งที่มีการส่งข้อมูล WebSocket ช่วยลดความล่าช้าในการส่งข้อมูลและทำให้การแสดงผลเป็นไปอย่างราบรื่นมากขึ้น

2. สามารถเพิ่มฟีเจอร์อื่น ๆ ในกราฟได้หรือไม่? 

แน่นอน คุณสามารถปรับแต่ง Chart.js เพื่อเพิ่มฟีเจอร์ต่าง ๆ เช่น การซูม การแพน หรือการเปลี่ยนแปลงรูปแบบกราฟ นอกจากนี้ยังสามารถเพิ่มข้อมูลอื่น ๆ เช่น อุณหภูมิ ความชื้น หรือข้อมูลจากเซ็นเซอร์อื่น ๆ เพื่อสร้างแดชบอร์ดที่มีประสิทธิภาพยิ่งขึ้น

3. การใช้งานในโปรเจคจริงทำได้ง่ายหรือไม่? 

การใช้งาน ESP32 และ WebSocket ในโปรเจคจริงทำได้ง่ายและมีความยืดหยุ่นสูง คุณสามารถนำไปใช้ในการตรวจสอบสถานะของระบบในอุตสาหกรรม การเฝ้าระวังสุขภาพ หรือการพัฒนาโปรเจค IoT อื่น ๆ ได้อย่างมีประสิทธิภาพ

4. สามารถใช้ ESP32 รุ่นอื่น ๆ ได้หรือไม่? 

ใช่ คุณสามารถใช้ ESP32 รุ่นอื่น ๆ ที่มีการรองรับ ADC และ WiFi ในตัว เช่น ESP32-WROOM-32 หรือ ESP32-WROVER แต่ควรตรวจสอบความเข้ากันได้ของไลบรารีและพอร์ตที่ใช้งาน

5. ข้อมูลแรงดันไฟฟ้าที่อ่านได้มีความแม่นยำเพียงใด? 

ความแม่นยำของข้อมูลแรงดันไฟฟ้าขึ้นอยู่กับคุณภาพของวงจร ADC บนบอร์ด ESP32 และการปรับเทียบค่า ADC ที่เหมาะสม ในบางกรณีอาจต้องมีการปรับเทียบเพิ่มเติมเพื่อให้ได้ค่าที่แม่นยำยิ่งขึ้น หวังว่าบทความนี้จะช่วยให้คุณมีความเข้าใจและสามารถเริ่มต้นสร้างโปรเจคของคุณเองได้อย่างง่ายดาย

Shopping Cart
Scroll to Top