Xiaomi LYWSD03MMC + HM10 + ESP8266 (WEMOS)

Zibi
Posty: 614
Rejestracja: śr lip 31, 2019 9:20 am
Lokalizacja: Białogard

To fajnie to mi chęci narobiłeś będę zamawiał.
andrew01
Posty: 162
Rejestracja: pt maja 24, 2019 6:49 am

Poprawiłem odczyt danych i całą obsługę przeniosłem do oddzielnej biblioteki

mijia.h:

Kod: Zaznacz cały

#include <SoftwareSerial.h>
#include <supla/sensor/therm_hygro_meter.h>

#define MIJIA_MAX_SENSOR_COUNT 10
//#define MIJIA_DEBUG

class mijiaSensor
{
public:
  double temp;
  double humi;
  double batt;
  double volt;
  double rssi;
  byte skippedReading;
  char addr[6];

  void clearValues()
  {
    Serial.print(F("*** MIJIA CLEAR VALUES "));
    for (int i = 0; i < 6; i++)
    {
      Serial.print(" ");
      Serial.printf("%02hhX", addr[i]);
    }
    Serial.println();    
    temp = TEMPERATURE_NOT_AVAILABLE;
    humi = TEMPERATURE_NOT_AVAILABLE;
    batt = 0;
    volt = 0;
    rssi = TEMPERATURE_NOT_AVAILABLE;
    skippedReading = 0;
  }  
};

class Mijia
{
private:
  char mijiaData[100];
  char checkedSymbol[8];
  byte mijiaIndex;
  unsigned long lastReadTime = 0;
  unsigned long lastReceiveTime; 
  char receivedAddr[6];
    
public:
  Mijia(int pinRX, int pinTX, int baudRate)
  {
    mySerial = new SoftwareSerial(pinRX,pinTX);
    mySerial->begin(baudRate);
    while (!mySerial)
    {
    }
    delay(500);
    mySerial->write("AT");
    delay(500);
    mySerial->write("AT+ROLE1");
    delay(500);
    mySerial->write("AT+IMME1");
    delay(500);
    mySerial->write("AT+RESET");
    delay(500);
  }
  
  mijiaSensor *mySensor[MIJIA_MAX_SENSOR_COUNT];
  SoftwareSerial *mySerial;
  int baudRate;
  int readInterval = 30000;
  int sensorCount;
  int maxSkippedReading = 5;

