insufficient accuracy for internal Vcc measurement
-
Hi,
I'm working on a battery operated node doing motion + temp, and I use Yveaux's Arduino_Vcc library to measure battery voltage.
I've tested the voltage from the 2 AAs and it's 2.99v, but the internal measurement gives 2.22v. I have a 25% difference where we should expect max 10%, shouldn't we ?
I'll try to debug that tomorrow with a dedicated sketch, but maybe someone can easily spot the error in the following code ?
/** * DESCRIPTION * Motion Sensor (HC-SR501) + Temp sensor (MCP9700 analog sensor) * inspired by : * mysensors PIR example created by Henrik Ekblad : http://www.mysensors.org/build/motion * Slim Node as a Mini 2AA Battery PIR Motion Sensor : http://forum.mysensors.org/topic/2715/slim-node-as-a-mini-2aa-battery-pir-motion-sensor * Kevin Kessler's blog for reading MCP9700 temperature sensor : http://blog.kkessler.com/2012/06/20/mcp9700/ */ #include <MySensor.h> #include <SPI.h> #include <Vcc.h> #define NODE_ID 30 #define MOTION_INPUT_PIN 3 // The digital input you attached your motion sensor. (Only 2 and 3 generates interrupt!) #define CHILD_ID_MOTION 1 #define CHILD_ID_TEMP 2 #define CHILD_ID_BATT 3 #define DOMOTICZ_OFF_DELAY 10000 #define MINIMUM_SEND_INTERVAL 86400000 // once a day #define TEMP_SEND_FREQ 300000 // every 5min #define TEMP_SEND_THRESHOLD 0.3 // do not send temp if variation is below delta #define VCC_MIN 1.9 #define VCC_MAX 3.3 float lastTemperature = 0;; float lastVoltage = 0; int loopCounter = 0; bool interruptReturn = false; // "false" will make the first loop disregard high output from HC-SR501 (from start-up) and make a battery+temp report instead. Vcc vcc(1.34); // 2.98/2.22=1.3423 . Can this be ok ??? MySensor gw; MyMessage msgMotion(CHILD_ID_MOTION, V_TRIPPED); MyMessage msgTemp(CHILD_ID_TEMP,V_TEMP); MyMessage msgBattery(CHILD_ID_BATT, V_VOLTAGE); void setup() { delay(100); // to settle power for radio gw.begin(NULL, NODE_ID); // Send the sketch version information to the gateway and Controller gw.sendSketchInfo("Motion & Temp Sensor", "1.0"); pinMode(MOTION_INPUT_PIN, INPUT); // sets the motion sensor digital pin as input // Register all sensors to gw (they will be created as child devices) gw.present(CHILD_ID_MOTION, S_MOTION); gw.present(CHILD_ID_TEMP, S_TEMP); gw.present(CHILD_ID_BATT, S_MULTIMETER); gw.sleep(20000); // Wait until motion sensor warmed-up and output returned low. } void loop() { int sleeptime = 0; if (interruptReturn) { // Woke up by rising pin gw.send(msgMotion.set("1")); // Domoticz will take care of setting the node off after some delay sleeptime = DOMOTICZ_OFF_DELAY; // sleep until domoticz sets the sensor off on its side } else { float voltage = vcc.Read_Volts(); float temperature = readMCP9700(4,0); // send if variation is enough or if delay was reached if (abs(temperature - lastTemperature) >= TEMP_SEND_THRESHOLD) { lastTemperature = temperature; sleeptime = 3000; loopCounter = 0; gw.send(msgTemp.set(temperature, 1)); } // send on first iteration, then if variation is enough or if delay was reached if (abs(voltage - lastVoltage) >= 0.1) { sendBatteryReport(voltage); sleeptime = 3000; loopCounter = 0; lastVoltage = voltage; } if (loopCounter++ * TEMP_SEND_FREQ >= MINIMUM_SEND_INTERVAL) { loopCounter = 0; sleeptime = 3000; gw.send(msgTemp.set(temperature, 1)); sendBatteryReport(voltage); } } if (sleeptime) { gw.sleep(sleeptime); // Make sure everything is stable before start to sleep with interrupts. (don't use "gw.wait()" here). Tests shows false trip ~2s after battery report otherwise. } interruptReturn = gw.sleep(MOTION_INPUT_PIN-2, RISING, TEMP_SEND_FREQ); } void sendBatteryReport(float voltage) { float perc = 100.0 * (voltage-VCC_MIN) / (VCC_MAX-VCC_MIN); gw.send(msgBattery.set(voltage, 2)); gw.sendBatteryLevel(static_cast<int>(perc)); } // this function comes from Kevin Kessler's blog : http://blog.kkessler.com/2012/06/20/mcp9700/ float readMCP9700(int pin,float offset) { analogReference(INTERNAL); for (int n=0;n<5;n++) analogRead(pin); int adc=analogRead(pin); float tSensor=((adc*(1.1/1024.0))-0.5+offset)*100; float error=244e-6*(125-tSensor)*(tSensor - -40.0) + 2E-12*(tSensor - -40.0)-2.0; float temp=tSensor-error; return temp; }Regards
Mikael
Hello! It looks like you're interested in this conversation, but you don't have an account yet.
Getting fed up of having to scroll through the same posts each visit? When you register for an account, you'll always come back to exactly where you were before, and choose to be notified of new replies (either via email, or push notification). You'll also be able to save bookmarks and upvote posts to show your appreciation to other community members.
With your input, this post could be even better 💗
Register Login