MySensor Network on RS485 - only single node visible



  • Hi,

    I'm trying to build my sensor network using MySensors over RS 485. As controller I'm using domoticz on Paspberry PI, gateway I build on arduino pro micro, the nodes are on arduino nano + MAX485 module. Between the nodes I use twisted Pair Cat 5E. the power supply in also on that cable (12V), it is used to power up nodes, gateway is powered up by USB.

    So far I've build 2 nodes with several sensors each. I've assigned MY_NODE_ID manually Gateway is MY_NODE_ID=0 nodes are 1 and 2.
    My problem is that only one of the nodes is visible at the time. When I connecting node 2 or 1 everything is fine, node is visible and updating. But when I connect node 2 and then node 1, node 2 is not updating any more, while node 1 is working fine. when I disconnecting node 2 and trying to connect it again, then node 2 is sending pair request but does not getting any response.

    So far I've change connection between each element, and removed the terminating resistors (First R7 and later two more 6 and 5) from node 1 MAX485 module, tried to change cable length (max for node 2 is 20m). Rewriting code for gateway and nodes...

    I would be grateful for any help. I've been struggling with this problem for several weeks now and have no idea how to solve it....

    The code for ...

    Gateway:

    
    //Sekcja Termometru
    #include <OneWire.h>
    #include <DallasTemperature.h>
    
    #define DS18B20_PIN 2
    
    OneWire oneWire(DS18B20_PIN);
    DallasTemperature ds18b20(&oneWire);
    
    //Definicje dla MySensors
    #define MY_DEBUG // Enable debug prints to serial monitor
    #define MY_RS485 // Enable RS485 transport layer
    
    #define MY_RS485_DE_PIN 8 // Define this to enables DE-pin management on defined pin
    
    
    
    #define MY_RS485_BAUD_RATE 9600 // Set RS485 baud rate to use
    #define MY_RS485_HWSERIAL Serial // Enable this if RS485 is connected to a hardware serial port
    #define MY_GATEWAY_SERIAL // Enable serial gateway
    
    #define MY_NODE_ID 0
    //#define MY_DEFAULT_LED_BLINK_PERIOD 300 // Set blinking period
    //#define MY_DEFAULT_ERR_LED_PIN 6
    //#define MY_DEFAULT_RX_LED_PIN  7
    //#define MY_DEFAULT_TX_LED_PIN  8
    
    #include <MySensors.h>
    
    uint32_t SLEEP_TIME = 120000; // Sleep time between reports (in milliseconds)
    #define CHILD_ID_TEMP 1
    double long lastmillis =0;
    MyMessage msgTemperature(CHILD_ID_TEMP, V_TEMP);
    
    
    void setup()
    {
      ds18b20.begin();
    }
    void presentation()
    {
      sendSketchInfo("MainGateway-temp,wind,rain sensors", "1.0");
    
      present(CHILD_ID_TEMP, S_TEMP, "Temperatura");
    
          ds18b20.requestTemperatures();
          send(msgTemperature.set((int)ds18b20.getTempCByIndex(0)));
    }
    
    void loop()
    {
      if (millis() - lastmillis >= 1800000) { //1800000 = 30 minut
        lastmillis = millis();
        ds18b20.requestTemperatures();
    
    #ifdef MY_DEBUG
        Serial.print("Aktualna temperatura: ");
        Serial.println(ds18b20.getTempCByIndex(0));
    #endif
    
        send(msgTemperature.set(ds18b20.getTempCByIndex(0),2));
    
      }
    }
    

    Node 1:

    #include <OneWire.h>
    #include <DallasTemperature.h>
    
    #define DS18B20_PIN 3
    
    // Enable debug prints to serial monitor
    #define MY_DEBUG
    
    // Enable RS485 transport layer
    #define MY_RS485
    
    // Define this to enables DE-pin management on defined pin
    #define MY_RS485_DE_PIN 2
    
    // Set RS485 baud rate to use
    #define MY_RS485_BAUD_RATE 9600
    
    // Enable this if RS485 is connected to a hardware serial port
    #define MY_RS485_HWSERIAL Serial
    
    #define MY_NODE_ID 1
    
    #include <MySensors.h>
    
    OneWire oneWire(DS18B20_PIN);
    DallasTemperature ds18b20(&oneWire);
    int gas_din = 4;
    int gas_ain = A0;
    double long lastmillis = 0;
    
    
    uint32_t SLEEP_TIME = 5000; // Sleep time between reports (in milliseconds)
    #define CHILD_ID_ANALOG 1
    #define CHILD_ID_BINARY 2
    #define CHILD_ID_TEMPERATURE 3
    
    // Initialize motion message
    MyMessage msg_gas_analog(CHILD_ID_ANALOG, V_LEVEL);
    MyMessage msg_gas_binary(CHILD_ID_BINARY, V_TRIPPED);
    MyMessage msg_temperature(CHILD_ID_TEMPERATURE, V_TEMP);
    
    void setup()
    {
      ds18b20.begin();
      pinMode(gas_din, INPUT);
      pinMode(gas_ain, INPUT);
    }
    
    void presentation()
    {
      // Send the sketch version information to the gateway and Controller
      sendSketchInfo("Gas Sensor", "1.0");
    
      // Register all sensors to gw (they will be created as child devices)
      present(CHILD_ID_ANALOG, S_AIR_QUALITY, "MQ5-poziom gazu");
      delay(50);
      present(CHILD_ID_BINARY, S_SMOKE, "MQ5 - Wyciek gazu");
      delay(50);
      present(CHILD_ID_TEMPERATURE, S_TEMP, "Temperatura z czujnika gazu");
    }
    
    void loop()
    {
    
    
    
      ds18b20.requestTemperatures();
      bool tripped = digitalRead(gas_din) == LOW;
    
      if ( (lastmillis == 0) || (millis() >= lastmillis + 1800000) || tripped ) { //1800000 = 30 minut
        lastmillis += 1800000;
    
        send(msg_gas_binary.set(tripped ? "1" : "0"));
        delay(10);
        send(msg_gas_analog.set(analogRead(gas_ain)));
        delay(10);
        send(msg_temperature.set(ds18b20.getTempCByIndex(0), 2));
        delay(1000);
      }
    //  sleep(SLEEP_TIME);
      delay(10000);
    }
    

    Node 2:

    #include "DHT.h"          // biblioteka DHT
    #include <OneWire.h>
    #include <DallasTemperature.h>
    #include <Wire.h>
    #include <LPS.h>
    #include <NeoSWSerial.h>
    
    // pins for SoftwareSerial
    #define SDS_PIN_RX 4
    #define SDS_PIN_TX 2
    
    NeoSWSerial mySerial(SDS_PIN_RX, SDS_PIN_TX); // RX, TX
    
    
    // Enable debug prints to serial monitor
    #define MY_DEBUG
    
    // Enable RS485 transport layer
    #define MY_RS485
    
    // Define this to enables DE-pin management on defined pin
    #define MY_RS485_DE_PIN 3
    
    // Set RS485 baud rate to use
    #define MY_RS485_BAUD_RATE 9600
    
    #define MY_NODE_ID 2
    
    // Enable this if RS485 is connected to a hardware serial port
    //#define MY_RS485_HWSERIAL Serial1
    #define MY_RS485_SWSERIAL mySerial
    
    #include <MySensors.h>
    
    uint32_t SLEEP_TIME = 1800000 ; // Sleep time between reports (in milliseconds) 1800000 is 30 minutes
    //#define DIGITAL_INPUT_SENSOR 3   // The digital input you attached your motion sensor.  (Only 2 and 3 generates interrupt!)
    #define CHILD_ID_DTH_TEMP 1
    #define CHILD_ID_DTH_HUM 2
    #define CHILD_ID_DS_TEMP 3
    #define CHILD_ID_PS_TEMP 4
    #define CHILD_ID_PS_BARO 5
    
    
    
    #define DHTPIN 6       // numer pinu sygnałowego
    #define DHTTYPE DHT21     // typ czujnika (DHT11). Jesli posiadamy DHT22 wybieramy DHT22
    #define DS18B20_PIN 5
    
    
    DHT dht(DHTPIN, DHTTYPE);
    OneWire oneWire(DS18B20_PIN);
    DallasTemperature ds18b20(&oneWire);
    LPS ps;
    
    MyMessage msgDthTemp(CHILD_ID_DTH_TEMP, V_TEMP);
    MyMessage msgDthHum(CHILD_ID_DTH_HUM, V_HUM);
    MyMessage msgDsTemp(CHILD_ID_DS_TEMP, V_TEMP);
    MyMessage msgPsTemp(CHILD_ID_PS_TEMP, V_TEMP);
    MyMessage msgPsPressure(CHILD_ID_PS_BARO, V_PRESSURE);
    
    void setup()
    {
      dht.begin();
      ds18b20.begin();
    
      Wire.begin();
    
      if (!ps.init())
      {
        Serial.println("Failed to autodetect pressure sensor!");
        while (1);
      }
    
      ps.enableDefault();
    
    }
    
    void presentation()
    {
      // Send the sketch version information to the gateway and Controller
      sendSketchInfo("Weather Sensor", "1.0");
    
      // Register all sensors to gw (they will be created as child devices)
      present(CHILD_ID_DTH_TEMP, S_TEMP);
      delay(50);
      present(CHILD_ID_DTH_HUM, S_HUM);
      delay(50);
      present(CHILD_ID_DS_TEMP, S_TEMP);
      delay(50);
      present(CHILD_ID_PS_TEMP, S_TEMP);
      delay(50);
      present(CHILD_ID_PS_BARO, V_PRESSURE);
    }
    
    void loop()
    {
    
      float t = dht.readTemperature();
      float h = dht.readHumidity();
    
      // Sprawdzamy czy są odczytane wartości
      if (isnan(t) || isnan(h))
      {
        Serial.println("Blad odczytu danych z czujnika");
      } else
      {
        send(msgDthTemp.set(t, 1));
        delay(10);
        send(msgDthHum.set(h, 1));
        delay(10);
      }
      ds18b20.requestTemperatures();
      send(msgDsTemp.set(ds18b20.getTempCByIndex(0), 1));
      delay(10);
      send(msgPsTemp.set(ps.readTemperatureC(), 1));
      delay(10);
      send(msgPsPressure.set(ps.readPressureMillibars(), 1));
      delay(10);
      // Sleep until interrupt comes in on motion sensor. Send update every two minute.
      sleep(SLEEP_TIME);
    }
    

    Regards



  • @Rysiek As you are using a Pro Micro as a GW, imo the RS485 modules should be connected to Serial1 instead of Serial (which goes to USB).



  • @rejoe2 said in MySensor Network on RS485 - only single node visible:

    @Rysiek As you are using a Pro Micro as a GW, imo the RS485 modules should be connected to Serial1 instead of Serial (which goes to USB).

    Hi, well actually it is Serial1, Serial will not compile on pro Micro, I was trying to use nano as gateway, but it took no effect. the code I pasted is from that. in Pro Micro Gateway it is of course Serial1.



  • OK, so thanks for info.

    Some additional remarks:

    • using a GW also as a sensor node might cause trouble, too. I'd recommend to avoid that (though it's possible, no question). This recommendation is even stronger here, because reading DS18B20 might be blocking for short periods of time (see "conversion time").
    • That conversion time may be an additional point to look at at the GW node. Didn't do investiagations on that, but your measurement might not deliever reliable results due to lack of delay.
    • In general, I'd also recommend to use non-blocking-loops for all central powered nodes. Putting the nodes 1 and 2 to sleep or let them "delay" for longer periods might also cause trouble. Better start with "dumb" messages (e.g. send a "tripped" message every 30 seconds) to test if your problems are more on the physical communication layer or on the software/firmware side.


  • Hi,
    Thank you for your comments. it gave me a little thinking and I guess I will remove temp sensor from gateway.
    Also I will not put them into sleep... I will try to check what effect will I get when I put some nodes to sleep for that 30 minutes. (BTW what kind of trouble you have in mind?). From my perspective putting nodes to sleep will save some power. I can of course "wake" them every 30 seconds for loop or two :P.

    Anyway, I tried to do as you suggested, and find out that effect will be the same... node 2 is somehow blocking node 1 communication and when node 2 is connected node 1 is not visible.
    BUT... while testing is I have a thought of possible reason. Node 2 and the gateway are using HW serial for communication while node 1 is using software library. I've made another node on prototype board and connected it to the bus... and both node 2 and new node 3 were visible (no 1 was not). I will made PCB and try to replace node1 with HW serial communication.
    Let you know if it works.

    Regards



  • @Rysiek In general, I don't see any problem in mixing softwareserial and hardwareserial (I did that in the past, too).
    Wrt. to sleep: My entire RS485-MySensors-setup consumes ~3W (dependent on relay states), so powering down the arduinos most likely will save some power, yes; but imo that's negilable.
    What might happen when powering down: the bus might get blocked, if one of the nodes keeps bus on "high" level. I had some nasty problems wrt to that, so I make sure, there is nothing (slightly) suspective of such behaviour (additionally, I changed the RS485 Modules with CAN ones (MCP2551) - they don't need no DE/RE/interrupt, too and can be used as a drop-in-replacement. The only disadvantage: they are not PIN-compatible when using SOIC-8 variants, so you can't use most of the board designs from openhardware.io).



  • @rejoe2 Hi, Thank for description. I'm a little confused with this HW/SW serial, because I've also mixed them while building prototypes and it worked. Today I'm going to test it once again. I've already build node using HW serial and later today going to replace old one. We'll see how it will work.

    As for CAN.. well I have to read more about it, lacking compatibility with existing PCBs is not a problem, I used to build my own PCBs.



  • You should use terminating resistors on both ends. But also try to add or change resistor(10k) between A to VCC and B to GND. It's R5 and R6 on schematic.



  • @Jarosław-Narbut What do you mean by "changing resistors" as they already exists... what values do you propose??

    Anyway, when I've replace node that used SW for serial communication with HW one, the problem is gone.

    Regards
    Ryszard



  • @Rysiek said in MySensor Network on RS485 - only single node visible:

    @Jarosław-Narbut What do you mean by "changing resistors" as they already exists... what values do you propose??

    Anyway, when I've replace node that used SW for serial communication with HW one, the problem is gone.

    Regards
    Ryszard

    MAX485-Module-Sch1.jpg
    R5 and R6 change or add to 10k.

    I have 11 nodes with SW serial, 1 with HW, and GW mqtt with HW. RS485 speed set to 57600kbps.



  • @Jarosław-Narbut , thanks I will try that.



  • Having a deeper look at resistor values is always a good idea.
    Indeed, optimal values depend on a lot of parameters. You might find a helpful tool for getting the best values for your setup here: http://www.alciro.org/tools/RS-485/RS485-resistor-termination-calculator.jsp



  • Very useful topic for me, thanks. Even though it's been a long time, the information was useful to me. And especially the information on the link you sent.


Log in to reply
 

Suggested Topics

57
Online

11.4k
Users

11.1k
Topics

112.6k
Posts