Autor Thema: Batteriestatus  (Gelesen 2068 mal)

Offline The-Holgi

  • Sr. Member
  • ****
  • Beiträge: 652
Batteriestatus
« am: 19 Januar 2019, 07:45:12 »
Hallo,
habe mit folgendem sketch das Problem, das unsinnige Batteriewerte 150 bis 153% angezeigt werden.
// Enable debug prints to serial monitor
#define MY_DEBUG

// Enable and select radio type attached
#define MY_RADIO_NRF24
//#define MY_RADIO_RFM69

#include <SPI.h>
#include <MySensors.h> 
#include <BH1750.h>
#include <Wire.h>

#define CHILD_ID_LIGHT 0
unsigned long SLEEP_TIME = 30000; // Sleep time between reads (in milliseconds)

BH1750 lightSensor;

// V_LIGHT_LEVEL should only be used for uncalibrated light level 0-100%.
// If your controller supports the new V_LEVEL variable, use this instead for
// transmitting LUX light level.
MyMessage msg(CHILD_ID_LIGHT, V_LIGHT_LEVEL);
// MyMessage msg(CHILD_ID_LIGHT, V_LEVEL); 
uint16_t lastlux;

//=========================
// BATTERY VOLTAGE DIVIDER SETUP
// 1M, 470K divider across battery and using internal ADC ref of 1.1V
// Sense point is bypassed with 0.1 uF cap to reduce noise at that point
// ((1e6+470e3)/470e3)*1.1 = Vmax = 3.44 Volts
// 3.44/1023 = Volts per bit = 0.003363075
#define VBAT_PER_BITS 0.003363075 
#define VMIN 1.9                                  //  Vmin (radio Min Volt)=1.9V (564v)
#define VMAX 3.0                                  //  Vmax = (2xAA bat)=3.0V (892v)
int batteryPcnt = 0;                              // Calc value for battery %
int batLoop = 0;                                  // Loop to help calc average
int batArray[3];                                  // Array to store value for average calc.
int BATTERY_SENSE_PIN = A0;                       // select the input pin for the battery sense point
//=========================

void setup() 
{
  lightSensor.begin();
}

void presentation()  {
  // Send the sketch version information to the gateway and Controller
  sendSketchInfo("Light Lux Sensor", "1.0");

  // Register all sensors to gateway (they will be created as child devices)
  present(CHILD_ID_LIGHT, S_LIGHT_LEVEL);
}

void loop()     
{     
  uint16_t lux = lightSensor.readLightLevel();// Get Lux value
  Serial.println(lux);
  if (lux != lastlux) {
      send(msg.set(lux));
      lastlux = lux;
  }
   batM();
  sleep(SLEEP_TIME); //sleep a bit
}

void batM() //The battery calculations
{
   delay(500);
   // Battery monitoring reading
   int sensorValue = analogRead(BATTERY_SENSE_PIN);   
   delay(500);
   
   // Calculate the battery in %
   float Vbat  = sensorValue * VBAT_PER_BITS;
   int batteryPcnt = static_cast<int>(((Vbat-VMIN)/(VMAX-VMIN))*100.);
   Serial.print("Battery percent: "); Serial.print(batteryPcnt); Serial.println(" %"); 
   
   // Add it to array so we get an average of 3 (3x20min)
   batArray[batLoop] = batteryPcnt;
 
   if (batLoop > 2) { 
     batteryPcnt = (batArray[0] + batArray[1] + batArray[2] + batArray[3]);
     batteryPcnt = batteryPcnt / 3;
 
   if (batteryPcnt > 100) {
     batteryPcnt=100;
 }
 
     Serial.print("Battery Average (Send): "); Serial.print(batteryPcnt); Serial.println(" %");
       sendBatteryLevel(batteryPcnt);
       batLoop = 0;
      }
     else
     {
     batLoop++;
     }

  sleep(SLEEP_TIME);
}

