Battery reporting keeps increasing not decreasing
-
Hello,
I have a normal door sensor based on My Slim node design. It has been running for around 3 months till now but the battery percentage is abnormal.
At the beginning I remember that the percentage begun as 72% so I thought maybe this is because my max voltage is defined as 3.3v not 3v. After some time, maybe 2 weeks it was 75%. It has been like this for like 2 months. Then I switched my gateway OFF for 3 weeks and switched it back ON now to see the battery voltage percentage and found it to be 80%
The batteries are two AAA 1.5v each.
Sketch:
/** * The MySensors Arduino library handles the wireless radio link and protocol * between your home built sensors/actuators and HA controller of choice. * The sensors forms a self healing radio network with optional repeaters. Each * repeater and gateway builds a routing tables in EEPROM which keeps track of the * network topology allowing messages to be routed to nodes. * * Created by Henrik Ekblad <henrik.ekblad@mysensors.org> * Copyright (C) 2013-2015 Sensnology AB * Full contributor list: https://github.com/mysensors/Arduino/graphs/contributors * * Documentation: http://www.mysensors.org * Support Forum: http://forum.mysensors.org * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * version 2 as published by the Free Software Foundation. * ******************************* * * REVISION HISTORY * Version 1.0 - Henrik Ekblad * * DESCRIPTION * Motion Sensor example using HC-SR501 * http://www.mysensors.org/build/motion * */ #define MY_BAUD_RATE 9600 // For 1 MHz // Enable debug prints #define MY_DEBUG #ifdef MY_DEBUG #define DEBUG #endif #ifdef DEBUG #define DEBUG_SERIAL(x) Serial.begin(x) #define DEBUG_PRINT(x) Serial.print(x) #define DEBUG_PRINTLN(x) Serial.println(x) #else #define DEBUG_SERIAL(x) #define DEBUG_PRINT(x) #define DEBUG_PRINTLN(x) #endif // Enable and select radio type attached #define MY_RADIO_NRF24 //#define MY_RADIO_RFM69 #if 0 // Select soft/hardware signing method #define MY_SIGNING_SOFT //!< Software signing //#define MY_SIGNING_ATSHA204 //!< Hardware signing using ATSHA204A // Enable node whitelisting //#define MY_SIGNING_NODE_WHITELISTING {{.nodeId = GATEWAY_ADDRESS,.serial = {0x09,0x08,0x07,0x06,0x05,0x04,0x03,0x02,0x01}}} // Enable this if you want destination node to sign all messages sent to this node. #define MY_SIGNING_REQUEST_SIGNATURES // SETTINGS FOR MY_SIGNING_SOFT /// Set the soft_serial value to an arbitrary value for proper security (9 bytes) #define MY_SIGNING_SOFT_SERIAL 0x11,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09 /// Key to use for HMAC calculation in soft signing (32 bytes) #define MY_SIGNING_SOFT_HMAC_KEY 0x10,0x20,0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 #define MY_SIGNING_SOFT_RANDOMSEED_PIN A7 //!< Unconnected analog pin for random seed #endif #include <SPI.h> #include <MySensor.h> unsigned long SLEEP_TIME = 120000; // Sleep time between reports (in milliseconds) #define DIGITAL_INPUT_SENSOR 3 // The digital input you attached your motion sensor. (Only 2 and 3 generates interrupt!) #define INTERRUPT DIGITAL_INPUT_SENSOR-2 // Usually the interrupt = pin -2 (on uno/nano anyway) #define CHILD_ID 0 // Id of the sensor child #define CHILD_ID_BATTERY 1 //#define BATTERY_FULL 3000 // 3,000 millivolts for 2xAA (DOLA - changed to 5000 as it was tested on a laptop) //#define BATTERY_ZERO 1900 // 1,900 millivolts (1.9V, limit for nrf24l01 without step-up. 2.8V limit for Atmega328 without BOD disabled)) #define VMIN 1900 #define VMAX 3300 long readVcc(); // Initialize motion message MyMessage msg(CHILD_ID, V_TRIPPED); unsigned int ADCValue; double Voltage; double Vcc; long oldvoltage = 0; void setup() { pinMode(DIGITAL_INPUT_SENSOR, INPUT); // sets the motion sensor digital pin as input } void presentation() { // Send the sketch version information to the gateway and Controller sendSketchInfo("Door Sensor", "1.0"); // Register all sensors to gw (they will be created as child devices) present(CHILD_ID, S_MOTION); } void loop() { wait(25); // Short delay to allow switch to properly settle // Read digital motion value boolean tripped = digitalRead(DIGITAL_INPUT_SENSOR) == HIGH; // Serial.println(tripped); // send(msg.set(tripped?"OPEN":"CLOSED")); // Send tripped value to gw (OPENHAB) send(msg.set(tripped?"1":"0")); // Send tripped value to gw (Domoticz) /* Vcc = readVcc()/1000.0; ADCValue = analogRead(0); Voltage = (ADCValue / 1023.0) * Vcc; */ long voltage = readVcc(); //Serial.println(voltage); if (oldvoltage != voltage) { // Only send battery information if voltage has changed, to conserve battery. long batteryVolt = readVcc(); DEBUG_PRINT("Battery voltage: "); DEBUG_PRINT(batteryVolt); DEBUG_PRINTLN(" mV"); uint8_t batteryPcnt = constrain(map(batteryVolt,VMIN,VMAX,0,100),0,255); DEBUG_PRINT("Battery percent: "); DEBUG_PRINT(batteryPcnt); DEBUG_PRINTLN(" %"); sendBatteryLevel(batteryPcnt); // sendBatteryLevel(round((voltage - BATTERY_ZERO) * 100.0 / (BATTERY_FULL - BATTERY_ZERO))); oldvoltage = voltage; } // Serial.print(Vcc); // Serial.print ( " " ); // Serial.println(Voltage); // Sleep until interrupt comes in on motion sensor. Send update every two minute. sleep(INTERRUPT,CHANGE); } long readVcc() { // From http://provideyourown.com/2012/secret-arduino-voltmeter-measure-battery-voltage/ // Read 1.1V reference against AVcc // set the reference to Vcc and the measurement to the internal 1.1V reference #if defined(__AVR_ATmega32U4__) || defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__) ADMUX = _BV(REFS0) | _BV(MUX4) | _BV(MUX3) | _BV(MUX2) | _BV(MUX1); #elif defined (__AVR_ATtiny24__) || defined(__AVR_ATtiny44__) || defined(__AVR_ATtiny84__) ADMUX = _BV(MUX5) | _BV(MUX0); #elif defined (__AVR_ATtiny25__) || defined(__AVR_ATtiny45__) || defined(__AVR_ATtiny85__) ADMUX = _BV(MUX3) | _BV(MUX2); #else ADMUX = _BV(REFS0) | _BV(MUX3) | _BV(MUX2) | _BV(MUX1); #endif delay(2); // Wait for Vref to settle ADCSRA |= _BV(ADSC); // Start conversion while (bit_is_set(ADCSRA, ADSC)); // measuring uint8_t low = ADCL; // must read ADCL first - it then locks ADCH uint8_t high = ADCH; // unlocks both long result = (high << 8) | low; result = 1125300L / result; // Calculate Vcc (in mV); 1125300 = 1.1*1023*1000 return result; // Vcc in millivolts }
Code has lots of unused variables and commented lines and the signing is not compiled in the project. a bit messy and needs to be cleaned up.
Thanks.
-
I think I remembered some graph on this forum. A battery will report a higher percentage when it's starting lose it's power. So the readings seem to be normal.
-
@ahmedadelhosni There is a (positive) voltage - temperature relation with Alkaline cells. So for Egypt it could be an explanation..
With lithium cells I also found that voltage tends to decrease during a "stress" period and returns slowly to a higher voltage.
-
Impressive and annoying
So is there any workaround to solve this ? looks like it is a normal behavior and reproducible.
-
@ahmedadelhosni There is nothing to solve ... My Electric car runs 40 km on a load in winter (-2 C) and 80km in summer (22 C). Your sensor could run a few years if well built and using low self discharge batteries.
A graph of one of my sensors...you can see the temperature effect (although small).
-
Perpetuum mobile
-
@hek with the climate temperature rising each year... yes