MiJia Temperature Sensor + ESP32

พระเจ้าสร้างโลก ที่เหลือ xiaomi สร้าง คงไม่เกินจริงเท่าไหร่ เพราะมองไปทางไหนก็เจอแต่อุปกรณ์ของ Xiaomi ด้วย Business Model ที่สร้าง ecosystem ให้เอื้อกับบริการต่างๆจาก Partner โดยการเข้าไปถือหุ้นบริษัทผลิตอุปกรณ์เหล่านี้ แทนการสร้างด้วยตัวเองทั้งหมด ทำให้ eco ใหญ่ขึ้นอย่างรวดเร็ว

ตอนแรกว่าจะเขียน EP ต่อจากตอนที่แล้วของ ESP32 TTGO T-Camera แต่โดนดึงความสนใจไปเรื่องอื่นก่อน เพราะเข้าไปในกลุ่ม FB ของ Home Automation Thailand ไล่ๆอ่านแล้วน่าสนใจมากกับการใช้งาน Home Assistant OS ที่เป็นเหมือนตัวเชื่อม Platform Home Automation, IoT จากหลายๆค่ายมาไว้บนระบบเดียว เป็น Opensource และมี Community ที่แข็งแรง โดยอุปกรณ์ตัวนึงที่เห็นอยู่ในลิสต์จาก Xiaomi และนำมาใช้ก็คือ Mijia Temperature & Humidity Sensor ตัวเล็ก น่ารัก ก็เลยลองซื้อมาใช้งานดูบ้าง แพ้ค 2 ตัวตกตัวละประมาณ 5 USD เป็น Bluetooth ด้วย

Mijia Temperature & Humidity Sensor เทียบกับ ESP32 TTGO Mini32 V2.0

ถ้าคิดว่าจะทำ Remote Sensor เพื่อวัดอุณหภูมิ ความชื้น ใช้แบตเตอรี่ กินไฟน้อย ส่งข้อมูลเป็น Wireless ยังนึกไม่ออกว่าซื้ออุปกรณ์มาประกอบกัน ใส่แพ้คเกจดีๆหน่อย คงใช้งบเกิน 5 USD แน่นอน วันนี้เลยจะเอาเจ้า Mijia Temperature & Humidity นี้มาใช้งานเป็น Remote Sensor โดยเชื่อมต่อกับ ESP32 ผ่าน Bluetooth

บอกก่อนว่าไม่ได้เขียนโปรแกรมโดยอาชีพ ที่เรียนเขียนโปรแกรมจริงจังก็ตอน ป.ตรีปี 1 กับ ปี 2 ที่เรียน Programing 101 กับ Advance Programing ซึ่งก็คืนอาจารย์ไปหมดแล้ว แล้วก็เรียนเขียน Assembly ตอนสมัยที่ยังใช้ MCS8051 ซึ่งไม่ต้องกล่าวถึง ความทรงจำแทบไม่เหลือ ฉะนั้นที่ทดลองทั้งหมดนี้ งานอดิเรกล้วนๆ อาศัยตัดแปะ Code จากที่อื่น ปรับโค้ดทดลองตามที่เข้าใจแบบ script kiddie มาเริ่มต้นการทดลองของเราวันนี้กันเลย อย่างแรกเราก็ต้องมี Bluetooth Address ของอุปกรณ์ Sensor ก่อน โดยสามารถดูได้จากหน้า About ของโปรแกรม MiHome

หรือใครจะใช้โปรแกรมประเภท BLE Scanner ก็ได้ เพราะเอาจริงๆตอนแรก จากการ Google หาวิธีในการเชื่อมต่อแล้วดึงข้อมูลมานั้น ก็ติดปัญหาเรื่องของ Service ID ที่ไม่ตรงกัน ซึ่งรุ่นที่ทดลองในวันนี้คือ lywsd03mmc ก็ต้องเอารุ่นไปหาใหม่ว่า จะต้องดึงข้อมูลจาก Service ID ตัวไหน

จากนั้นก็สามารถใช้ Code นี้ในการ Upload ไปที่ ESP32 TTGO Mini V2.0 ได้เลย หรือท่านไหนจะใช้บอร์ด ESP32 ตัวอื่นก็ได้


#include <BLEDevice.h>


BLEClient* pClient;

#define MJ_ADDR "A4:C1:38:14:8E:4C"
static BLEAddress MJAddress(MJ_ADDR);
static boolean connected = false;
static BLERemoteCharacteristic* pRemoteCharacteristic;
uint8_t* pData;
float temp = 0;
float humi =0;
float volt =0;



