Multiple sensors on one arduino, serial gateway, home assistant



  • Hi guys,

    I thought that I can extend my rpi's gpio ports with an arduino, so I plugged an arduino to one of the usb ports on the pi, and connected 2 HCSR501s, 5 DHT11s and 2 mosfets for led dimming. Because this is my first mysensors project, I have copy pasted some sketches together to control all of the sensors. Almost everything seems to be working fine, except the led dimming.
    It compiles and I can upload it to the arduino, all sensors are recognized by home assistant, but when I try to dim (or switch on) one led stripe the other does the same thing. So if I set 10% brightness on one light, the other turns on as well at 10%.
    This is the fourth or fifth version of the skecth I have now, but all seem to do the same, so maybe this is a problem with the HA mysensors integration...
    So the question is: Can anyone see the problem with my sketch?

    thanks
    tom

    #define MY_GATEWAY_SERIAL
    
    #include <SPI.h>
    #include <MySensors.h> 
    #include <DHT.h>
    
    #define SN "LivingRoom"
    #define SV "1.3"
    
    //Only pins 2 and 3 can be used as motion sensors, because these generate interrupts
    #define PIN_HCSR501_1 2
    #define PIN_HCSR501_2 3
    #define CHILD_ID_HCSR501_1 2
    #define CHILD_ID_HCSR501_2 3
    
    //DHTs
    #define PIN_DHT_1 4
    #define PIN_DHT_2 5
    #define PIN_DHT_3 6
    #define PIN_DHT_4 7
    #define PIN_DHT_5 8
    #define CHILD_ID_DHT_TEMP_1 4
    #define CHILD_ID_DHT_TEMP_2 5
    #define CHILD_ID_DHT_TEMP_3 6
    #define CHILD_ID_DHT_TEMP_4 7
    #define CHILD_ID_DHT_TEMP_5 8
    #define CHILD_ID_DHT_HUM_1 14
    #define CHILD_ID_DHT_HUM_2 15
    #define CHILD_ID_DHT_HUM_3 16
    #define CHILD_ID_DHT_HUM_4 17
    #define CHILD_ID_DHT_HUM_5 18
    
    #define PIN_LED_1 9
    #define PIN_LED_2 10
    #define CHILD_ID_LED_1 9
    #define CHILD_ID_LED_2 10
    #define FADE_DELAY 20  // Delay in ms for each percentage fade up/down (10ms = 1s full-range dim)
    int WaitTime = 50;
    static int16_t currentLevel = 0;
    static int16_t currentLevel2 = 0;
    int requestedLevel;
    int requestedLevel2;
    
    bool metric = true;
    // Must be >1000ms for DHT22 and >2000ms for DHT11
    static const uint64_t UPDATE_INTERVAL = 60000;
    static bool first_message_sent = false;
    
    
    
    MyMessage dimmerMsg1(CHILD_ID_LED_1, V_DIMMER);
    MyMessage lightMsg1(CHILD_ID_LED_1, V_LIGHT);
    MyMessage dimmerMsg2(CHILD_ID_LED_2, V_DIMMER);
    MyMessage lightMsg2(CHILD_ID_LED_2, V_LIGHT);
    
    MyMessage tempMsg1(CHILD_ID_DHT_TEMP_1, V_TEMP); //Dishwasher
    MyMessage tempMsg2(CHILD_ID_DHT_TEMP_2, V_TEMP); //LR door
    MyMessage tempMsg3(CHILD_ID_DHT_TEMP_3, V_TEMP); //Oven
    MyMessage tempMsg4(CHILD_ID_DHT_TEMP_4, V_TEMP); //Room2
    MyMessage tempMsg5(CHILD_ID_DHT_TEMP_5, V_TEMP); //LR window
    MyMessage humMsg1(CHILD_ID_DHT_HUM_1, V_HUM);
    MyMessage humMsg2(CHILD_ID_DHT_HUM_2, V_HUM);
    MyMessage humMsg3(CHILD_ID_DHT_HUM_3, V_HUM);
    MyMessage humMsg4(CHILD_ID_DHT_HUM_4, V_HUM);
    MyMessage humMsg5(CHILD_ID_DHT_HUM_5, V_HUM);
    
    MyMessage moveMsg1(CHILD_ID_HCSR501_1, V_TRIPPED); //Kitchen movement
    MyMessage moveMsg2(CHILD_ID_HCSR501_2, V_TRIPPED); //LR movement
    //MyMessage moveMsg1a(CHILD_ID_HCSR501_1, V_ARMED);
    //MyMessage moveMsg2a(CHILD_ID_HCSR501_2, V_ARMED);
    
    DHT dht1;
    DHT dht2;
    DHT dht3;
    DHT dht4;
    DHT dht5;
    
    void before() {
      pinMode(PIN_HCSR501_1, INPUT);
      pinMode(PIN_HCSR501_2, INPUT);
      
      pinMode(PIN_LED_1, OUTPUT);
      pinMode(PIN_LED_2, OUTPUT);
    }
    
    void setup()  
    { 
      dht1.setup(PIN_DHT_1);
      dht2.setup(PIN_DHT_2);
      dht3.setup(PIN_DHT_3);
      dht4.setup(PIN_DHT_4);
      dht5.setup(PIN_DHT_5);
      request(CHILD_ID_LED_1, V_DIMMER);
      request(CHILD_ID_LED_2, V_DIMMER);
    }
    
    void presentation() {
      sendSketchInfo(SN, SV);
      present(CHILD_ID_HCSR501_1, S_MOTION);
      wait(WaitTime);
      present(CHILD_ID_HCSR501_2, S_MOTION);
      wait(WaitTime);
      present(CHILD_ID_DHT_TEMP_1, S_TEMP);
      wait(WaitTime);
      present(CHILD_ID_DHT_TEMP_2, S_TEMP);
      wait(WaitTime);
      present(CHILD_ID_DHT_TEMP_3, S_TEMP);
      wait(WaitTime);
      present(CHILD_ID_DHT_TEMP_4, S_TEMP);
      wait(WaitTime);
      present(CHILD_ID_DHT_TEMP_5, S_TEMP);
      wait(WaitTime);
      present(CHILD_ID_DHT_HUM_1, S_HUM);
      wait(WaitTime);
      present(CHILD_ID_DHT_HUM_2, S_HUM);
      wait(WaitTime);
      present(CHILD_ID_DHT_HUM_3, S_HUM);
      wait(WaitTime);
      present(CHILD_ID_DHT_HUM_4, S_HUM);
      wait(WaitTime);
      present(CHILD_ID_DHT_HUM_5, S_HUM);
      wait(WaitTime);
      present(CHILD_ID_LED_1, S_DIMMER);
      wait(WaitTime);
      present(CHILD_ID_LED_2, S_DIMMER);
      wait(WaitTime);
    }
    
    void loop() {
      dht1.readSensor(true);
      dht2.readSensor(true);
      dht3.readSensor(true);
      dht4.readSensor(true);
      dht5.readSensor(true);
      //
      float temperature1 = dht1.getTemperature();
      float humidity1 = dht1.getHumidity();
      
      float temperature2 = dht2.getTemperature();
      float humidity2 = dht2.getHumidity();
      
      float temperature3 = dht3.getTemperature();
      float humidity3 = dht3.getHumidity();
      
      float temperature4 = dht4.getTemperature();
      float humidity4 = dht4.getHumidity();
      
      float temperature5 = dht5.getTemperature();
      float humidity5 = dht5.getHumidity();
      //
      send(tempMsg1.set(temperature1, 1));
      send(humMsg1.set(humidity1, 1));
      
      send(tempMsg2.set(temperature2, 1));
      send(humMsg2.set(humidity2, 1));
      
      send(tempMsg3.set(temperature3, 1));
      send(humMsg3.set(humidity3, 1));
      
      send(tempMsg4.set(temperature4, 1));
      send(humMsg4.set(humidity4, 1));
      
      send(tempMsg5.set(temperature5, 1));
      send(humMsg5.set(humidity5, 1));
        
      int tripped1 = digitalRead(PIN_HCSR501_1) == HIGH;
      int tripped2 = digitalRead(PIN_HCSR501_2) == HIGH;
      send(moveMsg1.set(tripped1? 1 : 0));
      //send(moveMsg1a.set(1));
      send(moveMsg2.set(tripped2? 1 : 0));
      //send(moveMsg2a.set(1));
    
      if ( first_message_sent == false ) {
        send(lightMsg1.set(currentLevel > 0));
        send(dimmerMsg1.set(currentLevel));
        send(lightMsg2.set(currentLevel2 > 0));
        send(dimmerMsg2.set(currentLevel2));
        first_message_sent = true;
      }
    
      wait(UPDATE_INTERVAL);
    }
    
    
    
    void receive(const MyMessage &message) {
      if (message.type == V_LIGHT || message.type == V_DIMMER) {
            
              if ((message.sensor == CHILD_ID_LED_1) || (message.sensor == 0)) {
                requestedLevel = atoi( message.data );
                // Adjust incoming level if this is a V_LIGHT variable update [0 == off, 1 == on]
                requestedLevel *= ( message.type == V_LIGHT ? 0 : 1 );
                requestedLevel = requestedLevel > 100 ? 100 : requestedLevel;
                requestedLevel = requestedLevel < 0   ? 0   : requestedLevel;
                
                int delta = ( requestedLevel - currentLevel ) < 0 ? -1 : 1;
                while ( currentLevel != requestedLevel ) {
                        currentLevel += delta;
                        analogWrite( PIN_LED_1, (int)(currentLevel / 100. * 255) );
                        delay( FADE_DELAY );
                }
                
                send(lightMsg1.set(currentLevel > 0));
                send( dimmerMsg1.set(currentLevel) );
              }
              if ((message.sensor == CHILD_ID_LED_2) || (message.sensor == 0)) {
                requestedLevel2 = atoi( message.data );
                // Adjust incoming level if this is a V_LIGHT variable update [0 == off, 1 == on]
                requestedLevel2 *= ( message.type == V_LIGHT ? 0 : 1 );
                requestedLevel2 = requestedLevel2 > 100 ? 100 : requestedLevel2;
                requestedLevel2 = requestedLevel2 < 0   ? 0   : requestedLevel2;
                
                int delta2 = ( requestedLevel2 - currentLevel2 ) < 0 ? -1 : 1;
                while ( currentLevel2 != requestedLevel2 ) {
                        currentLevel2 += delta2;
                        analogWrite( PIN_LED_2, (int)(currentLevel2 / 100. * 255) );
                        delay( FADE_DELAY );
                }
                
                send(lightMsg2.set(currentLevel2 > 0));
                send( dimmerMsg2.set(currentLevel2) );
              }
            }
       }
    

  • Mod

    @towme the sketch looks fine to me, except maybe that using sendor=0 would result in the behavior you describe.

    Debug output from the node would be your best next step.



  • Yeah, but don't really know howto solve that.
    The arduino is plugged in to the usb port of the rpi, I have no radio whatsoever. So I remove all the serialprint lines from sketches, because they cause error messages in HA. (which seems logical because debug messages are not sensor messages)
    Forgot to mention the things I have already tried.
    I have started off with this sketch: https://www.mysensors.org/build/dimmer
    (It works fine with one led. either of the leds)

    Then I modified the above sketch with adding LedPin to the fadelevel function. That resulted in some strange working because I could switch the leds on and off, but the dimming worked on only one led.

    Then I thought I use the switch/case option, but that results the same problem that I am in now.

    Then I have duplicated everything. Made a fadelevel2 function, with requestedlevel2, tolevel2, and so on. Same result again.

    I am starting to think that there is a strange limitation in the arduino that I am not aware of. Like the motion sensors can only be hooked up to pins 2 and 3, so maybe the 9 and 10 pins are not that kind of pwm like the others. (I know it sounds dumb 🙂 )

    I will try to separate the leds "far" from each other, so use pin 9 for one and 5 fo the other.
    (This is an arduino uno btw.)



  • Had some time to troubleshoot my setup, and it turns out that my problem has nothing to do with mysensors.... 🙂
    As usual it was a user error.
    I have put both of the mosfets on the same cooler and the middle pins (drain) got in contact throught the screw that held the mostfet to the cooler.
    Separated the coolers and voila everything works
    Yeah!


  • Mod

    @towme great that you found the problem. Thanks for reporting back. I could easily have done the same thing, now I know that I shouldn't 🙂


 

321
Online

7.7k
Users

8.6k
Topics

92.3k
Posts