XIAOMI LYWSD03MMC - odczyt przez ESP32

User avatar
Duch__
Posts: 1785
Joined: Wed Aug 24, 2016 7:26 pm
Location: Opole

Post

LYW.png
Witam.

Wrzucam dla potomnych programik odczytujący czujniki XIAOMI LYWSD03MMC (temperatura, wilgotność, poziom naładowania baterii) przez moduł WIFI ESP32. Wymagane jest aby moduły XIAOMI miały zmienione oprogramowanie na ATC_Thermometer.bin pobrane ze strony https://github.com/atc1441/ATC_MiThermometer poprzez "programator" https://atc1441.github.io/TelinkFlasher.html. Zmiana oprogramowania jest bezinwazyjna, nie wymaga otwierania obudowy, lutowania etc. W każdej chwili można przywrócić oryginalny soft. Jest to alternatywne do bramki na raspberry pi.
Telink.png



Soft jest rozwojowy:

Code: Select all

//Do poprawnej pracy wymagana jest zmiana firmware w module LYWSD03MMC na ATC_Thermometer.bin (https://github.com/atc1441/ATC_MiThermometer) i wgranie go przez tą stronę https://atc1441.github.io/TelinkFlasher.html


#include <sstream>

#include <BLEDevice.h>
#include <BLEScan.h>
#include <BLEAdvertisedDevice.h>

#define SCAN_TIME  20 // seconds

#define Blue_LED 2

boolean METRIC = true; //Set true for metric system; false for imperial

String text01;
String text02;
String text03;
String text04;
String text05;
String text06;
String text07;
String text08;
String text09;
String text10;
String text11;
String text12;
String text13;
String text14;
String text15;
String zmienna;
String MAC_ADR;
byte BLE_DEVICE;
bool wyswietl = 0;

#define XIAOMI_BLE_DEVICE_1_MAC "A4:C1:38:9C:1E:8B"
#define XIAOMI_BLE_DEVICE_2_MAC "A4:C1:38:4F:AC:B8"
#define XIAOMI_BLE_DEVICE_3_MAC "A4:C1:38:00:00:01"
#define XIAOMI_BLE_DEVICE_4_MAC "A4:C1:38:00:00:02"
#define XIAOMI_BLE_DEVICE_5_MAC "A4:C1:38:00:00:03"
#define XIAOMI_BLE_DEVICE_6_MAC "A4:C1:38:00:00:04"
#define XIAOMI_BLE_DEVICE_7_MAC "A4:C1:38:00:00:05"
#define XIAOMI_BLE_DEVICE_8_MAC "A4:C1:38:00:00:06"
#define XIAOMI_BLE_DEVICE_9_MAC "A4:C1:38:00:00:07"
#define XIAOMI_BLE_DEVICE_10_MAC "A4:C1:38:00:00:08"
#define XIAOMI_BLE_DEVICE_11_MAC "A4:C1:38:00:00:09"
#define XIAOMI_BLE_DEVICE_12_MAC "A4:C1:38:00:00:0A"
#define XIAOMI_BLE_DEVICE_13_MAC "A4:C1:38:00:00:0B"
#define XIAOMI_BLE_DEVICE_14_MAC "A4:C1:38:00:00:0C"
#define XIAOMI_BLE_DEVICE_15_MAC "A4:C1:38:00:00:0D"
#define XIAOMI_BLE_DEVICE_16_MAC "A4:C1:38:00:00:0E"
#define XIAOMI_BLE_DEVICE_17_MAC "A4:C1:38:00:00:0F"
#define XIAOMI_BLE_DEVICE_18_MAC "A4:C1:38:00:00:10"
#define XIAOMI_BLE_DEVICE_19_MAC "A4:C1:38:00:00:11"
#define XIAOMI_BLE_DEVICE_20_MAC "A4:C1:38:00:00:12"





int current_humidity;
int current_batt;

word val;

BLEScan *pBLEScan;

void IRAM_ATTR resetModule(){
    ets_printf("reboot\n");
    esp_restart();
}

