Navigation

    • Register
    • Login
    • OpenHardware.io
    • Categories
    • Recent
    • Tags
    • Popular
    1. Home
    2. jaszczomb
    • Profile
    • Following
    • Followers
    • Topics
    • Posts
    • Best
    • Groups

    jaszczomb

    @jaszczomb

    0
    Reputation
    1
    Posts
    148
    Profile views
    0
    Followers
    0
    Following
    Joined Last Online

    jaszczomb Follow

    Best posts made by jaszczomb

    This user hasn't posted anything yet.

    Latest posts made by jaszczomb

    • Dimmer problem (value changes by the sensor)

      Hi
      I have a problem with Dimmer updated by “sensor” rotary encoder from Mysensors gateway.

      Project:
      The Rotary encoder updates the dimmer by a value in the domoticz, then by the script or group other dimmers are updated with the same value (rotary encoder).

      What works:
      Dimmer is successfully updated by (sensor) mysensors gateway, I see visually that value bar is moving and setup on correct value, but…

      Does not works:
      ...that's it, nothing changes on other dimmers, like rotary was set up with value but not trigger, no actions are made. In the dimmer log tab, I can see when dimmer from the dashboard is setup (set up: specific value ) and linked dimmers are updated too, but when the main dimmer is updated by rotary encoder there is only “ON’ word and linked dimmers do not receive any data.

      This is a bug? Wrong Arduino script? Or do I have to do additional actions in domoticz? :?

      // ========================================================
      // INCLUDES
      // ========================================================
      #define MY_GATEWAY_SERIAL
      #define MY_DEBUG
      // for display
      #include <Arduino.h>
      #include <Wire.h>
      #include <U8g2lib.h>
      #include <MySensors.h>
      // for timer
      #include <TimerOne.h>
      // for rotary encoder
      #include <Rotary.h>
      
      // ========================================================
      // DEBUG
      // ========================================================
      
      
      //=========================================================
      //sciemniacz
      //=======================================================
      #define FADE_DELAY 10              // Delay in ms for each percentage fade up/down (10ms = 1s full-range dim)
      #define SEND_THROTTLE_DELAY 400    // Number of milliseconds before sending after user stops turning knob 
      #define SN "DimmableLED 2"
      #define SV "1"
      #define EEPROM_DIM_LEVEL_LAST 1
      #define EEPROM_DIM_LEVEL_SAVE 2
      #define LIGHT_OFF 0
      #define LIGHT_ON 1
      int dimValue;
      int fadeTo;
      int fadeDelta;
      byte oldButtonVal;
      bool changedByKnob=false;
      bool sendDimValue=false;
      unsigned long lastFadeStep;
      unsigned long sendDimTimeout;
      char convBuffer[10];
      #define LED_PIN 7           // Arduino pin attached to MOSFET Gate pin
      MyMessage dimmer_msg(1, V_PERCENTAGE);
      MyMessage light_msg(1, V_STATUS);
      MyMessage dimmerinp(8, V_PERCENTAGE);
      MyMessage lightinp(8, V_STATUS);
      static int16_t currentLevel = 0;  // Current dim level...
      #define LIGHT_OFF 0
      #define LIGHT_ON 1
      int16_t last_state = LIGHT_ON;
      int16_t last_dim = 100;
      int16_t dupa = 10;
      // ========================================================
      // DEFAULTS
      // ========================================================
      
      #define VERSION_TITLE "OLED MENU PAGES"
      #define VERSION_HW "Corridor 2 Rev. B"
      #define VERSION_SUBTITLE "by @schlueri 2017"
      #define VERSION "0.32B"
      
      // Status LED
      #define STATUS_LED_PIN 9
      bool statusLedOn = false;
      
      // Timer
      #define TIMER 1000
      
      // Display and menu stuff
      int displayCurrentPage = 0;
      bool setNeedsDisplay = false;
      
      // Main menu fixed to 3 items, left, center, right...
      #define MENU_SELECTED_TIMEOUT 4000
      #define MENU_POS_Y 62
      #define MENU_POS_Y_HIDDEN 76
      #define MENU_ANIMATION_PIXEL_STEP 2
      String menuItems[3] = {"MAIN", "NETWORK", "SETUP"};
      int menuActive = 1;             // left active
      int menuSelected = menuActive;  // selected
      bool menuPageMode = true;      // true => rotary encoder control page and not menu
      
      // Menu animation
      bool menuAnimationRunning = true;
      int menuPosY = MENU_POS_Y;
      
      // Rotary encoder with switch
      #define ROTARY_SWITCH 5  // A1
      #define ROTARY_PIN1 2
      #define ROTARY_PIN2 3
      #define ROTARY_ACCEL_OFFSET1 20
      #define ROTARY_ACCEL_OFFSET2 50
      #define ROTARY_ACCEL_OFFSET3 70
      unsigned long rotaryLastMove;
      bool rotaryButtonPressed = false;
      
      
      // Test slider
      int sliderPosX = 64;
      
      // Logic
      long int heartbeat = 0;
      #define HEARTBEAT_TRIGGER 1000
      #define HEARTBEAT_TRIGGER_TIME 50
      
      // ========================================================
      // PAGES STUFF
      // ========================================================
      
      #define SETUP_MENU_ITEMS 8
      String setupMenuItems[SETUP_MENU_ITEMS] = {"EXIT", "LDR LEVEL", "LDR THRESHOLD", "PIR SENSOR", "LED COLOR", "LED ANIMATION", "LED OUT TEST", "VERSION & INFO"};
      int setupMenuSelected = 0;
      
      // ========================================================
      // INITS
      // ========================================================
      
      // Display
      U8G2_SH1106_128X64_NONAME_F_HW_I2C u8g2(U8G2_R0, /* reset=*/ U8X8_PIN_NONE);
      // Rotary Encoder
      Rotary rotary = Rotary(ROTARY_PIN1, ROTARY_PIN2);
      
      // ========================================================
      // SETUP
      // ========================================================
       
      void setup()
      {
        // put your setup code here, to run once:
      
        // Status LED
        pinMode(STATUS_LED_PIN, OUTPUT);
        digitalWrite(STATUS_LED_PIN, HIGH);
      
      #ifdef DEBUG
        Serial.begin(DEBUG_BAUD);
        Serial.println("DEBUG MODE");
        Serial.print("Version ");
        Serial.print(VERSION);
        Serial.print("\n\n");
      #endif
      
        // Menu Button
        pinMode(ROTARY_SWITCH, INPUT);
        digitalWrite(ROTARY_SWITCH, INPUT_PULLUP);
      
      #ifdef BUTTON1_PIN
        pinMode(BUTTON1_PIN, INPUT);
        digitalWrite(BUTTON1_PIN, INPUT_PULLUP);
      #endif
      
        // OLED Display
        u8g2.begin(/* menu_select_pin= */ 5, /* menu_next_pin= */ 0, /* menu_prev_pin= */ 0, /* menu_home_pin= */ 0);
      
        setNeedsDisplay = true;
      
        Timer1.initialize(TIMER);
        Timer1.attachInterrupt(timerEvent);
      
      =======================================
      
       fadeTo = dimValue = 0;
      
        update_light();
      }
      
      // ========================================================
      // LOOP
      // ========================================================
      
      void loop() {
        // put your main code here, to run repeatedly:
      
        digitalWrite(STATUS_LED_PIN, statusLedOn);
      
        if (menuAnimationRunning) {
          if (menuPageMode && menuPosY < MENU_POS_Y_HIDDEN) {
            // do animation
            menuPosY = menuPosY + MENU_ANIMATION_PIXEL_STEP;
            setNeedsDisplay = true;
          }
          if (!menuPageMode && menuPosY > MENU_POS_Y) {
            // do animation
            menuPosY = menuPosY - MENU_ANIMATION_PIXEL_STEP;
            setNeedsDisplay = true;
          }
        }
        if (menuAnimationRunning && (menuPosY == MENU_POS_Y || menuPosY == MENU_POS_Y_HIDDEN)) {
          // looks like animation is done
          menuAnimationRunning = false;
        }
      
        if (setNeedsDisplay) {
         
          displayRenderCurrentPage();
          setNeedsDisplay = false;
        }
        
      checkRotaryEncoder();
      
       {
        //In MySensors2.x, first message must come from within loop()
        static bool first_message_sent = false;
        if ( first_message_sent == false ) {
          Serial.println( "Sending initial state..." );
          send_dimmer_message();
          send_status_message();
          first_message_sent = true;
        }
      }
      }
      // ========================================================
      // TIMER
      // ========================================================
      
      void timerEvent() {
        // Heartbeat
        if (heartbeat > HEARTBEAT_TRIGGER) {
          statusLedOn = true;
        }
        if (heartbeat > HEARTBEAT_TRIGGER + HEARTBEAT_TRIGGER_TIME) {
          statusLedOn = false;
          heartbeat = 0;
        }
        heartbeat++;
      
        // Menu logic
        unsigned long timeOffset = millis() - rotaryLastMove;
        if (timeOffset > MENU_SELECTED_TIMEOUT) {
          // deselect menu
          menuSelected = menuActive;
          rotaryLastMove = millis();
          setNeedsDisplay = true;
        }
        
        // Rotary Encoder
        unsigned char result = rotary.process();
        if (result) {
      
          if (!menuPageMode) {
            if (result == DIR_CW) {
              // right
              if (menuSelected < 3) {
                menuSelected++;
              }
            } else {
              // left
              if (menuSelected > 1) {
                menuSelected--;
              }
            }
            setNeedsDisplay = true;
          } else {
      
            // Acceleration
            byte acceleration = 1;
            unsigned long timeOffset = millis() - rotaryLastMove;
            
            //Serial.println(timeOffset);
      
            if (displayCurrentPage == 0 || displayCurrentPage == 1) {
              if (timeOffset < ROTARY_ACCEL_OFFSET1) {
                acceleration = 16;
              } else if (timeOffset < ROTARY_ACCEL_OFFSET2) {
                acceleration = 4;
              } else if (timeOffset < ROTARY_ACCEL_OFFSET3) {
                acceleration = 2;
              }
            
              // Development test => control slider
              if (result == DIR_CW) {
                // right
                if (sliderPosX < 128) {
                  sliderPosX = sliderPosX + acceleration;
                }
              } else {
                // left
                if (sliderPosX > 0) {
                  sliderPosX = sliderPosX - acceleration;
                }
              }
              setNeedsDisplay = true;
            }
      
            if (displayCurrentPage == 2) {
              if (result == DIR_CW) {
                // right
                setupMenuSelected++;
              } else {
                // left
                setupMenuSelected--;
              }
              if (setupMenuSelected > SETUP_MENU_ITEMS - 1) {
                setupMenuSelected = SETUP_MENU_ITEMS - 1;
              }
              if (setupMenuSelected < 1) {
                setupMenuSelected = 0;
              }
              setNeedsDisplay = true;
            }
      
          }
      
          rotaryLastMove = millis();
          
        }
      
        // Rotary button
        if (buttonEvent()) {
          rotaryLastMove = millis();
          if (menuActive == menuSelected) {
            if (!menuPageMode) {
              // give controls to page (button press on selected page)
              menuPageMode = true;
              menuAnimationRunning = true;
              
              sliderPosX = 64;
              
              setNeedsDisplay = true;
              
              #ifdef DEBUG
              Serial.println("PAGE MODE ON");
              #endif
            } else {
              menuPageMode = false;   
              menuAnimationRunning = true;
              setNeedsDisplay = true;
              sliderPosX = 64;
      
              setupMenuSelected = 0;
              
              #ifdef DEBUG
              Serial.println("PAGE MODE OFF"); 
              #endif
            }
          }
          if (!menuPageMode) {
            menuActive = menuSelected;
            if (menuActive == 1) {
              displayCurrentPage = 0;
            }
            if (menuActive == 2) {
              displayCurrentPage = 1;
            }
            if (menuActive == 3) {
              displayCurrentPage = 2;
            }
            setNeedsDisplay = true;
          }
        }
      
        // Action button => reset page mode during development
      #ifdef BUTTON1_PIN
        if (digitalRead(BUTTON1_PIN) == 0 && menuPageMode) {
          menuPageMode = false;   
          menuAnimationRunning = true;
          setNeedsDisplay = true;
         // sliderPosX = 64;
          #ifdef DEBUG
          Serial.println("PAGE MODE OFF"); 
          #endif
        }
      #endif
        
      }
      
      // ========================================================
      // MENU BUTTON
      // ========================================================
      
      bool buttonEvent() {
        bool result = false;
        bool menuButton = false;
        if (digitalRead(ROTARY_SWITCH) == 1) {
          menuButton = true;
        }
        if (menuButton && !rotaryButtonPressed) {
          rotaryButtonPressed = true;
        } else if (!menuButton && rotaryButtonPressed) {
          rotaryButtonPressed = false;
          result = true;
          // FIXME: debounce for try, check if it's really needed
          //delay(4);
        }
        return result;
      }
      
      // ========================================================
      // DISPLAY - Screen Drawing
      // ========================================================
      
      void displayRenderCurrentPage() {
        // OLED Display update
        u8g2.firstPage();
        do {
      
          if (displayCurrentPage == 0) {
            u8g2.setFont(u8g2_font_8x13B_tr);
            u8g2.drawStr(0, 12, "Main Page");
          }
      
          if (displayCurrentPage == 1) {
            u8g2.setFont(u8g2_font_8x13B_tr);
            u8g2.drawStr(0, 12, "Network Page");
          }
      
          if (displayCurrentPage == 2) {
            if (!menuPageMode) {
              u8g2.setFont(u8g2_font_8x13B_tr);
              u8g2.drawStr(0, 10, "Setup Page");
              u8g2.setFont(u8g2_font_5x7_tr);
              u8g2.drawStr(0, 28, "PRESS BUTTON FOR SUBMENU");
            } else {
              drawPageMenu();
      
              if (setupMenuSelected == 0) {
                u8g2.setFont(u8g2_font_5x7_tr);
                u8g2.drawStr(0, 28, "DEMO MODE");
                u8g2.drawStr(0, 38, "PRESS BUTTON TO EXIT");
              }
      
              if (setupMenuSelected == 7) {
                // Version & Info
                u8g2.setFont(u8g2_font_5x7_tr);
                u8g2.setCursor(0, 28);
                u8g2.print(VERSION_TITLE);
                u8g2.print(" ");
                u8g2.print(VERSION);
      
                u8g2.setCursor(0, 38);
                u8g2.print(VERSION_SUBTITLE);
      
                u8g2.setCursor(0, 56);
                u8g2.print("HW: ");
                u8g2.print(VERSION_HW);
                
      
              }
            }
          }
      
          if (displayCurrentPage == 0 || displayCurrentPage == 1) {
            u8g2.setFont(u8g2_font_5x7_tr);
            if (menuPageMode) { 
              u8g2.drawStr(0, 28, "ROTARY CONTROL ON PAGE");
              u8g2.setCursor(0, 46);
              u8g2.print("VALUE ");
              u8g2.print(sliderPosX);
            } else {
              u8g2.drawStr(0, 28, "ROTARY CONTROL ON MENU");
            }
            drawSlider(31);
          }
      
          drawMenuBar();
          
        } while ( u8g2.nextPage() );
      }
      
      void drawPageMenu() {
        u8g2.setFont(u8g2_font_6x12_tr);
        if (displayCurrentPage == 2) {
          String text = setupMenuItems[setupMenuSelected];
          // center text
          int textWidth = u8g2.getStrWidth(text.c_str());
          int textX = (128 - textWidth) / 2;
          int textXPadding = 4;
          u8g2.drawRBox(textX - textXPadding, 0, textWidth + textXPadding + textXPadding, 11, 2);
          u8g2.setDrawColor(0);
          u8g2.setCursor(textX, 11 - 2);
          u8g2.print(text);
          u8g2.setDrawColor(1);
      
          bool drawLeftTriangle = false;
          bool drawRightTriangle = false;
      
          if (setupMenuSelected < SETUP_MENU_ITEMS - 1) {
            drawRightTriangle = true;
          }
          if (setupMenuSelected > 0) {
            drawLeftTriangle = true;
          }
      
          if (drawLeftTriangle) {
            // Triangle left
            u8g2.drawTriangle(4, 1, 4, 9, 0, 5);
          }
          if (drawRightTriangle) {
            // Triangle right
            u8g2.drawTriangle(128 - 5, 1, 128 - 5, 9, 127, 5);
          }
          u8g2.drawHLine(0, 14, 128);
        }
        
      }
      
      void drawSlider(int yPos) {
        u8g2.drawFrame(0, yPos, 100, 6);
        if (sliderPosX < 1) {
          sliderPosX = 0;
        }
        if (sliderPosX > 100) {
          sliderPosX = 100;
        }
        u8g2.drawVLine(sliderPosX, yPos, 6);
      }
      
      void drawMenuBar() {
        int textX = 0;
        int textY = menuPosY;
        int textWidth = 0;
        int textXPadding = 4;
        
        u8g2.setFont(u8g2_font_6x12_tr);
        u8g2.setDrawColor(1);
      
        u8g2.drawHLine(0, textY - 11 - 2, 128);
      
        if (textY < MENU_POS_Y_HIDDEN) {
          // center menu
          String text = menuItems[1];
          textWidth = u8g2.getStrWidth(text.c_str());
          textX = (128 - textWidth) / 2;
          if (menuActive == 2) {
            u8g2.drawRBox(textX - textXPadding, textY + 2 - 11, textWidth + textXPadding + textXPadding, 11, 2);
            u8g2.setDrawColor(0);
          } 
          if (menuActive != menuSelected && menuSelected == 2) {
            u8g2.drawRFrame(textX - textXPadding, textY + 2 - 11, textWidth + textXPadding + textXPadding, 11, 2);
            u8g2.setDrawColor(1);
          }
        
          u8g2.setCursor(textX, textY);
          u8g2.print(text);
          u8g2.setDrawColor(1);
        
          // left menu
          text = menuItems[0];
          textX = textXPadding;
          textWidth = u8g2.getStrWidth(text.c_str());
          if (menuActive == 1) {
            u8g2.drawRBox(textX - textXPadding, textY + 2 - 11, textWidth + textXPadding + textXPadding, 11, 2);
            u8g2.setDrawColor(0);
          } 
          if (menuActive != menuSelected && menuSelected == 1) {
            u8g2.drawRFrame(textX - textXPadding, textY + 2 - 11, textWidth + textXPadding + textXPadding, 11, 2);
            u8g2.setDrawColor(1);
          }
          u8g2.setCursor(textX, textY);
          u8g2.print(text);
          u8g2.setDrawColor(1);
        
          // right menu
          text = menuItems[2];
          textWidth = u8g2.getStrWidth(text.c_str());
          textX = 128 - textWidth - textXPadding;
          if (menuActive == 3) {
            u8g2.drawRBox(textX - textXPadding, textY + 2 - 11, textWidth + textXPadding + textXPadding, 11, 2);
            u8g2.setDrawColor(0);
          }
          if (menuActive != menuSelected && menuSelected == 3) {
            u8g2.drawRFrame(textX - textXPadding, textY + 2 - 11, textWidth + textXPadding + textXPadding, 11, 2);
            u8g2.setDrawColor(1);
          }
          u8g2.setCursor(textX, textY);
          u8g2.print(text);
          u8g2.setDrawColor(1);
        }
        
      }
      
      void presentation() {
        sendSketchInfo(SN, SV);
        // led
        present(1, S_DIMMER, 1);
           // rotary
          present( 8, S_DIMMER, 1 );
      
          
      }
      
      void receive(const MyMessage &message)
      
      {
        //When receiving a V_STATUS command, switch the light between OFF
        //and the last received dimmer value  
        
       if (message.sensor == 1){
          if (message.type == V_STATUS) 
        {
          Serial.println( "V_STATUS command received..." );
      
          int lstate = message.getInt();
          if (( lstate < 0 ) || ( lstate > 1 )) {
            Serial.println( "V_STATUS data invalid (should be 0/1)" );
            return;
          }
          last_state = lstate;
      
          //If last dimmer state is zero, set dimmer to 100
          if (( last_state == LIGHT_ON ) && ( last_dim == 0 )) {
            last_dim=10;
          }
      
          //Update constroller status
          send_status_message();
      
        } else if (message.type == V_PERCENTAGE)
        {
          Serial.println( "V_PERCENTAGE command received..." );
          int dim_value = constrain( message.getInt(), 0, 100 );
          if ( dim_value == 0 ) {
            last_state = LIGHT_OFF;
      
            //Update constroller with dimmer value & status
            send_dimmer_message();
            send_status_message();      
          } else {
            last_state = LIGHT_ON;
            last_dim = dim_value;
      
            //Update constroller with dimmer value
            send_dimmer_message();
          }
      
        } else {
          Serial.println( "Invalid command received..." );
          return;
        }
      
        //Here you set the actual light state/level
        update_light();
      }
      }   
      
      
      void update_light()
      {
        //For this example, just print the light status to console.
        if ( last_state == LIGHT_OFF ) {
          Serial.println( "Light state: OFF" );
        } else {
          Serial.print( "Light state: ON, Level: " );
          Serial.println( last_dim );
         analogWrite( LED_PIN, (last_dim) );
        }
      }
      
      void send_dimmer_message()
      {
        send( dimmer_msg.set( last_dim ) );
      }
      
      void send_status_message()
      {
        if ( last_state == LIGHT_OFF ) {
          send( light_msg.set( (int16_t)0) );
        } else {
          send( light_msg.set( (int16_t)1) );
        }
      }
      
      void checkRotaryEncoder() {
      
        if (sliderPosX > 100) {
          sliderPosX = 100;
        } else if (sliderPosX < 0) {
          sliderPosX = 0;
        }
        if (sliderPosX != dupa) { 
          dupa = sliderPosX;
          changedByKnob = true;
        send_dimmer_message_rottary();
        }
      }
      
      
      void send_dimmer_message_rottary()
      {
       send(dimmerinp.set(dupa),1);
      }```
      posted in Troubleshooting
      jaszczomb
      jaszczomb