// The remote service we wish to connect to.
static BLEUUID serviceUUID("ebe0ccb0-7a0a-4b0c-8a1a-6ff2997da3a6"); //
// The characteristic of the remote service we are interested in.
static BLEUUID    charUUID("ebe0ccc1-7a0a-4b0c-8a1a-6ff2997da3a6"); //

static void notifyCallback(
  BLERemoteCharacteristic* pBLERemoteCharacteristic,
  uint8_t* pData,
  size_t length,
  bool isNotify) {
    
    Serial.println("---------------------------------");
    Serial.print("Notify callback for characteristic ");
    Serial.print(pBLERemoteCharacteristic->getUUID().toString().c_str());
    Serial.print(" of data length ");
    Serial.println(length);
    
    temp = (pData[0] | (pData[1] << 8)) * 0.01;
    Serial.println("Temp: "+String(temp));
    
    humi = pData[2];
    Serial.println("Humidity: "+String(humi));

    volt = ((pData[4] * 256) + pData[3]) / 1000.0;
    Serial.println("Voltage: "+String(volt));
    Serial.println("Battery Percentage: "+String(((volt - 2.1) * 100.0)));
    Serial.println("---------------------------------");

    
}



class MyClientCallback : public BLEClientCallbacks {
  void onConnect(BLEClient* pclient) {
    Serial.println("on connect");    
    connected = true;
  }

  void onDisconnect(BLEClient* pclient) {
    connected = false;
    Serial.println("onDisconnect");
    
  }
};

void getSensorData1(){
  
  Serial.println("Connecting to BLE Device");
  connectToServer(MJAddress);
  
}



void connectToServer(BLEAddress pAddress){
 

  
  pClient->setClientCallbacks(new MyClientCallback());
  
  Serial.println("=================== Forming a connection to Mijia device ====================");
  Serial.println(pAddress.toString().c_str());
  Serial.println(" - Connection to Mijia Device");
  
  pClient->connect(pAddress);

  Serial.println(" - Connected to Mijia Device");
 

  // Obtain a reference to the service we are after in the remote BLE server.
  BLERemoteService* pRemoteService = pClient->getService(serviceUUID);
    if (pRemoteService == nullptr) {
      Serial.print("Failed to find our service UUID: ");
      Serial.println(serviceUUID.toString().c_str());
      pClient->disconnect();
    }
    Serial.println(" - Found our service");

    // Obtain a reference to the characteristic in the service of the remote BLE server.
    pRemoteCharacteristic = pRemoteService->getCharacteristic(charUUID);
    if (pRemoteCharacteristic == nullptr) {
      Serial.print("Failed to find our characteristic UUID: ");
      Serial.println(charUUID.toString().c_str());
      pClient->disconnect();      
    }
    Serial.println(" - Found our characteristic");
    
    pRemoteCharacteristic->registerForNotify(notifyCallback);
    
        
  
}

void setup() {
  Serial.begin(115200);
  Serial.println("------ Starting ESP32 Bluetooth client... ------");
  

  BLEDevice::init("");
  delay(500);
  
  
  pClient  = BLEDevice::createClient();
  Serial.println("BLE Device - Client Created");
  delay(500);


  getSensorData1();

 
}

void loop() {

 
}

เมื่อ Connect เข้ากับ Xiaomi Mijia Temperature & Humidity Sensor ได้แล้ว ก็จะรับ Notify ที่ส่งออกมา รวมถึงค่า Voltage ที่เอามาคิดเป็น % ของ Battery ได้ด้วย ซึ่งพอได้ค่าตรงนี้มาแล้ว ใครจะ bridge เพื่อโยนขึ้น Cloud จะส่งเข้า InfluxDB หรือเก็บค่าลง Google Sheet ก็ได้ ผมว่าก็สะดวกดีเหมือนกัน กับการใช้วัดอุณหภูมิ ความชื้น แบบนำไปวาง แค่อยู่ในระยะที่รับได้ของ Bluetooth เท่านั้นก็พอ ปัญหาเท่าที่เจอ อาจจะมีบางครั้งที่ Connect ได้แล้วมี error ไม่ส่งค่าคืนกลับมาบ้างแล้วทำให้ตัว ESP32 Hang ไปเลย ตรงนี้ก็อาจต้องมี Watchdog ในการดูเพื่อ Restart Node ESP32 ให้กลับมาทำงานใหม่ และไม่ควร Connect Node EPS32 กับ Sensor ตลอดเวลา เพราะก็จะทำให้เปลืองแบตของทางฝั่ง Sensor ได้เหมือนกันครับ

ที่มา:

Author: Joe D.S.
Just a man on earth

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.