Laut dem Sketch dürfte doch garnichts über 100% angezeigt werden oder?
Sp siehts in der Konsole aus:
Battery percent: -81 %
Battery Average (Send): -105 %
794046 TSF:MSG:SEND,101-101-0-0,s=255,c=3,t=0,pt=1,l=1,sg=0,ft=0,st=OK:151
794054 MCO:SLP:MS=30000,SMS=0,I1=255,M1=255,I2=255,M2=255
794060 TSF:TDI:TSL

Hier das device in fhem:
defmod MYSENSOR_101 MYSENSORS_DEVICE 101
attr MYSENSOR_101 IODev MySensorUnoGateway
attr MYSENSOR_101 mapReading_brightness 0 brightness
attr MYSENSOR_101 mapReading_id1 1 id
attr MYSENSOR_101 mapReading_level 0 level
attr MYSENSOR_101 mode node
attr MYSENSOR_101 room MY_Sensors
attr MYSENSOR_101 stateFormat Helligkeit:brightness lux

edit:

// Enable debug prints to serial monitor
#define MY_DEBUG

// Enable and select radio type attached
#define MY_RADIO_NRF24
//#define MY_RADIO_RFM69

#include <SPI.h>
#include <MySensors.h> 
#include <BH1750.h>
#include <Wire.h>

#define CHILD_ID_LIGHT 0
unsigned long SLEEP_TIME = 30000; // Sleep time between reads (in milliseconds)

BH1750 lightSensor;

// V_LIGHT_LEVEL should only be used for uncalibrated light level 0-100%.
// If your controller supports the new V_LEVEL variable, use this instead for
// transmitting LUX light level.
MyMessage msg(CHILD_ID_LIGHT, V_LIGHT_LEVEL);
// MyMessage msg(CHILD_ID_LIGHT, V_LEVEL); 
uint16_t lastlux;

//=========================
// BATTERY VOLTAGE DIVIDER SETUP
// 1M, 470K divider across battery and using internal ADC ref of 1.1V
// Sense point is bypassed with 0.1 uF cap to reduce noise at that point
// ((1e6+470e3)/470e3)*1.1 = Vmax = 3.44 Volts
// 3.44/1023 = Volts per bit = 0.003363075
#define VBAT_PER_BITS 0.003363075 
#define VMIN 1.9                                  //  Vmin (radio Min Volt)=1.9V (564v)
#define VMAX 3.5                                  //  Vmax = (2xAA bat)=3.0V (892v)
int batteryPcnt = 0;                              // Calc value for battery %
int batLoop = 0;                                  // Loop to help calc average
int batArray[3];                                  // Array to store value for average calc.
int BATTERY_SENSE_PIN = A0;                       // select the input pin for the battery sense point
//=========================

void setup() 
{
  analogReference(INTERNAL);             // For battery sensing

  delay(500); // Allow time for radio if power used as reset
 
  lightSensor.begin();
}

void presentation()  {
  // Send the sketch version information to the gateway and Controller
  sendSketchInfo("Light Lux Sensor", "1.0");

  // Register all sensors to gateway (they will be created as child devices)
  present(CHILD_ID_LIGHT, S_LIGHT_LEVEL);
}

void loop()     
{     
  uint16_t lux = lightSensor.readLightLevel();// Get Lux value
  Serial.println(lux);
  if (lux != lastlux) {
      send(msg.set(lux));
      lastlux = lux;
  }
   batM();
  sleep(SLEEP_TIME); //sleep a bit
}

