Duplicate Child ID 0
-
Im hoping there is a simple fix, ive gone through the forum for over a week and cant believe no-one else has experienced the same issue.
I have multiple sensors on a node that all report as Child ID 0, not what i'd like. We are supposed to have different child id for each sensor.
There are different types of sensors (so topics are different) so the readings go through MQTT ok and even read and sent by openhab ok, but i know its not how its meant to be.This is from serial monitor (with added sensor type comment)
TSP:MSG:SEND 9-9-0-0 s=0,c=1,t=16,pt=1,l=1,sg=0,ft=0,st=ok:1 SWITCHES
TSP:MSG:SEND 9-9-0-0 s=1,c=1,t=16,pt=1,l=1,sg=0,ft=0,st=ok:1 SWITCHES
TSP:MSG:SEND 9-9-0-0 s=2,c=1,t=16,pt=1,l=1,sg=0,ft=0,st=ok:1 SWITCHES
TSP:MSG:SEND 9-9-0-0 s=3,c=1,t=16,pt=1,l=1,sg=0,ft=0,st=ok:1 SWITCHES
TSP:MSG:SEND 9-9-0-0 s=4,c=1,t=16,pt=1,l=1,sg=0,ft=0,st=ok:1 SWITCHESTSP:MSG:SEND 9-9-0-0 s=0,c=1,t=0,pt=7,l=5,sg=0,ft=0,st=ok:18.4 DALLAS
TSP:MSG:SEND 9-9-0-0 s=1,c=1,t=0,pt=7,l=5,sg=0,ft=0,st=ok:18.2 DALLASTSP:MSG:SEND 9-9-0-0 s=10,c=1,t=1,pt=7,l=5,sg=0,ft=0,st=ok:64.7 DHT HUMID
TSP:MSG:SEND 9-9-0-0 s=11,c=1,t=0,pt=7,l=5,sg=0,ft=0,st=ok:21.5 DHT TEMPTSP:MSG:SEND 9-9-0-0 s=40,c=0,t=16,pt=0,l=0,sg=0,ft=0,st=ok: LIGHT LEVEL
TSP:MSG:SEND 9-9-0-0 s=45,c=0,t=16,pt=0,l=0,sg=0,ft=0,st=ok: UV FLAME LIGHT
TSP:MSG:SEND 9-9-0-0 s=50,c=0,t=13,pt=0,l=0,sg=0,ft=0,st=ok: POWER WATTTSP:MSG:SEND 9-9-0-0 s=1,c=0,t=3,pt=0,l=0,sg=0,ft=0,st=ok: RELAYS x8
TSP:MSG:SEND 9-9-0-0 s=2,c=0,t=3,pt=0,l=0,sg=0,ft=0,st=ok:
TSP:MSG:SEND 9-9-0-0 s=3,c=0,t=3,pt=0,l=0,sg=0,ft=0,st=ok:
TSP:MSG:SEND 9-9-0-0 s=4,c=0,t=3,pt=0,l=0,sg=0,ft=0,st=ok:
TSP:MSG:SEND 9-9-0-0 s=5,c=0,t=3,pt=0,l=0,sg=0,ft=0,st=ok:
TSP:MSG:SEND 9-9-0-0 s=6,c=0,t=3,pt=0,l=0,sg=0,ft=0,st=ok:
TSP:MSG:SEND 9-9-0-0 s=7,c=0,t=3,pt=0,l=0,sg=0,ft=0,st=ok:
TSP:MSG:SEND 9-9-0-0 s=8,c=0,t=3,pt=0,l=0,sg=0,ft=0,st=ok:As you can see, for example there are duplicates of s=0, s-1 etc
I have used sketches that allow multiple relays/dallas/swicthes and the first child id of each set of sensors is 0, so i have many id 0, 1, 2, 3 etc as its seems the child id is being auto generated.
I think its something to do with these lines but i have changed i=0 or sensors=0 to say =60 and when i upload child id 60 isnt showing in serial monitor.for (int sensor=1, pin=RELAY_1; sensor<=NUMBER_OF_RELAYS;sensor++, pin++) {
for (int i=0; i<numSensors && i<MAX_ATTACHED_DS18B20; i++) {
for (int i = 0; i < NUMBER_OF_SWITCHES; i++)Anyone have any ideas?
-
This post is deleted!
-
[code]
/**- Mysensors node talks to mqtt ethernet gateway client
- dht 1 (2 VALUES)
- relays 8
- light level 1
- uv flame level 1
- energy 1
- servo speed 4
- dallas 2
- switches 4
*/
#define MY_NODE_ID 9
// Enable debug prints
#define MY_DEBUG// Enable and select radio type attached
#define MY_RADIO_NRF24
//#define MY_RADIO_RFM69#include <VarSpeedServo.h>
#include <SPI.h>
#include <MySensors.h>
#include <DHT.h>
#include <DallasTemperature.h> // For Dallas temp sensor
#include <OneWire.h> // For Dallas temp sensor
#include <Bounce2.h>#define CHILD_ID_HUM 10
#define CHILD_ID_TEMP 11
#define HUMIDITY_SENSOR_DIGITAL_PIN 48
#define DHTTYPE DHT22 // DHT 22 (AM2302), AM2321unsigned long SLEEP_TIME = 30000; // Sleep time between reads (in milliseconds)
unsigned long lastRefreshTime = 0; // Use this to implement a non-blocking delay function
#define RELAY_1 22 // Arduino Digital I/O pin number for first relay (second on pin+1 etc)
#define NUMBER_OF_RELAYS 8 // Total number of attached relays
#define RELAY_ON 0 // GPIO value to write to turn on attached relay
#define RELAY_OFF 1 // GPIO value to write to turn off attached relay#define CHILD_ID_LIGHT 40
#define LIGHT_SENSOR_ANALOG_PIN 0#define CHILD_ID_FLAME 45
#define FLAME_SENSOR_ANALOG_PIN 1#define ONE_WIRE_BUS 49 // DALLAS pin
#define MAX_ATTACHED_DS18B20 2 // DALLAS max nr. of sensors#include <EmonLib.h> // Include Emon Library
EnergyMonitor emon1; // Create an instance
#define CHILD_ID_ENERGY 50 //Current Sense Pin#define NUMBER_OF_SWITCHES 5
Bounce debouncer[NUMBER_OF_SWITCHES];
int oldValue[NUMBER_OF_SWITCHES];
byte switchPin[NUMBER_OF_SWITCHES] = {34,35,36,37,38}; //<<<<<<<<<<< set your switch pins hereunsigned long lastSend;
unsigned long SEND_FREQUENCY = 10000; // Minimum time between send (in milliseconds). We don't wnat to spam the gateway.// Store variables
//long previousMillis = 0; // last time the sensors are updated
long sensorInterval = 20000; // interval at which we will take a measurement ( 5 seconds)
int lastLightLevel; // Holds last light level
int lastFlameLevel; // Holds last FLAME level
float lastTemperature[MAX_ATTACHED_DS18B20]; // Holds DALLAS temperatures
int numSensors=0; // Holds number of sensors
//boolean metric = true; // Celcius or fahrenheid
int calibrationTime = 30; // the time we give the sensor to calibrate (10-60 secs according to the datasheet)const int NBR_SERVOS = 4; // the number of servos
VarSpeedServo Servos[NBR_SERVOS]; // servo objects
int servoPins[NBR_SERVOS] = {44, 45, 6, 5}; // servo pins
int servoSpeeds[NBR_SERVOS] = {5, 10, 100, 255}; // sweep speed, 1 is slowest, 255 fastest)
int servoMinPosition[NBR_SERVOS] = {45, 20, 30, 40}; // the minumum servo angle
int servoMaxPosition[NBR_SERVOS] = {135, 130, 140, 150};// Initialize dallas
OneWire oneWire(ONE_WIRE_BUS);
DallasTemperature sensors(&oneWire);DHT dht(HUMIDITY_SENSOR_DIGITAL_PIN, DHTTYPE);
float lastTemp;
float lastHum;
boolean metric = true;
MyMessage msgHum(CHILD_ID_HUM, V_HUM);
MyMessage msgTemp(CHILD_ID_TEMP, V_TEMP);
MyMessage msgLLight(CHILD_ID_LIGHT, V_LIGHT_LEVEL);
MyMessage msgFLight(CHILD_ID_FLAME, V_LIGHT_LEVEL);
MyMessage msgDallas(ONE_WIRE_BUS,V_TEMP);
MyMessage IrmsMsg(CHILD_ID_ENERGY,V_WATT);
MyMessage msgDoor(0,V_TRIPPED);void setup()
{
for (int i = 0; i < NUMBER_OF_SWITCHES; i++)
{
pinMode(switchPin[i],INPUT_PULLUP);
debouncer[i] = Bounce();
debouncer[i].attach(switchPin[i]);
debouncer[i].interval(5);
}
for (int i = 0; i < NUMBER_OF_SWITCHES; i++)
{
present(i, S_DOOR);
delay(250);
}for(int i=0; i < NBR_SERVOS; i++)
{
Servos[i].attach(servoPins[i]);
Servos[i].slowmove(servoMinPosition[i],servoSpeeds[i]) ; // start sweeping from min position
}dht.begin();
metric = getConfig().isMetric;
for (int sensor=1, pin=RELAY_1; sensor<=NUMBER_OF_RELAYS;sensor++, pin++) { // Then set relay pins in output mode pinMode(pin, OUTPUT); // Set relay to last known state (using eeprom storage) digitalWrite(pin, loadState(sensor)?RELAY_ON:RELAY_OFF);
}
sensors.begin();
numSensors = sensors.getDeviceCount();
// Present all sensors to controller
for (int i=0; i<numSensors && i<MAX_ATTACHED_DS18B20; i++) {
present(i, S_TEMP);
}}
void presentation()
{// Send the Sketch Version Information to the Gateway
sendSketchInfo("Terrace", "Garden");// Register all sensors to gw (they will be created as child devices)
present(CHILD_ID_HUM, S_HUM);
present(CHILD_ID_TEMP, S_TEMP);
present(CHILD_ID_LIGHT, S_LIGHT_LEVEL);
present(CHILD_ID_FLAME, S_LIGHT_LEVEL);
present(CHILD_ID_ENERGY, S_POWER);for (int sensor=1, pin=RELAY_1; sensor<=NUMBER_OF_RELAYS;sensor++, pin++) {
// Register all sensors to gw (they will be created as child devices)
present(sensor, S_LIGHT);
}emon1.current(A2, 29.0); // Current: input pin, calibration.
}
void loop()
{
/////////////
///INSTANST READINGS/COMMANDS SECTION
////////////
for (int i = 0; i < NUMBER_OF_SWITCHES; i++)
{
debouncer[i].update();
int value = debouncer[i].read();
if (value != oldValue[i])
{
send(msgDoor.setSensor(i).set(value == HIGH? true : false), false);
}
oldValue[i] = value;
}// sweep the servos
for(int i=0; i < NBR_SERVOS; i++)
{
if( Servos[i].read() == servoMinPosition[i])
Servos[i].slowmove(servoMaxPosition[i],servoSpeeds[i]) ;
else if( Servos[i].read() == servoMaxPosition[i])
Servos[i].slowmove(servoMinPosition[i],servoSpeeds[i]) ;
}////////////////
///START LONG INTERVAL READINGS ONLY
///////////////
boolean needRefresh = (millis() - lastRefreshTime) > SLEEP_TIME;
if (needRefresh)
{
lastRefreshTime = millis();float temperature = dht.readTemperature(); if (isnan(temperature)) { Serial.println("Failed reading temperature from DHT"); } else if (temperature != lastTemp) { lastTemp = temperature; if (!metric) { } send(msgTemp.set(temperature, 1)); Serial.print("Temperature: "); Serial.println(temperature); } // dht readings float humidity = dht.readHumidity(); if (isnan(humidity)) { Serial.println("Failed reading humidity from DHT"); } else if (humidity != lastHum) { lastHum = humidity; send(msgHum.set(humidity, 1)); Serial.print("Humidity: "); Serial.println(humidity); } // light level int lightLevel = (1023-analogRead(LIGHT_SENSOR_ANALOG_PIN))/10.23; Serial.print("Light Percentage: "); Serial.println(lightLevel); if (lightLevel != lastLightLevel) { send(msgLLight.set(lightLevel)); lastLightLevel = lightLevel; } // flame level int flameLevel = (1023-analogRead(FLAME_SENSOR_ANALOG_PIN))/10.23; Serial.print("Flame Percentage: "); Serial.println(flameLevel); if (flameLevel != lastFlameLevel) { send(msgFLight.set(flameLevel)); lastFlameLevel = flameLevel; } unsigned long now = millis(); double Irms = emon1.calcIrms(1480); // Calculate Irms only bool sendTime = now - lastSend > SEND_FREQUENCY; if (sendTime) { send(IrmsMsg.set((Irms*232.0), 1)); Serial.print("Watt: "); Serial.println(Irms*232.0); // send(kWhMsg.set((Irms*232.0)/1000, 1)); // Serial.print("kWH: "); // Serial.println((Irms*232.0)/1000); lastSend = now; } // Begin dallas temperature // Fetch temperatures from Dallas sensors sensors.requestTemperatures(); // Read temperatures and send them to controller for (int i=0; i<numSensors && i<MAX_ATTACHED_DS18B20; i++) { // Fetch and round temperature to one decimal float temperature = static_cast<float>(static_cast<int>((getConfig().isMetric?sensors.getTempCByIndex(i):sensors.getTempFByIndex(i)) * 10.)) / 10.; Serial.print("Dallas "); Serial.print(i); Serial.print(" "); Serial.println(temperature); // Only send data if temperature has changed and no error if (lastTemperature[i] != temperature && temperature != -127.00) { // Send in the new temperature send(msgDallas.setSensor(i).set(temperature,1)); lastTemperature[i]=temperature; } } // End dallas temperarures } // END LONG READ/SAMPLE INTERVAL
}
void receive(const MyMessage &message)
{
// We only expect one type of message from controller. But we better check anyway.
if (message.type==V_STATUS) {
// Change relay state
digitalWrite(message.sensor-1+RELAY_1, message.getBool()?RELAY_ON:RELAY_OFF);
// Store state in eeprom
saveState(message.sensor, message.getBool());
// Write some debug info
Serial.print("Incoming change for sensor:");
Serial.print(message.sensor);
Serial.print(", New status: ");
Serial.println(message.getBool());
}
}[/code]
-
Welcome to the MySensors community @Tris !
Code is marked as code by three backticks (`) or just press the code button (</>) on the toolbar. It is possible to edit previous posts by clicking on the three dots in the lower right corner of the post.
You are on the right track with solving the problem. Each loop starts over at 0 and that makes it re-use the same IDs. You need to do something like this for the second and third loop, change
for (int i=0; i<numSensors && i<MAX_ATTACHED_DS18B20; i++) { present(i, S_TEMP); }
to
for (int i=0; i<numSensors && i<MAX_ATTACHED_DS18B20; i++) { present(NUMBER_OF_SWITCHES + i, S_TEMP); }
You will also have to define all CHILD_ID_xxx to be outside of the numbers used by the for loops.
I would not want to manage so many sensors on a single node though. The wires and the code will be a mess. If you can, consider using a few different Arduinos to make each sketch simpler. A complex sketch will be harder to troubleshoot.
-
Thanks @mfalkvidd, im very grateful!
I am confident handling the hardware of that many sensors on a Mega, and I cut and paste all the code in small increments, and by doing so, learnt how most of it works - so its reasonably manageable....
I have another Mega handling the more intricate code/sensors like gas/smoke so i would really like to keep this Arduino to the big amount of simple sensors.
Im now stuck on adding the relays, to the switches and dallas that you combined -which resulted in unique, sequential sensors ID's..
How do i add
for (int i=0; i<numSensors && i<MAX_ATTACHED_DS18B20; i++) { present(NUMBER_OF_SWITCHES + i, S_TEMP); }
to this
for (int sensor=1, pin=RELAY_1; sensor<=NUMBER_OF_RELAYS;sensor++, pin++) present(sensor, S_LIGHT);
Ive tried every combination i can think of, but everything ive done either duplicates sets of sensors or ignores them!
Any pointers would be great
-
@Tris I think this would work:
present(sensor + MAX_ATTACHED_DS18B2 + NUMBER_OF_SWITCHES, S_LIGHT);