  void Iterate()
  {
    if (mySerial->available() > 0) 
    {
      mijiaData[mijiaIndex] = mySerial->read();
      lastReceiveTime = millis();
      mijiaIndex++;
    }
    
    if (mijiaIndex >= 8)
    {
      //jeżeli odebraliśmy OK+DISAS lub OK+DISA: lub OK+DISAE to uznajemy, że skończyła się poprzednia paczka i można analizować to co otrzymaliśmy
      //wyodrębnieneie ostatnich 8 otrzymanych bajtów
      for (int i = 0; i < 8; i++)
      {
        checkedSymbol[i] = mijiaData[mijiaIndex - 8 + i];
      }

      if (strncmp(checkedSymbol,"OK+DISAS",8) == 0 or
          strncmp(checkedSymbol,"OK+DISA:",8) == 0 or
          strncmp(checkedSymbol,"OK+DISAE",8) == 0)
      {
        #if defined(MIJIA_DEBUG)
        Serial.print("NOWA PACZKA DANYCH, BAJTÓW: ");
        Serial.println(mijiaIndex);
        {
          Serial.print("HEX: ");
          for (int i = 0; i < mijiaIndex; i++)
          {
            Serial.print(mijiaData[i],HEX);
            Serial.print(" ");
          }
          Serial.println();
      
          Serial.print("DEC: ");
          for (int i = 0; i < mijiaIndex; i++)
          {
            Serial.print(mijiaData[i],DEC);
            Serial.print(" ");
          }
          Serial.println();        
        }
        #endif

        //mamy paczkę, sprawdzamy czy jest to UUID 181A i czy jest >= 25
        if (mijiaIndex >= 25 and
            (int)mijiaData[11] == 0x1A and //UUID 181A
            (int)mijiaData[12] == 0x18)
        {
          //wyodrębnienia adresu urządzenia
          for (int i = 13; i < 19; i++) receivedAddr[i - 13] = mijiaData[i];
          
          #if defined(MIJIA_DEBUG)
          Serial.print("PACZKA DANYCH UUID 181A: ");

          for (int j = 0; j < 6; j++)
          {
            Serial.print(" ");
            Serial.printf("%02hhX", receivedAddr[j]);
          }
          Serial.println();     
          #endif           

          //sprawdzenie czy adres jest znany
          for (int i = 0; i < sensorCount; i++)
          {
            if (strncmp(receivedAddr,mySensor[i]->addr,6) == 0)
            {
              //zerowanie wskaźnika pominięć
              mySensor[i]->skippedReading = 0;
              
              Serial.print("ZNANY CZUJNIK:");
              for (int j = 0; j < 6; j++)
              {
                Serial.print(" ");
                Serial.printf("%02hhX", receivedAddr[j]);
              }
              Serial.println();
              
              mySensor[i]->temp = ((double)mijiaData[19] * 256 + (double)mijiaData[20]) / 10;
              mySensor[i]->humi = mijiaData[21];
              mySensor[i]->batt = mijiaData[22];
              mySensor[i]->volt = ((double)mijiaData[23] * 256 + (double)mijiaData[24]) / 1000;
              mySensor[i]->rssi = (double)mijiaData[7] - 256;
  
              Serial.print("Temp: ");
              Serial.println(mySensor[i]->temp);
              Serial.print("Humi: ");
              Serial.println(mySensor[i]->humi);
              Serial.print("Batt: ");
              Serial.println(mySensor[i]->batt);
              Serial.print("Volt: ");
              Serial.println(mySensor[i]->volt);
              Serial.print("Rssi: ");
              Serial.println(mySensor[i]->rssi);
            }
          }          
        }

        mijiaIndex = 0;
        memset(mijiaData, 0, sizeof(mijiaData));    
      }
    }

    //odczyt danych
    if (mySerial->available() == 0 and ((millis() - lastReadTime > readInterval) or (lastReadTime == 0)))
    {
      Serial.println("***** ODCZYT DANYCH MIJIA *****");
      lastReadTime = millis();
      lastReceiveTime = millis();
      //licznik pominiętych odczytów
      for (int i = 0; i < sensorCount; i++)
      {
        mySensor[i]->skippedReading++; 
        if (mySensor[i]->skippedReading > maxSkippedReading) mySensor[i]->clearValues();
      }
      mijiaIndex = 0;
      memset(mijiaData, 0, sizeof(mijiaData));
      mySerial->write("AT+DISA?");
    }
  }
};

class mijiaThermHygroMeter : public Supla::Sensor::ThermHygroMeter
{
public:

  mijiaThermHygroMeter(Mijia *myMijia, char *addr)
  {
    lastReadTime = 0;
    strncpy(mySensor.addr,addr,6);
    myMijia->mySensor[myMijia->sensorCount] = &mySensor;
    myMijia->sensorCount++;
    mySensor.clearValues();
  }

  void onInit()
  {
    channel.setNewValue(getTemp(), getHumi());
  }

  double getTemp()
  {
    return mySensor.temp;
  }
  double getHumi()
  {
    return mySensor.humi;
  }