void batM() //The battery calculations
{
   delay(500);
   // Battery monitoring reading
   int sensorValue = analogRead(BATTERY_SENSE_PIN);   
   delay(500);
   
   // Calculate the battery in %
   float Vbat  = sensorValue * VBAT_PER_BITS;
   int batteryPcnt = static_cast<int>(((Vbat-VMIN)/(VMAX-VMIN))*100.);
   Serial.print("Battery percent: "); Serial.print(batteryPcnt); Serial.println(" %"); 
   
   // Add it to array so we get an average of 3 (3x20min)
   batArray[batLoop] = batteryPcnt;
 
   if (batLoop > 2) { 
     batteryPcnt = (batArray[0] + batArray[1] + batArray[2] + batArray[3]);
     batteryPcnt = batteryPcnt / 3;
 
   if (batteryPcnt > 100) {
     batteryPcnt=100;
 }
 
     Serial.print("Battery Average (Send): "); Serial.print(batteryPcnt); Serial.println(" %");
       sendBatteryLevel(batteryPcnt);
       batLoop = 0;
      }
     else
     {
     batLoop++;
     }

}

So sieht es besser aus.
Gruß Holger
« Letzte Änderung: 19 Januar 2019, 09:01:19 von The-Holgi »
HP T610 Thin Client; Docker Fhem 5.9; 2X CUL V3 868mhz; Max Heizungssteuerung; FS20kse; FS20UWS; FS20S8-3; 2 FS20DI; HM-CFG-LAN,HM-LC-SW1-PL,HM-SEC-SD, HM-SE1PBU-FM;
Harmony Hub;Hue-Bridge mit Iris, E27 Bulb & FLS-PP

Offline alru

  • Full Member
  • ***
  • Beiträge: 143
Antw:Batteriestatus
« Antwort #1 am: 19 Januar 2019, 09:35:28 »
Moin,

hast du das Problem jetzt mit #define VMAX 3.5  behoben ?

Ich hab beim überfliegen des Codes nicht feststellen können, wieso du negative Werte für den Batteriestatus bekommst. Deine Begrenzung auf  100 % mit if (batteryPcnt > 100) {
     batteryPcnt=100;
 }
dürfte dann nämlich nicht funktionieren.

Noch eine paar Fragen: Ist die Durchschnittsermittlung wirklich nötig? Hast du dir mal das Array anzeigen lassen? Sind die Werte wirklich unterschiedlich? Trotz des 0.1µF am Eingang?
Gruß,

Stefan
(Raspi 3B - Stretch / HM-LGW / HomeMatic / MySensors)

Offline The-Holgi

  • Sr. Member
  • ****
  • Beiträge: 652
Antw:Batteriestatus
« Antwort #2 am: 19 Januar 2019, 10:11:33 »
Hallo,
die negativen Werte sind mit dem unteren code weg.
Mit #define VMAX 3.5  sollten die Werte ungefähr passen, denke ich.
Bei 2,6V Batteriespannung werden 70% in  fhem angezeigt.
Weiß nur nicht warum das so ist. Wenn ich ehrlich bin hab ich mir den code aus "geklauten" schnipseln zusammen gebastelt.
Ob die Durchschnittsermittlung nötig ist weiß ich nicht.

Gruß Holger

HP T610 Thin Client; Docker Fhem 5.9; 2X CUL V3 868mhz; Max Heizungssteuerung; FS20kse; FS20UWS; FS20S8-3; 2 FS20DI; HM-CFG-LAN,HM-LC-SW1-PL,HM-SEC-SD, HM-SE1PBU-FM;
Harmony Hub;Hue-Bridge mit Iris, E27 Bulb & FLS-PP

Offline alru

  • Full Member
  • ***
  • Beiträge: 143
Antw:Batteriestatus
« Antwort #3 am: 19 Januar 2019, 15:11:12 »
Hallo,

ich habe auch diesen Code hier im Einsatz:
https://www.mysensors.org/build/battery#measuring-and-reporting-battery-level
Allerdings brauchte ich keine Änderungen vornehmen.

Die 70% Anzeige müsste meiner Meinung nach ungefähr passen...
(1-2% Toleranz bei den Widerstandsangaben + Toleranz bei der Spannungsmessung + ....)
Es dürften bei deinen Angaben rechnerisch ca. 0,83V an A0 anliegen. Das sind ca. 75% der Referenzspannung von 1,1V.
Gruß,

Stefan
(Raspi 3B - Stretch / HM-LGW / HomeMatic / MySensors)