Check out the RadioHead library, it implements a mesh network on RFM69
Carywin
Posts
-
is mesh n/w possible using RFM69 without using gateway? -
Ethernet/WiFi-Client GatewayIf you’re using sensors over wifi you don’t need MySensors, you can just use PubSubClient. MySensors is primarily for mesh network sensors not using wifi.
-
Want Wired Ethernet For All Sensor Nodes / GatewayYou don’t need MySensors for this, PubSubClient will do what you need.
-
Using an 802.11g wifi transportWhat you need is an MQTT broker and the PubSubClient library. MySensors is not useful to you.
-
Leonardo/RFM69HW ethernet gateway not working -
I need some help about sensorsI have used VL53L0X laser time-of-flight sensors for things like this. They work great, are inexpensive, and reliable. They're available for a few dollars from the usual Chinese suppliers.
-
RFM69HW 868MHz working on 915MHzI accidentally used a 915 MHz part at 433 MHz and even that worked, albeit at substantially reduced range.
-
RS485 Baud Rate Errors - Mixing HWSerial Devices Can Cause ProblemsHi Folks,
This is more of a troubleshooting report than a request for help. I thought I'd report my findings here in hopes of saving someone else the headaches I've had recently.What it boils down to is: the default clocks used on the common 3V3 and 5V Arduino boards cause small errors in actual baud rate on the hardware USART serial ports, and at certain rates the error difference between the two variants is opposite and results in no communications being possible between them.
Some background:
I have a small but growing RS485 MySensors network incorporated into my OpenHAB-based home automation system. It started out with just a MQTT gateway and a single node, being a weather station mounted up on the roof about 5 metres away. RS485 was chosen because getting RF signals through the metal roof was problematic, and I was sick of climbing up there to change batteries. Both the gateway and the WXS were built with 3V3 8MHz 32u4 based Arduinos, because then I could use the hardware USART port for RS485 comms while still having the USB port for debugging. Cat-6 cable was used, with one pair for the RS485 comms and a pair each for +12V and GND. The baud rate was set at 115200 bps and this setup worked flawlessly for about a year.
So pleased was I with the reliability, that I decided all sensor nodes on my upper storey that had easy access for a cable would be wired nodes on the RS485 network going forward.
The second node to be deployed on the network was a light/heat/fan controller for the bathroom. This node used a 5V 16MHz 32u4 Arduino. When built and tested on the bench, this node worked perfectly; but when deployed into the roof space and connected to mains power it flatly refused to work, spitting FPAR:NOREPLY errors forever. I spent a lot of time trying to troubleshoot the comms issues by investigating ground loops or other noise, termination, or power supply issues. I pulled the AC/DC supply off it and used the central +12V one. I changed the baud rates around and got some intermittent success. At one point I even fried both the Arduino and my laptop when some stray high-power-switching surges tried to find their way to ground through the USB cable. Nothing seemed to work in the roof, everything worked fine on the bench.After much longer scratching my head than I feel comfortable admitting I examined the differences between the MQTT gateway and my test setup, investigated how the oscillator clock is divided down to determine the baud rate, and stumbled upon the answer:
at fosc = 8 MHz (3V3 parts), 115.2kbps, Error = -3.5%
at fosc = 16 MHz (5V parts), 115.2kbps, Error = 2.1%
Total error: 5.6%, somewhat outside the tolerable window of ~5% for baud rate error.In the end the solution was as simple as lowering the baud rate on the 5V 16MHz part by ~4% to 110600 bps. The new node then instantly connected and has been reliable ever since.
-
💬 RS485This is great, thanks!
One suggestion: add a switch mode regulator that can handle 12 or 24 volt DC input. This will allow small sensor devices to hang off a typical bus network having extra pairs for the central power supply. -
LAN connected MQTT nodesYou don’t need MySensors for a direct connection to MQTT. Just use pubsubclient.
-
Introductions and Range IssuesGood luck! I tried sticking with NRF long past when would be sensible, and still ended up changing to RFM69 (433 MHz in my case).
Inner-city areas are just too crowded on 2.4G now, but paradoxically 433 MHz is becoming freeer thanks to the slow death of landlines and DECT phones. -
MQTTClient - Arduino uno - Ethernet Shield WIZ5100 - RFM69I got it to work using Leonardo, but the same process would work for Uno I think:
https://forum.mysensors.org/topic/6249/mqtt-ethernet-gateway-using-leonardo-32u4-w5100-rfm69h-hard-spi -
6/8 Buttons battery remote node@neverdie This is correct, but this testing is all handled by the EnableInterrupt library
-
6/8 Buttons battery remote node@dbemowsk The Pro Mini does have pin change interrupts on every pin
-
6/8 Buttons battery remote node@gohan Sorry I don't have a way to measure current that small, but given that it's already run for months on the original batteries, I'm going to assume it's a "normal" Atmega sleep state
-
6/8 Buttons battery remote nodeYou can use pin change interrupts with MySensors sleep loops with an easy hack. Here's the code I use for 4 button battery powered nodes that also report temperature and humidity using DHT a sensor. I run them from 2 AA and so far they've been running for more than 6 months without showing signs of discharge. This could be easily modified for 6 or 8 buttons.
// MySensors EnviroButtons // Temperature and Humidity Sensor with 4 Push Buttons // Battery Powered Node // Don't forget to change buttons and VCC_CAL for each node // Cary Wintle - July 2017 // MySensors configuration // ----------------------- #define SN "EnviroButtons" // Software name #define SV "0.4" // Version number //#define MY_DEBUG #define MY_NODE_ID 6 #define MY_RADIO_RFM69 #define MY_RFM69_NETWORKID 137 #define MY_RFM69_ENABLE_ENCRYPTION #define MY_RFM69_NEW_DRIVER #define MY_RFM69_FREQUENCY RFM69_433MHZ #define MY_IS_RFM69HW #include <MySensors.h> #include <SPI.h> #include <DHT.h> #define EI_NOTEXTERNAL // External interrupts managed by built-in routines #include <EnableInterrupt.h> // Pin-change interrupts // Set this to the pin you connected the DHT's data pin to #define DHT_DATA_PIN 8 // Buttons #define BUTTON1_PIN A1 // 5: A1 - 6: A1 #define BUTTON2_PIN A2 // 5: A3 - 6: A2 #define BUTTON3_PIN A3 // 5: A2 - 6: A3 #define BUTTON4_PIN A0 // 5: A0 - 6: A0 // Set this offset if the sensor has a permanent small offset to the real temperatures #define SENSOR_TEMP_OFFSET 0 // Sleep time between sensor updates (in milliseconds) // Must be >1000ms for DHT22 and >2000ms for DHT11 static const uint64_t UPDATE_INTERVAL = 120000; #define BAT_UPDATE_INTERVAL 720 // 24 hrs - Interval between battery updates (multiples of UPDATE_INTERVAL) // VCC Calibration Values // Node 5: 1128953L // Node 6: 1125300L #define VCC_CAL 1125300L // Force sending an update of the temperature after n sensor reads, so a controller showing the // timestamp of the last update doesn't show something like 3 hours in the unlikely case, that // the value didn't change since; // i.e. the sensor would force sending an update every UPDATE_INTERVAL*FORCE_UPDATE_N_READS [ms] static const uint8_t FORCE_UPDATE_N_READS = 30; // After an hour float lastTemp; float lastHum; uint8_t nNoUpdatesTemp; uint8_t nNoUpdatesHum; int cycleCount = BAT_UPDATE_INTERVAL; // Send battery update immediately volatile byte B1Int = 0, B2Int = 0, B3Int = 0, B4Int = 0; // Interrupt button flags uint32_t now; MyMessage msgHum(0, V_HUM); MyMessage msgTemp(0, V_TEMP); MyMessage msgButtons(0, V_SCENE_ON); MyMessage msgBattV(0, V_VOLTAGE); DHT dht; void presentation() { // Send the sketch version information to the gateway sendSketchInfo(SN,SV); // Present the sensor present(0, S_CUSTOM, "Temp/Humid/Buttons"); } void setup() { // Setup pins the DHT sensor is on digitalWrite(6, LOW); pinMode(6, OUTPUT); digitalWrite(7, LOW); pinMode(7, OUTPUT); digitalWrite(9, HIGH); pinMode(9, OUTPUT); sleep(2000); dht.setup(DHT_DATA_PIN); // Setup the DHT sensor pinMode(BUTTON1_PIN,INPUT_PULLUP); pinMode(BUTTON2_PIN,INPUT_PULLUP); pinMode(BUTTON3_PIN,INPUT_PULLUP); pinMode(BUTTON4_PIN,INPUT_PULLUP); enableInterrupt(BUTTON1_PIN,Button1,FALLING); enableInterrupt(BUTTON2_PIN,Button2,FALLING); enableInterrupt(BUTTON3_PIN,Button3,FALLING); enableInterrupt(BUTTON4_PIN,Button4,FALLING); } void Button1() { B1Int++; _wokeUpByInterrupt = 0xFE; // Dirty hack to get out of MySensors sleep loop } void Button2() { B2Int++; _wokeUpByInterrupt = 0xFE; // Dirty hack to get out of MySensors sleep loop } void Button3() { B3Int++; _wokeUpByInterrupt = 0xFE; // Dirty hack to get out of MySensors sleep loop } void Button4() { B4Int++; _wokeUpByInterrupt = 0xFE; // Dirty hack to get out of MySensors sleep loop } void loop() { _wokeUpByInterrupt = INVALID_INTERRUPT_NUM; // Power up the DHT sensor digitalWrite(9, HIGH); // Process buttons if(B1Int > 0) { send(msgButtons.set(1)); B1Int = 0; } else if(B2Int > 0) { send(msgButtons.set(2)); B2Int = 0; } else if(B3Int > 0) { send(msgButtons.set(3)); B3Int = 0; } else if(B4Int > 0) { send(msgButtons.set(4)); B4Int = 0; } // Wait for the DHT sensor to init sleep(2000); // Force reading sensor, so it works also after sleep() dht.readSensor(true); // Get temperature from DHT library float temperature = dht.getTemperature(); if (isnan(temperature)) { Serial.println("Failed reading temperature from DHT!"); } else if (temperature != lastTemp || nNoUpdatesTemp == FORCE_UPDATE_N_READS) { // Only send temperature if it changed since the last measurement or if we didn't send an update for n times lastTemp = temperature; // Reset no updates counter nNoUpdatesTemp = 0; temperature += SENSOR_TEMP_OFFSET; send(msgTemp.set(temperature, 1)); #ifdef MY_DEBUG Serial.print("T: "); Serial.println(temperature); #endif } else { // Increase no update counter if the temperature stayed the same nNoUpdatesTemp++; } // Get humidity from DHT library byte humidity = (byte)dht.getHumidity(); if (humidity != lastHum || nNoUpdatesHum == FORCE_UPDATE_N_READS) { // Only send humidity if it changed since the last measurement or if we didn't send an update for n times lastHum = humidity; // Reset no updates counter nNoUpdatesHum = 0; send(msgHum.set(humidity, 1)); #ifdef MY_DEBUG Serial.print("H: "); Serial.println(humidity); #endif } else { // Increase no update counter if the humidity stayed the same nNoUpdatesHum++; } if (cycleCount >= BAT_UPDATE_INTERVAL) { cycleCount = 0; int BatV = readVCC(); #ifdef MY_DEBUG Serial.print("BatVR: "); Serial.println(BatV); #endif float BatVolts = BatV / 1000.0; #ifdef MY_DEBUG Serial.print("BatV: "); Serial.println(BatVolts); #endif send(msgBattV.set(BatVolts, 2)); float BatPercent = (BatVolts - 2.8) / 0.6 * 100; if(BatPercent > 100) BatPercent = 100; #ifdef MY_DEBUG Serial.print("Bat%: "); Serial.println(BatPercent); #endif sendBatteryLevel((int)BatPercent); } cycleCount++; // Power down the DHT sensor digitalWrite(9, LOW); // Sleep for a while to save energy sleep(UPDATE_INTERVAL); } int readVCC() { // Read 1.1V reference against AVcc // set the reference to Vcc and the measurement to the internal 1.1V reference ADMUX = _BV(REFS0) | _BV(MUX3) | _BV(MUX2) | _BV(MUX1); wait(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 int result = (high<<8) | low; #ifdef MY_DEBUG Serial.print("R: "); Serial.println(result); #endif result = VCC_CAL / result; // Calculate Vcc (in mV); 1125300 = 1.1*1023*1000 return result; // Vcc in millivolts } -
does MySensors use a guaranteed transport protocol or a best effort ?@neverdie The bulk of MySensors nodes run on Atmega328P, with 2k of SRAM they're already quite resource-constrained in some of these sensors.
-
LED lamp dimmer questions: Flickering, LED lifetime, power consumptionPower = Current squared x Resistance, so for your example of 5 A and 0.035 Ron the power dissipated is 0.875 W. It's still not a lot but it's substantially more than was stated.
-
💬 MyMultisensorsOkay I played around with this tonight and had some struggles. I couldn't get serial uploading working on any of the Gert Sanders bootloaders, so I had to use Arduino as ISP and Upload via Programmer.
However since I have encryption enabled, I need the AES key in EEPROM before my nodes will work.
So I had to enable the fuse that prevents EEPROM being erased when programming.I experimented with using the 1 MHz oscillator option, but the sketch didn't run properly. It was sending 5-8 copies of every message at a very slow rate.
So now I'm trying the 8 MHz internal oscillator with BOD at 1.8 V to see if that works at a lower voltage than the crystal.
If anyone knows if MySensors works at 1 MHz, or what might cause it to send multiple copies of the same message, speak up please!
-
💬 MyMultisensorsThanks!
I should have mentioned that I already set the BOD to 1.8V, but that doesn't help when the XTAL oscillator stops working at 2.6.
I'll try one of those other bootloaders and see what flies.