  void handleGetChannelState(TDSC_ChannelState &channelState) {
    channelState.Fields = SUPLA_CHANNELSTATE_FIELD_MAC |
                          SUPLA_CHANNELSTATE_FIELD_BATTERYLEVEL |
                          SUPLA_CHANNELSTATE_FIELD_BATTERYPOWERED |
                          SUPLA_CHANNELSTATE_FIELD_WIFIRSSI |
                          SUPLA_CHANNELSTATE_FIELD_WIFISIGNALSTRENGTH;
                           
    channelState.BatteryLevel = mySensor.batt;
    channelState.BatteryPowered = true;
    channelState.WiFiRSSI = mySensor.rssi;

    for (int j = 0; j < 6; j++)
    {
       channelState.MAC[j] = (unsigned char)(int)mySensor.addr[j];
    }
    
    if (mySensor.rssi > -50) {
      channelState.WiFiSignalStrength = 100;
    } else if (mySensor.rssi <= -100) {
      channelState.WiFiSignalStrength = 0;
    } else {
      channelState.WiFiSignalStrength = 2 * (mySensor.rssi + 100);
    }
  }

  mijiaSensor mySensor;
};

mijia.ino:

Kod: Zaznacz cały

#include <SuplaDevice.h>
#include <supla/network/esp_wifi.h>
#include <mijia.h>

#define MODULE_NAME "Xiaomi Mijia" //Nazwa modułu
#define STASSID "..."
#define STAPSK  "..."

Supla::ESPWifi wifi(STASSID, STAPSK);

int suplaStatus;
void status_func(int status, const char *msg)
{
  suplaStatus = status;
  Serial.println(msg);
}

Mijia myMijia(D5,D6,9600); //HM-10 RX,TX,BAUD RATE

void setup() { 
  
  Serial.begin(9600);
  while (!Serial) 
  {
  }
  delay(200);
  Serial.println("SERIAL STARTED");

  char addr1[] = {0xA4, 0xC1, 0x38, 0x0E, 0x36, 0x8F};
  char addr2[] = {0xA4, 0xC1, 0x38, 0x66, 0x23, 0x63};

  new mijiaThermHygroMeter(&myMijia, addr1);
  new mijiaThermHygroMeter(&myMijia, addr2);

  SuplaDevice.setStatusFuncImpl(&status_func);
  
  // Replace the following AUTHKEY with value that you can retrieve from: https://www.supla.org/arduino/get-guid
  char GUID[SUPLA_GUID_SIZE] = {...};
  // Replace the following AUTHKEY with value that you can retrieve from: https://www.supla.org/arduino/get-authkey
  char AUTHKEY[SUPLA_AUTHKEY_SIZE] = {...};

  SuplaDevice.setName(MODULE_NAME);
  SuplaDevice.begin(GUID,                 // Global Unique Identifier
                    "...",    // SUPLA server address
                    "...", // Email address used to login to Supla Cloud
                    AUTHKEY);             // Authorization key         // Location Password  
}

void loop() { 

  SuplaDevice.iterate();

  if (suplaStatus == 17)
    myMijia.Iterate();

}

Pozdrawiam
Andrzej
Zibi
Posty: 614
Rejestracja: śr lip 31, 2019 9:20 am
Lokalizacja: Białogard

Xiaomi zamówione u maj frendów te kwadratowe.
Andrew01 na tych HM10 jaki miałeś zasięg?
andrew01
Posty: 162
Rejestracja: pt maja 24, 2019 6:49 am

Bez dodatkowej anteny max 4-5 metrów, przez ścianę już problemy, o stropie nie wspominając.
Po podłączeniu anteny zdecydowanie lepiej, zasięg dla mnie akceptowalny.

Bez anteny przez strop brak zasięgu, z anteną -75dB.

Mam nadzieję, ze z tym modułem co zamówiłem będzie lepiej, ze względu na normalne gniazdo do podłączenia anteny, obecnie przewody przylutowałem do modułu.

Pozdrawiam
Andrzej
Ostatnio zmieniony pn lis 02, 2020 6:58 am przez andrew01, łącznie zmieniany 1 raz.
George2002
Posty: 188
Rejestracja: pn maja 01, 2017 2:00 am

