Sari la conținut
ELFORUM - Forumul electronistilor

Problema cantar la iesirea din deep sleep


Postări Recomandate

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 spre comentariu
  • Răspunsuri 44
  • Creat
  • Ultimul Răspuns

Top autori în acest subiect

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. 

Editat de Bandi Szasz
Link spre comentariu

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 spre comentariu

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 spre comentariu
Vizitator
5 hours ago, piratu2ro said:

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

Ciudat acest numar 72..., 0x1AD274800 in hex.
Accepta deepSleep() valori peste 32 de biti ?

Editat de Vizitator
Link spre comentariu

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 spre comentariu
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 spre comentariu
Vizitator
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 spre comentariu
Vizitator
13 minutes ago, Bandi Szasz said:

Da, deepSleep are ca parametru "uint64_t"

Ok. acum am citit. O singura data m-am jucat cu ESP. Atunci avea maxim 32 de biti :)

 

Link spre comentariu
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 spre comentariu

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 spre comentariu
Vizitator

@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 spre comentariu

Creează un cont sau autentifică-te pentru a adăuga comentariu

Trebuie să fi un membru pentru a putea lăsa un comentariu.

Creează un cont

Înregistrează-te pentru un nou cont în comunitatea nostră. Este simplu!

Înregistrează un nou cont

Autentificare

Ai deja un cont? Autentifică-te aici.

Autentifică-te acum



×
×
  • Creează nouă...

Informații Importante

Am plasat cookie-uri pe dispozitivul tău pentru a îmbunătății navigarea pe acest site. Poți modifica setările cookie, altfel considerăm că ești de acord să continui.Termeni de Utilizare si Ghidări