Merry Christmas!!!
You're doing a really great job and I hope to do some cool projects with MySensors!
iahim67
@iahim67
Best posts made by iahim67
-
RE: Merry X-mas and Happy New 2018
-
RE: Unknown battery drain
@Richard-van-der-Plas - you can use any Arduino Mini or Mini Pro for a battery powered sensor.
It does not matter much if you buy a 5V or a 3V3 Mini Pro version as you will better flash an internal 8MHz bootloader, remove the linear voltage regulator on these boards and the LED or LEDs as well. I use battery powered temperature sensors (with thermistors)since November 2017 and they still work fine -> I use 2xR6 batteries. Things you can do (like I did, after lots of reading on this forum):- important! remove the LDO (the low drop output voltage regulator) equipped on the Arduinos
- remove the LED or LEDs
- flash an 8MHz internal oscillator bootloader (I read in this forum that using 1MHz internal osc. may give you occasional faults, don't know if that is still valid!) - do you know how to do that?
- internal 8MHz could be precise enough to work with your Dallas temperature sensors, I'm not sure without checking the datasheet
- an 8MHz Arduino (ATMega328P in this case) can work down to about 2V4 according to the datasheet, while the radio works down to 1V9
- either use 2 x R6 batteries to power both the Arduino and the radio module
- or use 3 xR6 batteries to power the Arduino BUT (important!) get power for the radio only from two of the R6 batteries or you'll damage it
- I bought battery powered Christmas lights from LIDL and Kaufland, they had very cheap Christmas lights with both 2 and 3 R6 batteries - so I just use the very convenient battery plastic housing equipped with an ON/OFF switch. Or just look for some R6 or AAA battery holders ...
- make sure you connect the Ground of both the Arduino and the Radio to the "-" of the battery string
- NiMH rechargeable batteries have a much higher self discharge rate than alkaline non rechargeable batteries, NiMH would not be a good option to me as I would have to replace them quite often, but may fit your needs:-)
- ATMega328P can measure its internal 1V1 reference and by doing that you can calculate the battery voltage without a resistor divider that would drain a few more uA, use this library:
https://forum.mysensors.org/topic/186/new-library-to-read-arduino-vcc-supply-level-without-resistors-for-battery-powered-sensor-nodes-that-do-not-use-a-voltage-regulator-but-connect-directly-to-the-batteries - you can use thermistors to measure the temperature as they are very cheap and most important - you can power the thermistor from an Arduino pin by making it an OUTPUT and set it HIGH. After reading the temperature set it back to LOW and put the Arduino to sleep. You will conserve even more power this way. Hope it helps ...
- forgot to clarify, you are supposed to connect the "+" of the battery string to the 5V pin header on the Arduino (there are 2 such pins I think), not to the RAW pin header. 5V can be anything between 2V4 and 5V (for an 8MHz Arduino) and goes directly to the ATMega VCC pin while RAW connector goes to the input of the Linear Voltage Regulator you are supposed to remove
- while looking to your code I can see you have many delay() lines which means your Arduino is awake for many seconds, that's just not good enough for a battery powered sensor :-), try to remove these delays as much as possible, use different sensors that do not require delays eventually as the Arduino should be mostly sleeping. Use eventually a
#define DEBUG x
statement (x=1 if you like to have a serial debug output or x=0 if you don't) and only output the Serial.print when needed.Here is an example for a temperature sensor with a thermistor and 2xR6 batteries (not using here the VCC library I mentioned before but something similar):
// Enable debug prints to serial monitor //#define MY_DEBUG #define MY_RADIO_NRF24 #define MY_NODE_ID 10 #define DEBUG 0 #define BATTERY_SENSOR 1 #include <MySensors.h> #define TH1_CHILD_ID 11 #define VOLTAGE_CHILD_ID 12 #define TH_PIN 3 int _nominal_resistor = 4700; int _nominal_temperature = 25; int _b_coefficient = 3950; int _series_resistor = 4877; int _pin = 0; float BatteryMin = 2.4; float BatteryMax = 3.0; MyMessage msgTemp(TH1_CHILD_ID, V_TEMP); MyMessage msgVoltage(VOLTAGE_CHILD_ID, V_VOLTAGE); void setup() { //Serial.begin(115200); } void presentation() { // Send the sketch version information to the gateway and Controller sendSketchInfo("TH1_Mini_2xR6", "1.0"); present(TH1_CHILD_ID, S_TEMP, "TH1"); present(VOLTAGE_CHILD_ID, S_MULTIMETER, "TH1_Batt_Voltage"); } void loop() { tempReport(); batteryReport(); sleep(180000); } // Measure VCC float getVcc() { #ifndef MY_GATEWAY_ESP8266 // Measure Vcc against 1.1V Vref #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 // Vref settle wait(70); // Do conversion ADCSRA |= _BV(ADSC); while (bit_is_set(ADCSRA, ADSC)) {}; // return Vcc in mV return (float)((1125300UL) / ADC) / 1000; #else return (float)0; #endif } // Send a battery level report to the controller void batteryReport() { // measure the board vcc float volt = getVcc(); // calculate the percentage int percentage = ((volt - BatteryMin) / (BatteryMax - BatteryMin)) * 100; if (percentage > 100) percentage = 100; if (percentage < 0) percentage = 0; #if DEBUG == 1 Serial.print(F("BATT V=")); Serial.print(volt); Serial.print(F(" P=")); Serial.println(percentage); #endif #if BATTERY_SENSOR == 1 // report battery voltage send(msgVoltage.set(volt, 3)); #endif // report battery level percentage sendBatteryLevel(percentage); } void tempReport() { // set TH pin in output mode pinMode(TH_PIN, OUTPUT); // set TH_PIN HIGH digitalWrite(TH_PIN, HIGH); wait(1); // read the voltage across the thermistor float adc = analogRead(_pin); // set TH_PIN LOW digitalWrite(TH_PIN, LOW); // calculate the temperature float reading = (1023 / adc) - 1; reading = _series_resistor / reading; float temperature; temperature = reading / _nominal_resistor; // (R/Ro) temperature = log(temperature); // ln(R/Ro) temperature /= _b_coefficient; // 1/B * ln(R/Ro) temperature += 1.0 / (_nominal_temperature + 273.15); // + (1/To) temperature = 1.0 / temperature; // Invert temperature -= 273.15; // convert to C #if DEBUG == 1 Serial.print(F("THER I=")); Serial.print(TH1_CHILD_ID); Serial.print(F(" V=")); Serial.print(adc); Serial.print(F(" T=")); Serial.println(temperature); #endif send(msgTemp.set(temperature, 1)); }```
-
RE: Garage door status sensors ideas
Hi, maybe you can use the reed switch in a different way, I mean do not use it like contact closed or contact opened as this would cause you overshoot issues.
When the magnet attached to the door slides in front of the reed switch, then you'll have the reed switch closed for a short time at least, most likely, you can test that. You can use the reed just like you would use a motion detector.
I mean connect the reed to pin 3 - interrupt - and put this at the end of your code, so when an interrupt occurs you will know the door has moved (and you can keep track of movement of course so you would know if the door is open or close) ... just an idea ... :sleep(digitalPinToInterrupt(DIGITAL_INPUT_SENSOR), CHANGE, SLEEP_TIME);
-
RE: 💬 Door, Window and Push-button Sensor
Perhaps it would be good to update the example code. I mean the pull-up sequence:
"It is recommended to set the pinMode() to INPUT_PULLUP to enable the internal pull-up resistor." - https://www.arduino.cc/reference/en/language/functions/digital-io/digitalwrite/
The following seems to be obsolete:
// Setup the button
pinMode(BUTTON_PIN,INPUT);
// Activate internal pull-up
digitalWrite(BUTTON_PIN,HIGH);
Latest posts made by iahim67
-
RE: 💬 Door, Window and Push-button Sensor
Perhaps it would be good to update the example code. I mean the pull-up sequence:
"It is recommended to set the pinMode() to INPUT_PULLUP to enable the internal pull-up resistor." - https://www.arduino.cc/reference/en/language/functions/digital-io/digitalwrite/
The following seems to be obsolete:
// Setup the button
pinMode(BUTTON_PIN,INPUT);
// Activate internal pull-up
digitalWrite(BUTTON_PIN,HIGH); -
RE: Arduino ProMini 3.3V on 1MHz + RFM69W missing ACKs
Hi, as a side note - check the datasheet of the 100uf capacitor you have used for the leakage current as it could be as high a few uA which is comparable with the current of a sleeping ATMega328 / Arduino board. Make sure you use a low leakage capacitor for a longer battery life.
For a low current temperature sensor you can use a thermistor (like 4k7 @ 25 Celsius) in series with a resistor (4k7 1%). Connect one end of the th to the GND, one end of the resistor to a digital output of the Arduino and the common connection of the th and resistor to an analog input of Arduino. You will power on (make the output HIGH) the th+resistor string from the digital out shortly before making the measurement then make the output LOW after the measurement.
Means you will only use power to measure the temperature for a very short time.
Here is my code (I am not a professional firmware guy ) for such a temperature sensor:// ver. v1.2 /* Mini v5 TH: Th=GND, Series Resistor=3, Middle=A0 check Radio connections/wires check power supply +5V */ //Enable debug prints to serial monitor //#define MY_DEBUG #define MY_RADIO_NRF24 #define MY_NODE_ID 9 #define DEBUG 0 #define BATTERY_SENSOR 1 #include <MySensors.h> #include <Vcc.h> #define TH_LIBRARY_CHILD_ID 1 #define VOLTAGE_CHILD_ID 2 #define TH_PIN 3 int _nominal_resistor = 4700; int _nominal_temperature = 25; int _b_coefficient = 3950; int _series_resistor = 4877; int _pin = 0; int batt_report_count = 120; const float VccMin = 1.8; const float VccMax = 3.0; const float VccCorrection = 1.0 / 1.0; // Measured Vcc by multimeter divided by reported Vcc Vcc vcc(VccCorrection); MyMessage msgTemp(TH_LIBRARY_CHILD_ID, V_TEMP); MyMessage msgVoltage(VOLTAGE_CHILD_ID, V_VOLTAGE); void setup() { //Serial.begin(115200); } void presentation() { // Send the sketch version information to the gateway and Controller sendSketchInfo("TH_LIBRARY@Mini_2xR6", "1.2_FOTA"); wait(1); present(TH_LIBRARY_CHILD_ID, S_TEMP, "TH_LIBRARY"); wait(1); present(VOLTAGE_CHILD_ID, S_MULTIMETER, "TH_LIBRARY_BATT"); wait(1); } void loop() { if (batt_report_count == 120) { batteryReport(); } batt_report_count--; if (batt_report_count == 0) { batt_report_count = 120; } tempReport(); smartSleep(180000); } //############################################################### // Send a battery level report to the controller void batteryReport() { // measure the board vcc float v = vcc.Read_Volts(); float p = vcc.Read_Perc(VccMin, VccMax); #if DEBUG Serial.print("VCC = "); Serial.print(v); Serial.println(" Volts"); Serial.print("VCC = "); Serial.print(p); Serial.println(" %"); #endif #if BATTERY_SENSOR // report battery voltage send(msgVoltage.set(v, 3)); wait(1); #endif // report battery level percentage sendBatteryLevel(p); wait(1); } //################################################################## void tempReport() { // set TH pin in output mode pinMode(TH_PIN, OUTPUT); // set TH_PIN HIGH digitalWrite(TH_PIN, HIGH); wait(1); // read the voltage across the thermistor float adc = analogRead(_pin); // set TH_PIN LOW digitalWrite(TH_PIN, LOW); // calculate the temperature float reading = (1023 / adc) - 1; reading = _series_resistor / reading; float temperature; temperature = reading / _nominal_resistor; // (R/Ro) temperature = log(temperature); // ln(R/Ro) temperature /= _b_coefficient; // 1/B * ln(R/Ro) temperature += 1.0 / (_nominal_temperature + 273.15); // + (1/To) temperature = 1.0 / temperature; // Invert temperature -= 273.15; // convert to C #if DEBUG == 1 Serial.print(F("THER I=")); Serial.print(TH1_CHILD_ID); Serial.print(F(" V=")); Serial.print(adc); Serial.print(F(" T=")); Serial.println(temperature); #endif send(msgTemp.set(temperature, 1)); wait(1); }
-
RE: How to send serial commands (v_var) from Domoticz to serial gateway
@Inso - you can eventually register a few TEXT devices with one of your Arduino sensors, like:
present(LCD_LINE1_CHILD_ID, S_INFO, LCD_LINE1);
then periodically ask data back from Domoticz like:
if (!line1received) { request(LCD_LINE1_CHILD_ID, V_TEXT); #if DEBUG == 1 Serial.println("Requested line1 from gw !"); #endif wait(5000, 2, V_TEXT); // wait for 5s or until a message of type V_TEXT is received }
just define this first:
bool line1received = false;
For more details on the DzVents (2.4x) side have a look in the Domoticz installation folder, there are a few good DzVents examples, this is the path in Windows7:
C:\Program Files (x86)\Domoticz\scripts\dzVents\examplesHope it helps ...
-
RE: low voltage temperature sensor in tht package
@rozpruwacz - one more thing you can do is to place a small ceramic capacitor (like 1nF to 10nF ... or just experiment with other values) in parallel to the thermistor, that will also filter noise.
-
RE: low voltage temperature sensor in tht package
@Nca78 - good to know, thanks!
@rozpruwacz - having a 4K7 thermistor at the end of a few meters of cable is OK ... unless the cable is an inch away from a power motor, fluorescent light, etc. Does not matter much what type of cable you use if you keep it short (a couple of meters).
Don't use large value thermistors like 1Meg.
Try to use twisted cable to connect the thermistor to Arduino if shielded is not an option, twisted cables can reduce some type of interference and noise.
These things may help you ... hopefully -
RE: low voltage temperature sensor in tht package
@rozpruwacz, have you considered a simple and cheap thermistor? If you need temperature measurement and nothing else then a thermistor in series with a resistor (connected to an Arduino output pin) works at any voltage and is very fast - means Arduino will spend more time sleeping. It will be the Arduino itself limiting the lower threshold of you voltage supply.
If you burn a 1MHz internal oscillator boot-loader you can use your rechargeable or non-rechargeable batteries down to 1.8V as you can see in the ATMega328P datasheet:
It may require more investigation however - I read on this forum that MySensors gives random faults when Arduino is running @ 1MHz internal oscillator!?
It would be useful if someone could validate / invalidate the issue or share experience about running @ 1MHz internal oscillator ... -
RE: MySensors - Get Temperature value from another node through the Gateway
@Joe13, I am new to DzVents too ... but it is a great opportunity to learn
Have a look into the Domoticz installation folder, can't remember now exactly where but there is a sub-folder with interesting examples, when you start reading these examples you may have a better overall understanding of how DzVents works.
Their wiki is also very usefull:
https://www.domoticz.com/wiki/DzVents:_next_generation_LUA_scripting
Have fun @Joe13 ... -
RE: MySensors - Get Temperature value from another node through the Gateway
Hi @Joe13, I managed to request information from the Domoticz controller and put it on a LCD (LCD2004A in my case). My Arduino code below, not very polished nor optimized as I am not a programmer but it works nicely so far. This code running on the Arduino Nano will create 4 text devices on the Domoticz side: LCD1_LINE1, LCD1_LINE2, LCD1_LINE3 and LCD1_LINE4 then it will display what ever Domoticz will put (change) in these text devices. At the end of the Arduino sketch there is a DzVents code that will count both Mysensors devices (except text devices) and Domoticz devices (all) and will place this information in the text device LCD1_LINE3 which will be displayed on my LCD accordingly - on the third line. You can create DzVents (or LUA) code that will place in these text devices virtually anything available in Domoticz, temperature included of course.
Second DzVents code at the end of my Arduino code will display on the first line on my LCD the temperature set on a virtual TERMOSTAT device and the current temperature measured with a cheap thermistor on the same node as the LCD device.
Comment this line if you use the default radion channel: #define MY_RF24_CHANNEL 83
Hope it helps .../* LCD2004A 20x4 - LCD pin 1 --> GND - LCD pin 2 --> +5V - LCD pin 3 --> (1K - 10K) POTI - LCD pin 5 --> GND - LCD pin 15 --> to +5V in series with 100 OHM (Backlight "+") - LCD pin 16 --> GND (Backlight "-") - LCD function: RS, E, D4, D5, D6, D7 - LCD2004A pins: 4 , 6 ,11 ,12, 13, 14 - NANO pins: 3, 4, 5, 6, 7, 8 Thermistor: 4K7 / B57164K0472J000 in series with 4K7 resistor TH pin1 to GND TH pin2 to pin2 of the series resistor and together to A0 on the Arduino side Series resistor pin1 to +5V _nominal_resistor adjusted to 4660 (compared to Fluke TK80 thermocouple module + Fluke 87 multimeter) to get the same temperature as the Fluke thermocouple @ around 25 Celsius - each Thermistor requires individual "calibration" */ // Enable debug prints to serial monitor //#define MY_DEBUG #define MY_RADIO_NRF24 #define MY_NODE_ID 240 // Enable repeater functionality for this node #define MY_REPEATER_FEATURE #define MY_RF24_CHANNEL 83 #define DEBUG 1 #include <MySensors.h> // Node specific #define SKETCH_NAME "LCD2004A_1_Nano" #define SKETCH_VERSION "1.0_2.2.0" #define SENSOR_DESCRIPTION "LCD1_MySensors" #define LCD_TH "LCD1_TH" #define LCD_LINE1 "LCD1_LINE1" #define LCD_LINE2 "LCD1_LINE2" #define LCD_LINE3 "LCD1_LINE3" #define LCD_LINE4 "LCD1_LINE4" #define LCD_TH_CHILD_ID 241 #define LCD_LINE1_CHILD_ID 242 #define LCD_LINE2_CHILD_ID 243 #define LCD_LINE3_CHILD_ID 244 #define LCD_LINE4_CHILD_ID 245 // Node specific #include "LiquidCrystal.h" LiquidCrystal lcd(3, 4, 5, 6, 7, 8); int _nominal_resistor = 4660; int _nominal_temperature = 25; int _b_coefficient = 3950; int _series_resistor = 4697; int _pin = 0; String line1 = "line1 "; String line2 = "line2 "; String line3 = "line3 "; String line4 = "line4 "; bool line1received = false; bool line2received = false; bool line3received = false; bool line4received = false; MyMessage msgTemp(LCD_TH_CHILD_ID, V_TEMP); MyMessage msgLine1(LCD_LINE1_CHILD_ID, V_TEXT); MyMessage msgLine2(LCD_LINE2_CHILD_ID, V_TEXT); MyMessage msgLine3(LCD_LINE3_CHILD_ID, V_TEXT); MyMessage msgLine4(LCD_LINE1_CHILD_ID, V_TEXT); void setup() { Serial.begin(115200); // put your setup code here, to run once: // set up the LCD's number of columns and rows: lcd.begin(20, 4); lcd.clear(); lcd.home(); LCD_test(); } void presentation() { // Send the sketch version information to the gateway and Controller sendSketchInfo(SKETCH_NAME, SKETCH_VERSION); // Register all sensors to gw (they will be created as child devices) present(LCD_TH_CHILD_ID, S_TEMP, LCD_TH); present(LCD_LINE1_CHILD_ID, S_INFO, LCD_LINE1); present(LCD_LINE2_CHILD_ID, S_INFO, LCD_LINE2); present(LCD_LINE3_CHILD_ID, S_INFO, LCD_LINE3); present(LCD_LINE4_CHILD_ID, S_INFO, LCD_LINE4); } void loop() { line1received = false; line2received = false; line3received = false; line4received = false; tempReport(); if (!line1received) { request(LCD_LINE1_CHILD_ID, V_TEXT); #if DEBUG == 1 Serial.println("Requested line1 from gw !"); #endif wait(5000, 2, V_TEXT); // wait for 5s or until a message of type V_TEXT is received } if (!line2received) { request(LCD_LINE2_CHILD_ID, V_TEXT); #if DEBUG == 1 Serial.println("Requested line1 from gw !"); #endif wait(5000, 2, V_TEXT); // wait for 5s or until a message of type V_TEXT is received } if (!line3received) { request(LCD_LINE3_CHILD_ID, V_TEXT); #if DEBUG == 1 Serial.println("Requested line1 from gw !"); #endif wait(5000, 2, V_TEXT); // wait for 5s or until a message of type V_TEXT is received } if (!line4received) { request(LCD_LINE4_CHILD_ID, V_TEXT); #if DEBUG == 1 Serial.println("Requested line1 from gw !"); #endif wait(5000, 2, V_TEXT); // wait for 5s or until a message of type V_TEXT is received } wait(15000); } // Temperature report void tempReport() { wait(100); // read the voltage across the thermistor float adc = analogRead(_pin); // set TH_PIN LOW //digitalWrite(TH_PIN, LOW); // calculate the temperature float reading = (1023 / adc) - 1; reading = _series_resistor / reading; float temperature; temperature = reading / _nominal_resistor; // (R/Ro) temperature = log(temperature); // ln(R/Ro) temperature /= _b_coefficient; // 1/B * ln(R/Ro) temperature += 1.0 / (_nominal_temperature + 273.15); // + (1/To) temperature = 1.0 / temperature; // Invert temperature -= 273.15; // convert to C #if DEBUG == 1 Serial.print(F("THER I=")); Serial.print(LCD_TH_CHILD_ID); Serial.print(F(" V=")); Serial.print(adc); Serial.print(F(" T=")); Serial.println(temperature); #endif // Send temperature to the controller send(msgTemp.set(temperature, 1)); } void receive(const MyMessage &message) { int ID = message.sensor; if (ID == LCD_LINE1_CHILD_ID) { // Receive line1 if (message.type == V_TEXT) { line1 = message.getString(); #if DEBUG == 1 Serial.print("Sensor: "); Serial.println(ID); Serial.print("Received line1 from gw: "); Serial.println(line1); #endif line1received = true; printline1(); } } if (ID == LCD_LINE2_CHILD_ID) { // Receive line2 if (message.type == V_TEXT) { line2 = message.getString(); #if DEBUG == 1 Serial.print("Sensor: "); Serial.println(ID); Serial.print("Received line2 from gw: "); Serial.println(line2); #endif line2received = true; printline2(); } } if (ID == LCD_LINE3_CHILD_ID) { // Receive line3 if (message.type == V_TEXT) { line3 = message.getString(); #if DEBUG == 1 Serial.print("Sensor: "); Serial.println(ID); Serial.print("Received line3 from gw: "); Serial.println(line3); #endif line3received = true; printline3(); } } if (ID == LCD_LINE4_CHILD_ID) { // Receive line4 if (message.type == V_TEXT) { line4 = message.getString(); #if DEBUG == 1 Serial.print("Sensor: "); Serial.println(ID); Serial.print("Received line4 from gw: "); Serial.println(line4); #endif line4received = true; printline4(); } } } // Print line1 void printline1() { lcd.setCursor(0, 0); lcd.print(line1.substring(0, 20)); } // Print line2 void printline2() { lcd.setCursor(0, 1); lcd.print(line2.substring(0, 20)); } // Print line3 void printline3() { lcd.setCursor(0, 2); lcd.print(line3.substring(0, 20)); } // Print line4 void printline4() { lcd.setCursor(0, 3); lcd.print(line4.substring(0, 20)); } // LCD test void LCD_test(void) { // show some output lcd.setCursor(0, 0); lcd.print("hello world, line 1!"); lcd.setCursor(0, 1); lcd.print("hello world, line 2!"); lcd.setCursor(0, 2); lcd.print("hello world, line 3!"); lcd.setCursor(0, 3); lcd.print("hello world, line 4!"); } /* On the Domoticz side, this DzVents 2.4.x code will display MySensors devices and Domoticz devices on line 3 of the LCD. Replace MySensorsGW_CH83 with whatever you see in Setup/Devices under the Hardware column for your MySensors devices (i.e. not Domoticz dummy devices ... etc.) --------------------------------------------------------------------------------------------------------------------- return { on = { timer = {'every minute'} }, execute = function(domoticz) count_mys = domoticz.devices().reduce(function(mys, device) if (device.hardwareName == 'MySensorsGW_CH83') and (device.deviceSubType ~= 'Text') then mys = mys + 1 -- increase the accumulator --domoticz.log(device.hardwareName) end return mys -- return count of MySensors devices end, 0) count_domo = domoticz.devices().reduce(function(domo, device) domo = domo + 1 -- increase the accumulator --domoticz.log(device.name) --domoticz.log(device.idx .. " @ " .. device.name) return domo -- return count of Domoticz devices end, 0) domoticz.log("MySDom count " .. count_mys .. "/" .. count_domo) domoticz.devices('LCD1_LINE3').updateText("MySDom count " .. count_mys .. "/" .. count_domo .. " ") end } -------------------------------------------------------------------------------------------------------------------------- return { on = { devices = { 'LCD1_TH', 'TERMOSTAT' } }, execute = function(domoticz, LCD1_TH) domoticz.log(LCD1_TH.name) domoticz.log(LCD1_TH.state) domoticz.devices().forEach(function(device) if (device.name == 'TERMOSTAT') then domoticz.log(device.name) domoticz.log(device.state) domoticz.devices('LCD1_LINE1').updateText("SET " .. device.state .. " ACT " .. LCD1_TH.state .. "`C ") end end) end } */
-
RE: LCD Node scanner
@johnny-b-good do NOT give up please
This is very interesting, I'll try to study your code. It would be very useful if I could list all RF24 devices registered in the network on the same channel. I assume (as did not read your code yet) you're only listing the nodes transmitting to the scanner. I'll have a look to this by all means! Thank you. -
RE: Unknown battery drain
@Richard-van-der-Plas - you can use any Arduino Mini or Mini Pro for a battery powered sensor.
It does not matter much if you buy a 5V or a 3V3 Mini Pro version as you will better flash an internal 8MHz bootloader, remove the linear voltage regulator on these boards and the LED or LEDs as well. I use battery powered temperature sensors (with thermistors)since November 2017 and they still work fine -> I use 2xR6 batteries. Things you can do (like I did, after lots of reading on this forum):- important! remove the LDO (the low drop output voltage regulator) equipped on the Arduinos
- remove the LED or LEDs
- flash an 8MHz internal oscillator bootloader (I read in this forum that using 1MHz internal osc. may give you occasional faults, don't know if that is still valid!) - do you know how to do that?
- internal 8MHz could be precise enough to work with your Dallas temperature sensors, I'm not sure without checking the datasheet
- an 8MHz Arduino (ATMega328P in this case) can work down to about 2V4 according to the datasheet, while the radio works down to 1V9
- either use 2 x R6 batteries to power both the Arduino and the radio module
- or use 3 xR6 batteries to power the Arduino BUT (important!) get power for the radio only from two of the R6 batteries or you'll damage it
- I bought battery powered Christmas lights from LIDL and Kaufland, they had very cheap Christmas lights with both 2 and 3 R6 batteries - so I just use the very convenient battery plastic housing equipped with an ON/OFF switch. Or just look for some R6 or AAA battery holders ...
- make sure you connect the Ground of both the Arduino and the Radio to the "-" of the battery string
- NiMH rechargeable batteries have a much higher self discharge rate than alkaline non rechargeable batteries, NiMH would not be a good option to me as I would have to replace them quite often, but may fit your needs:-)
- ATMega328P can measure its internal 1V1 reference and by doing that you can calculate the battery voltage without a resistor divider that would drain a few more uA, use this library:
https://forum.mysensors.org/topic/186/new-library-to-read-arduino-vcc-supply-level-without-resistors-for-battery-powered-sensor-nodes-that-do-not-use-a-voltage-regulator-but-connect-directly-to-the-batteries - you can use thermistors to measure the temperature as they are very cheap and most important - you can power the thermistor from an Arduino pin by making it an OUTPUT and set it HIGH. After reading the temperature set it back to LOW and put the Arduino to sleep. You will conserve even more power this way. Hope it helps ...
- forgot to clarify, you are supposed to connect the "+" of the battery string to the 5V pin header on the Arduino (there are 2 such pins I think), not to the RAW pin header. 5V can be anything between 2V4 and 5V (for an 8MHz Arduino) and goes directly to the ATMega VCC pin while RAW connector goes to the input of the Linear Voltage Regulator you are supposed to remove
- while looking to your code I can see you have many delay() lines which means your Arduino is awake for many seconds, that's just not good enough for a battery powered sensor :-), try to remove these delays as much as possible, use different sensors that do not require delays eventually as the Arduino should be mostly sleeping. Use eventually a
#define DEBUG x
statement (x=1 if you like to have a serial debug output or x=0 if you don't) and only output the Serial.print when needed.Here is an example for a temperature sensor with a thermistor and 2xR6 batteries (not using here the VCC library I mentioned before but something similar):
// Enable debug prints to serial monitor //#define MY_DEBUG #define MY_RADIO_NRF24 #define MY_NODE_ID 10 #define DEBUG 0 #define BATTERY_SENSOR 1 #include <MySensors.h> #define TH1_CHILD_ID 11 #define VOLTAGE_CHILD_ID 12 #define TH_PIN 3 int _nominal_resistor = 4700; int _nominal_temperature = 25; int _b_coefficient = 3950; int _series_resistor = 4877; int _pin = 0; float BatteryMin = 2.4; float BatteryMax = 3.0; MyMessage msgTemp(TH1_CHILD_ID, V_TEMP); MyMessage msgVoltage(VOLTAGE_CHILD_ID, V_VOLTAGE); void setup() { //Serial.begin(115200); } void presentation() { // Send the sketch version information to the gateway and Controller sendSketchInfo("TH1_Mini_2xR6", "1.0"); present(TH1_CHILD_ID, S_TEMP, "TH1"); present(VOLTAGE_CHILD_ID, S_MULTIMETER, "TH1_Batt_Voltage"); } void loop() { tempReport(); batteryReport(); sleep(180000); } // Measure VCC float getVcc() { #ifndef MY_GATEWAY_ESP8266 // Measure Vcc against 1.1V Vref #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 // Vref settle wait(70); // Do conversion ADCSRA |= _BV(ADSC); while (bit_is_set(ADCSRA, ADSC)) {}; // return Vcc in mV return (float)((1125300UL) / ADC) / 1000; #else return (float)0; #endif } // Send a battery level report to the controller void batteryReport() { // measure the board vcc float volt = getVcc(); // calculate the percentage int percentage = ((volt - BatteryMin) / (BatteryMax - BatteryMin)) * 100; if (percentage > 100) percentage = 100; if (percentage < 0) percentage = 0; #if DEBUG == 1 Serial.print(F("BATT V=")); Serial.print(volt); Serial.print(F(" P=")); Serial.println(percentage); #endif #if BATTERY_SENSOR == 1 // report battery voltage send(msgVoltage.set(volt, 3)); #endif // report battery level percentage sendBatteryLevel(percentage); } void tempReport() { // set TH pin in output mode pinMode(TH_PIN, OUTPUT); // set TH_PIN HIGH digitalWrite(TH_PIN, HIGH); wait(1); // read the voltage across the thermistor float adc = analogRead(_pin); // set TH_PIN LOW digitalWrite(TH_PIN, LOW); // calculate the temperature float reading = (1023 / adc) - 1; reading = _series_resistor / reading; float temperature; temperature = reading / _nominal_resistor; // (R/Ro) temperature = log(temperature); // ln(R/Ro) temperature /= _b_coefficient; // 1/B * ln(R/Ro) temperature += 1.0 / (_nominal_temperature + 273.15); // + (1/To) temperature = 1.0 / temperature; // Invert temperature -= 273.15; // convert to C #if DEBUG == 1 Serial.print(F("THER I=")); Serial.print(TH1_CHILD_ID); Serial.print(F(" V=")); Serial.print(adc); Serial.print(F(" T=")); Serial.println(temperature); #endif send(msgTemp.set(temperature, 1)); }```