Skip to content
  • OpenHardware.io
  • Categories
  • Recent
  • Tags
  • Popular
Skins
  • Light
  • Brite
  • Cerulean
  • Cosmo
  • Flatly
  • Journal
  • Litera
  • Lumen
  • Lux
  • Materia
  • Minty
  • Morph
  • Pulse
  • Sandstone
  • Simplex
  • Sketchy
  • Spacelab
  • United
  • Yeti
  • Zephyr
  • Dark
  • Cyborg
  • Darkly
  • Quartz
  • Slate
  • Solar
  • Superhero
  • Vapor

  • Default (No Skin)
  • No Skin
Collapse
Brand Logo
  1. Home
  2. Troubleshooting
  3. Adding 4th dimmer. Struggle.
  • Getting Started
  • Controller
  • Build
  • Hardware
  • Download/API
  • Forum
  • Store

Adding 4th dimmer. Struggle.

Scheduled Pinned Locked Moved Troubleshooting
9 Posts 4 Posters 2.6k Views 3 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • M Offline
    M Offline
    moskovskiy82
    wrote on last edited by
    #1

    Had a code which was working for a long time. Decided to add another dimmer. And now having hard time. Seems to work light switches on - then never goes off. One dimmer is on 100% of the time. Any help much appreciated. Added comments on changed lines //ADDED
    Guess screwed up with currentLevel but not sure

    #define SN "MYS Kitchen Hood"
    #define SV "2.1"
    
    //System settings
    #define MY_RADIO_NRF24
    #define MY_RF24_CE_PIN 8 //ADDED
    
    
    // Include all the libraries
    #include <MySensors.h> 
    #include <SPI.h>
    #include <DHT.h> 
    #include <math.h>
    #include <Wire.h>
    #include <Bounce2.h>
    
    #define MY_NODE_ID 71
    
    //DEFINE CHILD_IDS
    #define DIMMER_NODE_1 0
    #define DIMMER_NODE_2 1
    #define DIMMER_NODE_3 2
    #define DIMMER_NODE_4 3 //ADDED
    #define CHILD_ID_HUM 4
    #define CHILD_ID_TEMP 5
    #define CHILD_ID_MQ 6
    #define CHILD_BUT1 7
    #define CHILD_BUT2 8
    #define CHILD_BUT3 9
    #define CHILD_BUT4 10
    //BUTTONS
    #define BUTTON_PIN1  A0
    #define BUTTON_PIN2  A1
    #define BUTTON_PIN3  A2
    #define BUTTON_PIN4  A3
    //SENSORS
    #define DHT_PIN 8
    const int MQ_Pin = A4;
    //DIMMER
    #define LED_PIN_1 3
    #define LED_PIN_2 5
    #define LED_PIN_3 6
    #define LED_PIN_4 9 //ADDED
    #define FADE_DELAY 5
    
    DHT dht;
    
    //BUTTONS
    Bounce debouncer_1 = Bounce(); 
    Bounce debouncer_2 = Bounce();
    Bounce debouncer_3 = Bounce();
    Bounce debouncer_4 = Bounce();
    int oldValue_1=-1;
    int oldValue_2=-1;
    int oldValue_3=-1;
    int oldValue_4=-1;
    bool state1;
    bool state2;
    bool state3;
    bool state4;
    MyMessage msgbut1(CHILD_BUT1,V_STATUS);
    MyMessage msgbut2(CHILD_BUT2,V_STATUS);
    MyMessage msgbut3(CHILD_BUT3,V_STATUS);
    MyMessage msgbut4(CHILD_BUT4,V_STATUS);
    //SENSORS
    float lastTemp;
    float lastHum;
    float hum_floa;
    float last_mq_reading;
    long Millis = 0;
    long Millis_interval = 30000;
    MyMessage msgHum(CHILD_ID_HUM, V_HUM);
    MyMessage msgTemp(CHILD_ID_TEMP, V_TEMP);
    MyMessage msgMQ(CHILD_ID_MQ, V_LEVEL);
    //DIMMER
    //byte currentLevel[3] = {0,0,0};
    byte currentLevel[4] = {0,0,0,0}; //added
    MyMessage dimmerMsg0(0, V_PERCENTAGE);
    MyMessage lightMsg0(0, V_STATUS);
    MyMessage dimmerMsg1(1, V_PERCENTAGE);
    MyMessage lightMsg1(1, V_STATUS);
    MyMessage dimmerMsg2(2, V_PERCENTAGE);
    MyMessage lightMsg2(2, V_STATUS);
    MyMessage dimmerMsg3(3, V_PERCENTAGE); //ADDED
    MyMessage lightMsg2(3, V_STATUS); //ADDED
    
    void before() 
    {
      dht.setup(DHT_PIN);
      analogWrite( LED_PIN_1, 0); 
      analogWrite( LED_PIN_2, 0);
      analogWrite( LED_PIN_3, 0);
      analogWrite( LED_PIN_4, 0); //ADDED
      pinMode(BUTTON_PIN1,INPUT);
      digitalWrite(BUTTON_PIN1, HIGH);
      pinMode(BUTTON_PIN2,INPUT);
      digitalWrite(BUTTON_PIN2, HIGH);
      pinMode(BUTTON_PIN3,INPUT);
      digitalWrite(BUTTON_PIN3, HIGH);
      pinMode(BUTTON_PIN4,INPUT);
      digitalWrite(BUTTON_PIN4, HIGH);
      debouncer_1.attach(BUTTON_PIN1);
      debouncer_1.interval(5);
      debouncer_2.attach(BUTTON_PIN2);
      debouncer_2.interval(5);
      debouncer_3.attach(BUTTON_PIN3);
      debouncer_3.interval(5);
      debouncer_4.attach(BUTTON_PIN4);
      debouncer_4.interval(5);
    }
    void setup() 
    { }
    
    void presentation()  
    { 
      sendSketchInfo(SN, SV);
      present(CHILD_ID_HUM, S_HUM);
      present(CHILD_ID_TEMP, S_TEMP);
      present(CHILD_ID_MQ, S_AIR_QUALITY);  
    
      present( DIMMER_NODE_1, S_DIMMER );
      send(dimmerMsg0.set(0));
      present( DIMMER_NODE_2, S_DIMMER );
      send(dimmerMsg1.set(0));
      present( DIMMER_NODE_3, S_DIMMER );
      send(dimmerMsg2.set(0));
      present( DIMMER_NODE_4, S_DIMMER ); //ADDED
      send(dimmerMsg3.set(0)); //ADDED
      present(CHILD_BUT1, S_BINARY);
      present(CHILD_BUT2, S_BINARY);
      present(CHILD_BUT3, S_BINARY);
      present(CHILD_BUT4, S_BINARY);
    }
    
    void loop() 
    {
      int value_but_1 = debouncer_1.read();
      int value_but_2 = debouncer_2.read();
      int value_but_3 = debouncer_3.read();
      int value_but_4 = debouncer_4.read(); 
    //DHT+MQ
    unsigned long Current_Millis = millis();
    if((unsigned long)(Current_Millis - Millis) >= Millis_interval)
      {
      Millis = Current_Millis; 
      delay(dht.getMinimumSamplingPeriod());
      float temperature = dht.getTemperature();
      float humidity = dht.getHumidity();
      float mq_reading = analogRead(MQ_Pin);
        
        if (isnan(temperature)) 
          {Serial.println("Failed reading temperature from DHT");} 
        if (isnan(humidity)) 
          {Serial.println("Failed reading humidity from DHT");} 
        if (isnan(mq_reading)) 
          { Serial.println("Failed mq_reading"); } 
    
        else 
        {
          send(msgTemp.set(temperature, 1));
          send(msgHum.set(humidity, 1));
          send(msgMQ.set(mq_reading, 1));
        }
      }
    //BUTTONS
      debouncer_1.update();
      if (value_but_1 != oldValue_1) 
      { 
      if ( value_but_1==0)
        {
        state1 = !state1;
        send(msgbut1.set(state1));
        }
      oldValue_1 = value_but_1;
      }
      debouncer_2.update();
      if (value_but_2 != oldValue_2) 
      { 
      if ( value_but_2==0)
        {
        state2 = !state2;
        send(msgbut2.set(state2));
        }
      oldValue_2 = value_but_2;
      }
      debouncer_3.update();
      if (value_but_3 != oldValue_3) 
      { 
        if ( value_but_3==0)
        {
        state3 = !state3;
        send(msgbut3.set(state3));
        }
      oldValue_3 = value_but_3;
      }
      debouncer_4.update();
      if (value_but_4 != oldValue_4) 
      { 
        if ( value_but_4==0)
        {
        state4 = !state4;
        send(msgbut4.set(state4));
        }
      oldValue_4 = value_but_4;
      }
    }
    //DIMMER
    void receive(const MyMessage &message) 
    {
      if (message.type == V_STATUS || message.type == V_PERCENTAGE)
      {
        int requestedLevel = atoi( message.data );
        requestedLevel *= ( message.type == V_STATUS ? 100 : 1 );
        requestedLevel = requestedLevel > 100 ? 100 : requestedLevel;
        requestedLevel = requestedLevel < 0   ? 0   : requestedLevel;
        fadeToLevel( requestedLevel, message.sensor);
          switch(message.sensor)
        {
        case 0:
          send(lightMsg0.set(currentLevel[0] > 0 ? 1 : 0));
          send( dimmerMsg0.set(currentLevel[0]) );
        break;
        case 1:
          send(lightMsg1.set(currentLevel[1] > 0 ? 1 : 0));
          send( dimmerMsg1.set(currentLevel[1]) );
        break;
        case 2:
          send(lightMsg2.set(currentLevel[2] > 0 ? 1 : 0));
          send( dimmerMsg2.set(currentLevel[2]) );
        break; 
        //ADDED CASE 3
        case 3:
          send(lightMsg3.set(currentLevel[3] > 0 ? 1 : 0));
          send( dimmerMsg3.set(currentLevel[3]) );
        break;  
        }
        }
    }
    void fadeToLevel( int toLevel, byte sensorId ) 
    {
      int delta = ( toLevel - currentLevel[sensorId] ) < 0 ? -1 : 1;
      while ( currentLevel[sensorId] != toLevel )
      {
        currentLevel[sensorId] += delta;
        switch(sensorId)
        {
        case 0:
          analogWrite( LED_PIN_1, (int)(currentLevel[sensorId] / 100. * 255) );
        break;
        case 1:
          analogWrite( LED_PIN_2, (int)(currentLevel[sensorId] / 100. * 255) );  
        break;
        case 2:
          analogWrite( LED_PIN_3, (int)(currentLevel[sensorId] / 100. * 255) );
        break; 
        //ADDED CASE3
        case 3:
          analogWrite( LED_PIN_4, (int)(currentLevel[sensorId] / 100. * 255) );
        break;           
        }
      delay( FADE_DELAY );
      }
    }
    
    1 Reply Last reply
    0
    • BulldogLowellB Offline
      BulldogLowellB Offline
      BulldogLowell
      Contest Winner
      wrote on last edited by
      #2

      Its probably a good time to start learning about arrays.

      M 1 Reply Last reply
      0
      • BulldogLowellB BulldogLowell

        Its probably a good time to start learning about arrays.

        M Offline
        M Offline
        moskovskiy82
        wrote on last edited by
        #3

        @BulldogLowell Read about them. But still seems i address the array correctly. Or i'm wrong?

        BulldogLowellB 1 Reply Last reply
        0
        • M moskovskiy82

          @BulldogLowell Read about them. But still seems i address the array correctly. Or i'm wrong?

          BulldogLowellB Offline
          BulldogLowellB Offline
          BulldogLowell
          Contest Winner
          wrote on last edited by
          #4

          @moskovskiy82

          Sorry, I meant that your code could be extremely simplified by using arrays.

          Yours is a good example of how it is much harder to refactor in the case (like yours) where you simply need to add one more of some object.

          things like this can be problematic:

          #define DIMMER_NODE_1 0
          #define DIMMER_NODE_2 1
          #define DIMMER_NODE_3 2
          #define DIMMER_NODE_4 3 //ADDED
          

          where 1 = 0, 2 = 1, etc.... it is not very intuitive

          I cannot find the problem in your code... are you sure you are wired up correctly?

          1 Reply Last reply
          1
          • M Offline
            M Offline
            moskovskiy82
            wrote on last edited by
            #5

            Well after much trial and error - seems that pin5 is behaving erratically. Don't know why. Rewired to an external dimmer board. Changed arduinos. Nothing helps which is extremly strange

            rejoe2R 1 Reply Last reply
            0
            • V Offline
              V Offline
              vikasjee
              wrote on last edited by
              #6

              Just out of curiosity, Is there a standard dimmer module you are using or is it custom made?

              Hope you have checked the current being supplied since that is limited. The current (signal) amplifier configuration on the dimmer module may be an issue if not designed for low current signals (especially if there are multiple parts attached to the same arduino).

              1 Reply Last reply
              0
              • M moskovskiy82

                Well after much trial and error - seems that pin5 is behaving erratically. Don't know why. Rewired to an external dimmer board. Changed arduinos. Nothing helps which is extremly strange

                rejoe2R Offline
                rejoe2R Offline
                rejoe2
                wrote on last edited by
                #7

                @moskovskiy82 You may at least have to chang this:

                MyMessage lightMsg2(2, V_STATUS);
                MyMessage dimmerMsg3(3, V_PERCENTAGE); //ADDED
                MyMessage lightMsg2(3, V_STATUS); //ADDED
                

                The second imo should be lightMsg3...

                I completely agree with @BulldogLowell : Better use arrays for nodes like yours. Good example: https://forum.mysensors.org/topic/4847/multi-button-relay-sketch/33#

                Controller: FHEM; MySensors: 2.3.1, RS485,nRF24,RFM69, serial Gateways

                BulldogLowellB 1 Reply Last reply
                1
                • rejoe2R rejoe2

                  @moskovskiy82 You may at least have to chang this:

                  MyMessage lightMsg2(2, V_STATUS);
                  MyMessage dimmerMsg3(3, V_PERCENTAGE); //ADDED
                  MyMessage lightMsg2(3, V_STATUS); //ADDED
                  

                  The second imo should be lightMsg3...

                  I completely agree with @BulldogLowell : Better use arrays for nodes like yours. Good example: https://forum.mysensors.org/topic/4847/multi-button-relay-sketch/33#

                  BulldogLowellB Offline
                  BulldogLowellB Offline
                  BulldogLowell
                  Contest Winner
                  wrote on last edited by
                  #8

                  @rejoe2 said in Adding 4th dimmer. Struggle.:

                  I completely agree with @BulldogLowell : Better use arrays for nodes like yours. Good example: https://forum.mysensors.org/topic/4847/multi-button-relay-sketch/33#

                  and I don't like the blocking nature of the fading. that should be refactored.

                  plus, the fyi the Bounce2 library has another constructor which sets pinMode...
                  instead of this:

                    pinMode(BUTTON_PIN1,INPUT);
                    digitalWrite(BUTTON_PIN1, HIGH);
                  
                  //...
                  debouncer_1.attach(BUTTON_PIN1);
                    debouncer_1.interval(5);
                  

                  just this:

                  debouncer_1.attach(BUTTON_PIN1, INPUT_PULLUP);
                  debouncer_1.interval(5);
                  

                  i'll post an alternative if I get the chance...

                  1 Reply Last reply
                  1
                  • BulldogLowellB Offline
                    BulldogLowellB Offline
                    BulldogLowell
                    Contest Winner
                    wrote on last edited by
                    #9

                    I can't test this but something like:

                    #define SN "Four Fader Test"
                    #define SV "0.1a"
                    
                    #define NUMBER_OF_DIMMERS 4
                    
                    //System settings
                    #define MY_RADIO_NRF24
                    #define MY_RF24_CE_PIN 8 //ADDED
                    #define MY_NODE_ID 71
                    
                    #include <MySensors.h>
                    #include <SPI.h>
                    #include "Fade.h"
                    
                    MyMessage dimmer[NUMBER_OF_DIMMERS];
                    MyMessage light[NUMBER_OF_DIMMERS];
                    
                    Fade fader[NUMBER_OF_DIMMERS];
                    byte leds[NUMBER_OF_DIMMERS] = {3, 5, 6, 9};
                    
                    void before()
                    {
                      int i = 0;
                      for (auto fdr : fader)
                      {
                        fdr = Fade(leds[i++], 10, 0, 255, MILLIS_TIMER); // led speed 5 milliseconds/step; pwm at 0 min and 255 max  (MILLIS_TIMER)
                        fdr.begin();
                      }
                      i = 0;
                      for (auto msg : dimmer)
                        msg = MyMessage(i++, S_DIMMER);
                      i = 0;
                      for (auto msg : light)
                        msg = MyMessage(i++, S_BINARY);
                    }
                    void presentation()
                    {
                      sendSketchInfo(SN, SV);
                      int i = 0;
                      for (auto d : dimmer)
                        present(i++, S_DIMMER);
                    }
                    
                    void setup()
                    {
                      Serial.begin(9600);
                      Serial.println(F("Setup Complete..."));
                    }
                    
                    void loop()
                    {
                      uint32_t currentMillis = millis();
                      for (auto fdr : fader)
                        fdr.update(currentMillis);
                    }
                    
                    void receive(const MyMessage &message)
                    {
                      if (message.type == V_STATUS || message.type == V_PERCENTAGE)
                      {
                        int requestedLevel = atoi(message.data);
                        if (message.type == V_STATUS)
                          requestedLevel = requestedLevel ? 100 : 0;
                        else
                          requestedLevel = constrain(requestedLevel, 0, 100);
                        fader[message.sensor].setTarget(map(requestedLevel, 0, 100, 0, 255));
                        send(light[message.sensor].set(requestedLevel > 0 ? 1 : 0));
                        send(dimmer[message.sensor].set(requestedLevel));
                      }
                    }
                    

                    I used my non-blocking Fade.h:

                    #ifndef Fade_h
                    #define Fade_h
                    
                    #include <Arduino.h>
                    
                    enum timer{
                      MILLIS_TIMER, 
                      MICROS_TIMER
                    };
                    
                    class Fade
                    {
                      public:
                        Fade() {};
                        Fade(int pin, uint32_t timeStep = 15, uint8_t minVal = 0, uint8_t maxVal = 255, timer timerSelect = MILLIS_TIMER);
                        void begin(); 
                        void setTarget(int to);
                        void update();
                        void update(uint32_t time);
                        uint8_t getMin();
                        uint8_t getMax();
                        uint8_t getCurrent();
                        uint32_t readSpeed();
                        uint32_t writeSpeed(uint32_t time);
                        uint8_t getSetpoint();
                      private:
                        uint8_t _min;
                        uint8_t _max;
                        uint8_t _targetFade;
                        uint8_t _pwmRate;
                        uint32_t _time;
                        uint32_t _last;
                        uint8_t _pin;
                        bool _microsTimer;
                    };
                    
                    #endif
                    

                    and my Fade.cpp:

                    
                    #include "Fade.h"
                    #include <Arduino.h>
                    
                    Fade::Fade(int pin, uint32_t timeStep, uint8_t minVal, uint8_t maxVal, timer timerSelect)
                    {
                      _pin = pin;
                      _time = timeStep;
                      _min = minVal;
                      _max = maxVal;
                      analogWrite(_pin, _min);
                      _pwmRate = _min;
                      _microsTimer = timerSelect;
                    }
                    
                    void Fade::begin()
                    {
                      analogWrite(_pin, _min);
                    }
                    
                    void Fade::setTarget(int to)
                    {
                      _targetFade = (uint8_t) constrain(to, _min, _max);
                    
                      this->update();
                    }
                    
                    void Fade::update()
                    {
                      this->update(_microsTimer? micros() : millis());
                    }
                    
                    void Fade::update(uint32_t time)
                    {
                      if (time - _time > _last)
                      {
                        _last = time;
                        if (_pwmRate > _targetFade) analogWrite(_pin, --_pwmRate);
                        if (_pwmRate < _targetFade) analogWrite(_pin, ++_pwmRate);
                      }
                    }
                    
                    uint8_t Fade::getSetpoint()
                    {
                      return _targetFade;
                    }
                    
                    uint8_t Fade::getCurrent()
                    {
                      return _pwmRate;
                    }
                    
                    uint32_t Fade::readSpeed()
                    {
                      return _time;
                    }
                    
                    uint32_t Fade::writeSpeed(uint32_t time)
                    {
                      _time = time;
                    }
                    
                    uint8_t Fade::getMin()
                    {
                      return _min;
                    }
                    
                    uint8_t Fade::getMax()
                    {
                      return _max;
                    }
                    
                    
                    1 Reply Last reply
                    0
                    Reply
                    • Reply as topic
                    Log in to reply
                    • Oldest to Newest
                    • Newest to Oldest
                    • Most Votes


                    3

                    Online

                    11.7k

                    Users

                    11.2k

                    Topics

                    113.0k

                    Posts


                    Copyright 2019 TBD   |   Forum Guidelines   |   Privacy Policy   |   Terms of Service
                    • Login

                    • Don't have an account? Register

                    • Login or register to search.
                    • First post
                      Last post
                    0
                    • OpenHardware.io
                    • Categories
                    • Recent
                    • Tags
                    • Popular