klew pisze: pt paź 30, 2020 11:55 am
George2002 pisze: pt paź 30, 2020 10:52 am
artur_n pisze: pt paź 30, 2020 10:38 am Mam 4 czujniki które bezczynnie stoją. Czas się tym zająć. Jaki moduł Bluetooth kupić aby był dobry zasięg oraz był kompatybilny??
Mogę prosić o jakiś link?

Pozdrawia
Artur
Najlepiej aby ktoś to przeportował na esp32 bo ma w sobie Bluetooth :)
Podchodziłbym do BLE na ESP32 dość ostrożnie. ESP32 ma jedno fizyczne radio, które może być w danym momencie używane wyłącznie przez WiFi lub przez Bluetooth. Ludzie w sieci często mają problemy z uruchomieniem obu na raz, ale niekrórym się to udało.
A to nawet nie wiedziałem o takich problemach - dobrze wiedzieć :)
Krzyśku
Posty: 144
Rejestracja: pn wrz 16, 2019 7:22 pm
Lokalizacja: Gorzów

andrew01 pisze: ndz lis 01, 2020 9:02 pm Bez dodatkowej anteny max 4-5 metrów, przez ścianę już problemy, o stropie nie wspominając.
Po podłączeniu anteny zdecydowanie lepiej, zasięg dla mnie akceptowalny.

Bez anteny przez strop brak zasięgu, z anteną -75dB.

Mam nadzieję, ze z tym modułem co zamówiłem będzie lepiej, ze względu na normalne gniazdo do podłączenia anteny, obecnie przewody przylutowałem do modułu.

Pozdrawiam
Andrzej
Daj znać jak przyjdą i zamontujesz antenę :)
Awatar użytkownika
artur_n
Posty: 435
Rejestracja: czw sie 17, 2017 2:24 pm
Lokalizacja: RJA

andrew01 pisze: ndz lis 01, 2020 9:02 pm Bez dodatkowej anteny max 4-5 metrów, przez ścianę już problemy, o stropie nie wspominając.
Po podłączeniu anteny zdecydowanie lepiej, zasięg dla mnie akceptowalny.

Bez anteny przez strop brak zasięgu, z anteną -75dB.

Mam nadzieję, ze z tym modułem co zamówiłem będzie lepiej, ze względu na normalne gniazdo do podłączenia anteny, obecnie przewody przylutowałem do modułu.

Pozdrawiam
Andrzej
Jak spiąć ten moduł z aliexpress z wemosem?
Awatar użytkownika
Robert Błaszczak
Posty: 3970
Rejestracja: sob gru 22, 2018 8:55 pm
Lokalizacja: Zielona Góra
Kontakt:

Przecież @andrew01 zapoczątkował ten temat szczegółowym opisem, jak to ze sobą ma działać.
Pozdrawiam
Robert Błaszczak


Moja prywatna strona: www.blaszczak.pl
bigthomas
Posty: 234
Rejestracja: pn sie 12, 2019 3:35 pm

andrew01 pisze: pt paź 30, 2020 1:46 pm U mnie na razie dwa czujniki, 4 dodatkowe już zamówione :)

Zamówiłem też poniższy moduł aby takiego druciarstwa nie było z podłączeniem anteny zewnętrznej:

https://www.aliexpress.com/item/1005001 ... 4c4dltt5ok

Pozdrawiam
Andrzej
Doszły może już te moduły? Jest lepiej z zasięgiem?
andrew01
Posty: 162
Rejestracja: pt maja 24, 2019 6:49 am

bigthomas pisze: pn gru 28, 2020 10:05 am Doszły może już te moduły? Jest lepiej z zasięgiem?
Doszły ale niestety w wersji bez złącza antenowego, więc złożyłem reklamację i zamówiłem z innego miejsca.
ODPOWIEDZ

Wróć do „Ogólna dyskusja”