float current_temperature;

class MyAdvertisedDeviceCallbacks : public BLEAdvertisedDeviceCallbacks {
    void onResult(BLEAdvertisedDevice advertisedDevice)
    {
        if (advertisedDevice.haveName() && advertisedDevice.haveServiceData() /*&& !advertisedDevice.getName().compare("ATC_9C1E8B")*/) {

            int serviceDataCount = advertisedDevice.getServiceDataCount();
            std::string strServiceData = advertisedDevice.getServiceData(0);

            uint8_t cServiceData[100];
            char charServiceData[100];

            strServiceData.copy((char *)cServiceData, strServiceData.length(), 0);

            //Serial.printf("\n\nAdvertised Device: %s\n", advertisedDevice.toString().c_str());

            for (int i=0;i<strServiceData.length();i++) {
                sprintf(&charServiceData[i*2], "%02x", cServiceData[i]);
            }

            std::stringstream ss;
            ss << "fe95" << charServiceData;

            

            text01 = String(charServiceData[0]) + String(charServiceData[1]);      //Serial.print(text1); Serial.print(" ");
            text02 = String(charServiceData[2]) + String(charServiceData[3]);      //Serial.print(text2); Serial.print(" ");
            text03 = String(charServiceData[4]) + String(charServiceData[5]);      //Serial.print(text3); Serial.print(" ");
            text04 = String(charServiceData[6]) + String(charServiceData[7]);      //Serial.print(text4); Serial.print(" ");
            text05 = String(charServiceData[8]) + String(charServiceData[9]);      //Serial.print(text5); Serial.print(" "); 
            text06 = String(charServiceData[10]) + String(charServiceData[11]);    //Serial.print(text6); Serial.print(" "); 
            text07 = String(charServiceData[12]) + String(charServiceData[13]);    //Serial.print(text7); Serial.print(" "); 
            text08 = String(charServiceData[14]) + String(charServiceData[15]);    //Serial.print(text8); Serial.print(" "); 
            text09 = String(charServiceData[16]) + String(charServiceData[17]);    //Serial.print(text9); Serial.print(" "); 
            text10 = String(charServiceData[18]) + String(charServiceData[19]);   //Serial.print(text10); Serial.print(" "); 
            text11 = String(charServiceData[20]) + String(charServiceData[21]);   //Serial.print(text11); Serial.print(" "); 
            text12 = String(charServiceData[22]) + String(charServiceData[23]);   //Serial.print(text12); Serial.print(" "); 
            
            //Serial.println();

            zmienna = text01; Zamien_litery(); text01 = zmienna;
            zmienna = text02; Zamien_litery(); text02 = zmienna;
            zmienna = text03; Zamien_litery(); text03 = zmienna;
            zmienna = text04; Zamien_litery(); text04 = zmienna;
            zmienna = text05; Zamien_litery(); text05 = zmienna;
            zmienna = text06; Zamien_litery(); text06 = zmienna;
            zmienna = text07; Zamien_litery(); text07 = zmienna;
            zmienna = text08; Zamien_litery(); text08 = zmienna;
            zmienna = text09; Zamien_litery(); text09 = zmienna;
            zmienna = text10; Zamien_litery(); text10 = zmienna;
            zmienna = text11; Zamien_litery(); text11 = zmienna;
            zmienna = text12; Zamien_litery(); text12 = zmienna;
            zmienna = text13; Zamien_litery(); text13 = zmienna;
            zmienna = text14; Zamien_litery(); text14 = zmienna;
            zmienna = text15; Zamien_litery(); text15 = zmienna;




            Konwersja();


            
        }
    }
};

void setup() {
  
  pinMode(Blue_LED,OUTPUT);

  Serial.begin(115200);
  Serial.println("ESP32 XIAOMI LYWSD03MMC");
 
  initBluetooth();


}

