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 SWITCHES

    TSP: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 DALLAS

    TSP: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 TEMP

    TSP: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 WATT

    TSP: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), AM2321

    unsigned 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 here

    unsigned 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]


  • Mod

    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


  • Mod

    @Tris I think this would work:

    present(sensor + MAX_ATTACHED_DS18B2 + NUMBER_OF_SWITCHES, S_LIGHT);
    

Log in to reply
 

Suggested Topics

  • 4
  • 17
  • 20
  • 15
  • 3
  • 2

0
Online

11.4k
Users

11.1k
Topics

112.7k
Posts