Reads the boards voltage supply and using a settable threshold below which the condition is true
Inputs
THRES (number, default=?) — The voltage threshold below which this node outputs true.
UPD (pulse, default=loop) — When the voltage read is updated; never, loop, boot
Outputs
LOW (boolean, default=0) — True (1) is voltage below THRES node input number.
VOLT (number, default=?) — The supply voltage.
The use case here is because of an automatic chicken door which is left to do it’s thing day after day, running on a battery.
This node would be able to light an LED when the voltage gets to a settable low threshold, so I know it’ll be time to change the battery soon before the board stops functioning.
Understandably, without having to use external components to do this, the voltage read is not super accurate with the 1.1v variance -+ 0.1v. But certainly good enough for many use cases to indicate low battery.
I do not know how to implement this into a node! I’m not a coder, but I always try to work it out when I need too, so please help. From several sources I’ve got this code below.
Thanks for your help.
long readVcc() {
long result; // Read 1.1V reference against AVcc
ADMUX = _BV(REFS0) | _BV(MUX3) | _BV(MUX2) | _BV(MUX1);
delay(2); // Wait for Vref to settle
ADCSRA |= _BV(ADSC); // Convert
while (bit_is_set(ADCSRA,ADSC));
result = ADCL;
result |= ADCH<<8;
result = 1126400L / result; // Back-calculate AVcc in mV
return result;
}
I’ve tried to implement the code into a simple number out, but it doesn’t work, what is wrong with this? How do I write the result number to the output? Should the first section #endif be contained in a setup?
struct State {
};
{{ GENERATED_CODE }}
void evaluate(Context ctx) {
// 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
emitValue<output_OUT>(ctx, result);
}
Do you really want to use a microprocessor for this? I’m no electronics guru but it seems to me a hardware solution might be better. Some good examples here. https://www.eleccircuit.com/simple-led-display-warn-battery-low/
How about a rechargeable battery and solar cell? Never change the battery again.