About battery level
-
In case you can post your sensor code here I can have a look at it. Normally you just use
sendBatteryLevel(batteryPcnt);
in your sketch and it will be send (I think) with sensor ID 255 to the controller -
@Anduril Thanks for helping me on this
get a look at the following pleas
This is the code without the battery
// Enable debug prints to serial monitor #define MY_DEBUG // Enable and select radio type attached #define MY_RADIO_NRF24 #define CHILD_ID 0 #include <MySensors.h> // Here we are setting up some water thresholds that we will // use later. Note that you will need to change these to match // your soil type and environment. It doesn't do much for me because I'm using domoticz int thresholdUp = 400; int thresholdDown = 075; MyMessage msg(CHILD_ID, V_LEVEL); unsigned long SLEEP_TIME = 30000; // We are setting up the pin A0 on the redboard to be our sensor // pin input: int sensorPin = A0; const int buzzer = 8; //buzzer to arduino pin 8 void setup(){ pinMode(buzzer, OUTPUT); // Set buzzer - pin 8 as an output } void presentation() { sendSketchInfo("Soil Moisture Sensor", "1.0"); present(CHILD_ID, S_MOISTURE); } void loop() { int sensorValue; sensorValue = analogRead(sensorPin); //send back the values send(msg.set(sensorValue)); if (sensorValue <= 800){ tone(buzzer, 2000); delay(1000); noTone(buzzer); delay(500); Serial.println(sensorValue); } else{ Serial.println(sensorValue); } // delay until next measurement (msec) sleep(SLEEP_TIME); }
This is the code with battery code that seems to work ( I am waiting for the battery to run out to see if the values shown are correct)
// Enable debug prints to serial monitor #define MY_DEBUG // Enable and select radio type attached #define MY_RADIO_NRF24 #define CHILD_ID 0 #include <MySensors.h> // Here we are setting up some water thresholds that we will // use later. Note that you will need to change these to match // your soil type and environment. It doesn't do much for me because I'm using domoticz int thresholdUp = 400; int thresholdDown = 075; MyMessage msg(CHILD_ID, V_LEVEL); unsigned long SLEEP_TIME = 30000; //unsigned long SLEEP_TIME = 900000; //15 minutes // We are setting up the pin A0 on the redboard to be our sensor // pin input: int sensorPin = A0; const int buzzer = 8; //buzzer to arduino pin 8 void setup(){ pinMode(buzzer, OUTPUT); // Set buzzer - pin 8 as an output } void presentation() { sendSketchInfo("Soil Moisture Sensor", "1.0"); present(CHILD_ID, S_MOISTURE); } void loop() { int sensorValue; sensorValue = analogRead(sensorPin); //send back the values send(msg.set(sensorValue)); if (sensorValue <= 800){ tone(buzzer, 2000); delay(1000); noTone(buzzer); delay(1000); Serial.println(sensorValue); } else{ Serial.println(sensorValue); } // delay until next measurement (msec) #define MIN_V 2700 #define MAX_V 4100 int batteryPcnt = min(map(readVcc(), MIN_V, MAX_V, 0, 100), 100); // Convert voltage to percentage sendBatteryLevel(batteryPcnt); // Send battery percentage to gateway sleep(SLEEP_TIME); } long readVcc() { // 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 }
And this is the code with the battery from mysensors that is not working as I don't t get values from the soil moisture sensor and I am not sure that the battery level is working
// Enable debug prints to serial monitor #define MY_DEBUG // Enable and select radio type attached #define MY_RADIO_NRF24 #define CHILD_ID 0 #include <MySensors.h> // Here we are setting up some water thresholds that we will // use later. Note that you will need to change these to match // your soil type and environment. It doesn't do much for me because I'm using domoticz int thresholdUp = 400; int thresholdDown = 075; MyMessage msg(CHILD_ID, V_LEVEL); unsigned long SLEEP_TIME = 30000; // We are setting up the pin A0 on the redboard to be our sensor // pin input: int sensorPin = A1; int BATTERY_SENSE_PIN = A0; // select the input pin for the battery sense point const int buzzer = 8; //buzzer to arduino pin 8 int oldBatteryPcnt = 0; void setup(){ pinMode(buzzer, OUTPUT); // Set buzzer - pin 8 as an output // use the 1.1 V internal reference #if defined(__AVR_ATmega2560__) analogReference(INTERNAL1V1); #else analogReference(INTERNAL); #endif } void presentation() { sendSketchInfo("Soil Moisture Sensor", "1.0"); present(CHILD_ID, S_MOISTURE); } void loop() { int sensorValue; sensorValue = analogRead(sensorPin); //send back the values send(msg.set(sensorValue)); if (sensorValue <= 800){ tone(buzzer, 2000); delay(1000); noTone(buzzer); delay(500); Serial.println(sensorValue); } else{ Serial.println(sensorValue); } // delay until next measurement (msec) // get the battery Voltage int sensorValueBat = analogRead(BATTERY_SENSE_PIN); #ifdef MY_DEBUG Serial.println(sensorValueBat); #endif // 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 int batteryPcnt = sensorValueBat / 10; #ifdef MY_DEBUG float batteryV = sensorValueBat * 0.003363075; Serial.print("Battery Voltage: "); Serial.print(batteryV); Serial.println(" V"); Serial.print("Battery percent: "); Serial.print(batteryPcnt); Serial.println(" %"); #endif if (oldBatteryPcnt != batteryPcnt) { // Power up radio after sleep sendBatteryLevel(batteryPcnt); oldBatteryPcnt = batteryPcnt; } sleep(SLEEP_TIME); }
Also I have another issue I would like that the sleep function works differently for the sensor and for the battery level and I cannot figure how to do this yet
Thanks
-
Hey,
I have a sensor working also using the readVCC lib as in your working example. But I don't see any obvious problem in your example using the voltage divider to read the battery voltage. Maybe you have a problem in your hardware connection to pin A1?
Also one suggestion: between sending 2 messages, I prefer to include a wait(50). I had problems with lost messages when sending too fast, maybe my caps were depleted and my voltage dropped during sending.
For your other problem I know how to do this, here an example:int counter=0 void loop() if counter=120 { sendBatteryLevel(batteryPcnt); counter=0; } counter++ sleep(30000);
That way your battery is transmitted only once an hour, I use this also for my own sensor and it works great.
-
@Anduril thanks
I will try your code for sending the battery status once an hour
As for the A0, A1, A2 etc pins when I am using them alone they worked just fine but when I have A0 on battery and A1 on soil moisture the A1 never sends any signal (for the battery I don't know as the sensor don't work I did not connect the battery) -
Hell @Anduril I try to add your code for having moisture level every 30 seconds and battery level every 50 minutes but look at my serial monitor I get the two values at the same time.
Probably I am doing something wrong. Could you have a look at the loop code one more time please2413 MCO:SLP:WUP=-1 2415 TSF:MSG:READ,0-0-2,s=255,c=3,t=6,pt=0,l=6,sg=0:Metric 2422 TSF:MSG:SEND,2-2-0-0,s=0,c=1,t=37,pt=2,l=2,sg=0,ft=0,st=OK:1021 1021 2433 TSF:MSG:SEND,2-2-0-0,s=255,c=3,t=0,pt=1,l=1,sg=0,ft=0,st=OK:100 2439 MCO:SLP:MS=30000,SMS=0,I1=255,M1=255,I2=255,M2=255 2444 MCO:SLP:TPD 2446 MCO:SLP:WUP=-1 2450 TSF:MSG:SEND,2-2-0-0,s=0,c=1,t=37,pt=2,l=2,sg=0,ft=0,st=OK:1022 1022 2460 TSF:MSG:SEND,2-2-0-0,s=255,c=3,t=0,pt=1,l=1,sg=0,ft=0,st=OK:100 2467 MCO:SLP:MS=30000,SMS=0,I1=255,M1=255,I2=255,M2=255 2472 MCO:SLP:TPD
my loop code is here:
void loop() { int sensorValue; sensorValue = analogRead(sensorPin); send(msg.set(sensorValue)); if (sensorValue <= 800){ tone(buzzer, 2000); delay(1000); noTone(buzzer); delay(1000); } else{ } // Battery #define MIN_V 2700 #define MAX_V 3700 int batteryPcnt = min(map(readVcc(), MIN_V, MAX_V, 0, 100), 100); // Convert voltage to percentage int counter=0; if (counter = 120) { sendBatteryLevel(batteryPcnt); counter=0; } counter++; sleep(30000); }
-
I see an error,
if (counter = 120)
should beif (counter == 120)
-
thanks @jkandasa I will correct this
Is the rest of code Ok? -
@bmanos I do not see any other issues
-
-
-
@bmanos said in About battery level:
delay until ne
One thing i saw in your sketch is this line
delay(1000);
Delay will stop all processing, also the mysensors code...
what you preferably should use is:wait(1000);
In this case mysensors is still able to process
(just a little tip which will help coding, see this link for more information)