Jump to content
ELFORUM - Forumul electronistilor
piratu2ro

Problema cantar la iesirea din deep sleep

Recommended Posts

Hristos a inviat!

 

Va cer si eu ajutorul pentru o problema intalnita la un cantar cu ESP 8266, o sa atasej mai jos codul, problema este ca la iesirea din deep sleep, cantarul se calibreaza la 0 si imi trimite 0Kg de fiecare data .

Citat

#include <dht.h>
#include "HX711.h"
#include <SoftwareSerial.h>
#include <Adafruit_BMP280.h>
#include <Adafruit_Sensor.h>
#include <Wire.h>
#include <SPI.h>
#include <ESP8266WiFi.h>

const int LOADCELL_DOUT_PIN = D5;
const int LOADCELL_SCK_PIN = D6;

#define DEBUG true

HX711 scale; // working

dht DHT;
Adafruit_BMP280 barometru;

int k = 0;
int offset = -200; // corectie citire tensiune baterie
char diviziune;

#include "Ubido5656roESP8266.h"
#define TOKEN  "BBFF-Ii8776T4h5IuX9JB0"  // Put here your Ubidots TOKEN
#define WIFISSID "8888"
#define PASSWORD "666"

Ubidots client(TOKEN);
unsigned long lastMillis = 0;

void setup() {

  Serial.begin(115200);
  delay(10);
  client.wifiConnection(WIFISSID, PASSWORD);

  if (! barometru.begin(0x76 )) {
    Serial.println("Lipsa senzor BMP280, Verifica cablaj!");
    while (1);
  }

  scale.begin(LOADCELL_DOUT_PIN, LOADCELL_SCK_PIN);
  scale.read();                 // print a raw reading from the ADC
  scale.read_average(20);       // print the average of 20 readings from the ADC
  scale.get_value(5);           // print the average of 5 readings from the ADC minus the tare weight (not set yet)
  scale.get_units(5), 1;        // print the average of 5 readings from the ADC minus tare weight (not set) divided
  scale.set_scale(393.95f);     // corectie celula greutate

  scale.tare();                 // resetare cantar 0
  scale.read();                 // print a raw reading from the ADC
  scale.read_average(20);       // print the average of 20 readings from the ADC


}

int kg = 0;

 