void loop() {
  
    char printLog[256];
    Serial.println(" ");
    Serial.println(" ");
    Serial.println(" ");
    Serial.println(" ");
    Serial.println(" ");
    Serial.printf("Start skanowania BLE przez %d sekund...\n", SCAN_TIME);
    BLEScan* pBLEScan = BLEDevice::getScan(); //create new scan
    pBLEScan->setAdvertisedDeviceCallbacks(new MyAdvertisedDeviceCallbacks());
    pBLEScan->setActiveScan(true); //active scan uses more power, but get results faster
    BLEScanResults foundDevices = pBLEScan->start(SCAN_TIME);
    int count = foundDevices.getCount();

    printf("Liczba znalezionych urządzeń : %d\n", count);

    delay(100);
}



void initBluetooth()
{
    BLEDevice::init("");
    pBLEScan = BLEDevice::getScan(); //create new scan
    pBLEScan->setAdvertisedDeviceCallbacks(new MyAdvertisedDeviceCallbacks());
    pBLEScan->setActiveScan(true); //active scan uses more power, but get results faster
    pBLEScan->setInterval(0x50);
    pBLEScan->setWindow(0x30);
}

void Konwersja()
{
  int number;
  String hexstring;
  int t1;
  int t2;


  hexstring = "#" + text07;
  number = (int) strtol( &hexstring[1], NULL, 16);
  t1 = number & 0xFF;                        

  hexstring = "#" + text08;
  number = (int) strtol( &hexstring[1], NULL, 16);
  t2 = number & 0xFF;

  current_temperature = t1 * 256;
  current_temperature = current_temperature + t2;
  current_temperature = current_temperature / 10;
  // Konwersja z Faranheitów na Celsjusze
                                      
  hexstring = "#" + text09;
  number = (int) strtol( &hexstring[1], NULL, 16);
  current_humidity = number & 0xFF;

  hexstring = "#" + text10;
  number = (int) strtol( &hexstring[1], NULL, 16);
  current_batt = number & 0xFF;
  
  MAC_ADR = "";
  MAC_ADR = MAC_ADR + text01 + ":";
  MAC_ADR = MAC_ADR + text02 + ":";
  MAC_ADR = MAC_ADR + text03 + ":";
  MAC_ADR = MAC_ADR + text04 + ":";
  MAC_ADR = MAC_ADR + text05 + ":";
  MAC_ADR = MAC_ADR + text06;

  BLE_DEVICE = 0;
  if(MAC_ADR == XIAOMI_BLE_DEVICE_1_MAC){BLE_DEVICE = 1; wyswietl = 1; Wyswietl();} 
  if(MAC_ADR == XIAOMI_BLE_DEVICE_2_MAC){BLE_DEVICE = 2; wyswietl = 1; Wyswietl();}
  if(MAC_ADR == XIAOMI_BLE_DEVICE_3_MAC){BLE_DEVICE = 3; wyswietl = 1; Wyswietl();} 
  if(MAC_ADR == XIAOMI_BLE_DEVICE_4_MAC){BLE_DEVICE = 4; wyswietl = 1; Wyswietl();} 
  if(MAC_ADR == XIAOMI_BLE_DEVICE_5_MAC){BLE_DEVICE = 5; wyswietl = 1; Wyswietl();} 
  if(MAC_ADR == XIAOMI_BLE_DEVICE_6_MAC){BLE_DEVICE = 6; wyswietl = 1; Wyswietl();}
  if(MAC_ADR == XIAOMI_BLE_DEVICE_7_MAC){BLE_DEVICE = 7; wyswietl = 1; Wyswietl();} 
  if(MAC_ADR == XIAOMI_BLE_DEVICE_8_MAC){BLE_DEVICE = 8; wyswietl = 1; Wyswietl();}
  if(MAC_ADR == XIAOMI_BLE_DEVICE_9_MAC){BLE_DEVICE = 9; wyswietl = 1; Wyswietl();} 
  if(MAC_ADR == XIAOMI_BLE_DEVICE_10_MAC){BLE_DEVICE = 10; wyswietl = 1; Wyswietl();}
  if(MAC_ADR == XIAOMI_BLE_DEVICE_11_MAC){BLE_DEVICE = 11; wyswietl = 1; Wyswietl();} 
  if(MAC_ADR == XIAOMI_BLE_DEVICE_12_MAC){BLE_DEVICE = 12; wyswietl = 1; Wyswietl();}
  if(MAC_ADR == XIAOMI_BLE_DEVICE_13_MAC){BLE_DEVICE = 13; wyswietl = 1; Wyswietl();} 
  if(MAC_ADR == XIAOMI_BLE_DEVICE_14_MAC){BLE_DEVICE = 14; wyswietl = 1; Wyswietl();}
  if(MAC_ADR == XIAOMI_BLE_DEVICE_15_MAC){BLE_DEVICE = 15; wyswietl = 1; Wyswietl();} 
  if(MAC_ADR == XIAOMI_BLE_DEVICE_16_MAC){BLE_DEVICE = 16; wyswietl = 1; Wyswietl();}
  if(MAC_ADR == XIAOMI_BLE_DEVICE_17_MAC){BLE_DEVICE = 17; wyswietl = 1; Wyswietl();} 
  if(MAC_ADR == XIAOMI_BLE_DEVICE_18_MAC){BLE_DEVICE = 18; wyswietl = 1; Wyswietl();}
  if(MAC_ADR == XIAOMI_BLE_DEVICE_19_MAC){BLE_DEVICE = 19; wyswietl = 1; Wyswietl();} 
  if(MAC_ADR == XIAOMI_BLE_DEVICE_20_MAC){BLE_DEVICE = 20; wyswietl = 1; Wyswietl();}
  
}

