vineri, 16 iunie 2017

ESP8266 outdoor module solar powered - Domoticz, MQTT

English:
I put together a device for outdoor use: it is based on ESP8266 (in fact ESP-07 module) to send various environmental measurements over WiFi.
This device is powered from a Lithium element recovered from a laptop battery (18650 unprotected element). Also the device has a small solar cell to harvest energy during sun hours and to store it on the 18650 Lithium element to be used over the night.
The device is sending data in JSON format to an MQTT local broker on a Raspberry Pi clone board.
The device can measure the voltage on the battery (voltage divider), can use I2C, OneWire and so on - various sensors.
For the moment I can share some pictures and the code which is sending the ADC value (corresponding to the voltage on the 18650 battery). The PCB was not the greatest PCB done with toner transfer method, but I'll improve.
On the same Raspberry Pi clone, I run Domoticz home automation server to log data in a database. Domoticz, among many other wonderful things, can plot data in a nice looking format. I logged for instance the ADC read values from the moment I put there a fresh charged 18650 battery until the moment the battery was depleted, every 5 minutes I had a value read and sent to MQTT broker, then Domoticz plotted the values.
Arduino code is not my personal creation, I compiled code from a few sources, unfortunately I did not keep the track of these sources.
Below, at the end, you can see the plot of the logged data from the battery voltage (actually the readings from the ADC). It is interesting to see that while charging is complete, the battery management system will disconnect the 18650 battery, ESP8266 will start consumuing the power from the battery, when the voltage < 4.2V, charging will start again, therefore the saw tooth plot.


****************************************
Romana:
Am construit un aparat care poate fi utilizat in mediul natural: foloseste cipul ESP8266 (un modul ESP-07). Acest aparat trimite valorile diversilor parametri de mediu prin WiFi.
Aparatul este alimentat de la un element cu litiu 18650 recuperat dintr-un acumulator de laptop. De asemenea aparatul are un panou solar care incarca acumulatorul cu litiu.
Datele trimise de aparat sunt in format JSON si merg catre un broker local MQTT instalat pe o clona de placa Raspberry Pi.
Aparatul poate masura tensiunea de pe acumulator (cu un divizor rezistiv), poate utiliza senzori diversi (I2C, OneWire etc).
Pentru moment am doar poze cu aparatul si cod care trimite valoarea ADC (corespunzatoare tensiunii de la acumulator). Cablajul imprimat nu este bine realizat, e metoda cu transfer termic, insa invat si o voi imbunatati.
Pe clona Raspberry Pi ruleaza un server de home automation Domoticz care ia datele de la brokerul local MQTT si le afiseaza intr-un grafic (Domoticz poate face mai multe de atat).
Codul  Arduino prezentat mai jos nu este creatia mea, e format din parti de cod gasite pe Internet. Din pacate nu mai sursa tuturor acestor bucati de cod.
Mai jos, la finalul articolului, sunt graficele cu tensiunea pe acumulatorul 18650 (de fapt sunt valorile ADCului). este interesant de observat graficul dinte de fierastrau care reprezinta momentul cand incarcarea este finalizata si controllerul de incarcare permite consumul din acumulator. Cand tensiunea scade sub 4,2V, atunci controllerul incepe din nou incarcarea, se ajunge din nou la >4,2V, se conecteaza acumulatorul samd.


10cm X 10cm 


 
Reset button

Power stage (blue module) + 3V3 LDO (SMT) HT7333.
Partea de alimentare (modulul albastru) + 3V3 LDO (SMT) HT7333

Power controller (battery management system).
Controllerul de alimentare / incarcare 

 
LEDs on the BMS: Charged.
LEDurile pe controllerul de incarcare: Complet incarcat

LEDs on the BMS: Charging
LEDurile pe controllerul de incarcare: In curs de incarcare


***************************************************
#include
#include

const int AnalogIn  = A0;  //ADC pin
const int Enable_Div = 14;  //enable signal for voltage divider

int readingIn = 0;

const char* ssid = "SSID_aici"; //SSIDul de la reteaua unde vrem sa ne conectam
const char* password = "parola_aici"; //parola retelei
const char* mqtt_server = "192.168.IP.SERVER"; //IPul brokerului MQTT

WiFiClient espClient;
PubSubClient client(espClient);


long lastMsg = 0; //pt intervalul de trimitere date
char msgBatt[50]; //pt mesajul MQTT pt valoarea ADC

void setup() {
  Serial.begin(115200);
  setup_wifi();
  client.setServer(mqtt_server, 1883);
  client.setCallback(callback);
  pinMode(Enable_Div, OUTPUT); //pinul de activare al divizorului rezistiv
}

//aici incercam sa ne conectam la WiFi
void setup_wifi() {

  delay(10);
  // We start by connecting to a WiFi network
  Serial.println();
  Serial.print("Connecting to ");
  Serial.println(ssid);

  WiFi.begin(ssid, password);

  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }

  Serial.println("");
  Serial.println("WiFi connected");
  Serial.println("IP address: ");
  Serial.println(WiFi.localIP());
}

//asta proceseaza mesajele MQTT venite pe un topic la care suntem abonati
//in cazul de fata este domoticz/out
void callback(char* topic, byte* payload, unsigned int length) {
  Serial.print("Mesajul primit de la topicul [");
  Serial.print(topic);
  Serial.print("] ");
  for (int i = 0; i < length; i++) {
    Serial.print((char)payload[i]);
  }
  Serial.println();
}

void reconnect() {
  // Loop until we're reconnected
  while (!client.connected()) {
    Serial.print("Attempting MQTT connection...");
    // Attempt to connect
    if (client.connect("ESP8266Client")) {
      Serial.println("connected");
      // Once connected, publish an announcement...
      client.publish("domoticz/in", "ESP8266 conectat");
      // ... and resubscribe
      client.subscribe("domoticz/out");
    } else {
      Serial.print("failed, rc=");
      Serial.print(client.state());
      Serial.println(" try again in 5 seconds");
      // Wait 5 seconds before retrying
      delay(5000);
    }
  }
}
void loop() {

  if (!client.connected()) {
    reconnect();
  }
  client.loop();

  long now = millis();  
  if (now - lastMsg > 300000) { //daca au trecut 5 minute, publica date noi
    lastMsg = now; 
    digitalWrite(Enable_Div, HIGH);
    delay(2000);
    //citim analog input value     
    Serial.print("ADC value:");
    readingIn = analogRead(AnalogIn);
    Serial.println(readingIn);
    delay(1000);
    digitalWrite(Enable_Div, LOW);
        
    //pregatim mesajul MQTT cu valoarea ADC in format JSON
    snprintf (msgBatt, 75, "{ \"idx\" : 6, \"nvalue\" : 0, \"svalue\" : \"%s\" }", String(readingIn).c_str());
    Serial.println(msgBatt); //sa vedem ce trimite
    client.publish("domoticz/in", msgBatt);
    }
}

*********************************************************

logged data during charging / graficul in timpul incarcarii

battery level is going down / descarcare

battery went so low that the ESP8266 cannot receive enough power
bateria s-a descarcat complet

after battery was discharged, I reconnected the charger, thus the ramp-up shape
dupa descarcare, am conectat incarcatorul, de unde si forma de rampa crescatoare



Niciun comentariu:

Trimiteți un comentariu