void loop() {

  int volt = analogRead(A0);  // pin citire tensiune
  double voltage = map(volt, 0, 1023, 0, 2500) + offset; // map 0-1023 la 0-2500 si factor de corectie
  voltage /= 100;                                       // mv --> V

  float diviziune = (3.7 - 2.5) / 100  ;
  float procent = (voltage - 2.5) / diviziune;
  procent = constrain(procent, 0, 100);

  float khali = scale.get_units(10);
  kg = 0;
  if (khali >= 1000.0) // Done
  { khali = khali / 1000;
    kg = 1;
  }
  String weight =  String (khali);
  if (kg == 1)
  {
    weight = weight  + String("kg");
  }
  else
  {
    weight = weight  + String("g");
  }

  if (millis() - lastMillis > 10000) {  ///every 10S
    int readData = DHT.read22(D7);
    float UmiditateExterioara = DHT.humidity;
    float TemperaturaExterioara = DHT.temperature;
    float PresiuneAtmosferica = barometru.readPressure() / 100;
    float weight = khali;

    lastMillis = millis();
    client.add("UmiditateExterioara",UmiditateExterioara );
    client.add("TemperaturaExterioara", TemperaturaExterioara );
    client.add("PresiuneAtmosferica", PresiuneAtmosferica );
    //client.add("voltage", voltage );
    client.add("procent", procent );
    client.add("weight", weight );

    client.sendAll(true);

  }
ESP.deepSleep(7200000000); // la 2 h

 

Link to post
Share on other sites

Salut,

  ESP -urile sunt putin mai aparte la partea de deep-sleep fata de PIC-uri sau Atmega, la deep-sleep ele parctic se opresc complet in fara de partea de RTC care este utilizat pentru generarea intreruperii de wake-up. Pentru ca ele se opresc complet singura posibilitate de trezire este un reset care inseamna ca porneste de la 0. 

  Mai pe scurt o iesire din deep-sleep la ESP-uri este 99% la fell ca un reset manual sau on/off la alimentare, se pierd toate datele si programul ruleaza de la inceput adica inclusiv partea de "setup" unde ai linia de "scale.tare();                 // resetare cantar 0".  Trebuie cumva regandit tot codul astfel incat calibarea sa se efectueze doar la cerere prin apasearea unui buton sau ceva similar, iar datele rezultate dupa calibare sa fie stocate in memoria RTC ( singura parte a memoriei care poate pastra valori dupa  deep-sleep) iar dupa trezire folosind datele de calibrare initale care au fost salvate in RTC sa fie folosite pentru initierea librariei HX711. 

Edited by Bandi Szasz
Link to post
Share on other sites

da la asta m-am gandit si eu, nu stiam daca e posibil asa ceva, eu nu ma prea pricep la programare, programul asta l-am facut dupa ce am vazut multe filmulete pe youtube si cu ajutorul unui coleg de pe forum care ma ajutat la partea de monitorizare a bateriei, daca m-ati putea ajuta putin mai mult , adica cu niste exemple sau ceva asemanator din care sa ma pot inspira putin

Link to post
Share on other sites

Ceva de genul acesta:

 

  La linia 29 am definit butonul, eu l-am pus pe pin 4 insa il poti schimba pe altul, iar codul modificat incepe pe la linia 56. Functionarea ar fi cam asa: se tine butonul apasat si se alimenteaza montajul, acesta vede butonul apasat si face resetarea la 0 si stocheaza valoarea in memoria RTC, cand el porneste din nou cu reset din deep-sleep vede ca butonul nu mai este apasat atunci nu face resetare la 0 ci citeste valoarea salvata in RTC si il seteaza manual in libraria HX711.

 

#include <dht.h>
#include "HX711.h"
#include <SoftwareSerial.h>
#include <Adafruit_BMP280.h>
#include <Adafruit_Sensor.h>
#include <Wire.h>
#include <SPI.h>
#include <ESP8266WiFi.h>

const int LOADCELL_DOUT_PIN = D5;
const int LOADCELL_SCK_PIN = D6;

#define DEBUG true

HX711 scale; // working

dht DHT;
Adafruit_BMP280 barometru;

int k = 0;
int offset = -200; // corectie citire tensiune baterie
char diviziune;

#include "Ubido5656roESP8266.h"
#define TOKEN  "BBFF-Ii8776T4h5IuX9JB0"  // Put here your Ubidots TOKEN
#define WIFISSID "8888"
#define PASSWORD "666"

#define buttonPin 4 // Aici se schimba pin-ul la care este pus buttonul

Ubidots client(TOKEN);
unsigned long lastMillis = 0;

void setup() {
  pinMode(buttonPin, INPUT_PULLUP);

  Serial.begin(115200);
  delay(10);
  client.wifiConnection(WIFISSID, PASSWORD);

  if (! barometru.begin(0x76 )) {
    Serial.println("Lipsa senzor BMP280, Verifica cablaj!");
    while (1);
  }

  scale.begin(LOADCELL_DOUT_PIN, LOADCELL_SCK_PIN);
  scale.read();                 // print a raw reading from the ADC
  scale.read_average(20);       // print the average of 20 readings from the ADC
  scale.get_value(5);           // print the average of 5 readings from the ADC minus the tare weight (not set yet)
  scale.get_units(5), 1;        // print the average of 5 readings from the ADC minus tare weight (not set) divided
  scale.set_scale(393.95f);     // corectie celula greutate

  scale.read();                 // print a raw reading from the ADC
  scale.read_average(20);       // print the average of 20 readings from the ADC
  
  if (digitalRead(buttonPin)) { // butonul de calibrare este apasat
    scale.tare(); // resetare cantar 0 
	double calib = scale.get_offset(); // luam valorile de calibrare obtinute dupa resetare;
	system_rtc_mem_write(70, calib, sizeof(calib)); // stocam valoarea de calibrare in memoria RTC care supravietuieste dupa deep-sleep
  } else {
    double calib;
    system_rtc_mem_read(70, &calib, sizeof(calib)); // butonul nu este apasat asa ca citim datele de calibrare stocate
	scale.set_offset(calib); // setam manual calibrarea
  }
 }


int kg = 0;

 

void loop() {

  int volt = analogRead(A0);  // pin citire tensiune
  double voltage = map(volt, 0, 1023, 0, 2500) + offset; // map 0-1023 la 0-2500 si factor de corectie
  voltage /= 100;                                       // mv --> V

  float diviziune = (3.7 - 2.5) / 100  ;
  float procent = (voltage - 2.5) / diviziune;
  procent = constrain(procent, 0, 100);

  float khali = scale.get_units(10);
  kg = 0;
  if (khali >= 1000.0) // Done
  { khali = khali / 1000;
    kg = 1;
  }
  String weight =  String (khali);
  if (kg == 1)
  {
    weight = weight  + String("kg");
  }
  else
  {
    weight = weight  + String("g");
  }

  if (millis() - lastMillis > 10000) {  ///every 10S
    int readData = DHT.read22(D7);
    float UmiditateExterioara = DHT.humidity;
    float TemperaturaExterioara = DHT.temperature;
    float PresiuneAtmosferica = barometru.readPressure() / 100;
    float weight = khali;

    lastMillis = millis();
    client.add("UmiditateExterioara",UmiditateExterioara );
    client.add("TemperaturaExterioara", TemperaturaExterioara );
    client.add("PresiuneAtmosferica", PresiuneAtmosferica );
    //client.add("voltage", voltage );
    client.add("procent", procent );
    client.add("weight", weight );

    client.sendAll(true);

  }
ESP.deepSleep(7200000000); // la 2 h

 

Link to post
Share on other sites

multumesc mult de tot, am incercat sa incarc programul dar imi da o eroare

 

  double calib = scale.get_offset(); // luam valorile de calibrare obtinute dupa resetare;
  system_rtc_mem_write(70, calib, sizeof(calib)); // stocam valoarea de calibrare in memoria RTC care supravietuieste dupa deep-sleep
  } else {

 

cannot convert 'double' to 'const void*' for argument '2' to 'bool system_rtc_mem_write(uint8, const void*, uint16)'

Link to post
Share on other sites
Acum 14 minute, piratu2ro a spus:

multumesc mult de tot, am incercat sa incarc programul dar imi da o eroare

 

  double calib = scale.get_offset(); // luam valorile de calibrare obtinute dupa resetare;
  system_rtc_mem_write(70, calib, sizeof(calib)); // stocam valoarea de calibrare in memoria RTC care supravietuieste dupa deep-sleep
  } else {

 

cannot convert 'double' to 'const void*' for argument '2' to 'bool system_rtc_mem_write(uint8, const void*, uint16)'

Incearca cu un "&" inainte de "calib". Eu am lucrat doar cu ESP32 si ala are o alta modalitate de stocare in RTC si nu am gasit daca merge si cu 8266, functia asta de rtc_mem_write inca nu l-am folosit personal

 

 system_rtc_mem_write(70, &calib, sizeof(calib));

 

Link to post
Share on other sites
13 minutes ago, piratu2ro said:

cannot convert 'double' to 'const void*' for argument '2' to 'bool system_rtc_mem_write(uint8, const void*, uint16)'

Incearca sa ai si tu o contributie la acest program.
Sigur au sa-ti raspunda colegii si au sa te resolve.
Dar, hai, ca nu-i greu sa resolvi si singur eroarea asta.

Link to post
Share on other sites

Acum 4 ore, mihaicozac a spus:

Parametrii de calibrare s-ar putea stoca în EEPROM, de unde să se citească după fiecare reset.

 

S-ar putea stoca insa nu in EEPROM pentru ca ESP-urile nu au EEPROM ci in flash. Libraria EEPROM la ESP-uri este doar o "intefata" pentru a mentine uniformitatea cu modulele bazate pe Atmega insa in implementare se foloseste de memoria flash ( isi mentine liber o mica parte din flash pentru a emula un mic EEPROM). In cazul de fata nu se pune problema insa in alte aplicatii te poti pacalii asteptand ca EEPROM-ul sa reziste la 1 million de scrieri pe cand de fapt scrii in flash care are doar undeva la 100k de scrieri.

Link to post
Share on other sites

Ok, hai sa le luam pe rand ca acum m-am uitat putin mai atent pe ce ai facut acolo si ai niste probleme de logica pe acolo. In primul rand descrie pe scrut ce doresti sa faca acel cod pentru ca prin "loop" ai pus o conditie cu "millis"  la care ai pus comment "///every 10S" si dupa conditia respectiva ai ESP.deepSleep, ma mira faptul ca tu vezi ceva ca in mod normal cand intra in loop daca functia de setup nu a durat cel putin 10s sare peste conditie si intra direct in sleep iar la trezire millis este iara 0 si povestea se repeta. 

 

Deci pana la urma ce dorest cu conditia aia de cel putin 10s daca oricum bagi ESP-ul la somn 2h ?

Link to post
Share on other sites

@Bandi Szasz
Este un copy/paste de pe net.
Sunt unii care publica tot felul de coduri scrise la misto. Au un simt al umorului mai dezvoltat.
Sunt destui care sa le incerce.
Si apoi cineva ca tine care sa se chinuiasca sa gaseasca eroarea.
A devenit programarea asta un sport national. International :)


 

Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.


×
×
  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.Terms of Use si Guidelines