void Wyswietl(){
  if(wyswietl == 1){
    Serial.print("Urządzenie:");
    Serial.print(BLE_DEVICE);
    Serial.print(" MAC: "); 
    Serial.print(MAC_ADR);
                                   
    Serial.print(" Temp: ");
    Serial.print(current_temperature,1);
    Serial.print("stC. Wilgotnosc: ");
    Serial.print(current_humidity);
    Serial.print("%. Bateria: ");
    Serial.print(current_batt);
    Serial.println("%.");   
    wyswietl = 0; 
  }
  else
  {
    Serial.print("Wykryto nieznane urządzenie");
    Serial.print(" MAC: "); 
    Serial.print(MAC_ADR);
    Serial.println(" ");
    wyswietl = 0;
  }
}

void Zamien_litery()  //Zamieniamy otrzymywane małe litery na duże
{
  zmienna.replace('a', 'A');
  zmienna.replace('b', 'B');
  zmienna.replace('c', 'C');
  zmienna.replace('d', 'D');
  zmienna.replace('e', 'E');
  zmienna.replace('f', 'F');
}
Przykładowy wynik odczytu:
BLE.png
You do not have the required permissions to view the files attached to this post.
Last edited by Duch__ on Tue Aug 23, 2022 6:23 pm, edited 1 time in total.
Image
krycha88
Posts: 5208
Joined: Fri Nov 16, 2018 7:25 am

Post

Jaki jest zasięg takich czujników?
https://gui-generic-builder.supla.io/
User avatar
Duch__
Posts: 1785
Joined: Wed Aug 24, 2016 7:26 pm
Location: Opole

Post

Jeden wyłapuje w odległości 5m (przez ścianę murowaną 12cm), a drugi w okolicy 10m (przez strop teriva + żelbet + 2 ściany działowe).
Image
mdi87
Posts: 492
Joined: Thu Sep 17, 2020 10:00 am
Location: Leoncin

Post

Może i głupie pytanie bo nie do końca wiem o co chodzi, czy widać temperure w aplikacji ?
User avatar
artur_n
Posts: 435
Joined: Thu Aug 17, 2017 2:24 pm
Location: RJA

Post

Kod nie wykazuje żadnych powiązań z Supla, więc nie widać tych odczytów w aplikacji.
JaG
Posts: 18
Joined: Sun Jun 06, 2021 7:09 am

Post

A czy jest jakiś gotowiec w gui generic żeby tylko zmienić tylko trzeba było soft w czujnikach by to połączyć z suplą ?
User avatar
klimasstudio
Posts: 1117
Joined: Wed Aug 28, 2019 9:35 pm
Location: localhost

Post

Dobra czyli tym softem zaczytasz dane z czujników i co dalej z tymi odczytami się dzieje ?
Więc chodź OSUPLUJE Ci dom :mrgreen:

Druk 3D - > https://klimastech.eu.org/druk-3d
User avatar
klew
Posts: 8357
Joined: Thu Jun 27, 2019 12:16 pm
Location: Wrocław

Post

Ten soft to niezwiązany z Suplą przykład, jak odczytać dane z czujników Xiaomi na ESP32.
Nic do Supli się nie wysyła, ani nie wyświetla. Jeśli ktoś by chciał to na podstawie tego przykładu można dodać taki czujnik do Supli.
Tylko kiedyś czytałem, że równoległe używanie BLE i Wi-Fi na ESP32 pogarsza jakość obu interfejsów. Ale sam tego nie testowałem.
Widzimy się na Supla Offline Party vol. 2 :!:
User avatar
veeroos
Posts: 293
Joined: Sun Mar 20, 2022 9:30 am
Location: Głogów

Post

@Duch__ kawał dobrej roboty odwaliłeś. Ja ze swojej strony wrzuciłem wysyłanie na ESP32 do Supli. Taka alternatywa do RPi ;-). No i teraz tak na ESP32 Dev niestety nie chce to za bardzo działać, maksymalny czas działania jaki wyciągnąłem z tego modułu to 10 minut, po tym czasie w logach widzę, że Bluetooth odnajduje czujniki, ale niestety urządzenie już nie chce łączyć się z siecią Wi-Fi. Poszedłem więc krok dalej i kupiłem moduł ESP32 S3 Dev. no i tutaj sytuacja wygląda na chwilę obecną tak: od godziny wszystko działa poprawnie, no ale jest małe "ale" nie widzę żadnych logów po USB. Mam więc do wszystkich pytanie co jest nie tak, ten sam program został wgrany do obu płytek, jedna daje logi, a druga nie. Program zrobiłem na bazie przykładu Webinterface, dodałem obsługę czujników z przykładu kolegi @Duch__ dodałem klasy które pchają dane do Supli no i w sumie tyle. Na razie nie wysyłam danych dotyczących baterii, bo w sumie chciałem tylko bramkę uruchomić. Jak testy wyjdą pozytywnie to wrzucę kod źródłowy na forum. Ale chciałbym podglądać logi z działania urządzenia, a nic nie widzę, może trzeba jakoś inaczej skonfigurować interfejs, albo na innych pinach czytać?
Zamel Mew-01, Wemos D1 mini Pro + Ikea vindriktning + BME280, 3x - SonOff mini, 3x - SonOff Basic, 3xGosund SP111, SonOff S55, 2x GOSUND WB4
User avatar
klew
Posts: 8357
Joined: Thu Jun 27, 2019 12:16 pm
Location: Wrocław

Post

veeroos wrote: Tue Feb 14, 2023 8:23 pm Ale chciałbym podglądać logi z działania urządzenia, a nic nie widzę, może trzeba jakoś inaczej skonfigurować interfejs, albo na innych pinach czytać?
Podgląd seriala jest na tych samych pinach, co wgrywanie danych, także powinno działać.
Czego używasz do podglądu? Spróbuj różnych programów do tego (u mnie w sumie serial monitor z Arduino IDE działa prawie zawsze, putty też się dobrze sprawdza).

Jak nie będzie nadal działać, to wrzuć tam prawie pusty program w Arduino i dodaj tylko logowanie (np. "jesteś super" co 1 s).
Widzimy się na Supla Offline Party vol. 2 :!:

Return to “Zagadnienia ogólne”