Skip to content
  • MySensors
  • 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. OpenHardware.io
  3. 💬 Gesture controlled MySensors, Floor lamp

💬 Gesture controlled MySensors, Floor lamp

Scheduled Pinned Locked Moved OpenHardware.io
mysensorsfloor lampgesture controlledcontest2016
39 Posts 10 Posters 6.1k Views 11 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.
  • P Offline
    P Offline
    pjjarzembowski
    wrote on last edited by pjjarzembowski
    #18

    Hi, I'am new with this but I am going to build a kitchen lamp with this scetch. Unfortunately it doesn't work with Mysensors 2.0 library :( Befor I bought a devices for the lamp I was trying to remake the program for mysensors 2.0 I have to wait for my devices from aliexpress for almost two another months so I am going to post my correctet program and I would like to ask someone who has this lamp build with old library if he could test it. Thenk you very much in advance.

    And this is the code. It compiles well in compiler program.

    /****************************************************************
      Title: MySensors enabled, gesture controlled lamp.
      
      V1.1 March 2016 by Theo
      
      This lamp can be turned on/off, and dimmed by gestures. And it can be controlled by any Home Automation
      system, that can talk with MySensors.
      
      Supported gesture:
      1. Left to right stroke: turns lamp on
      2. Right to left stroke: turns lamp off
      3. Down to up stroke: increases brightness (When brightness is already at max, the lamp will blink - duration and blink count can be changed in the sketch)
      4. Up to down stroke: decreases brgihtness (When brightness level is at 0 the lamp is off)
      
      The gesture sensor ues in this Sketch is an APDS-9960 RGB and Gesture Sensor, sold by SparkFun. They can be found on eBay and Aliexpress as well.
      See Sparkfuns hookup guide for pin lay-out ( https://learn.sparkfun.com/tutorials/apds-9960-rgb-and-gesture-sensor-hookup-guide ) 
      IMPORTANT: The APDS-9960 can only accept 3.3V! Use bi direction level converter when using another Arduino than a Pro Mini 3.3V
    
      This Sketch is based upon the GestureTest exampl developped by,
      Shawn Hymel @ SparkFun Electronics on May 30, 2014. See https://github.com/sparkfun/APDS-9960_RGB_and_Gesture_Sensor
    
      The lamp itself is a white LED strip, controlled by an N channel MOSFET.
      
      Fore more details on the used hardware and libraries (see https://www.openhardware.io/view/50/Gesture-controlled-MySensors-Floor-lamp )
      
      Developed and test with MySensors release 1.5.4
      
      Revision history:
      3-07-2017 Changed for tests on Mysensors 2.0 
      - The change was not made by the original author of the program
    
      
    
      
      20-03-2016 Version 1.1:
          - set the brightness level to defined BRIGHTNESS_INCREMENT, when lamp is being turned on be a gesture and the current brightness level is 0.
            This was a little bug in previous version. It sometimes seemed that the APDS didn't work, but in some cases I had to increase brightness after
            I turned the lamp on.
          - cleaned up the code a bit
      19-03-2016 Version 1.0
    ****************************************************************/
    // Import libraries used by the Sketch.
    // added some of my radio definitions (must be before #includes)
    #define MY_DEBUG
    #define MY_RADIO_NRF24
    #define MY_RF24_PA_LEVEL RF24_PA_MAX
    #define MY_NODE_ID 10
    
    
    #include <SPI.h>
    #include <MySensors.h>  
    #include <Wire.h>
    #include <SparkFun_APDS9960.h>
    
    
    
    // Constants declaration(s)
    #define APDS9960_INT                      2   // Needs to be an interrupt pin. We should be able to use the Arduino's pin 3 as well.
    #define LED_PIN                           3   // The led PWM pin, that drives the LED strip. This is the pin thats attached to the mosfet.
    #define MAXDIMLEVELS                     100  // The maximum number of dim levels. Domoticz supports 0-100 (we'll transalate thim in an array)
    #define BRIGHTNESS_INCREMENT             15   // Dimmer increment for gesture(s). Play with this value yourself. The amount of gesture controlled
                                                  // dim levels is MAXDIMLEVELS / BRIGHTNESS_INCREMENT having 8 to 5 levels feels more natural to me.
    #define MAX_LEVEL_REACHED_DELAY          150  // Short blinking delay when increasing the dimmer while the dimmer is already at max
                                                  // Had some troubles in the past with tha acurateness of the gw.wait on pro mini's. But that'll probably
                                                  // not be noticeable with this short delay. Delay is in milliseconds
    #define MAX_LEVEL_REACHED_SIGNAL_COUNT   2    // The amount of blinks, when the max dim level already has been reached. It's just a way to let the user know
                                                  // that the lamp can not be more brighter than the current brightness
    #define CHILD_ID_LIGHT                   1    // The child id of the Node. Only one Node on this sensor though. See MySensors documentation
    #define LIGHT_OFF                        0    // Constant indicating the lamp on state
    #define LIGHT_ON                         1    // Constant indicationg light off state
    //#define SN "Gesture controlled lamp"          // Description of this sketch. 
    //#define SV                               "1.1" // The version of the Sketch
    
    // Global Variables
    SparkFun_APDS9960 apds = SparkFun_APDS9960(); // Initialize a SparkFun_APDS9960 object. This does all the magic incl. i2c communication with the sensor.
    int isr_flag = 0;                             // interrupt flag, triggered when a gesture has been dectected. Used to detect gesture detection in the interrupt handler
                                                  // the actual handling is done in the main loop. This allows is the keep the interrupt handler is lightweight is possible
                                                  // which is a good practice. Otherwise you'll get some behaviour you don't expect.
    int LastLightState=LIGHT_OFF;                 // The current lamp state. Wel'll turn it off for first time useage. The Sketch will query your Home Automation System for
                                                  // the last value when it's being reboot.
    int LastDimValue=MAXDIMLEVELS;                // last known dim value (Only initial value. Value is retrieved from your HA system)
    
    /**
     * Values could be calculated. But the sketch is small and storing in an Array is just faster. Otherwise we have to do calculations that incl Floats.
     * Floats take up a lot of your arduino memory
     */
    int dimlevels[ MAXDIMLEVELS ] =  // PWM values used for translating home automation dimmer levels. This gives smoother transations
      {   0,   1,   2,   3,   4,   5,   6,   7,   8,   9,
         10,  11,  12,  13,  14,  15,  16,  17,  18,  19,
         20,  21,  22,  23,  24,  25,  26,  27,  28,  29,
         30,  31,  32,  35,  39,  42,  46,  49,  52,  56,
         59,  62,  66,  69,  73,  76,  79,  83,  86,  89,
         93,  96, 100, 103, 106, 110, 113, 116, 120, 123,
        126, 130, 133, 137, 140, 144, 147, 150, 154, 157,
        160, 164, 167, 171, 174, 177, 181, 184, 187, 191,
        194, 197, 201, 204, 208, 211, 215, 218, 221, 225,
        228, 231, 235, 238, 242, 245, 246, 250, 251, 255 };
    
    /**
     * Variables needed for setting up and communication with MySensors. These variables will handle all of the MySensors magic for you.
     */
    //MySensor gw;
    MyMessage lightMsg(CHILD_ID_LIGHT, V_LIGHT);
    MyMessage dimmerMsg(CHILD_ID_LIGHT, V_DIMMER);
    
    /**
     * Initializing code. Basicly we'll setup MySensors communication and test if we can communicate with the gesture sensor. See comment in setup method for more details
     */
     // interrupt handler. Is being triggered by the gesture sensor whenever a gesture has been detected. We've setup this up in the setup.
    void interruptRoutine() {
      isr_flag = 1;
    }
    
    void setup() {
      // Initialize NFR24L01+ radio for enabling MySensors );
      //gw.begin(incomingMessage, AUTO, false);
    
      // Send the Sketch Version Information to the Gateway. Domoticz seems to ignore this. Don't know about the other HA systems. 
     // gw.sendSketchInfo(SN, SV);
    sendSketchInfo("Led Kuchnia Lampa", "2.0");
      // Present the dimmable lamp is a child node to the HA system. We'll enable ACK communication.
     // gw.present(CHILD_ID_LIGHT, S_DIMMER, "floor lamp", true );
      present(CHILD_ID_LIGHT, S_DIMMER);
      // declare output pin for PWM control of the MOSFET
      pinMode( LED_PIN, OUTPUT );
    
      // APDS Initialization code
      pinMode(APDS9960_INT, INPUT);   // Set interrupt pin as input. @@Note: this should be handled my the library. But it isn't
      attachInterrupt(0, interruptRoutine, FALLING);   // Initialize interrupt service routine. Basicly it'll call our interrupt routine
    
      if ( apds.init() ) { // Initialize APDS-9960 (configure I2C and initial values)
        // @@NOTE: original value is two. But it looks like the modern gesture sensor or more sensitive. 1 does it for me
        apds.setGestureGain( 1 );
      }
      
      if ( apds.enableGestureSensor(true) ) { // Start running the APDS-9960 gesture sensor engine. Sensor support more functions than gesture detection only.
        analogWrite( LED_PIN, 0 ); // Turn the lamp off.
        //gw.request( CHILD_ID_LIGHT, V_PERCENTAGE ); // Request current dimvalue from HA. The current value is being handled in the incomming method.
       request( CHILD_ID_LIGHT, V_PERCENTAGE ); // Request current dimvalue from HA. The current value is being handled in the incomming method.
        //gw.request( CHILD_ID_LIGHT, V_STATUS ); // Request current lamp state from HA. The current value is being handled in the incomming method.
      request( CHILD_ID_LIGHT, V_STATUS ); // Request current lamp state from HA. The current value is being handled in the incomming method.
      }
      }
    // }
    
    // Main loop. Does twoe things. Handle gestures if detected by the interrupt routine. And give the MySensors lib the oppurtunity to handle incomming messages.
    void loop() {
      if( isr_flag == 1 ) {
        detachInterrupt(0);
        handleGesture();
        isr_flag = 0;
        attachInterrupt(0, interruptRoutine, FALLING);
      }
      //gw.process();
    }
    
    
    
    
    //here originaly was
    // interrupt handler. Is being triggered by the gesture sensor whenever a gesture has been detected. We've setup this up in the setup.
    //void interruptRoutine() {
    //  isr_flag = 1;
    //}
    
    
    // Determine gesture and handle accordingly.We'll ignore FAR and NEAR gestures. Do didn't feel natural to me anyway.
    void handleGesture() {
      if ( apds.isGestureAvailable() ) { // Check if there's a gesture available. Which should be, because the interrupt handler told us so.
        switch ( apds.readGesture() ) { // Get the gesture type.
          case DIR_UP: // Handle up stroke (Brightness increasing)
            if ( LastDimValue + BRIGHTNESS_INCREMENT > ( MAXDIMLEVELS - 1 ) ) {
              for ( int i = 0; i < MAX_LEVEL_REACHED_SIGNAL_COUNT; i++ ) {
                analogWrite( LED_PIN, dimlevels[ 0 ] );
                //gw.wait( MAX_LEVEL_REACHED_DELAY );
                wait( MAX_LEVEL_REACHED_DELAY );
                analogWrite( LED_PIN, dimlevels[ MAXDIMLEVELS - 1 ] );
                //gw.wait(MAX_LEVEL_REACHED_DELAY );
                wait(MAX_LEVEL_REACHED_DELAY );
              }
              LastDimValue = ( MAXDIMLEVELS - 1 );
            }
            else {
               LastDimValue += BRIGHTNESS_INCREMENT;
            }
            LastLightState = LIGHT_ON;
            SetCurrentState2Hardware();
            break;
          case DIR_DOWN: // Handle down stroke (Brightness decreasing)
            if ( LastDimValue - BRIGHTNESS_INCREMENT <= 0 ) {
              LastDimValue = 0;
            }
            else {
               LastDimValue -= BRIGHTNESS_INCREMENT;
            }
            if ( LastDimValue == 0 ) {
              LastLightState = LIGHT_OFF;
            }
            else {
              LastLightState = LIGHT_ON;
            }
            SetCurrentState2Hardware();
            break;
          case DIR_LEFT: // Handle left stroke. Turn lamp off
            LastLightState = LIGHT_OFF;
            SetCurrentState2Hardware();
            break;
          case DIR_RIGHT: // Handle right stroke. Turn lamp on
            LastLightState = LIGHT_ON;
            if ( LastDimValue == 0 ) { // @@Version 1.1 addition Slight modification. When the dimValue was 0, the light stayed off when turned on.
              LastDimValue = BRIGHTNESS_INCREMENT; // Just used the first Gesture dimming stage (2 times would be better for my taste though. Might change that in the future)
            }
            SetCurrentState2Hardware();
            break;
        }
      }
    }
    
    /**
     * Handler for message send by the MySensor gateway.
     */ 
    void receive(const MyMessage &message) {
      if ( message.type == V_LIGHT ) { // Gateway reports a new Light state
        int lstate= atoi( message.data );
        if ( ( lstate < 0 ) || ( lstate > 1 ) ) {
          return;
        }
        LastLightState=lstate;
        if ( ( LastLightState == LIGHT_ON ) &&( LastDimValue == 0 ) ) {
           //In the case that the Light State = On, but the dimmer value is zero, then something (probably the controller) did something wrong,
           //for the Dim value to 100%
          LastDimValue = 100;
        }
        
        //When receiving a V_LIGHT command we switch the light between OFF and the last received dimmer value
        //This means if you previously set the lights dimmer value to 50%, and turn the light ON
        //it will do so at 50%
      }
      else if (message.type == V_DIMMER) { // Gateway reports new dimmer level. We'l adjust it to the new value
        int dimvalue= atoi( message.data );
        if ( ( dimvalue < 0 ) || ( dimvalue > 100 ) ) {
          return;
        }
        if ( dimvalue == 0 ) {
          LastLightState = LIGHT_OFF;
        }
        else {
          LastLightState = LIGHT_ON;
          LastDimValue = dimvalue;
        }
      }
      //Here we'll set the actual light state/level
      SetCurrentState2Hardware();
    }
    
    // Send current values to the PWM controlled MOSFET
    void SetCurrentState2Hardware() {
      if (LastLightState==LIGHT_OFF) {
         analogWrite( LED_PIN, dimlevels[0] );
      }
      else {
         analogWrite( LED_PIN, dimlevels[ LastDimValue - 1 ] );
      }
    
      //Send current state to the controller
      SendCurrentState2Controller();
    }
    
    // Report new values to the Gateway.
    void SendCurrentState2Controller()
    {
      if ((LastLightState==LIGHT_OFF)||(LastDimValue==0)) {
        //gw.send(dimmerMsg.set(0));
        send(dimmerMsg.set(0));
      }
      else {
        //gw.send(dimmerMsg.set(LastDimValue));
        send(dimmerMsg.set(LastDimValue));
      }
    }
    
    
    TheoLT 1 Reply Last reply
    0
    • P pjjarzembowski

      Hi, I'am new with this but I am going to build a kitchen lamp with this scetch. Unfortunately it doesn't work with Mysensors 2.0 library :( Befor I bought a devices for the lamp I was trying to remake the program for mysensors 2.0 I have to wait for my devices from aliexpress for almost two another months so I am going to post my correctet program and I would like to ask someone who has this lamp build with old library if he could test it. Thenk you very much in advance.

      And this is the code. It compiles well in compiler program.

      /****************************************************************
        Title: MySensors enabled, gesture controlled lamp.
        
        V1.1 March 2016 by Theo
        
        This lamp can be turned on/off, and dimmed by gestures. And it can be controlled by any Home Automation
        system, that can talk with MySensors.
        
        Supported gesture:
        1. Left to right stroke: turns lamp on
        2. Right to left stroke: turns lamp off
        3. Down to up stroke: increases brightness (When brightness is already at max, the lamp will blink - duration and blink count can be changed in the sketch)
        4. Up to down stroke: decreases brgihtness (When brightness level is at 0 the lamp is off)
        
        The gesture sensor ues in this Sketch is an APDS-9960 RGB and Gesture Sensor, sold by SparkFun. They can be found on eBay and Aliexpress as well.
        See Sparkfuns hookup guide for pin lay-out ( https://learn.sparkfun.com/tutorials/apds-9960-rgb-and-gesture-sensor-hookup-guide ) 
        IMPORTANT: The APDS-9960 can only accept 3.3V! Use bi direction level converter when using another Arduino than a Pro Mini 3.3V
      
        This Sketch is based upon the GestureTest exampl developped by,
        Shawn Hymel @ SparkFun Electronics on May 30, 2014. See https://github.com/sparkfun/APDS-9960_RGB_and_Gesture_Sensor
      
        The lamp itself is a white LED strip, controlled by an N channel MOSFET.
        
        Fore more details on the used hardware and libraries (see https://www.openhardware.io/view/50/Gesture-controlled-MySensors-Floor-lamp )
        
        Developed and test with MySensors release 1.5.4
        
        Revision history:
        3-07-2017 Changed for tests on Mysensors 2.0 
        - The change was not made by the original author of the program
      
        
      
        
        20-03-2016 Version 1.1:
            - set the brightness level to defined BRIGHTNESS_INCREMENT, when lamp is being turned on be a gesture and the current brightness level is 0.
              This was a little bug in previous version. It sometimes seemed that the APDS didn't work, but in some cases I had to increase brightness after
              I turned the lamp on.
            - cleaned up the code a bit
        19-03-2016 Version 1.0
      ****************************************************************/
      // Import libraries used by the Sketch.
      // added some of my radio definitions (must be before #includes)
      #define MY_DEBUG
      #define MY_RADIO_NRF24
      #define MY_RF24_PA_LEVEL RF24_PA_MAX
      #define MY_NODE_ID 10
      
      
      #include <SPI.h>
      #include <MySensors.h>  
      #include <Wire.h>
      #include <SparkFun_APDS9960.h>
      
      
      
      // Constants declaration(s)
      #define APDS9960_INT                      2   // Needs to be an interrupt pin. We should be able to use the Arduino's pin 3 as well.
      #define LED_PIN                           3   // The led PWM pin, that drives the LED strip. This is the pin thats attached to the mosfet.
      #define MAXDIMLEVELS                     100  // The maximum number of dim levels. Domoticz supports 0-100 (we'll transalate thim in an array)
      #define BRIGHTNESS_INCREMENT             15   // Dimmer increment for gesture(s). Play with this value yourself. The amount of gesture controlled
                                                    // dim levels is MAXDIMLEVELS / BRIGHTNESS_INCREMENT having 8 to 5 levels feels more natural to me.
      #define MAX_LEVEL_REACHED_DELAY          150  // Short blinking delay when increasing the dimmer while the dimmer is already at max
                                                    // Had some troubles in the past with tha acurateness of the gw.wait on pro mini's. But that'll probably
                                                    // not be noticeable with this short delay. Delay is in milliseconds
      #define MAX_LEVEL_REACHED_SIGNAL_COUNT   2    // The amount of blinks, when the max dim level already has been reached. It's just a way to let the user know
                                                    // that the lamp can not be more brighter than the current brightness
      #define CHILD_ID_LIGHT                   1    // The child id of the Node. Only one Node on this sensor though. See MySensors documentation
      #define LIGHT_OFF                        0    // Constant indicating the lamp on state
      #define LIGHT_ON                         1    // Constant indicationg light off state
      //#define SN "Gesture controlled lamp"          // Description of this sketch. 
      //#define SV                               "1.1" // The version of the Sketch
      
      // Global Variables
      SparkFun_APDS9960 apds = SparkFun_APDS9960(); // Initialize a SparkFun_APDS9960 object. This does all the magic incl. i2c communication with the sensor.
      int isr_flag = 0;                             // interrupt flag, triggered when a gesture has been dectected. Used to detect gesture detection in the interrupt handler
                                                    // the actual handling is done in the main loop. This allows is the keep the interrupt handler is lightweight is possible
                                                    // which is a good practice. Otherwise you'll get some behaviour you don't expect.
      int LastLightState=LIGHT_OFF;                 // The current lamp state. Wel'll turn it off for first time useage. The Sketch will query your Home Automation System for
                                                    // the last value when it's being reboot.
      int LastDimValue=MAXDIMLEVELS;                // last known dim value (Only initial value. Value is retrieved from your HA system)
      
      /**
       * Values could be calculated. But the sketch is small and storing in an Array is just faster. Otherwise we have to do calculations that incl Floats.
       * Floats take up a lot of your arduino memory
       */
      int dimlevels[ MAXDIMLEVELS ] =  // PWM values used for translating home automation dimmer levels. This gives smoother transations
        {   0,   1,   2,   3,   4,   5,   6,   7,   8,   9,
           10,  11,  12,  13,  14,  15,  16,  17,  18,  19,
           20,  21,  22,  23,  24,  25,  26,  27,  28,  29,
           30,  31,  32,  35,  39,  42,  46,  49,  52,  56,
           59,  62,  66,  69,  73,  76,  79,  83,  86,  89,
           93,  96, 100, 103, 106, 110, 113, 116, 120, 123,
          126, 130, 133, 137, 140, 144, 147, 150, 154, 157,
          160, 164, 167, 171, 174, 177, 181, 184, 187, 191,
          194, 197, 201, 204, 208, 211, 215, 218, 221, 225,
          228, 231, 235, 238, 242, 245, 246, 250, 251, 255 };
      
      /**
       * Variables needed for setting up and communication with MySensors. These variables will handle all of the MySensors magic for you.
       */
      //MySensor gw;
      MyMessage lightMsg(CHILD_ID_LIGHT, V_LIGHT);
      MyMessage dimmerMsg(CHILD_ID_LIGHT, V_DIMMER);
      
      /**
       * Initializing code. Basicly we'll setup MySensors communication and test if we can communicate with the gesture sensor. See comment in setup method for more details
       */
       // interrupt handler. Is being triggered by the gesture sensor whenever a gesture has been detected. We've setup this up in the setup.
      void interruptRoutine() {
        isr_flag = 1;
      }
      
      void setup() {
        // Initialize NFR24L01+ radio for enabling MySensors );
        //gw.begin(incomingMessage, AUTO, false);
      
        // Send the Sketch Version Information to the Gateway. Domoticz seems to ignore this. Don't know about the other HA systems. 
       // gw.sendSketchInfo(SN, SV);
      sendSketchInfo("Led Kuchnia Lampa", "2.0");
        // Present the dimmable lamp is a child node to the HA system. We'll enable ACK communication.
       // gw.present(CHILD_ID_LIGHT, S_DIMMER, "floor lamp", true );
        present(CHILD_ID_LIGHT, S_DIMMER);
        // declare output pin for PWM control of the MOSFET
        pinMode( LED_PIN, OUTPUT );
      
        // APDS Initialization code
        pinMode(APDS9960_INT, INPUT);   // Set interrupt pin as input. @@Note: this should be handled my the library. But it isn't
        attachInterrupt(0, interruptRoutine, FALLING);   // Initialize interrupt service routine. Basicly it'll call our interrupt routine
      
        if ( apds.init() ) { // Initialize APDS-9960 (configure I2C and initial values)
          // @@NOTE: original value is two. But it looks like the modern gesture sensor or more sensitive. 1 does it for me
          apds.setGestureGain( 1 );
        }
        
        if ( apds.enableGestureSensor(true) ) { // Start running the APDS-9960 gesture sensor engine. Sensor support more functions than gesture detection only.
          analogWrite( LED_PIN, 0 ); // Turn the lamp off.
          //gw.request( CHILD_ID_LIGHT, V_PERCENTAGE ); // Request current dimvalue from HA. The current value is being handled in the incomming method.
         request( CHILD_ID_LIGHT, V_PERCENTAGE ); // Request current dimvalue from HA. The current value is being handled in the incomming method.
          //gw.request( CHILD_ID_LIGHT, V_STATUS ); // Request current lamp state from HA. The current value is being handled in the incomming method.
        request( CHILD_ID_LIGHT, V_STATUS ); // Request current lamp state from HA. The current value is being handled in the incomming method.
        }
        }
      // }
      
      // Main loop. Does twoe things. Handle gestures if detected by the interrupt routine. And give the MySensors lib the oppurtunity to handle incomming messages.
      void loop() {
        if( isr_flag == 1 ) {
          detachInterrupt(0);
          handleGesture();
          isr_flag = 0;
          attachInterrupt(0, interruptRoutine, FALLING);
        }
        //gw.process();
      }
      
      
      
      
      //here originaly was
      // interrupt handler. Is being triggered by the gesture sensor whenever a gesture has been detected. We've setup this up in the setup.
      //void interruptRoutine() {
      //  isr_flag = 1;
      //}
      
      
      // Determine gesture and handle accordingly.We'll ignore FAR and NEAR gestures. Do didn't feel natural to me anyway.
      void handleGesture() {
        if ( apds.isGestureAvailable() ) { // Check if there's a gesture available. Which should be, because the interrupt handler told us so.
          switch ( apds.readGesture() ) { // Get the gesture type.
            case DIR_UP: // Handle up stroke (Brightness increasing)
              if ( LastDimValue + BRIGHTNESS_INCREMENT > ( MAXDIMLEVELS - 1 ) ) {
                for ( int i = 0; i < MAX_LEVEL_REACHED_SIGNAL_COUNT; i++ ) {
                  analogWrite( LED_PIN, dimlevels[ 0 ] );
                  //gw.wait( MAX_LEVEL_REACHED_DELAY );
                  wait( MAX_LEVEL_REACHED_DELAY );
                  analogWrite( LED_PIN, dimlevels[ MAXDIMLEVELS - 1 ] );
                  //gw.wait(MAX_LEVEL_REACHED_DELAY );
                  wait(MAX_LEVEL_REACHED_DELAY );
                }
                LastDimValue = ( MAXDIMLEVELS - 1 );
              }
              else {
                 LastDimValue += BRIGHTNESS_INCREMENT;
              }
              LastLightState = LIGHT_ON;
              SetCurrentState2Hardware();
              break;
            case DIR_DOWN: // Handle down stroke (Brightness decreasing)
              if ( LastDimValue - BRIGHTNESS_INCREMENT <= 0 ) {
                LastDimValue = 0;
              }
              else {
                 LastDimValue -= BRIGHTNESS_INCREMENT;
              }
              if ( LastDimValue == 0 ) {
                LastLightState = LIGHT_OFF;
              }
              else {
                LastLightState = LIGHT_ON;
              }
              SetCurrentState2Hardware();
              break;
            case DIR_LEFT: // Handle left stroke. Turn lamp off
              LastLightState = LIGHT_OFF;
              SetCurrentState2Hardware();
              break;
            case DIR_RIGHT: // Handle right stroke. Turn lamp on
              LastLightState = LIGHT_ON;
              if ( LastDimValue == 0 ) { // @@Version 1.1 addition Slight modification. When the dimValue was 0, the light stayed off when turned on.
                LastDimValue = BRIGHTNESS_INCREMENT; // Just used the first Gesture dimming stage (2 times would be better for my taste though. Might change that in the future)
              }
              SetCurrentState2Hardware();
              break;
          }
        }
      }
      
      /**
       * Handler for message send by the MySensor gateway.
       */ 
      void receive(const MyMessage &message) {
        if ( message.type == V_LIGHT ) { // Gateway reports a new Light state
          int lstate= atoi( message.data );
          if ( ( lstate < 0 ) || ( lstate > 1 ) ) {
            return;
          }
          LastLightState=lstate;
          if ( ( LastLightState == LIGHT_ON ) &&( LastDimValue == 0 ) ) {
             //In the case that the Light State = On, but the dimmer value is zero, then something (probably the controller) did something wrong,
             //for the Dim value to 100%
            LastDimValue = 100;
          }
          
          //When receiving a V_LIGHT command we switch the light between OFF and the last received dimmer value
          //This means if you previously set the lights dimmer value to 50%, and turn the light ON
          //it will do so at 50%
        }
        else if (message.type == V_DIMMER) { // Gateway reports new dimmer level. We'l adjust it to the new value
          int dimvalue= atoi( message.data );
          if ( ( dimvalue < 0 ) || ( dimvalue > 100 ) ) {
            return;
          }
          if ( dimvalue == 0 ) {
            LastLightState = LIGHT_OFF;
          }
          else {
            LastLightState = LIGHT_ON;
            LastDimValue = dimvalue;
          }
        }
        //Here we'll set the actual light state/level
        SetCurrentState2Hardware();
      }
      
      // Send current values to the PWM controlled MOSFET
      void SetCurrentState2Hardware() {
        if (LastLightState==LIGHT_OFF) {
           analogWrite( LED_PIN, dimlevels[0] );
        }
        else {
           analogWrite( LED_PIN, dimlevels[ LastDimValue - 1 ] );
        }
      
        //Send current state to the controller
        SendCurrentState2Controller();
      }
      
      // Report new values to the Gateway.
      void SendCurrentState2Controller()
      {
        if ((LastLightState==LIGHT_OFF)||(LastDimValue==0)) {
          //gw.send(dimmerMsg.set(0));
          send(dimmerMsg.set(0));
        }
        else {
          //gw.send(dimmerMsg.set(LastDimValue));
          send(dimmerMsg.set(LastDimValue));
        }
      }
      
      
      TheoLT Offline
      TheoLT Offline
      TheoL
      Contest Winner
      wrote on last edited by
      #19

      @pjjarzembowski I'm sorry my dear friend. I've been really occupied the last month. Can't wait until it's getting less busy at work. Than I'll have some time to see if I can help you.
      But I've read somewhere that the cheaper versions of the gesture sensors aren't that great. Curious about your findings.

      1 Reply Last reply
      0
      • P Offline
        P Offline
        pjjarzembowski
        wrote on last edited by
        #20
        This post is deleted!
        P 1 Reply Last reply
        0
        • P pjjarzembowski

          This post is deleted!

          P Offline
          P Offline
          pjjarzembowski
          wrote on last edited by pjjarzembowski
          #21

          @pjjarzembowski said in 💬 Gesture controlled MySensors, Floor lamp:
          Hello!!
          I can now say that the program below, is working in mysensors 2.0. It was tested in arduino Uno (china clone) and in arduino Nano (china clone). The gesture controller is also from China.
          But additionaly I had to change the line:
          void incomingMessage(const MyMessage &message) {
          to
          void receive(const MyMessage &message) {

          and I had to change the file in arduino library:

          In the file SparkFun_APDS9960.cpp, search and find the line:
          if( !setLEDBoost(LED_BOOST_300) ) {
          and edit it to read:
          if( !setLEDBoost(LED_BOOST_100) ) {

          That is all. It works fine :)
          Thanks Theo for a Great program :)

          1 Reply Last reply
          0
          • P Offline
            P Offline
            pjjarzembowski
            wrote on last edited by pjjarzembowski
            #22

            For those eager to built something more I am posting a new version, with included sensors for temperature and Himidity DHT22 (Pin D4), MQ135 (Pin AI 3), KY-026 IR Flame Sensor (Pin AI 1) it could also be a light sensor LM393, Led (Pin D3), I used LM2596 for 5V which I have taken from 12V power strip. 3.3 V I have taken from arduino UNO. I got some problems with arduino nano, when dealing with bigger powers for led like 50W so that is why I used arduino Uno, it works fine. The problems was that it freezes (I think it was because the quality of power for 3.3V). In the lower powers like 10W there was no problems for arduino nano.

            
            /****************************************************************
              Title: MySensors enabled, gesture controlled lamp.
              
              V1.1 March 2016 by Theo
              
              This lamp can be turned on/off, and dimmed by gestures. And it can be controlled by any Home Automation
              system, that can talk with MySensors.
              
              Supported gesture:
              1. Left to right stroke: turns lamp on
              2. Right to left stroke: turns lamp off
              3. Down to up stroke: increases brightness (When brightness is already at max, the lamp will blink - duration and blink count can be changed in the sketch)
              4. Up to down stroke: decreases brgihtness (When brightness level is at 0 the lamp is off)
              
              The gesture sensor ues in this Sketch is an APDS-9960 RGB and Gesture Sensor, sold by SparkFun. They can be found on eBay and Aliexpress as well.
              See Sparkfuns hookup guide for pin lay-out ( https://learn.sparkfun.com/tutorials/apds-9960-rgb-and-gesture-sensor-hookup-guide ) 
              IMPORTANT: The APDS-9960 can only accept 3.3V! Use bi direction level converter when using another Arduino than a Pro Mini 3.3V
            
              This Sketch is based upon the GestureTest exampl developped by,
              Shawn Hymel @ SparkFun Electronics on May 30, 2014. See https://github.com/sparkfun/APDS-9960_RGB_and_Gesture_Sensor
            
              The lamp itself is a white LED strip, controlled by an N channel MOSFET.
              
              Fore more details on the used hardware and libraries (see https://www.openhardware.io/view/50/Gesture-controlled-MySensors-Floor-lamp )
              
              Developed and test with MySensors release 1.5.4
              
              Revision history:
              3-07-2017 Changed for tests on Mysensors 2.0 
              - The change was not made by the original author of the program
            
              
            
              
              20-03-2016 Version 1.1:
                  - set the brightness level to defined BRIGHTNESS_INCREMENT, when lamp is being turned on be a gesture and the current brightness level is 0.
                    This was a little bug in previous version. It sometimes seemed that the APDS didn't work, but in some cases I had to increase brightness after
                    I turned the lamp on.
                  - cleaned up the code a bit
              19-03-2016 Version 1.0
            ****************************************************************/
            // Import libraries used by the Sketch.
            // added some of my radio definitions (must be before #includes)
            #define MY_DEBUG
            #define MY_RADIO_NRF24
            #define MY_RF24_PA_LEVEL RF24_PA_MAX
            #define MY_NODE_ID 10
            // Enable repeater functionality for this node
            #define MY_REPEATER_FEATURE
            
            #include <SPI.h>
            #include <MySensors.h>  
            #include <Wire.h>
            #include <SparkFun_APDS9960.h>
            #include <DHT.h>
            
            
            // Constants declaration(s)
            #define APDS9960_INT                      2   // Needs to be an interrupt pin. We should be able to use the Arduino's pin 3 as well.
            #define LED_PIN                           3   // The led PWM pin, that drives the LED strip. This is the pin thats attached to the mosfet.
            #define MAXDIMLEVELS                     100  // The maximum number of dim levels. Domoticz supports 0-100 (we'll transalate thim in an array)
            #define BRIGHTNESS_INCREMENT             15   // Dimmer increment for gesture(s). Play with this value yourself. The amount of gesture controlled
                                                          // dim levels is MAXDIMLEVELS / BRIGHTNESS_INCREMENT having 8 to 5 levels feels more natural to me.
            #define MAX_LEVEL_REACHED_DELAY          150  // Short blinking delay when increasing the dimmer while the dimmer is already at max
                                                          // Had some troubles in the past with tha acurateness of the gw.wait on pro mini's. But that'll probably
                                                          // not be noticeable with this short delay. Delay is in milliseconds
            #define MAX_LEVEL_REACHED_SIGNAL_COUNT   2    // The amount of blinks, when the max dim level already has been reached. It's just a way to let the user know
                                                          // that the lamp can not be more brighter than the current brightness
            #define CHILD_ID_LIGHT                   1    // The child id of the Node. Only one Node on this sensor though. See MySensors documentation
            #define LIGHT_OFF                        0    // Constant indicating the lamp on state
            #define LIGHT_ON                         1    // Constant indicationg light off state
            //#define SN "Gesture controlled lamp"          // Description of this sketch. 
            //#define SV                               "1.1" // The version of the Sketch
            
            #define DHT_DATA_PIN 4
            //#define CHILD_ID_AIQ 0
            #define AIQ_SENSOR_ANALOG_PIN 3  //bylo 6
            
            // Set this offset if the sensor has a permanent small offset to the real temperatures
            #define SENSOR_TEMP_OFFSET 0
            #define MQ135_DEFAULTPPM 399 //default ppm of CO2 for calibration
            //#define MQ135_DEFAULTRO 68550 //default Ro for MQ135_DEFAULTPPM ppm of CO2
            #define MQ135_DEFAULTRO 229550 //default Ro for MQ135_DEFAULTPPM ppm of CO2
            #define MQ135_SCALINGFACTOR 116.6020682 //CO2 gas value
            #define MQ135_EXPONENT -2.769034857 //CO2 gas value
            #define MQ135_MAXRSRO 2.428 //for CO2
            #define MQ135_MINRSRO 0.358 //for CO2
            
            #define CHILD_ID_HUM 0
            #define CHILD_ID_TEMP 1
            
            #define CHILD_ID_LIGHTpoz 2
            #define LIGHT_SENSOR_ANALOG_PIN 0 //bylo 7
            
            //VARIABLES
            double mq135_ro = 10000;    // this has to be tuned 10K Ohm
            double val = 0;                 // variable to store the value coming from the sensor
            double valAIQ =0;
            double lastAIQ =0;
            
            // Sleep time between sensor updates (in milliseconds)
            // Must be >1000ms for DHT22 and >2000ms for DHT11
            static const uint64_t UPDATE_INTERVAL = 30000;
            
            
            // Force sending an update of the temperature after n sensor reads, so a controller showing the
            // timestamp of the last update doesn't show something like 3 hours in the unlikely case, that
            // the value didn't change since;
            // i.e. the sensor would force sending an update every UPDATE_INTERVAL*FORCE_UPDATE_N_READS [ms]
            static const uint8_t FORCE_UPDATE_N_READS = 10;
            
            unsigned long lastRefreshTime = 0; // Use this to implement a non-blocking delay function
            float lastTemp;
            float lastHum;
            float lastLightLevel;
            uint8_t nNoUpdatesTemp;
            uint8_t nNoUpdatesHum;
            uint8_t nNoUpdatesLight;
            float lastLightLevelpoz;
            uint8_t nNoUpdatesLightpoz;
            bool metric = true;
            uint8_t nNoUpdatesvalr;
            
            
            // Global Variables
            SparkFun_APDS9960 apds = SparkFun_APDS9960(); // Initialize a SparkFun_APDS9960 object. This does all the magic incl. i2c communication with the sensor.
            int isr_flag = 0;                             // interrupt flag, triggered when a gesture has been dectected. Used to detect gesture detection in the interrupt handler
                                                          // the actual handling is done in the main loop. This allows is the keep the interrupt handler is lightweight is possible
                                                          // which is a good practice. Otherwise you'll get some behaviour you don't expect.
            int LastLightState=LIGHT_OFF;                 // The current lamp state. Wel'll turn it off for first time useage. The Sketch will query your Home Automation System for
                                                          // the last value when it's being reboot.
            int LastDimValue=MAXDIMLEVELS;                // last known dim value (Only initial value. Value is retrieved from your HA system)
            
            /**
             * Values could be calculated. But the sketch is small and storing in an Array is just faster. Otherwise we have to do calculations that incl Floats.
             * Floats take up a lot of your arduino memory
             */
            int dimlevels[ MAXDIMLEVELS ] =  // PWM values used for translating home automation dimmer levels. This gives smoother transations
              {   0,   1,   2,   3,   4,   5,   6,   7,   8,   9,
                 10,  11,  12,  13,  14,  15,  16,  17,  18,  19,
                 20,  21,  22,  23,  24,  25,  26,  27,  28,  29,
                 30,  31,  32,  35,  39,  42,  46,  49,  52,  56,
                 59,  62,  66,  69,  73,  76,  79,  83,  86,  89,
                 93,  96, 100, 103, 106, 110, 113, 116, 120, 123,
                126, 130, 133, 137, 140, 144, 147, 150, 154, 157,
                160, 164, 167, 171, 174, 177, 181, 184, 187, 191,
                194, 197, 201, 204, 208, 211, 215, 218, 221, 225,
                228, 231, 235, 238, 242, 245, 246, 250, 251, 255 };
            
            /**
             * Variables needed for setting up and communication with MySensors. These variables will handle all of the MySensors magic for you.
             */
            //MySensor gw;
            MyMessage lightMsg(CHILD_ID_LIGHT, V_LIGHT);
            MyMessage dimmerMsg(CHILD_ID_LIGHT, V_DIMMER);
            
            
            MyMessage msg(AIQ_SENSOR_ANALOG_PIN, V_LEVEL);
            MyMessage msgHum(CHILD_ID_HUM, V_HUM);
            MyMessage msgTemp(CHILD_ID_TEMP, V_TEMP );
            MyMessage msgLight(CHILD_ID_LIGHTpoz, V_LIGHT_LEVEL);
            DHT dht;
            
            /**
             * Initializing code. Basicly we'll setup MySensors communication and test if we can communicate with the gesture sensor. See comment in setup method for more details
             */
             // interrupt handler. Is being triggered by the gesture sensor whenever a gesture has been detected. We've setup this up in the setup.
            void interruptRoutine() {
              isr_flag = 1;
            }
            
            
            
            void presentation()  
            { 
              // Send the sketch version information to the gateway
              sendSketchInfo("Led Kuchnia Lampa", "2.0");
            
              // 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(AIQ_SENSOR_ANALOG_PIN, S_AIR_QUALITY);
              present(CHILD_ID_LIGHTpoz, S_LIGHT_LEVEL);
            
                present(CHILD_ID_LIGHT, S_DIMMER);
              metric = getControllerConfig().isMetric;
            }
            
            
            
            void setup() {
              // Initialize NFR24L01+ radio for enabling MySensors );
              //gw.begin(incomingMessage, AUTO, false);
            
              // Send the Sketch Version Information to the Gateway. Domoticz seems to ignore this. Don't know about the other HA systems. 
             // gw.sendSketchInfo(SN, SV);
            ///sendSketchInfo("Led Kuchnia Lampa", "2.0");
              // Present the dimmable lamp is a child node to the HA system. We'll enable ACK communication.
             // gw.present(CHILD_ID_LIGHT, S_DIMMER, "floor lamp", true );
             // present(CHILD_ID_LIGHT, S_DIMMER);
              // declare output pin for PWM control of the MOSFET
            
              dht.setup(DHT_DATA_PIN); // set data pin of DHT sensor
              if (UPDATE_INTERVAL <= dht.getMinimumSamplingPeriod()) {
                Serial.println("Warning: UPDATE_INTERVAL is smaller than supported by the sensor!");
              }
            
            
              
              pinMode( LED_PIN, OUTPUT );
            
              // APDS Initialization code
              pinMode(APDS9960_INT, INPUT);   // Set interrupt pin as input. @@Note: this should be handled my the library. But it isn't
              attachInterrupt(0, interruptRoutine, FALLING);   // Initialize interrupt service routine. Basicly it'll call our interrupt routine
            
              if ( apds.init() ) { // Initialize APDS-9960 (configure I2C and initial values)
                // @@NOTE: original value is two. But it looks like the modern gesture sensor or more sensitive. 1 does it for me
                apds.setGestureGain( 1 );
              }
              
              if ( apds.enableGestureSensor(true) ) { // Start running the APDS-9960 gesture sensor engine. Sensor support more functions than gesture detection only.
                analogWrite( LED_PIN, 0 ); // Turn the lamp off.
                //gw.request( CHILD_ID_LIGHT, V_PERCENTAGE ); // Request current dimvalue from HA. The current value is being handled in the incomming method.
               request( CHILD_ID_LIGHT, V_PERCENTAGE ); // Request current dimvalue from HA. The current value is being handled in the incomming method.
                //gw.request( CHILD_ID_LIGHT, V_STATUS ); // Request current lamp state from HA. The current value is being handled in the incomming method.
              request( CHILD_ID_LIGHT, V_STATUS ); // Request current lamp state from HA. The current value is being handled in the incomming method.
              }
              }
            
            
            
            /*
             * get the calibrated ro based upon read resistance, and a know ppm
             */
            long mq135_getro(long resvalue, double ppm) {
            return (long)(resvalue * exp( log(MQ135_SCALINGFACTOR/ppm) / MQ135_EXPONENT ));
            }
            
            /*
             * get the ppm concentration
             */
            double mq135_getppm(long resvalue, long ro) {
            double ret = 0;
            double validinterval = 0;
            validinterval = resvalue/(double)ro;
            if(validinterval<MQ135_MAXRSRO && validinterval>MQ135_MINRSRO) {
            ret = (double)((double)MQ135_SCALINGFACTOR * pow( ((double)resvalue/ro), MQ135_EXPONENT));
            }
            return ret;
            }
            
            
              
            // }
            
            // Main loop. Does twoe things. Handle gestures if detected by the interrupt routine. And give the MySensors lib the oppurtunity to handle incomming messages.
            
            
            void loop()      
            {  
              Serial.print ( "test 1" );
               boolean needRefresh = (millis() - lastRefreshTime) > UPDATE_INTERVAL;
               Serial.print ( "test 2 ");
              if (needRefresh)
              {
                   lastRefreshTime = millis();
                   Serial.print ( "test 3 ");
              // Force reading sensor, so it works also after sleep()
              dht.readSensor(true);
              
              // Get temperature from DHT library
                        float temperature = dht.getTemperature();
                        if (isnan(temperature)) {
                           Serial.println("Failed reading temperature from DHT!");
                        } else if (temperature != lastTemp || nNoUpdatesTemp == FORCE_UPDATE_N_READS) {
                        // Only send temperature if it changed since the last measurement or if we didn't send an update for n times
                        lastTemp = temperature;
                        if (!metric) {
                        temperature = dht.toFahrenheit(temperature);
                        }
                        // Reset no updates counter
                        nNoUpdatesTemp = 0;
                        temperature += SENSOR_TEMP_OFFSET;
                        send(msgTemp.set(temperature, 1));
            
                        #ifdef MY_DEBUG
                        Serial.print("T: ");
                        Serial.println(temperature);
                        #endif
                        } else {
                        // Increase no update counter if the temperature stayed the same
                        nNoUpdatesTemp++;
                        Serial.print ( "test 4 ");
                      }
            
                        // Get humidity from DHT library
                        float humidity = dht.getHumidity();
                        if (isnan(humidity)) {
                        Serial.println("Failed reading humidity from DHT");
                        } else if (humidity != lastHum || nNoUpdatesHum == FORCE_UPDATE_N_READS) {
                        // Only send humidity if it changed since the last measurement or if we didn't send an update for n times
                        lastHum = humidity;
                        // Reset no updates counter
                        nNoUpdatesHum = 0;
                        send(msgHum.set(humidity, 1));
                
                        #ifdef MY_DEBUG
                        Serial.print("H: ");
                        Serial.println(humidity);
                        #endif
                        } else {
                        // Increase no update counter if the humidity stayed the same
                        nNoUpdatesHum++;
                        Serial.print ( "test 5 ");
                       }
                // Tu wrzucam cala reszte ktora potrzebuje sleep
            //TU  Wrzucilem czujnik MQ135
            
            Serial.print ( "test 6 ");
              double valr = analogRead(AIQ_SENSOR_ANALOG_PIN);// Get AIQ value
              Serial.print ( "test 7 odczytano sensor MQ135 ");
              Serial.println(val);
               if (isnan(valr)) {
                Serial.println("Failed reading MQ135");
            
            
               
              double val =  ((float)22000*(1023-valr)/valr); 
              //during clean air calibration, read the Ro value and replace MQ135_DEFAULTRO value with it, you can even deactivate following function call.
              mq135_ro = mq135_getro(val, MQ135_DEFAULTPPM);
              //convert to ppm (using default ro)
              valAIQ = mq135_getppm(val, MQ135_DEFAULTRO);
            
              Serial.print ( "Val / Ro / value:");
              Serial.print ( val);
              Serial.print ( " / ");
              Serial.print ( mq135_ro);
              Serial.print ( " / ");
              Serial.print ( valAIQ);
            
            
              } else if (valAIQ != lastAIQ || nNoUpdatesvalr == FORCE_UPDATE_N_READS) {
            Serial.print (" test myk zaczal ");
            ////tu zaczalem myk
              double valr = analogRead(AIQ_SENSOR_ANALOG_PIN);// Get AIQ value
              Serial.println(val);
              Serial.print (" mysk w trakcie ");
              double val =  ((float)22000*(1023-valr)/valr); 
              //during clean air calibration, read the Ro value and replace MQ135_DEFAULTRO value with it, you can even deactivate following function call.
              mq135_ro = mq135_getro(val, MQ135_DEFAULTPPM);
              //convert to ppm (using default ro)
              valAIQ = mq135_getppm(val, MQ135_DEFAULTRO);
            
              Serial.print ( "Val / Ro / value:");
              Serial.print ( val);
              Serial.print ( " / ");
              Serial.print ( mq135_ro);
              Serial.print ( " / ");
              Serial.print ( valAIQ);
            
              // tu skonczylem myk
                
                  send(msg.set(MQ135_DEFAULTPPM+(int)ceil(valAIQ)));
                  lastAIQ = ceil(valAIQ);
                  nNoUpdatesvalr = 0;
            Serial.print (" test 7 ");
                  
              } else {
            
            
             // Increase no update counter if the lightlevel stayed the same
                        nNoUpdatesvalr++;
                        
            
                     }
            
            
                     
                ///// czujnik pozarowy
            
            
                           int16_t lightLevel = (1023-analogRead(LIGHT_SENSOR_ANALOG_PIN))/10.23;
                          if (isnan(lightLevel)) {
                          Serial.println(lightLevel);
                          Serial.println("Failed reading Light");
                          } else if (lightLevel != lastLightLevelpoz || nNoUpdatesLightpoz == FORCE_UPDATE_N_READS) {
                         
                           lastLightLevelpoz = lightLevel;
            
                           nNoUpdatesLightpoz = 0;
                           
                           send(msgLight.set(lightLevel, 1));
            
                           #ifdef MY_DEBUG
                        Serial.print("Lux: ");
                        Serial.println(lightLevel);
                        #endif
                        } else {
                        // Increase no update counter if the lightlevel stayed the same
                        nNoUpdatesLightpoz++;
                    }
               }
              // Sleep for a while to save energy
              // sleep(UPDATE_INTERVAL); 
              // Tu wrzucam cala reszte ktora nie potrzebuje sleep
              
                if( isr_flag == 1 ) {
                detachInterrupt(0);
                handleGesture();
                isr_flag = 0;
                attachInterrupt(0, interruptRoutine, FALLING);
              }
              
            }
            
            
            /*****************************  MQGetPercentage **********************************
            Input:   rs_ro_ratio - Rs divided by Ro
                     pcurve      - pointer to the curve of the target gas
            Output:  ppm of the target gas
            Remarks: By using the slope and a point of the line. The x(logarithmic value of ppm) 
                     of the line could be derived if y(rs_ro_ratio) is provided. As it is a 
                     logarithmic coordinate, power of 10 is used to convert the result to non-logarithmic 
                     value.
            ************************************************************************************/ 
            int  MQGetPercentage(float rs_ro_ratio, float ro, float *pcurve)
            {
              return (double)(pcurve[0] * pow(((double)rs_ro_ratio/ro), pcurve[1]));
            }
            
            
            
            //here originaly was
            // interrupt handler. Is being triggered by the gesture sensor whenever a gesture has been detected. We've setup this up in the setup.
            //void interruptRoutine() {
            //  isr_flag = 1;
            //}
            
            
            // Determine gesture and handle accordingly.We'll ignore FAR and NEAR gestures. Do didn't feel natural to me anyway.
            void handleGesture() {
              if ( apds.isGestureAvailable() ) { // Check if there's a gesture available. Which should be, because the interrupt handler told us so.
                switch ( apds.readGesture() ) { // Get the gesture type.
                  case DIR_UP: // Handle up stroke (Brightness increasing)
                    if ( LastDimValue + BRIGHTNESS_INCREMENT > ( MAXDIMLEVELS - 1 ) ) {
                      for ( int i = 0; i < MAX_LEVEL_REACHED_SIGNAL_COUNT; i++ ) {
                        analogWrite( LED_PIN, dimlevels[ 0 ] );
                        //gw.wait( MAX_LEVEL_REACHED_DELAY );
                        wait( MAX_LEVEL_REACHED_DELAY );
                        analogWrite( LED_PIN, dimlevels[ MAXDIMLEVELS - 1 ] );
                        //gw.wait(MAX_LEVEL_REACHED_DELAY );
                        wait(MAX_LEVEL_REACHED_DELAY );
                      }
                      LastDimValue = ( MAXDIMLEVELS - 1 );
                    }
                    else {
                       LastDimValue += BRIGHTNESS_INCREMENT;
                    }
                    LastLightState = LIGHT_ON;
                    SetCurrentState2Hardware();
                    break;
                  case DIR_DOWN: // Handle down stroke (Brightness decreasing)
                    if ( LastDimValue - BRIGHTNESS_INCREMENT <= 0 ) {
                      LastDimValue = 0;
                    }
                    else {
                       LastDimValue -= BRIGHTNESS_INCREMENT;
                    }
                    if ( LastDimValue == 0 ) {
                      LastLightState = LIGHT_OFF;
                    }
                    else {
                      LastLightState = LIGHT_ON;
                    }
                    SetCurrentState2Hardware();
                    break;
                  case DIR_LEFT: // Handle left stroke. Turn lamp off
                    LastLightState = LIGHT_OFF;
                    SetCurrentState2Hardware();
                    break;
                  case DIR_RIGHT: // Handle right stroke. Turn lamp on
                    LastLightState = LIGHT_ON;
                    if ( LastDimValue == 0 ) { // @@Version 1.1 addition Slight modification. When the dimValue was 0, the light stayed off when turned on.
                      LastDimValue = BRIGHTNESS_INCREMENT; // Just used the first Gesture dimming stage (2 times would be better for my taste though. Might change that in the future)
                    }
                    SetCurrentState2Hardware();
                    break;
                }
              }
            }
            
            /**
             * Handler for message send by the MySensor gateway.
             */ 
            void receive(const MyMessage &message) {
              if ( message.type == V_LIGHT ) { // Gateway reports a new Light state
                int lstate= atoi( message.data );
                if ( ( lstate < 0 ) || ( lstate > 1 ) ) {
                  return;
                }
                LastLightState=lstate;
                if ( ( LastLightState == LIGHT_ON ) &&( LastDimValue == 0 ) ) {
                   //In the case that the Light State = On, but the dimmer value is zero, then something (probably the controller) did something wrong,
                   //for the Dim value to 100%
                  LastDimValue = 100;
                }
                
                //When receiving a V_LIGHT command we switch the light between OFF and the last received dimmer value
                //This means if you previously set the lights dimmer value to 50%, and turn the light ON
                //it will do so at 50%
              }
              else if (message.type == V_DIMMER) { // Gateway reports new dimmer level. We'l adjust it to the new value
                int dimvalue= atoi( message.data );
                if ( ( dimvalue < 0 ) || ( dimvalue > 100 ) ) {
                  return;
                }
                if ( dimvalue == 0 ) {
                  LastLightState = LIGHT_OFF;
                }
                else {
                  LastLightState = LIGHT_ON;
                  LastDimValue = dimvalue;
                }
              }
              //Here we'll set the actual light state/level
              SetCurrentState2Hardware();
            }
            
            // Send current values to the PWM controlled MOSFET
            void SetCurrentState2Hardware() {
              if (LastLightState==LIGHT_OFF) {
                 analogWrite( LED_PIN, dimlevels[0] );
              }
              else {
                 analogWrite( LED_PIN, dimlevels[ LastDimValue - 1 ] );
              }
            
              //Send current state to the controller
              SendCurrentState2Controller();
            }
            
            // Report new values to the Gateway.
            void SendCurrentState2Controller()
            {
              if ((LastLightState==LIGHT_OFF)||(LastDimValue==0)) {
                //gw.send(dimmerMsg.set(0));
                send(dimmerMsg.set(0));
              }
              else {
                //gw.send(dimmerMsg.set(LastDimValue));
                send(dimmerMsg.set(LastDimValue));
              }
            }
            
            
            
            A 2 Replies Last reply
            1
            • P pjjarzembowski

              For those eager to built something more I am posting a new version, with included sensors for temperature and Himidity DHT22 (Pin D4), MQ135 (Pin AI 3), KY-026 IR Flame Sensor (Pin AI 1) it could also be a light sensor LM393, Led (Pin D3), I used LM2596 for 5V which I have taken from 12V power strip. 3.3 V I have taken from arduino UNO. I got some problems with arduino nano, when dealing with bigger powers for led like 50W so that is why I used arduino Uno, it works fine. The problems was that it freezes (I think it was because the quality of power for 3.3V). In the lower powers like 10W there was no problems for arduino nano.

              
              /****************************************************************
                Title: MySensors enabled, gesture controlled lamp.
                
                V1.1 March 2016 by Theo
                
                This lamp can be turned on/off, and dimmed by gestures. And it can be controlled by any Home Automation
                system, that can talk with MySensors.
                
                Supported gesture:
                1. Left to right stroke: turns lamp on
                2. Right to left stroke: turns lamp off
                3. Down to up stroke: increases brightness (When brightness is already at max, the lamp will blink - duration and blink count can be changed in the sketch)
                4. Up to down stroke: decreases brgihtness (When brightness level is at 0 the lamp is off)
                
                The gesture sensor ues in this Sketch is an APDS-9960 RGB and Gesture Sensor, sold by SparkFun. They can be found on eBay and Aliexpress as well.
                See Sparkfuns hookup guide for pin lay-out ( https://learn.sparkfun.com/tutorials/apds-9960-rgb-and-gesture-sensor-hookup-guide ) 
                IMPORTANT: The APDS-9960 can only accept 3.3V! Use bi direction level converter when using another Arduino than a Pro Mini 3.3V
              
                This Sketch is based upon the GestureTest exampl developped by,
                Shawn Hymel @ SparkFun Electronics on May 30, 2014. See https://github.com/sparkfun/APDS-9960_RGB_and_Gesture_Sensor
              
                The lamp itself is a white LED strip, controlled by an N channel MOSFET.
                
                Fore more details on the used hardware and libraries (see https://www.openhardware.io/view/50/Gesture-controlled-MySensors-Floor-lamp )
                
                Developed and test with MySensors release 1.5.4
                
                Revision history:
                3-07-2017 Changed for tests on Mysensors 2.0 
                - The change was not made by the original author of the program
              
                
              
                
                20-03-2016 Version 1.1:
                    - set the brightness level to defined BRIGHTNESS_INCREMENT, when lamp is being turned on be a gesture and the current brightness level is 0.
                      This was a little bug in previous version. It sometimes seemed that the APDS didn't work, but in some cases I had to increase brightness after
                      I turned the lamp on.
                    - cleaned up the code a bit
                19-03-2016 Version 1.0
              ****************************************************************/
              // Import libraries used by the Sketch.
              // added some of my radio definitions (must be before #includes)
              #define MY_DEBUG
              #define MY_RADIO_NRF24
              #define MY_RF24_PA_LEVEL RF24_PA_MAX
              #define MY_NODE_ID 10
              // Enable repeater functionality for this node
              #define MY_REPEATER_FEATURE
              
              #include <SPI.h>
              #include <MySensors.h>  
              #include <Wire.h>
              #include <SparkFun_APDS9960.h>
              #include <DHT.h>
              
              
              // Constants declaration(s)
              #define APDS9960_INT                      2   // Needs to be an interrupt pin. We should be able to use the Arduino's pin 3 as well.
              #define LED_PIN                           3   // The led PWM pin, that drives the LED strip. This is the pin thats attached to the mosfet.
              #define MAXDIMLEVELS                     100  // The maximum number of dim levels. Domoticz supports 0-100 (we'll transalate thim in an array)
              #define BRIGHTNESS_INCREMENT             15   // Dimmer increment for gesture(s). Play with this value yourself. The amount of gesture controlled
                                                            // dim levels is MAXDIMLEVELS / BRIGHTNESS_INCREMENT having 8 to 5 levels feels more natural to me.
              #define MAX_LEVEL_REACHED_DELAY          150  // Short blinking delay when increasing the dimmer while the dimmer is already at max
                                                            // Had some troubles in the past with tha acurateness of the gw.wait on pro mini's. But that'll probably
                                                            // not be noticeable with this short delay. Delay is in milliseconds
              #define MAX_LEVEL_REACHED_SIGNAL_COUNT   2    // The amount of blinks, when the max dim level already has been reached. It's just a way to let the user know
                                                            // that the lamp can not be more brighter than the current brightness
              #define CHILD_ID_LIGHT                   1    // The child id of the Node. Only one Node on this sensor though. See MySensors documentation
              #define LIGHT_OFF                        0    // Constant indicating the lamp on state
              #define LIGHT_ON                         1    // Constant indicationg light off state
              //#define SN "Gesture controlled lamp"          // Description of this sketch. 
              //#define SV                               "1.1" // The version of the Sketch
              
              #define DHT_DATA_PIN 4
              //#define CHILD_ID_AIQ 0
              #define AIQ_SENSOR_ANALOG_PIN 3  //bylo 6
              
              // Set this offset if the sensor has a permanent small offset to the real temperatures
              #define SENSOR_TEMP_OFFSET 0
              #define MQ135_DEFAULTPPM 399 //default ppm of CO2 for calibration
              //#define MQ135_DEFAULTRO 68550 //default Ro for MQ135_DEFAULTPPM ppm of CO2
              #define MQ135_DEFAULTRO 229550 //default Ro for MQ135_DEFAULTPPM ppm of CO2
              #define MQ135_SCALINGFACTOR 116.6020682 //CO2 gas value
              #define MQ135_EXPONENT -2.769034857 //CO2 gas value
              #define MQ135_MAXRSRO 2.428 //for CO2
              #define MQ135_MINRSRO 0.358 //for CO2
              
              #define CHILD_ID_HUM 0
              #define CHILD_ID_TEMP 1
              
              #define CHILD_ID_LIGHTpoz 2
              #define LIGHT_SENSOR_ANALOG_PIN 0 //bylo 7
              
              //VARIABLES
              double mq135_ro = 10000;    // this has to be tuned 10K Ohm
              double val = 0;                 // variable to store the value coming from the sensor
              double valAIQ =0;
              double lastAIQ =0;
              
              // Sleep time between sensor updates (in milliseconds)
              // Must be >1000ms for DHT22 and >2000ms for DHT11
              static const uint64_t UPDATE_INTERVAL = 30000;
              
              
              // Force sending an update of the temperature after n sensor reads, so a controller showing the
              // timestamp of the last update doesn't show something like 3 hours in the unlikely case, that
              // the value didn't change since;
              // i.e. the sensor would force sending an update every UPDATE_INTERVAL*FORCE_UPDATE_N_READS [ms]
              static const uint8_t FORCE_UPDATE_N_READS = 10;
              
              unsigned long lastRefreshTime = 0; // Use this to implement a non-blocking delay function
              float lastTemp;
              float lastHum;
              float lastLightLevel;
              uint8_t nNoUpdatesTemp;
              uint8_t nNoUpdatesHum;
              uint8_t nNoUpdatesLight;
              float lastLightLevelpoz;
              uint8_t nNoUpdatesLightpoz;
              bool metric = true;
              uint8_t nNoUpdatesvalr;
              
              
              // Global Variables
              SparkFun_APDS9960 apds = SparkFun_APDS9960(); // Initialize a SparkFun_APDS9960 object. This does all the magic incl. i2c communication with the sensor.
              int isr_flag = 0;                             // interrupt flag, triggered when a gesture has been dectected. Used to detect gesture detection in the interrupt handler
                                                            // the actual handling is done in the main loop. This allows is the keep the interrupt handler is lightweight is possible
                                                            // which is a good practice. Otherwise you'll get some behaviour you don't expect.
              int LastLightState=LIGHT_OFF;                 // The current lamp state. Wel'll turn it off for first time useage. The Sketch will query your Home Automation System for
                                                            // the last value when it's being reboot.
              int LastDimValue=MAXDIMLEVELS;                // last known dim value (Only initial value. Value is retrieved from your HA system)
              
              /**
               * Values could be calculated. But the sketch is small and storing in an Array is just faster. Otherwise we have to do calculations that incl Floats.
               * Floats take up a lot of your arduino memory
               */
              int dimlevels[ MAXDIMLEVELS ] =  // PWM values used for translating home automation dimmer levels. This gives smoother transations
                {   0,   1,   2,   3,   4,   5,   6,   7,   8,   9,
                   10,  11,  12,  13,  14,  15,  16,  17,  18,  19,
                   20,  21,  22,  23,  24,  25,  26,  27,  28,  29,
                   30,  31,  32,  35,  39,  42,  46,  49,  52,  56,
                   59,  62,  66,  69,  73,  76,  79,  83,  86,  89,
                   93,  96, 100, 103, 106, 110, 113, 116, 120, 123,
                  126, 130, 133, 137, 140, 144, 147, 150, 154, 157,
                  160, 164, 167, 171, 174, 177, 181, 184, 187, 191,
                  194, 197, 201, 204, 208, 211, 215, 218, 221, 225,
                  228, 231, 235, 238, 242, 245, 246, 250, 251, 255 };
              
              /**
               * Variables needed for setting up and communication with MySensors. These variables will handle all of the MySensors magic for you.
               */
              //MySensor gw;
              MyMessage lightMsg(CHILD_ID_LIGHT, V_LIGHT);
              MyMessage dimmerMsg(CHILD_ID_LIGHT, V_DIMMER);
              
              
              MyMessage msg(AIQ_SENSOR_ANALOG_PIN, V_LEVEL);
              MyMessage msgHum(CHILD_ID_HUM, V_HUM);
              MyMessage msgTemp(CHILD_ID_TEMP, V_TEMP );
              MyMessage msgLight(CHILD_ID_LIGHTpoz, V_LIGHT_LEVEL);
              DHT dht;
              
              /**
               * Initializing code. Basicly we'll setup MySensors communication and test if we can communicate with the gesture sensor. See comment in setup method for more details
               */
               // interrupt handler. Is being triggered by the gesture sensor whenever a gesture has been detected. We've setup this up in the setup.
              void interruptRoutine() {
                isr_flag = 1;
              }
              
              
              
              void presentation()  
              { 
                // Send the sketch version information to the gateway
                sendSketchInfo("Led Kuchnia Lampa", "2.0");
              
                // 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(AIQ_SENSOR_ANALOG_PIN, S_AIR_QUALITY);
                present(CHILD_ID_LIGHTpoz, S_LIGHT_LEVEL);
              
                  present(CHILD_ID_LIGHT, S_DIMMER);
                metric = getControllerConfig().isMetric;
              }
              
              
              
              void setup() {
                // Initialize NFR24L01+ radio for enabling MySensors );
                //gw.begin(incomingMessage, AUTO, false);
              
                // Send the Sketch Version Information to the Gateway. Domoticz seems to ignore this. Don't know about the other HA systems. 
               // gw.sendSketchInfo(SN, SV);
              ///sendSketchInfo("Led Kuchnia Lampa", "2.0");
                // Present the dimmable lamp is a child node to the HA system. We'll enable ACK communication.
               // gw.present(CHILD_ID_LIGHT, S_DIMMER, "floor lamp", true );
               // present(CHILD_ID_LIGHT, S_DIMMER);
                // declare output pin for PWM control of the MOSFET
              
                dht.setup(DHT_DATA_PIN); // set data pin of DHT sensor
                if (UPDATE_INTERVAL <= dht.getMinimumSamplingPeriod()) {
                  Serial.println("Warning: UPDATE_INTERVAL is smaller than supported by the sensor!");
                }
              
              
                
                pinMode( LED_PIN, OUTPUT );
              
                // APDS Initialization code
                pinMode(APDS9960_INT, INPUT);   // Set interrupt pin as input. @@Note: this should be handled my the library. But it isn't
                attachInterrupt(0, interruptRoutine, FALLING);   // Initialize interrupt service routine. Basicly it'll call our interrupt routine
              
                if ( apds.init() ) { // Initialize APDS-9960 (configure I2C and initial values)
                  // @@NOTE: original value is two. But it looks like the modern gesture sensor or more sensitive. 1 does it for me
                  apds.setGestureGain( 1 );
                }
                
                if ( apds.enableGestureSensor(true) ) { // Start running the APDS-9960 gesture sensor engine. Sensor support more functions than gesture detection only.
                  analogWrite( LED_PIN, 0 ); // Turn the lamp off.
                  //gw.request( CHILD_ID_LIGHT, V_PERCENTAGE ); // Request current dimvalue from HA. The current value is being handled in the incomming method.
                 request( CHILD_ID_LIGHT, V_PERCENTAGE ); // Request current dimvalue from HA. The current value is being handled in the incomming method.
                  //gw.request( CHILD_ID_LIGHT, V_STATUS ); // Request current lamp state from HA. The current value is being handled in the incomming method.
                request( CHILD_ID_LIGHT, V_STATUS ); // Request current lamp state from HA. The current value is being handled in the incomming method.
                }
                }
              
              
              
              /*
               * get the calibrated ro based upon read resistance, and a know ppm
               */
              long mq135_getro(long resvalue, double ppm) {
              return (long)(resvalue * exp( log(MQ135_SCALINGFACTOR/ppm) / MQ135_EXPONENT ));
              }
              
              /*
               * get the ppm concentration
               */
              double mq135_getppm(long resvalue, long ro) {
              double ret = 0;
              double validinterval = 0;
              validinterval = resvalue/(double)ro;
              if(validinterval<MQ135_MAXRSRO && validinterval>MQ135_MINRSRO) {
              ret = (double)((double)MQ135_SCALINGFACTOR * pow( ((double)resvalue/ro), MQ135_EXPONENT));
              }
              return ret;
              }
              
              
                
              // }
              
              // Main loop. Does twoe things. Handle gestures if detected by the interrupt routine. And give the MySensors lib the oppurtunity to handle incomming messages.
              
              
              void loop()      
              {  
                Serial.print ( "test 1" );
                 boolean needRefresh = (millis() - lastRefreshTime) > UPDATE_INTERVAL;
                 Serial.print ( "test 2 ");
                if (needRefresh)
                {
                     lastRefreshTime = millis();
                     Serial.print ( "test 3 ");
                // Force reading sensor, so it works also after sleep()
                dht.readSensor(true);
                
                // Get temperature from DHT library
                          float temperature = dht.getTemperature();
                          if (isnan(temperature)) {
                             Serial.println("Failed reading temperature from DHT!");
                          } else if (temperature != lastTemp || nNoUpdatesTemp == FORCE_UPDATE_N_READS) {
                          // Only send temperature if it changed since the last measurement or if we didn't send an update for n times
                          lastTemp = temperature;
                          if (!metric) {
                          temperature = dht.toFahrenheit(temperature);
                          }
                          // Reset no updates counter
                          nNoUpdatesTemp = 0;
                          temperature += SENSOR_TEMP_OFFSET;
                          send(msgTemp.set(temperature, 1));
              
                          #ifdef MY_DEBUG
                          Serial.print("T: ");
                          Serial.println(temperature);
                          #endif
                          } else {
                          // Increase no update counter if the temperature stayed the same
                          nNoUpdatesTemp++;
                          Serial.print ( "test 4 ");
                        }
              
                          // Get humidity from DHT library
                          float humidity = dht.getHumidity();
                          if (isnan(humidity)) {
                          Serial.println("Failed reading humidity from DHT");
                          } else if (humidity != lastHum || nNoUpdatesHum == FORCE_UPDATE_N_READS) {
                          // Only send humidity if it changed since the last measurement or if we didn't send an update for n times
                          lastHum = humidity;
                          // Reset no updates counter
                          nNoUpdatesHum = 0;
                          send(msgHum.set(humidity, 1));
                  
                          #ifdef MY_DEBUG
                          Serial.print("H: ");
                          Serial.println(humidity);
                          #endif
                          } else {
                          // Increase no update counter if the humidity stayed the same
                          nNoUpdatesHum++;
                          Serial.print ( "test 5 ");
                         }
                  // Tu wrzucam cala reszte ktora potrzebuje sleep
              //TU  Wrzucilem czujnik MQ135
              
              Serial.print ( "test 6 ");
                double valr = analogRead(AIQ_SENSOR_ANALOG_PIN);// Get AIQ value
                Serial.print ( "test 7 odczytano sensor MQ135 ");
                Serial.println(val);
                 if (isnan(valr)) {
                  Serial.println("Failed reading MQ135");
              
              
                 
                double val =  ((float)22000*(1023-valr)/valr); 
                //during clean air calibration, read the Ro value and replace MQ135_DEFAULTRO value with it, you can even deactivate following function call.
                mq135_ro = mq135_getro(val, MQ135_DEFAULTPPM);
                //convert to ppm (using default ro)
                valAIQ = mq135_getppm(val, MQ135_DEFAULTRO);
              
                Serial.print ( "Val / Ro / value:");
                Serial.print ( val);
                Serial.print ( " / ");
                Serial.print ( mq135_ro);
                Serial.print ( " / ");
                Serial.print ( valAIQ);
              
              
                } else if (valAIQ != lastAIQ || nNoUpdatesvalr == FORCE_UPDATE_N_READS) {
              Serial.print (" test myk zaczal ");
              ////tu zaczalem myk
                double valr = analogRead(AIQ_SENSOR_ANALOG_PIN);// Get AIQ value
                Serial.println(val);
                Serial.print (" mysk w trakcie ");
                double val =  ((float)22000*(1023-valr)/valr); 
                //during clean air calibration, read the Ro value and replace MQ135_DEFAULTRO value with it, you can even deactivate following function call.
                mq135_ro = mq135_getro(val, MQ135_DEFAULTPPM);
                //convert to ppm (using default ro)
                valAIQ = mq135_getppm(val, MQ135_DEFAULTRO);
              
                Serial.print ( "Val / Ro / value:");
                Serial.print ( val);
                Serial.print ( " / ");
                Serial.print ( mq135_ro);
                Serial.print ( " / ");
                Serial.print ( valAIQ);
              
                // tu skonczylem myk
                  
                    send(msg.set(MQ135_DEFAULTPPM+(int)ceil(valAIQ)));
                    lastAIQ = ceil(valAIQ);
                    nNoUpdatesvalr = 0;
              Serial.print (" test 7 ");
                    
                } else {
              
              
               // Increase no update counter if the lightlevel stayed the same
                          nNoUpdatesvalr++;
                          
              
                       }
              
              
                       
                  ///// czujnik pozarowy
              
              
                             int16_t lightLevel = (1023-analogRead(LIGHT_SENSOR_ANALOG_PIN))/10.23;
                            if (isnan(lightLevel)) {
                            Serial.println(lightLevel);
                            Serial.println("Failed reading Light");
                            } else if (lightLevel != lastLightLevelpoz || nNoUpdatesLightpoz == FORCE_UPDATE_N_READS) {
                           
                             lastLightLevelpoz = lightLevel;
              
                             nNoUpdatesLightpoz = 0;
                             
                             send(msgLight.set(lightLevel, 1));
              
                             #ifdef MY_DEBUG
                          Serial.print("Lux: ");
                          Serial.println(lightLevel);
                          #endif
                          } else {
                          // Increase no update counter if the lightlevel stayed the same
                          nNoUpdatesLightpoz++;
                      }
                 }
                // Sleep for a while to save energy
                // sleep(UPDATE_INTERVAL); 
                // Tu wrzucam cala reszte ktora nie potrzebuje sleep
                
                  if( isr_flag == 1 ) {
                  detachInterrupt(0);
                  handleGesture();
                  isr_flag = 0;
                  attachInterrupt(0, interruptRoutine, FALLING);
                }
                
              }
              
              
              /*****************************  MQGetPercentage **********************************
              Input:   rs_ro_ratio - Rs divided by Ro
                       pcurve      - pointer to the curve of the target gas
              Output:  ppm of the target gas
              Remarks: By using the slope and a point of the line. The x(logarithmic value of ppm) 
                       of the line could be derived if y(rs_ro_ratio) is provided. As it is a 
                       logarithmic coordinate, power of 10 is used to convert the result to non-logarithmic 
                       value.
              ************************************************************************************/ 
              int  MQGetPercentage(float rs_ro_ratio, float ro, float *pcurve)
              {
                return (double)(pcurve[0] * pow(((double)rs_ro_ratio/ro), pcurve[1]));
              }
              
              
              
              //here originaly was
              // interrupt handler. Is being triggered by the gesture sensor whenever a gesture has been detected. We've setup this up in the setup.
              //void interruptRoutine() {
              //  isr_flag = 1;
              //}
              
              
              // Determine gesture and handle accordingly.We'll ignore FAR and NEAR gestures. Do didn't feel natural to me anyway.
              void handleGesture() {
                if ( apds.isGestureAvailable() ) { // Check if there's a gesture available. Which should be, because the interrupt handler told us so.
                  switch ( apds.readGesture() ) { // Get the gesture type.
                    case DIR_UP: // Handle up stroke (Brightness increasing)
                      if ( LastDimValue + BRIGHTNESS_INCREMENT > ( MAXDIMLEVELS - 1 ) ) {
                        for ( int i = 0; i < MAX_LEVEL_REACHED_SIGNAL_COUNT; i++ ) {
                          analogWrite( LED_PIN, dimlevels[ 0 ] );
                          //gw.wait( MAX_LEVEL_REACHED_DELAY );
                          wait( MAX_LEVEL_REACHED_DELAY );
                          analogWrite( LED_PIN, dimlevels[ MAXDIMLEVELS - 1 ] );
                          //gw.wait(MAX_LEVEL_REACHED_DELAY );
                          wait(MAX_LEVEL_REACHED_DELAY );
                        }
                        LastDimValue = ( MAXDIMLEVELS - 1 );
                      }
                      else {
                         LastDimValue += BRIGHTNESS_INCREMENT;
                      }
                      LastLightState = LIGHT_ON;
                      SetCurrentState2Hardware();
                      break;
                    case DIR_DOWN: // Handle down stroke (Brightness decreasing)
                      if ( LastDimValue - BRIGHTNESS_INCREMENT <= 0 ) {
                        LastDimValue = 0;
                      }
                      else {
                         LastDimValue -= BRIGHTNESS_INCREMENT;
                      }
                      if ( LastDimValue == 0 ) {
                        LastLightState = LIGHT_OFF;
                      }
                      else {
                        LastLightState = LIGHT_ON;
                      }
                      SetCurrentState2Hardware();
                      break;
                    case DIR_LEFT: // Handle left stroke. Turn lamp off
                      LastLightState = LIGHT_OFF;
                      SetCurrentState2Hardware();
                      break;
                    case DIR_RIGHT: // Handle right stroke. Turn lamp on
                      LastLightState = LIGHT_ON;
                      if ( LastDimValue == 0 ) { // @@Version 1.1 addition Slight modification. When the dimValue was 0, the light stayed off when turned on.
                        LastDimValue = BRIGHTNESS_INCREMENT; // Just used the first Gesture dimming stage (2 times would be better for my taste though. Might change that in the future)
                      }
                      SetCurrentState2Hardware();
                      break;
                  }
                }
              }
              
              /**
               * Handler for message send by the MySensor gateway.
               */ 
              void receive(const MyMessage &message) {
                if ( message.type == V_LIGHT ) { // Gateway reports a new Light state
                  int lstate= atoi( message.data );
                  if ( ( lstate < 0 ) || ( lstate > 1 ) ) {
                    return;
                  }
                  LastLightState=lstate;
                  if ( ( LastLightState == LIGHT_ON ) &&( LastDimValue == 0 ) ) {
                     //In the case that the Light State = On, but the dimmer value is zero, then something (probably the controller) did something wrong,
                     //for the Dim value to 100%
                    LastDimValue = 100;
                  }
                  
                  //When receiving a V_LIGHT command we switch the light between OFF and the last received dimmer value
                  //This means if you previously set the lights dimmer value to 50%, and turn the light ON
                  //it will do so at 50%
                }
                else if (message.type == V_DIMMER) { // Gateway reports new dimmer level. We'l adjust it to the new value
                  int dimvalue= atoi( message.data );
                  if ( ( dimvalue < 0 ) || ( dimvalue > 100 ) ) {
                    return;
                  }
                  if ( dimvalue == 0 ) {
                    LastLightState = LIGHT_OFF;
                  }
                  else {
                    LastLightState = LIGHT_ON;
                    LastDimValue = dimvalue;
                  }
                }
                //Here we'll set the actual light state/level
                SetCurrentState2Hardware();
              }
              
              // Send current values to the PWM controlled MOSFET
              void SetCurrentState2Hardware() {
                if (LastLightState==LIGHT_OFF) {
                   analogWrite( LED_PIN, dimlevels[0] );
                }
                else {
                   analogWrite( LED_PIN, dimlevels[ LastDimValue - 1 ] );
                }
              
                //Send current state to the controller
                SendCurrentState2Controller();
              }
              
              // Report new values to the Gateway.
              void SendCurrentState2Controller()
              {
                if ((LastLightState==LIGHT_OFF)||(LastDimValue==0)) {
                  //gw.send(dimmerMsg.set(0));
                  send(dimmerMsg.set(0));
                }
                else {
                  //gw.send(dimmerMsg.set(LastDimValue));
                  send(dimmerMsg.set(LastDimValue));
                }
              }
              
              
              
              A Offline
              A Offline
              APL2017
              wrote on last edited by APL2017
              #23

              Hello. Can somebody publish working code just for gesture and LED dimming with latest mySensors library? Thank you.

              TheoLT 1 Reply Last reply
              0
              • mfalkviddM mfalkvidd

                Got my gesture sensor from China today. Took a while to figure out that I had to solder the bridge for the ir led. Thanks a lot for the notes about setting gesture gain, I wasn't able to get gestures working until I found that note. The sensor works great now!

                A Offline
                A Offline
                APL2017
                wrote on last edited by
                #24
                This post is deleted!
                1 Reply Last reply
                0
                • P pjjarzembowski

                  For those eager to built something more I am posting a new version, with included sensors for temperature and Himidity DHT22 (Pin D4), MQ135 (Pin AI 3), KY-026 IR Flame Sensor (Pin AI 1) it could also be a light sensor LM393, Led (Pin D3), I used LM2596 for 5V which I have taken from 12V power strip. 3.3 V I have taken from arduino UNO. I got some problems with arduino nano, when dealing with bigger powers for led like 50W so that is why I used arduino Uno, it works fine. The problems was that it freezes (I think it was because the quality of power for 3.3V). In the lower powers like 10W there was no problems for arduino nano.

                  
                  /****************************************************************
                    Title: MySensors enabled, gesture controlled lamp.
                    
                    V1.1 March 2016 by Theo
                    
                    This lamp can be turned on/off, and dimmed by gestures. And it can be controlled by any Home Automation
                    system, that can talk with MySensors.
                    
                    Supported gesture:
                    1. Left to right stroke: turns lamp on
                    2. Right to left stroke: turns lamp off
                    3. Down to up stroke: increases brightness (When brightness is already at max, the lamp will blink - duration and blink count can be changed in the sketch)
                    4. Up to down stroke: decreases brgihtness (When brightness level is at 0 the lamp is off)
                    
                    The gesture sensor ues in this Sketch is an APDS-9960 RGB and Gesture Sensor, sold by SparkFun. They can be found on eBay and Aliexpress as well.
                    See Sparkfuns hookup guide for pin lay-out ( https://learn.sparkfun.com/tutorials/apds-9960-rgb-and-gesture-sensor-hookup-guide ) 
                    IMPORTANT: The APDS-9960 can only accept 3.3V! Use bi direction level converter when using another Arduino than a Pro Mini 3.3V
                  
                    This Sketch is based upon the GestureTest exampl developped by,
                    Shawn Hymel @ SparkFun Electronics on May 30, 2014. See https://github.com/sparkfun/APDS-9960_RGB_and_Gesture_Sensor
                  
                    The lamp itself is a white LED strip, controlled by an N channel MOSFET.
                    
                    Fore more details on the used hardware and libraries (see https://www.openhardware.io/view/50/Gesture-controlled-MySensors-Floor-lamp )
                    
                    Developed and test with MySensors release 1.5.4
                    
                    Revision history:
                    3-07-2017 Changed for tests on Mysensors 2.0 
                    - The change was not made by the original author of the program
                  
                    
                  
                    
                    20-03-2016 Version 1.1:
                        - set the brightness level to defined BRIGHTNESS_INCREMENT, when lamp is being turned on be a gesture and the current brightness level is 0.
                          This was a little bug in previous version. It sometimes seemed that the APDS didn't work, but in some cases I had to increase brightness after
                          I turned the lamp on.
                        - cleaned up the code a bit
                    19-03-2016 Version 1.0
                  ****************************************************************/
                  // Import libraries used by the Sketch.
                  // added some of my radio definitions (must be before #includes)
                  #define MY_DEBUG
                  #define MY_RADIO_NRF24
                  #define MY_RF24_PA_LEVEL RF24_PA_MAX
                  #define MY_NODE_ID 10
                  // Enable repeater functionality for this node
                  #define MY_REPEATER_FEATURE
                  
                  #include <SPI.h>
                  #include <MySensors.h>  
                  #include <Wire.h>
                  #include <SparkFun_APDS9960.h>
                  #include <DHT.h>
                  
                  
                  // Constants declaration(s)
                  #define APDS9960_INT                      2   // Needs to be an interrupt pin. We should be able to use the Arduino's pin 3 as well.
                  #define LED_PIN                           3   // The led PWM pin, that drives the LED strip. This is the pin thats attached to the mosfet.
                  #define MAXDIMLEVELS                     100  // The maximum number of dim levels. Domoticz supports 0-100 (we'll transalate thim in an array)
                  #define BRIGHTNESS_INCREMENT             15   // Dimmer increment for gesture(s). Play with this value yourself. The amount of gesture controlled
                                                                // dim levels is MAXDIMLEVELS / BRIGHTNESS_INCREMENT having 8 to 5 levels feels more natural to me.
                  #define MAX_LEVEL_REACHED_DELAY          150  // Short blinking delay when increasing the dimmer while the dimmer is already at max
                                                                // Had some troubles in the past with tha acurateness of the gw.wait on pro mini's. But that'll probably
                                                                // not be noticeable with this short delay. Delay is in milliseconds
                  #define MAX_LEVEL_REACHED_SIGNAL_COUNT   2    // The amount of blinks, when the max dim level already has been reached. It's just a way to let the user know
                                                                // that the lamp can not be more brighter than the current brightness
                  #define CHILD_ID_LIGHT                   1    // The child id of the Node. Only one Node on this sensor though. See MySensors documentation
                  #define LIGHT_OFF                        0    // Constant indicating the lamp on state
                  #define LIGHT_ON                         1    // Constant indicationg light off state
                  //#define SN "Gesture controlled lamp"          // Description of this sketch. 
                  //#define SV                               "1.1" // The version of the Sketch
                  
                  #define DHT_DATA_PIN 4
                  //#define CHILD_ID_AIQ 0
                  #define AIQ_SENSOR_ANALOG_PIN 3  //bylo 6
                  
                  // Set this offset if the sensor has a permanent small offset to the real temperatures
                  #define SENSOR_TEMP_OFFSET 0
                  #define MQ135_DEFAULTPPM 399 //default ppm of CO2 for calibration
                  //#define MQ135_DEFAULTRO 68550 //default Ro for MQ135_DEFAULTPPM ppm of CO2
                  #define MQ135_DEFAULTRO 229550 //default Ro for MQ135_DEFAULTPPM ppm of CO2
                  #define MQ135_SCALINGFACTOR 116.6020682 //CO2 gas value
                  #define MQ135_EXPONENT -2.769034857 //CO2 gas value
                  #define MQ135_MAXRSRO 2.428 //for CO2
                  #define MQ135_MINRSRO 0.358 //for CO2
                  
                  #define CHILD_ID_HUM 0
                  #define CHILD_ID_TEMP 1
                  
                  #define CHILD_ID_LIGHTpoz 2
                  #define LIGHT_SENSOR_ANALOG_PIN 0 //bylo 7
                  
                  //VARIABLES
                  double mq135_ro = 10000;    // this has to be tuned 10K Ohm
                  double val = 0;                 // variable to store the value coming from the sensor
                  double valAIQ =0;
                  double lastAIQ =0;
                  
                  // Sleep time between sensor updates (in milliseconds)
                  // Must be >1000ms for DHT22 and >2000ms for DHT11
                  static const uint64_t UPDATE_INTERVAL = 30000;
                  
                  
                  // Force sending an update of the temperature after n sensor reads, so a controller showing the
                  // timestamp of the last update doesn't show something like 3 hours in the unlikely case, that
                  // the value didn't change since;
                  // i.e. the sensor would force sending an update every UPDATE_INTERVAL*FORCE_UPDATE_N_READS [ms]
                  static const uint8_t FORCE_UPDATE_N_READS = 10;
                  
                  unsigned long lastRefreshTime = 0; // Use this to implement a non-blocking delay function
                  float lastTemp;
                  float lastHum;
                  float lastLightLevel;
                  uint8_t nNoUpdatesTemp;
                  uint8_t nNoUpdatesHum;
                  uint8_t nNoUpdatesLight;
                  float lastLightLevelpoz;
                  uint8_t nNoUpdatesLightpoz;
                  bool metric = true;
                  uint8_t nNoUpdatesvalr;
                  
                  
                  // Global Variables
                  SparkFun_APDS9960 apds = SparkFun_APDS9960(); // Initialize a SparkFun_APDS9960 object. This does all the magic incl. i2c communication with the sensor.
                  int isr_flag = 0;                             // interrupt flag, triggered when a gesture has been dectected. Used to detect gesture detection in the interrupt handler
                                                                // the actual handling is done in the main loop. This allows is the keep the interrupt handler is lightweight is possible
                                                                // which is a good practice. Otherwise you'll get some behaviour you don't expect.
                  int LastLightState=LIGHT_OFF;                 // The current lamp state. Wel'll turn it off for first time useage. The Sketch will query your Home Automation System for
                                                                // the last value when it's being reboot.
                  int LastDimValue=MAXDIMLEVELS;                // last known dim value (Only initial value. Value is retrieved from your HA system)
                  
                  /**
                   * Values could be calculated. But the sketch is small and storing in an Array is just faster. Otherwise we have to do calculations that incl Floats.
                   * Floats take up a lot of your arduino memory
                   */
                  int dimlevels[ MAXDIMLEVELS ] =  // PWM values used for translating home automation dimmer levels. This gives smoother transations
                    {   0,   1,   2,   3,   4,   5,   6,   7,   8,   9,
                       10,  11,  12,  13,  14,  15,  16,  17,  18,  19,
                       20,  21,  22,  23,  24,  25,  26,  27,  28,  29,
                       30,  31,  32,  35,  39,  42,  46,  49,  52,  56,
                       59,  62,  66,  69,  73,  76,  79,  83,  86,  89,
                       93,  96, 100, 103, 106, 110, 113, 116, 120, 123,
                      126, 130, 133, 137, 140, 144, 147, 150, 154, 157,
                      160, 164, 167, 171, 174, 177, 181, 184, 187, 191,
                      194, 197, 201, 204, 208, 211, 215, 218, 221, 225,
                      228, 231, 235, 238, 242, 245, 246, 250, 251, 255 };
                  
                  /**
                   * Variables needed for setting up and communication with MySensors. These variables will handle all of the MySensors magic for you.
                   */
                  //MySensor gw;
                  MyMessage lightMsg(CHILD_ID_LIGHT, V_LIGHT);
                  MyMessage dimmerMsg(CHILD_ID_LIGHT, V_DIMMER);
                  
                  
                  MyMessage msg(AIQ_SENSOR_ANALOG_PIN, V_LEVEL);
                  MyMessage msgHum(CHILD_ID_HUM, V_HUM);
                  MyMessage msgTemp(CHILD_ID_TEMP, V_TEMP );
                  MyMessage msgLight(CHILD_ID_LIGHTpoz, V_LIGHT_LEVEL);
                  DHT dht;
                  
                  /**
                   * Initializing code. Basicly we'll setup MySensors communication and test if we can communicate with the gesture sensor. See comment in setup method for more details
                   */
                   // interrupt handler. Is being triggered by the gesture sensor whenever a gesture has been detected. We've setup this up in the setup.
                  void interruptRoutine() {
                    isr_flag = 1;
                  }
                  
                  
                  
                  void presentation()  
                  { 
                    // Send the sketch version information to the gateway
                    sendSketchInfo("Led Kuchnia Lampa", "2.0");
                  
                    // 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(AIQ_SENSOR_ANALOG_PIN, S_AIR_QUALITY);
                    present(CHILD_ID_LIGHTpoz, S_LIGHT_LEVEL);
                  
                      present(CHILD_ID_LIGHT, S_DIMMER);
                    metric = getControllerConfig().isMetric;
                  }
                  
                  
                  
                  void setup() {
                    // Initialize NFR24L01+ radio for enabling MySensors );
                    //gw.begin(incomingMessage, AUTO, false);
                  
                    // Send the Sketch Version Information to the Gateway. Domoticz seems to ignore this. Don't know about the other HA systems. 
                   // gw.sendSketchInfo(SN, SV);
                  ///sendSketchInfo("Led Kuchnia Lampa", "2.0");
                    // Present the dimmable lamp is a child node to the HA system. We'll enable ACK communication.
                   // gw.present(CHILD_ID_LIGHT, S_DIMMER, "floor lamp", true );
                   // present(CHILD_ID_LIGHT, S_DIMMER);
                    // declare output pin for PWM control of the MOSFET
                  
                    dht.setup(DHT_DATA_PIN); // set data pin of DHT sensor
                    if (UPDATE_INTERVAL <= dht.getMinimumSamplingPeriod()) {
                      Serial.println("Warning: UPDATE_INTERVAL is smaller than supported by the sensor!");
                    }
                  
                  
                    
                    pinMode( LED_PIN, OUTPUT );
                  
                    // APDS Initialization code
                    pinMode(APDS9960_INT, INPUT);   // Set interrupt pin as input. @@Note: this should be handled my the library. But it isn't
                    attachInterrupt(0, interruptRoutine, FALLING);   // Initialize interrupt service routine. Basicly it'll call our interrupt routine
                  
                    if ( apds.init() ) { // Initialize APDS-9960 (configure I2C and initial values)
                      // @@NOTE: original value is two. But it looks like the modern gesture sensor or more sensitive. 1 does it for me
                      apds.setGestureGain( 1 );
                    }
                    
                    if ( apds.enableGestureSensor(true) ) { // Start running the APDS-9960 gesture sensor engine. Sensor support more functions than gesture detection only.
                      analogWrite( LED_PIN, 0 ); // Turn the lamp off.
                      //gw.request( CHILD_ID_LIGHT, V_PERCENTAGE ); // Request current dimvalue from HA. The current value is being handled in the incomming method.
                     request( CHILD_ID_LIGHT, V_PERCENTAGE ); // Request current dimvalue from HA. The current value is being handled in the incomming method.
                      //gw.request( CHILD_ID_LIGHT, V_STATUS ); // Request current lamp state from HA. The current value is being handled in the incomming method.
                    request( CHILD_ID_LIGHT, V_STATUS ); // Request current lamp state from HA. The current value is being handled in the incomming method.
                    }
                    }
                  
                  
                  
                  /*
                   * get the calibrated ro based upon read resistance, and a know ppm
                   */
                  long mq135_getro(long resvalue, double ppm) {
                  return (long)(resvalue * exp( log(MQ135_SCALINGFACTOR/ppm) / MQ135_EXPONENT ));
                  }
                  
                  /*
                   * get the ppm concentration
                   */
                  double mq135_getppm(long resvalue, long ro) {
                  double ret = 0;
                  double validinterval = 0;
                  validinterval = resvalue/(double)ro;
                  if(validinterval<MQ135_MAXRSRO && validinterval>MQ135_MINRSRO) {
                  ret = (double)((double)MQ135_SCALINGFACTOR * pow( ((double)resvalue/ro), MQ135_EXPONENT));
                  }
                  return ret;
                  }
                  
                  
                    
                  // }
                  
                  // Main loop. Does twoe things. Handle gestures if detected by the interrupt routine. And give the MySensors lib the oppurtunity to handle incomming messages.
                  
                  
                  void loop()      
                  {  
                    Serial.print ( "test 1" );
                     boolean needRefresh = (millis() - lastRefreshTime) > UPDATE_INTERVAL;
                     Serial.print ( "test 2 ");
                    if (needRefresh)
                    {
                         lastRefreshTime = millis();
                         Serial.print ( "test 3 ");
                    // Force reading sensor, so it works also after sleep()
                    dht.readSensor(true);
                    
                    // Get temperature from DHT library
                              float temperature = dht.getTemperature();
                              if (isnan(temperature)) {
                                 Serial.println("Failed reading temperature from DHT!");
                              } else if (temperature != lastTemp || nNoUpdatesTemp == FORCE_UPDATE_N_READS) {
                              // Only send temperature if it changed since the last measurement or if we didn't send an update for n times
                              lastTemp = temperature;
                              if (!metric) {
                              temperature = dht.toFahrenheit(temperature);
                              }
                              // Reset no updates counter
                              nNoUpdatesTemp = 0;
                              temperature += SENSOR_TEMP_OFFSET;
                              send(msgTemp.set(temperature, 1));
                  
                              #ifdef MY_DEBUG
                              Serial.print("T: ");
                              Serial.println(temperature);
                              #endif
                              } else {
                              // Increase no update counter if the temperature stayed the same
                              nNoUpdatesTemp++;
                              Serial.print ( "test 4 ");
                            }
                  
                              // Get humidity from DHT library
                              float humidity = dht.getHumidity();
                              if (isnan(humidity)) {
                              Serial.println("Failed reading humidity from DHT");
                              } else if (humidity != lastHum || nNoUpdatesHum == FORCE_UPDATE_N_READS) {
                              // Only send humidity if it changed since the last measurement or if we didn't send an update for n times
                              lastHum = humidity;
                              // Reset no updates counter
                              nNoUpdatesHum = 0;
                              send(msgHum.set(humidity, 1));
                      
                              #ifdef MY_DEBUG
                              Serial.print("H: ");
                              Serial.println(humidity);
                              #endif
                              } else {
                              // Increase no update counter if the humidity stayed the same
                              nNoUpdatesHum++;
                              Serial.print ( "test 5 ");
                             }
                      // Tu wrzucam cala reszte ktora potrzebuje sleep
                  //TU  Wrzucilem czujnik MQ135
                  
                  Serial.print ( "test 6 ");
                    double valr = analogRead(AIQ_SENSOR_ANALOG_PIN);// Get AIQ value
                    Serial.print ( "test 7 odczytano sensor MQ135 ");
                    Serial.println(val);
                     if (isnan(valr)) {
                      Serial.println("Failed reading MQ135");
                  
                  
                     
                    double val =  ((float)22000*(1023-valr)/valr); 
                    //during clean air calibration, read the Ro value and replace MQ135_DEFAULTRO value with it, you can even deactivate following function call.
                    mq135_ro = mq135_getro(val, MQ135_DEFAULTPPM);
                    //convert to ppm (using default ro)
                    valAIQ = mq135_getppm(val, MQ135_DEFAULTRO);
                  
                    Serial.print ( "Val / Ro / value:");
                    Serial.print ( val);
                    Serial.print ( " / ");
                    Serial.print ( mq135_ro);
                    Serial.print ( " / ");
                    Serial.print ( valAIQ);
                  
                  
                    } else if (valAIQ != lastAIQ || nNoUpdatesvalr == FORCE_UPDATE_N_READS) {
                  Serial.print (" test myk zaczal ");
                  ////tu zaczalem myk
                    double valr = analogRead(AIQ_SENSOR_ANALOG_PIN);// Get AIQ value
                    Serial.println(val);
                    Serial.print (" mysk w trakcie ");
                    double val =  ((float)22000*(1023-valr)/valr); 
                    //during clean air calibration, read the Ro value and replace MQ135_DEFAULTRO value with it, you can even deactivate following function call.
                    mq135_ro = mq135_getro(val, MQ135_DEFAULTPPM);
                    //convert to ppm (using default ro)
                    valAIQ = mq135_getppm(val, MQ135_DEFAULTRO);
                  
                    Serial.print ( "Val / Ro / value:");
                    Serial.print ( val);
                    Serial.print ( " / ");
                    Serial.print ( mq135_ro);
                    Serial.print ( " / ");
                    Serial.print ( valAIQ);
                  
                    // tu skonczylem myk
                      
                        send(msg.set(MQ135_DEFAULTPPM+(int)ceil(valAIQ)));
                        lastAIQ = ceil(valAIQ);
                        nNoUpdatesvalr = 0;
                  Serial.print (" test 7 ");
                        
                    } else {
                  
                  
                   // Increase no update counter if the lightlevel stayed the same
                              nNoUpdatesvalr++;
                              
                  
                           }
                  
                  
                           
                      ///// czujnik pozarowy
                  
                  
                                 int16_t lightLevel = (1023-analogRead(LIGHT_SENSOR_ANALOG_PIN))/10.23;
                                if (isnan(lightLevel)) {
                                Serial.println(lightLevel);
                                Serial.println("Failed reading Light");
                                } else if (lightLevel != lastLightLevelpoz || nNoUpdatesLightpoz == FORCE_UPDATE_N_READS) {
                               
                                 lastLightLevelpoz = lightLevel;
                  
                                 nNoUpdatesLightpoz = 0;
                                 
                                 send(msgLight.set(lightLevel, 1));
                  
                                 #ifdef MY_DEBUG
                              Serial.print("Lux: ");
                              Serial.println(lightLevel);
                              #endif
                              } else {
                              // Increase no update counter if the lightlevel stayed the same
                              nNoUpdatesLightpoz++;
                          }
                     }
                    // Sleep for a while to save energy
                    // sleep(UPDATE_INTERVAL); 
                    // Tu wrzucam cala reszte ktora nie potrzebuje sleep
                    
                      if( isr_flag == 1 ) {
                      detachInterrupt(0);
                      handleGesture();
                      isr_flag = 0;
                      attachInterrupt(0, interruptRoutine, FALLING);
                    }
                    
                  }
                  
                  
                  /*****************************  MQGetPercentage **********************************
                  Input:   rs_ro_ratio - Rs divided by Ro
                           pcurve      - pointer to the curve of the target gas
                  Output:  ppm of the target gas
                  Remarks: By using the slope and a point of the line. The x(logarithmic value of ppm) 
                           of the line could be derived if y(rs_ro_ratio) is provided. As it is a 
                           logarithmic coordinate, power of 10 is used to convert the result to non-logarithmic 
                           value.
                  ************************************************************************************/ 
                  int  MQGetPercentage(float rs_ro_ratio, float ro, float *pcurve)
                  {
                    return (double)(pcurve[0] * pow(((double)rs_ro_ratio/ro), pcurve[1]));
                  }
                  
                  
                  
                  //here originaly was
                  // interrupt handler. Is being triggered by the gesture sensor whenever a gesture has been detected. We've setup this up in the setup.
                  //void interruptRoutine() {
                  //  isr_flag = 1;
                  //}
                  
                  
                  // Determine gesture and handle accordingly.We'll ignore FAR and NEAR gestures. Do didn't feel natural to me anyway.
                  void handleGesture() {
                    if ( apds.isGestureAvailable() ) { // Check if there's a gesture available. Which should be, because the interrupt handler told us so.
                      switch ( apds.readGesture() ) { // Get the gesture type.
                        case DIR_UP: // Handle up stroke (Brightness increasing)
                          if ( LastDimValue + BRIGHTNESS_INCREMENT > ( MAXDIMLEVELS - 1 ) ) {
                            for ( int i = 0; i < MAX_LEVEL_REACHED_SIGNAL_COUNT; i++ ) {
                              analogWrite( LED_PIN, dimlevels[ 0 ] );
                              //gw.wait( MAX_LEVEL_REACHED_DELAY );
                              wait( MAX_LEVEL_REACHED_DELAY );
                              analogWrite( LED_PIN, dimlevels[ MAXDIMLEVELS - 1 ] );
                              //gw.wait(MAX_LEVEL_REACHED_DELAY );
                              wait(MAX_LEVEL_REACHED_DELAY );
                            }
                            LastDimValue = ( MAXDIMLEVELS - 1 );
                          }
                          else {
                             LastDimValue += BRIGHTNESS_INCREMENT;
                          }
                          LastLightState = LIGHT_ON;
                          SetCurrentState2Hardware();
                          break;
                        case DIR_DOWN: // Handle down stroke (Brightness decreasing)
                          if ( LastDimValue - BRIGHTNESS_INCREMENT <= 0 ) {
                            LastDimValue = 0;
                          }
                          else {
                             LastDimValue -= BRIGHTNESS_INCREMENT;
                          }
                          if ( LastDimValue == 0 ) {
                            LastLightState = LIGHT_OFF;
                          }
                          else {
                            LastLightState = LIGHT_ON;
                          }
                          SetCurrentState2Hardware();
                          break;
                        case DIR_LEFT: // Handle left stroke. Turn lamp off
                          LastLightState = LIGHT_OFF;
                          SetCurrentState2Hardware();
                          break;
                        case DIR_RIGHT: // Handle right stroke. Turn lamp on
                          LastLightState = LIGHT_ON;
                          if ( LastDimValue == 0 ) { // @@Version 1.1 addition Slight modification. When the dimValue was 0, the light stayed off when turned on.
                            LastDimValue = BRIGHTNESS_INCREMENT; // Just used the first Gesture dimming stage (2 times would be better for my taste though. Might change that in the future)
                          }
                          SetCurrentState2Hardware();
                          break;
                      }
                    }
                  }
                  
                  /**
                   * Handler for message send by the MySensor gateway.
                   */ 
                  void receive(const MyMessage &message) {
                    if ( message.type == V_LIGHT ) { // Gateway reports a new Light state
                      int lstate= atoi( message.data );
                      if ( ( lstate < 0 ) || ( lstate > 1 ) ) {
                        return;
                      }
                      LastLightState=lstate;
                      if ( ( LastLightState == LIGHT_ON ) &&( LastDimValue == 0 ) ) {
                         //In the case that the Light State = On, but the dimmer value is zero, then something (probably the controller) did something wrong,
                         //for the Dim value to 100%
                        LastDimValue = 100;
                      }
                      
                      //When receiving a V_LIGHT command we switch the light between OFF and the last received dimmer value
                      //This means if you previously set the lights dimmer value to 50%, and turn the light ON
                      //it will do so at 50%
                    }
                    else if (message.type == V_DIMMER) { // Gateway reports new dimmer level. We'l adjust it to the new value
                      int dimvalue= atoi( message.data );
                      if ( ( dimvalue < 0 ) || ( dimvalue > 100 ) ) {
                        return;
                      }
                      if ( dimvalue == 0 ) {
                        LastLightState = LIGHT_OFF;
                      }
                      else {
                        LastLightState = LIGHT_ON;
                        LastDimValue = dimvalue;
                      }
                    }
                    //Here we'll set the actual light state/level
                    SetCurrentState2Hardware();
                  }
                  
                  // Send current values to the PWM controlled MOSFET
                  void SetCurrentState2Hardware() {
                    if (LastLightState==LIGHT_OFF) {
                       analogWrite( LED_PIN, dimlevels[0] );
                    }
                    else {
                       analogWrite( LED_PIN, dimlevels[ LastDimValue - 1 ] );
                    }
                  
                    //Send current state to the controller
                    SendCurrentState2Controller();
                  }
                  
                  // Report new values to the Gateway.
                  void SendCurrentState2Controller()
                  {
                    if ((LastLightState==LIGHT_OFF)||(LastDimValue==0)) {
                      //gw.send(dimmerMsg.set(0));
                      send(dimmerMsg.set(0));
                    }
                    else {
                      //gw.send(dimmerMsg.set(LastDimValue));
                      send(dimmerMsg.set(LastDimValue));
                    }
                  }
                  
                  
                  
                  A Offline
                  A Offline
                  APL2017
                  wrote on last edited by
                  #25
                  This post is deleted!
                  1 Reply Last reply
                  0
                  • mfalkviddM mfalkvidd

                    Got my gesture sensor from China today. Took a while to figure out that I had to solder the bridge for the ir led. Thanks a lot for the notes about setting gesture gain, I wasn't able to get gestures working until I found that note. The sensor works great now!

                    A Offline
                    A Offline
                    APL2017
                    wrote on last edited by
                    #26
                    This post is deleted!
                    1 Reply Last reply
                    0
                    • A APL2017

                      Hello. Can somebody publish working code just for gesture and LED dimming with latest mySensors library? Thank you.

                      TheoLT Offline
                      TheoLT Offline
                      TheoL
                      Contest Winner
                      wrote on last edited by TheoL
                      #27

                      @APL2017 Posting one question multiple times isn't gonna give you an answer quickly. I just wanted to say that.

                      I see the code on the website is still in pre MS 2.0. It should be easy to convert it to MS 2.0. The only problem is that I don't have the hardware setup to check if it works. If I can find some time this week I will convert it, so that it at least compiles. But I can not test it and can't promise I will finish it this week.

                      But @pjjarzembowski version should work, you should only strip out the extra sensors he attached to his node.

                      After playing with dimmers and Domoticz for quite some time, I've discovered that 15 brightness levels is all I need. Because it's hard to see the difference is brightness level if you have 100 levels. And also it takes a lot of gestures to move from max to min. So the code can be simplified more. By just mapping the Domotics level (1-100) to (1-15) and the opposite when you send the nodes brightness level to Domoticz.

                      Also Domoticz behaves odd when it comes to dimmer actuators as I discovered during a project I'm working on now. There are some work arounds for that, which envolve storing the brightness levels on the eeprom of your node. I know 100000 times is a lot. But I really don't see the need to store each brightness level change in the eeprom.

                      A 2 Replies Last reply
                      0
                      • TheoLT TheoL

                        @APL2017 Posting one question multiple times isn't gonna give you an answer quickly. I just wanted to say that.

                        I see the code on the website is still in pre MS 2.0. It should be easy to convert it to MS 2.0. The only problem is that I don't have the hardware setup to check if it works. If I can find some time this week I will convert it, so that it at least compiles. But I can not test it and can't promise I will finish it this week.

                        But @pjjarzembowski version should work, you should only strip out the extra sensors he attached to his node.

                        After playing with dimmers and Domoticz for quite some time, I've discovered that 15 brightness levels is all I need. Because it's hard to see the difference is brightness level if you have 100 levels. And also it takes a lot of gestures to move from max to min. So the code can be simplified more. By just mapping the Domotics level (1-100) to (1-15) and the opposite when you send the nodes brightness level to Domoticz.

                        Also Domoticz behaves odd when it comes to dimmer actuators as I discovered during a project I'm working on now. There are some work arounds for that, which envolve storing the brightness levels on the eeprom of your node. I know 100000 times is a lot. But I really don't see the need to store each brightness level change in the eeprom.

                        A Offline
                        A Offline
                        APL2017
                        wrote on last edited by APL2017
                        #28

                        @TheoL Sorry, I though that I deleted multiple posts. I understand about stripping the code, this is what I am trying to do, just got a bit confused between parts of the code responsible for measuring and controlling the light (similar variable names, etc.). Thanks for the idea about reducing number of light levels, totally make sense. My personal take on this project would be having gesture controller physically separate from the light controller with mySensors node to node communication between. May I ask you why you don't use this setup anymore? FYI, I use ioBroker as controller and happy with it (most of the time)

                        TheoLT 1 Reply Last reply
                        0
                        • A APL2017

                          @TheoL Sorry, I though that I deleted multiple posts. I understand about stripping the code, this is what I am trying to do, just got a bit confused between parts of the code responsible for measuring and controlling the light (similar variable names, etc.). Thanks for the idea about reducing number of light levels, totally make sense. My personal take on this project would be having gesture controller physically separate from the light controller with mySensors node to node communication between. May I ask you why you don't use this setup anymore? FYI, I use ioBroker as controller and happy with it (most of the time)

                          TheoLT Offline
                          TheoLT Offline
                          TheoL
                          Contest Winner
                          wrote on last edited by TheoL
                          #29

                          @APL2017 I think the gesture sensor is awesome. But just to switch things on and off. Because dimming with hand gestures is fun at the beginning, but I discovered I didn't use it much after a few months. To me most of my projects are just experiments on finding usable ways to interact with my house.
                          But there are some good use cases in where a gesture controller is the best switch you can imagine. Because it is contactless. Like in your garage when you are working on stuff like cars and get your hands dirty. You don't want to make you wall switches dirty.
                          Or in your kitching while cooking. But dimming with gesture is not very convenient. So I would set a max dimmer level of 5 or so.

                          A 1 Reply Last reply
                          0
                          • TheoLT TheoL

                            @APL2017 I think the gesture sensor is awesome. But just to switch things on and off. Because dimming with hand gestures is fun at the beginning, but I discovered I didn't use it much after a few months. To me most of my projects are just experiments on finding usable ways to interact with my house.
                            But there are some good use cases in where a gesture controller is the best switch you can imagine. Because it is contactless. Like in your garage when you are working on stuff like cars and get your hands dirty. You don't want to make you wall switches dirty.
                            Or in your kitching while cooking. But dimming with gesture is not very convenient. So I would set a max dimmer level of 5 or so.

                            A Offline
                            A Offline
                            APL2017
                            wrote on last edited by
                            #30

                            @TheoL Agree, my project is for kitchen for under the cabinets lights, so I can't imagine my wife adjusting brightness, may be 2-3 levels would be sufficient. Current slider dimmer is set to one position...

                            1 Reply Last reply
                            0
                            • TheoLT TheoL

                              @APL2017 Posting one question multiple times isn't gonna give you an answer quickly. I just wanted to say that.

                              I see the code on the website is still in pre MS 2.0. It should be easy to convert it to MS 2.0. The only problem is that I don't have the hardware setup to check if it works. If I can find some time this week I will convert it, so that it at least compiles. But I can not test it and can't promise I will finish it this week.

                              But @pjjarzembowski version should work, you should only strip out the extra sensors he attached to his node.

                              After playing with dimmers and Domoticz for quite some time, I've discovered that 15 brightness levels is all I need. Because it's hard to see the difference is brightness level if you have 100 levels. And also it takes a lot of gestures to move from max to min. So the code can be simplified more. By just mapping the Domotics level (1-100) to (1-15) and the opposite when you send the nodes brightness level to Domoticz.

                              Also Domoticz behaves odd when it comes to dimmer actuators as I discovered during a project I'm working on now. There are some work arounds for that, which envolve storing the brightness levels on the eeprom of your node. I know 100000 times is a lot. But I really don't see the need to store each brightness level change in the eeprom.

                              A Offline
                              A Offline
                              APL2017
                              wrote on last edited by APL2017
                              #31

                              @TheoL Please see attached stripped version of @pjjarzembowski code. I see that gesture is being detected, attempted to reduce number of light levels to 5. Having trouble with detecting UP and DOWN gestures - not always happening. Trying to understand how dimmer works.

                              /****************************************************************
                                Title: MySensors enabled, gesture controlled lamp.
                                
                                This lamp can be turned on/off, and dimmed by gestures. And it can be controlled by any Home Automation
                                system, that can talk with MySensors.
                                
                                Supported gesture:
                                1. Left to right stroke: turns lamp on
                                2. Right to left stroke: turns lamp off
                                3. Down to up stroke: increases brightness (When brightness is already at max, the lamp will blink - duration and blink count can be changed in the sketch)
                                4. Up to down stroke: decreases brgihtness (When brightness level is at 0 the lamp is off)
                                
                                The gesture sensor used in this Sketch is an APDS-9960 RGB and Gesture Sensor, sold by SparkFun. They can be found on eBay and Aliexpress as well.
                                See Sparkfuns hookup guide for pin lay-out ( https://learn.sparkfun.com/tutorials/apds-9960-rgb-and-gesture-sensor-hookup-guide ) 
                                IMPORTANT: The APDS-9960 can only accept 3.3V! Use bi direction level converter when using another Arduino than a Pro Mini 3.3V
                              
                                This Sketch is based upon the GestureTest exampl developped by,
                                Shawn Hymel @ SparkFun Electronics on May 30, 2014. See https://github.com/sparkfun/APDS-9960_RGB_and_Gesture_Sensor
                              
                                The lamp itself is a white LED strip, controlled by an N channel MOSFET.
                                
                                Fore more details on the used hardware and libraries (see https://www.openhardware.io/view/50/Gesture-controlled-MySensors-Floor-lamp )
                                  
                                Revision history:
                                25-1-2021 Version 2.1 Stripped from everything except gesture and light control.
                                3-07-2017 Version 2 by pjjarzembowski
                                    - Changed for tests on Mysensors 2.0      
                                20-03-2016 Version 1.1 by Theo:
                                    - set the brightness level to defined BRIGHTNESS_INCREMENT, when lamp is being turned on be a gesture and the current brightness level is 0.
                                      This was a little bug in previous version. It sometimes seemed that the APDS didn't work, but in some cases I had to increase brightness after
                                      I turned the lamp on.
                                    - cleaned up the code a bit
                                19-03-2016 Version 1.0 by Theo
                                    - Developed and test with MySensors release 1.5.4
                              ****************************************************************/
                              // Import libraries used by the Sketch.
                              // added some of my radio definitions (must be before #includes)
                              #define MY_DEBUG
                              #define MY_RADIO_RF24
                              #define MY_NODE_ID 27
                              
                              //#include <SPI.h>
                              #include <MySensors.h>  
                              #include <Wire.h>
                              #include <SparkFun_APDS9960.h>
                              
                              // Constants declaration(s)
                              #define APDS9960_INT                     2    // Needs to be an interrupt pin. We should be able to use the Arduino's pin 3 as well.
                              #define LED_PIN                          3    // The led PWM pin, that drives the LED strip. This is the pin thats attached to the mosfet.
                              #define MAXDIMLEVELS                     6    // The maximum number of dim levels. Domoticz supports 0-100 (we'll transalate thim in an array)
                              #define BRIGHTNESS_INCREMENT             20   // Dimmer increment for gesture(s). Play with this value yourself. The amount of gesture controlled
                                                                            // dim levels is MAXDIMLEVELS / BRIGHTNESS_INCREMENT having 8 to 5 levels feels more natural to me.
                              #define MAX_LEVEL_REACHED_DELAY          150  // Short blinking delay when increasing the dimmer while the dimmer is already at max
                                                                            // Had some troubles in the past with tha acurateness of the gw.wait on pro mini's. But that'll probably
                                                                            // not be noticeable with this short delay. Delay is in milliseconds
                              #define MAX_LEVEL_REACHED_SIGNAL_COUNT   2    // The amount of blinks, when the max dim level already has been reached. It's just a way to let the user know
                                                                            // that the lamp can not be more brighter than the current brightness
                              #define CHILD_ID_LIGHT                   1    // The child id of the Node. Only one Node on this sensor though. See MySensors documentation
                              #define LIGHT_OFF                        0    // Constant indicating the lamp on state
                              #define LIGHT_ON                         1    // Constant indicationg light off state
                              
                              // Global Variables
                              SparkFun_APDS9960 apds = SparkFun_APDS9960(); // Initialize a SparkFun_APDS9960 object. This does all the magic incl. i2c communication with the sensor.
                              int isr_flag = 0;                             // interrupt flag, triggered when a gesture has been dectected. Used to detect gesture detection in the interrupt handler
                                                                            // the actual handling is done in the main loop. This allows is the keep the interrupt handler is lightweight is possible
                                                                            // which is a good practice. Otherwise you'll get some behaviour you don't expect.
                              int LastLightState=LIGHT_OFF;                 // The current lamp state. Wel'll turn it off for first time useage. The Sketch will query your Home Automation System for
                                                                            // the last value when it's being reboot.
                              int LastDimValue=MAXDIMLEVELS;                // last known dim value (Only initial value. Value is retrieved from your HA system)
                              
                              int dimlevels[ MAXDIMLEVELS ] =  // PWM values used for translating home automation dimmer levels. This gives smoother transations
                                {   0,   50,   100,   150,   200,   255};
                              
                              MyMessage lightMsg(CHILD_ID_LIGHT, V_LIGHT);
                              MyMessage dimmerMsg(CHILD_ID_LIGHT, V_DIMMER);
                              
                              // interrupt handler. Is being triggered by the gesture sensor whenever a gesture has been detected. We've setup this up in the setup.
                              void interruptRoutine() {
                                isr_flag = 1;
                              }
                              
                              void presentation()  
                              { 
                                sendSketchInfo("Led with Gesture", "2.0");
                                present(CHILD_ID_LIGHT, S_DIMMER);
                                }
                              
                              void setup() {
                                pinMode( LED_PIN, OUTPUT );
                              
                                // APDS Initialization code
                                pinMode(APDS9960_INT, INPUT);   // Set interrupt pin as input. @@Note: this should be handled my the library. But it isn't
                                attachInterrupt(0, interruptRoutine, FALLING);   // Initialize interrupt service routine. Basicly it'll call our interrupt routine
                              
                                if ( apds.init() ) { // Initialize APDS-9960 (configure I2C and initial values)
                                  // @@NOTE: original value is two. But it looks like the modern gesture sensor more sensitive. 1 does it for me
                                  apds.setGestureGain( 2 );
                                }
                                
                                if ( apds.enableGestureSensor(true) ) { // Start running the APDS-9960 gesture sensor engine. Sensor support more functions than gesture detection only.
                                analogWrite( LED_PIN, 0 ); // Turn the lamp off.
                                // Request current dimvalue. The current value is being handled in the incomming method.
                                request( CHILD_ID_LIGHT, V_PERCENTAGE ); // Request current dimvalue from HA. The current value is being handled in the incomming method.
                                // Request current lamp state. The current value is being handled in the incomming method.
                                request( CHILD_ID_LIGHT, V_STATUS ); // Request current lamp state from HA. The current value is being handled in the incomming method.
                                }
                                }
                              
                              // Main loop. Does two things. Handle gestures if detected by the interrupt routine. And give the MySensors lib the oppurtunity to handle incomming messages.
                              
                              
                              void loop()      
                              {  
                                if( isr_flag == 1 ) {
                                detachInterrupt(0);
                                handleGesture();
                                isr_flag = 0;
                                attachInterrupt(0, interruptRoutine, FALLING);
                                }
                              }
                              
                              // Determine gesture and handle accordingly.We'll ignore FAR and NEAR gestures. Didn't feel natural to me anyway.
                              void handleGesture() {
                                if ( apds.isGestureAvailable() ) { // Check if there's a gesture available. Which should be, because the interrupt handler told us so.
                                  switch ( apds.readGesture() ) { // Get the gesture type.
                                    
                                    case DIR_UP: // Handle up stroke (Brightness increasing)
                                      Serial.println ("DIR_UP");
                                      if ( LastDimValue + BRIGHTNESS_INCREMENT > ( MAXDIMLEVELS - 1 ) ) {
                                        for ( int i = 0; i < MAX_LEVEL_REACHED_SIGNAL_COUNT; i++ ) {
                                          analogWrite( LED_PIN, dimlevels[ 0 ] );
                                          wait( MAX_LEVEL_REACHED_DELAY );
                                          analogWrite( LED_PIN, dimlevels[ MAXDIMLEVELS - 1 ] );
                                          wait(MAX_LEVEL_REACHED_DELAY );
                                        }
                                        LastDimValue = ( MAXDIMLEVELS - 1 );
                                      }
                                      else {
                                         LastDimValue += BRIGHTNESS_INCREMENT;
                                      }
                                      LastLightState = LIGHT_ON;
                                      SetCurrentState2Hardware();
                                      break;
                                      
                                    case DIR_DOWN: // Handle down stroke (Brightness decreasing)
                                      Serial.println ("DIR_DOWN");
                                      if ( LastDimValue - BRIGHTNESS_INCREMENT <= 0 ) {
                                        LastDimValue = 0;
                                      }
                                      else {
                                         LastDimValue -= BRIGHTNESS_INCREMENT;
                                      }
                                      if ( LastDimValue == 0 ) {
                                        LastLightState = LIGHT_OFF;
                                      }
                                      else {
                                        LastLightState = LIGHT_ON;
                                      }
                                      SetCurrentState2Hardware();
                                      break;
                                      
                                    case DIR_LEFT: // Handle left stroke. Turn lamp off
                                      Serial.println ("DIR_LEFT");
                                      LastLightState = LIGHT_OFF;
                                      SetCurrentState2Hardware();
                                      break;
                                      
                                    case DIR_RIGHT: // Handle right stroke. Turn lamp on
                                      Serial.println ("DIR_RIGHT");
                                      LastLightState = LIGHT_ON;
                                      if ( LastDimValue == 0 ) { // @@Version 1.1 addition Slight modification. When the dimValue was 0, the light stayed off when turned on.
                                        LastDimValue = BRIGHTNESS_INCREMENT; // Just used the first Gesture dimming stage (2 times would be better for my taste though. Might change that in the future)
                                      }
                                      SetCurrentState2Hardware();
                                      break;
                                  }
                                }
                              }
                              
                              /**
                               * Handler for message send by the MySensor gateway.
                               */ 
                              void receive(const MyMessage &message) {
                                //if ( message.type == V_LIGHT ) { // Gateway reports a new Light state
                                  if ( message.type == V_STATUS ) { // Gateway reports a new Light state
                                  int lstate= atoi( message.data );
                                  if ( ( lstate < 0 ) || ( lstate > 1 ) ) {
                                    return;
                                  }
                                  LastLightState=lstate;
                                  if ( ( LastLightState == LIGHT_ON ) &&( LastDimValue == 0 ) ) {
                                     //In the case that the Light State = On, but the dimmer value is zero, then something (probably the controller) did something wrong,
                                     //for the Dim value to 100%
                                    LastDimValue = 100;
                                  }
                                  
                                  //When receiving a V_LIGHT command we switch the light between OFF and the last received dimmer value
                                  //This means if you previously set the lights dimmer value to 50%, and turn the light ON
                                  //it will do so at 50%
                                }
                                //else if (message.type == V_PERCENTAGE) { // Gateway reports new dimmer level. We'l adjust it to the new value
                                  else if (message.type == V_DIMMER) { // Gateway reports new dimmer level. We'l adjust it to the new value
                                  int dimvalue= atoi( message.data );
                                  if ( ( dimvalue < 0 ) || ( dimvalue > 100 ) ) {
                                    return;
                                  }
                                  if ( dimvalue == 0 ) {
                                    LastLightState = LIGHT_OFF;
                                  }
                                  else {
                                    LastLightState = LIGHT_ON;
                                    LastDimValue = dimvalue;
                                  }
                                }
                                
                                SetCurrentState2Hardware();           //Here we'll set the actual light state/level
                              }
                              
                              void SetCurrentState2Hardware() {       // Send current values to the PWM controlled MOSFET
                                if (LastLightState==LIGHT_OFF) {
                                   analogWrite( LED_PIN, dimlevels[0] );
                                   Serial.print ("DIMELEVELS ");
                                   Serial.println (dimlevels[LastDimValue] );
                                }
                                else {
                                   analogWrite( LED_PIN, dimlevels[ LastDimValue - 1 ] );
                                }
                              
                                SendCurrentState2Controller();        //Send current state to the controller
                              }
                              
                              void SendCurrentState2Controller()      // Report new values to the Gateway
                              {
                                if ((LastLightState==LIGHT_OFF)||(LastDimValue==0)) {
                                  send(dimmerMsg.set(0));
                                }
                                else {
                                  send(dimmerMsg.set(LastDimValue));
                                }
                              }
                              
                              A 1 Reply Last reply
                              0
                              • A APL2017

                                @TheoL Please see attached stripped version of @pjjarzembowski code. I see that gesture is being detected, attempted to reduce number of light levels to 5. Having trouble with detecting UP and DOWN gestures - not always happening. Trying to understand how dimmer works.

                                /****************************************************************
                                  Title: MySensors enabled, gesture controlled lamp.
                                  
                                  This lamp can be turned on/off, and dimmed by gestures. And it can be controlled by any Home Automation
                                  system, that can talk with MySensors.
                                  
                                  Supported gesture:
                                  1. Left to right stroke: turns lamp on
                                  2. Right to left stroke: turns lamp off
                                  3. Down to up stroke: increases brightness (When brightness is already at max, the lamp will blink - duration and blink count can be changed in the sketch)
                                  4. Up to down stroke: decreases brgihtness (When brightness level is at 0 the lamp is off)
                                  
                                  The gesture sensor used in this Sketch is an APDS-9960 RGB and Gesture Sensor, sold by SparkFun. They can be found on eBay and Aliexpress as well.
                                  See Sparkfuns hookup guide for pin lay-out ( https://learn.sparkfun.com/tutorials/apds-9960-rgb-and-gesture-sensor-hookup-guide ) 
                                  IMPORTANT: The APDS-9960 can only accept 3.3V! Use bi direction level converter when using another Arduino than a Pro Mini 3.3V
                                
                                  This Sketch is based upon the GestureTest exampl developped by,
                                  Shawn Hymel @ SparkFun Electronics on May 30, 2014. See https://github.com/sparkfun/APDS-9960_RGB_and_Gesture_Sensor
                                
                                  The lamp itself is a white LED strip, controlled by an N channel MOSFET.
                                  
                                  Fore more details on the used hardware and libraries (see https://www.openhardware.io/view/50/Gesture-controlled-MySensors-Floor-lamp )
                                    
                                  Revision history:
                                  25-1-2021 Version 2.1 Stripped from everything except gesture and light control.
                                  3-07-2017 Version 2 by pjjarzembowski
                                      - Changed for tests on Mysensors 2.0      
                                  20-03-2016 Version 1.1 by Theo:
                                      - set the brightness level to defined BRIGHTNESS_INCREMENT, when lamp is being turned on be a gesture and the current brightness level is 0.
                                        This was a little bug in previous version. It sometimes seemed that the APDS didn't work, but in some cases I had to increase brightness after
                                        I turned the lamp on.
                                      - cleaned up the code a bit
                                  19-03-2016 Version 1.0 by Theo
                                      - Developed and test with MySensors release 1.5.4
                                ****************************************************************/
                                // Import libraries used by the Sketch.
                                // added some of my radio definitions (must be before #includes)
                                #define MY_DEBUG
                                #define MY_RADIO_RF24
                                #define MY_NODE_ID 27
                                
                                //#include <SPI.h>
                                #include <MySensors.h>  
                                #include <Wire.h>
                                #include <SparkFun_APDS9960.h>
                                
                                // Constants declaration(s)
                                #define APDS9960_INT                     2    // Needs to be an interrupt pin. We should be able to use the Arduino's pin 3 as well.
                                #define LED_PIN                          3    // The led PWM pin, that drives the LED strip. This is the pin thats attached to the mosfet.
                                #define MAXDIMLEVELS                     6    // The maximum number of dim levels. Domoticz supports 0-100 (we'll transalate thim in an array)
                                #define BRIGHTNESS_INCREMENT             20   // Dimmer increment for gesture(s). Play with this value yourself. The amount of gesture controlled
                                                                              // dim levels is MAXDIMLEVELS / BRIGHTNESS_INCREMENT having 8 to 5 levels feels more natural to me.
                                #define MAX_LEVEL_REACHED_DELAY          150  // Short blinking delay when increasing the dimmer while the dimmer is already at max
                                                                              // Had some troubles in the past with tha acurateness of the gw.wait on pro mini's. But that'll probably
                                                                              // not be noticeable with this short delay. Delay is in milliseconds
                                #define MAX_LEVEL_REACHED_SIGNAL_COUNT   2    // The amount of blinks, when the max dim level already has been reached. It's just a way to let the user know
                                                                              // that the lamp can not be more brighter than the current brightness
                                #define CHILD_ID_LIGHT                   1    // The child id of the Node. Only one Node on this sensor though. See MySensors documentation
                                #define LIGHT_OFF                        0    // Constant indicating the lamp on state
                                #define LIGHT_ON                         1    // Constant indicationg light off state
                                
                                // Global Variables
                                SparkFun_APDS9960 apds = SparkFun_APDS9960(); // Initialize a SparkFun_APDS9960 object. This does all the magic incl. i2c communication with the sensor.
                                int isr_flag = 0;                             // interrupt flag, triggered when a gesture has been dectected. Used to detect gesture detection in the interrupt handler
                                                                              // the actual handling is done in the main loop. This allows is the keep the interrupt handler is lightweight is possible
                                                                              // which is a good practice. Otherwise you'll get some behaviour you don't expect.
                                int LastLightState=LIGHT_OFF;                 // The current lamp state. Wel'll turn it off for first time useage. The Sketch will query your Home Automation System for
                                                                              // the last value when it's being reboot.
                                int LastDimValue=MAXDIMLEVELS;                // last known dim value (Only initial value. Value is retrieved from your HA system)
                                
                                int dimlevels[ MAXDIMLEVELS ] =  // PWM values used for translating home automation dimmer levels. This gives smoother transations
                                  {   0,   50,   100,   150,   200,   255};
                                
                                MyMessage lightMsg(CHILD_ID_LIGHT, V_LIGHT);
                                MyMessage dimmerMsg(CHILD_ID_LIGHT, V_DIMMER);
                                
                                // interrupt handler. Is being triggered by the gesture sensor whenever a gesture has been detected. We've setup this up in the setup.
                                void interruptRoutine() {
                                  isr_flag = 1;
                                }
                                
                                void presentation()  
                                { 
                                  sendSketchInfo("Led with Gesture", "2.0");
                                  present(CHILD_ID_LIGHT, S_DIMMER);
                                  }
                                
                                void setup() {
                                  pinMode( LED_PIN, OUTPUT );
                                
                                  // APDS Initialization code
                                  pinMode(APDS9960_INT, INPUT);   // Set interrupt pin as input. @@Note: this should be handled my the library. But it isn't
                                  attachInterrupt(0, interruptRoutine, FALLING);   // Initialize interrupt service routine. Basicly it'll call our interrupt routine
                                
                                  if ( apds.init() ) { // Initialize APDS-9960 (configure I2C and initial values)
                                    // @@NOTE: original value is two. But it looks like the modern gesture sensor more sensitive. 1 does it for me
                                    apds.setGestureGain( 2 );
                                  }
                                  
                                  if ( apds.enableGestureSensor(true) ) { // Start running the APDS-9960 gesture sensor engine. Sensor support more functions than gesture detection only.
                                  analogWrite( LED_PIN, 0 ); // Turn the lamp off.
                                  // Request current dimvalue. The current value is being handled in the incomming method.
                                  request( CHILD_ID_LIGHT, V_PERCENTAGE ); // Request current dimvalue from HA. The current value is being handled in the incomming method.
                                  // Request current lamp state. The current value is being handled in the incomming method.
                                  request( CHILD_ID_LIGHT, V_STATUS ); // Request current lamp state from HA. The current value is being handled in the incomming method.
                                  }
                                  }
                                
                                // Main loop. Does two things. Handle gestures if detected by the interrupt routine. And give the MySensors lib the oppurtunity to handle incomming messages.
                                
                                
                                void loop()      
                                {  
                                  if( isr_flag == 1 ) {
                                  detachInterrupt(0);
                                  handleGesture();
                                  isr_flag = 0;
                                  attachInterrupt(0, interruptRoutine, FALLING);
                                  }
                                }
                                
                                // Determine gesture and handle accordingly.We'll ignore FAR and NEAR gestures. Didn't feel natural to me anyway.
                                void handleGesture() {
                                  if ( apds.isGestureAvailable() ) { // Check if there's a gesture available. Which should be, because the interrupt handler told us so.
                                    switch ( apds.readGesture() ) { // Get the gesture type.
                                      
                                      case DIR_UP: // Handle up stroke (Brightness increasing)
                                        Serial.println ("DIR_UP");
                                        if ( LastDimValue + BRIGHTNESS_INCREMENT > ( MAXDIMLEVELS - 1 ) ) {
                                          for ( int i = 0; i < MAX_LEVEL_REACHED_SIGNAL_COUNT; i++ ) {
                                            analogWrite( LED_PIN, dimlevels[ 0 ] );
                                            wait( MAX_LEVEL_REACHED_DELAY );
                                            analogWrite( LED_PIN, dimlevels[ MAXDIMLEVELS - 1 ] );
                                            wait(MAX_LEVEL_REACHED_DELAY );
                                          }
                                          LastDimValue = ( MAXDIMLEVELS - 1 );
                                        }
                                        else {
                                           LastDimValue += BRIGHTNESS_INCREMENT;
                                        }
                                        LastLightState = LIGHT_ON;
                                        SetCurrentState2Hardware();
                                        break;
                                        
                                      case DIR_DOWN: // Handle down stroke (Brightness decreasing)
                                        Serial.println ("DIR_DOWN");
                                        if ( LastDimValue - BRIGHTNESS_INCREMENT <= 0 ) {
                                          LastDimValue = 0;
                                        }
                                        else {
                                           LastDimValue -= BRIGHTNESS_INCREMENT;
                                        }
                                        if ( LastDimValue == 0 ) {
                                          LastLightState = LIGHT_OFF;
                                        }
                                        else {
                                          LastLightState = LIGHT_ON;
                                        }
                                        SetCurrentState2Hardware();
                                        break;
                                        
                                      case DIR_LEFT: // Handle left stroke. Turn lamp off
                                        Serial.println ("DIR_LEFT");
                                        LastLightState = LIGHT_OFF;
                                        SetCurrentState2Hardware();
                                        break;
                                        
                                      case DIR_RIGHT: // Handle right stroke. Turn lamp on
                                        Serial.println ("DIR_RIGHT");
                                        LastLightState = LIGHT_ON;
                                        if ( LastDimValue == 0 ) { // @@Version 1.1 addition Slight modification. When the dimValue was 0, the light stayed off when turned on.
                                          LastDimValue = BRIGHTNESS_INCREMENT; // Just used the first Gesture dimming stage (2 times would be better for my taste though. Might change that in the future)
                                        }
                                        SetCurrentState2Hardware();
                                        break;
                                    }
                                  }
                                }
                                
                                /**
                                 * Handler for message send by the MySensor gateway.
                                 */ 
                                void receive(const MyMessage &message) {
                                  //if ( message.type == V_LIGHT ) { // Gateway reports a new Light state
                                    if ( message.type == V_STATUS ) { // Gateway reports a new Light state
                                    int lstate= atoi( message.data );
                                    if ( ( lstate < 0 ) || ( lstate > 1 ) ) {
                                      return;
                                    }
                                    LastLightState=lstate;
                                    if ( ( LastLightState == LIGHT_ON ) &&( LastDimValue == 0 ) ) {
                                       //In the case that the Light State = On, but the dimmer value is zero, then something (probably the controller) did something wrong,
                                       //for the Dim value to 100%
                                      LastDimValue = 100;
                                    }
                                    
                                    //When receiving a V_LIGHT command we switch the light between OFF and the last received dimmer value
                                    //This means if you previously set the lights dimmer value to 50%, and turn the light ON
                                    //it will do so at 50%
                                  }
                                  //else if (message.type == V_PERCENTAGE) { // Gateway reports new dimmer level. We'l adjust it to the new value
                                    else if (message.type == V_DIMMER) { // Gateway reports new dimmer level. We'l adjust it to the new value
                                    int dimvalue= atoi( message.data );
                                    if ( ( dimvalue < 0 ) || ( dimvalue > 100 ) ) {
                                      return;
                                    }
                                    if ( dimvalue == 0 ) {
                                      LastLightState = LIGHT_OFF;
                                    }
                                    else {
                                      LastLightState = LIGHT_ON;
                                      LastDimValue = dimvalue;
                                    }
                                  }
                                  
                                  SetCurrentState2Hardware();           //Here we'll set the actual light state/level
                                }
                                
                                void SetCurrentState2Hardware() {       // Send current values to the PWM controlled MOSFET
                                  if (LastLightState==LIGHT_OFF) {
                                     analogWrite( LED_PIN, dimlevels[0] );
                                     Serial.print ("DIMELEVELS ");
                                     Serial.println (dimlevels[LastDimValue] );
                                  }
                                  else {
                                     analogWrite( LED_PIN, dimlevels[ LastDimValue - 1 ] );
                                  }
                                
                                  SendCurrentState2Controller();        //Send current state to the controller
                                }
                                
                                void SendCurrentState2Controller()      // Report new values to the Gateway
                                {
                                  if ((LastLightState==LIGHT_OFF)||(LastDimValue==0)) {
                                    send(dimmerMsg.set(0));
                                  }
                                  else {
                                    send(dimmerMsg.set(LastDimValue));
                                  }
                                }
                                
                                A Offline
                                A Offline
                                APL2017
                                wrote on last edited by
                                #32

                                @APL2017 One of my issues is resolved - unstable operation of gesture detection. According to this discussion https://forum.arduino.cc/index.php?topic=483921.15 for some APDS-9960 modules (most likely the on that I use - with built-in 3.3V power regulator) it is critical to adjust LED_BOOST parameter in Sparkfuns library. After I set it to 100 as recommended in link above, my gesture detection became more stable. What is your experience with this?

                                TheoLT 1 Reply Last reply
                                0
                                • A APL2017

                                  @APL2017 One of my issues is resolved - unstable operation of gesture detection. According to this discussion https://forum.arduino.cc/index.php?topic=483921.15 for some APDS-9960 modules (most likely the on that I use - with built-in 3.3V power regulator) it is critical to adjust LED_BOOST parameter in Sparkfuns library. After I set it to 100 as recommended in link above, my gesture detection became more stable. What is your experience with this?

                                  TheoLT Offline
                                  TheoLT Offline
                                  TheoL
                                  Contest Winner
                                  wrote on last edited by TheoL
                                  #33

                                  @APL2017 I bought a real expensive one at the time from sparkfun. Maybe that's a difference, because it was stable. I think some where in the back of my drawer I have some cheap Chinese ones. But I'm in the middle of 3 other builds xd. So not sure if I can hook them up real soon. But great you solved a problem.
                                  I think the one I used original has no built in 3.3v regulator.

                                  A 1 Reply Last reply
                                  0
                                  • TheoLT TheoL

                                    @APL2017 I bought a real expensive one at the time from sparkfun. Maybe that's a difference, because it was stable. I think some where in the back of my drawer I have some cheap Chinese ones. But I'm in the middle of 3 other builds xd. So not sure if I can hook them up real soon. But great you solved a problem.
                                    I think the one I used original has no built in 3.3v regulator.

                                    A Offline
                                    A Offline
                                    APL2017
                                    wrote on last edited by
                                    #34

                                    @TheoL I ordered just in case couple of simple APDS modules without regulators. When you have a chance, no rush, please take look at the code, thank you.

                                    TheoLT 1 Reply Last reply
                                    0
                                    • A APL2017

                                      @TheoL I ordered just in case couple of simple APDS modules without regulators. When you have a chance, no rush, please take look at the code, thank you.

                                      TheoLT Offline
                                      TheoLT Offline
                                      TheoL
                                      Contest Winner
                                      wrote on last edited by TheoL
                                      #35

                                      @APL2017 I converted the MySensors 1.5 version to 2.x. It compiles but I can not test it since I don't have a hardware setup.

                                      Can you give it a try?

                                      /****************************************************************
                                        Title: MySensors enabled, gesture controlled lamp.
                                      
                                        V1.1 March 2016 by Theo
                                        v2.3 January 2021 by Theo (converted to MS 2.0)
                                      
                                        This lamp can be turned on/off, and dimmed by gestures. And it can be controlled by any Home Automation
                                        system, that can talk with MySensors.
                                      
                                        Supported gesture:
                                        1. Left to right stroke: turns lamp on
                                        2. Right to left stroke: turns lamp off
                                        3. Down to up stroke: increases brightness (When brightness is already at max, the lamp will blink - duration and blink count can be changed in the sketch)
                                        4. Up to down stroke: decreases brgihtness (When brightness level is at 0 the lamp is off)
                                      
                                        The gesture sensor ues in this Sketch is an APDS-9960 RGB and Gesture Sensor, sold by SparkFun. They can be found on eBay and Aliexpress as well.
                                        See Sparkfuns hookup guide for pin lay-out ( https://learn.sparkfun.com/tutorials/apds-9960-rgb-and-gesture-sensor-hookup-guide )
                                        IMPORTANT: The APDS-9960 can only accept 3.3V! Use bi direction level converter when using another Arduino than a Pro Mini 3.3V
                                      
                                        This Sketch is based upon the GestureTest exampl developped by,
                                        Shawn Hymel @ SparkFun Electronics on May 30, 2014. See https://github.com/sparkfun/APDS-9960_RGB_and_Gesture_Sensor
                                      
                                        The lamp itself is a white LED strip, controlled by an N channel MOSFET.
                                      
                                        Fore more details on the used hardware and libraries (see https://www.openhardware.io/view/50/Gesture-controlled-MySensors-Floor-lamp )
                                      
                                        Developed and test with MySensors release 1.5.4
                                      
                                        Revision history:
                                        31-02-2021 Version 2.2:
                                            - Sketch converted to MySensors 2.0+ (Not not tested)
                                        20-03-2016 Version 1.1:
                                            - set the brightness level to defined BRIGHTNESS_INCREMENT, when lamp is being turned on be a gesture and the current brightness level is 0.
                                              This was a little bug in previous version. It sometimes seemed that the APDS didn't work, but in some cases I had to increase brightness after
                                              I turned the lamp on.
                                            - cleaned up the code a bit
                                        19-03-2016 Version 1.0
                                      ****************************************************************/
                                      
                                      // Set the wait for ready to zero if you want the light the be operable even when the Gateway is off.
                                      //#define MY_TRANSPORT_WAIT_READY_MS 0
                                      
                                      
                                      // Enable and select radio type attached
                                      #define MY_RADIO_NRF24
                                      
                                      
                                      // Import libraries used by the Sketch.
                                      #include <SPI.h>
                                      #include <MySensors.h>
                                      #include <Wire.h>
                                      #include <SparkFun_APDS9960.h>
                                      
                                      // Constants declaration(s)
                                      #define APDS9960_INT                      2   // Needs to be an interrupt pin. We should be able to use the Arduino's pin 3 as well.
                                      #define LED_PIN                           3   // The led PWM pin, that drives the LED strip. This is the pin thats attached to the mosfet.
                                      #define MAXDIMLEVELS                     100  // The maximum number of dim levels. Domoticz supports 0-100 (we'll transalate thim in an array)
                                      #define BRIGHTNESS_INCREMENT             15   // Dimmer increment for gesture(s). Play with this value yourself. The amount of gesture controlled
                                      // dim levels is MAXDIMLEVELS / BRIGHTNESS_INCREMENT having 8 to 5 levels feels more natural to me.
                                      #define MAX_LEVEL_REACHED_DELAY          150  // Short blinking delay when increasing the dimmer while the dimmer is already at max
                                      // Had some troubles in the past with tha acurateness of the gw.wait on pro mini's. But that'll probably
                                      // not be noticeable with this short delay. Delay is in milliseconds
                                      #define MAX_LEVEL_REACHED_SIGNAL_COUNT   2    // The amount of blinks, when the max dim level already has been reached. It's just a way to let the user know
                                      // that the lamp can not be more brighter than the current brightness
                                      #define CHILD_ID_LIGHT                   1    // The child id of the Node. Only one Node on this sensor though. See MySensors documentation
                                      #define LIGHT_OFF                        0    // Constant indicating the lamp on state
                                      #define LIGHT_ON                         1    // Constant indicationg light off state
                                      #define SN "Gesture controlled lamp"          // Description of this sketch. 
                                      #define SV "2.2"                              // The version of the Sketch
                                      
                                      // Global Variables
                                      SparkFun_APDS9960 apds = SparkFun_APDS9960(); // Initialize a SparkFun_APDS9960 object. This does all the magic incl. i2c communication with the sensor.
                                      int isr_flag = 0;                             // interrupt flag, triggered when a gesture has been dectected. Used to detect gesture detection in the interrupt handler
                                      // the actual handling is done in the main loop. This allows is the keep the interrupt handler is lightweight is possible
                                      // which is a good practice. Otherwise you'll get some behaviour you don't expect.
                                      int LastLightState = LIGHT_OFF;               // The current lamp state. Wel'll turn it off for first time useage. The Sketch will query your Home Automation System for
                                      // the last value when it's being reboot.
                                      int LastDimValue = MAXDIMLEVELS;              // last known dim value (Only initial value. Value is retrieved from your HA system)
                                      
                                      /**
                                         Values could be calculated. But the sketch is small and storing in an Array is just faster. Otherwise we have to do calculations that incl Floats.
                                         Floats take up a lot of your arduino memory
                                      */
                                      int dimlevels[ MAXDIMLEVELS ] =  // PWM values used for translating home automation dimmer levels. This gives smoother transations
                                      { 0,   1,   2,   3,   4,   5,   6,   7,   8,   9,
                                        10,  11,  12,  13,  14,  15,  16,  17,  18,  19,
                                        20,  21,  22,  23,  24,  25,  26,  27,  28,  29,
                                        30,  31,  32,  35,  39,  42,  46,  49,  52,  56,
                                        59,  62,  66,  69,  73,  76,  79,  83,  86,  89,
                                        93,  96, 100, 103, 106, 110, 113, 116, 120, 123,
                                        126, 130, 133, 137, 140, 144, 147, 150, 154, 157,
                                        160, 164, 167, 171, 174, 177, 181, 184, 187, 191,
                                        194, 197, 201, 204, 208, 211, 215, 218, 221, 225,
                                        228, 231, 235, 238, 242, 245, 246, 250, 251, 255
                                      };
                                      
                                      /**
                                         Variables needed for setting up and communication with MySensors. These variables will handle all of the MySensors magic for you.
                                      */
                                      MyMessage lightMsg(CHILD_ID_LIGHT, V_LIGHT);
                                      MyMessage dimmerMsg(CHILD_ID_LIGHT, V_DIMMER);
                                      
                                      /**
                                         Initializing code. Basicly we'll setup MySensors communication and test if we can communicate with the gesture sensor. See comment in setup method for more details
                                      */
                                      void setup() {
                                        //  // Initialize NFR24L01+ radio for enabling MySensors );
                                        //  gw.begin(incomingMessage, AUTO, false);
                                      
                                      
                                        // declare output pin for PWM control of the MOSFET
                                        pinMode( LED_PIN, OUTPUT );
                                      
                                        // APDS Initialization code
                                        pinMode(APDS9960_INT, INPUT);   // Set interrupt pin as input. @@Note: this should be handled my the library. But it isn't
                                        attachInterrupt(0, interruptRoutine, FALLING);   // Initialize interrupt service routine. Basicly it'll call our interrupt routine
                                      
                                        if ( apds.init() ) { // Initialize APDS-9960 (configure I2C and initial values)
                                          // @@NOTE: original value is two. But it looks like the modern gesture sensor or more sensitive. 1 does it for me
                                          apds.setGestureGain( 1 );
                                        }
                                      
                                        if ( apds.enableGestureSensor(true) ) { // Start running the APDS-9960 gesture sensor engine. Sensor support more functions than gesture detection only.
                                          analogWrite( LED_PIN, 0 ); // Turn the lamp off.
                                        }
                                      }
                                      
                                      void presentation( ) {
                                        // Send the Sketch Version Information to the Gateway. Domoticz seems to ignore this. Don't know about the other HA systems.
                                        sendSketchInfo(SN, SV);
                                      
                                        delay( 50 ); // It can't hurt to add some delay. It gives the gateway some time to handle other messagess
                                      
                                        // Present the dimmable lamp is a child node to the HA system. We'll enable ACK communication.
                                        present(CHILD_ID_LIGHT, S_DIMMER, "floor lamp", true );
                                      
                                        delay( 50 ); // It can't hurt to add some delay. It gives the gateway some time to handle other messagess
                                      
                                        request( CHILD_ID_LIGHT, V_PERCENTAGE ); // Request current dimvalue from HA. The current value is being handled in the incomming method.
                                        delay( 50 ); // It can't hurt to add some delay. It gives the gateway some time to handle other messagess
                                        
                                        request( CHILD_ID_LIGHT, V_STATUS ); // Request current lamp state from HA. The current value is being handled in the incomming method.
                                        delay( 50 ); // It can't hurt to add some delay. It gives the gateway some time to handle other messagess
                                      
                                      }
                                      
                                      // Main loop. Does twoe things. Handle gestures if detected by the interrupt routine. And give the MySensors lib the oppurtunity to handle incomming messages.
                                      void loop() {
                                        if ( isr_flag == 1 ) {
                                          detachInterrupt(0);
                                          handleGesture();
                                          isr_flag = 0;
                                          attachInterrupt(0, interruptRoutine, FALLING);
                                        }
                                      }
                                      
                                      // interrupt handler. Is being triggered by the gesture sensor whenever a gesture has been detected. We've setup this up in the setup.
                                      void interruptRoutine() {
                                        isr_flag = 1;
                                      }
                                      
                                      // Determine gesture and handle accordingly.We'll ignore FAR and NEAR gestures. Do didn't feel natural to me anyway.
                                      void handleGesture() {
                                        if ( apds.isGestureAvailable() ) { // Check if there's a gesture available. Which should be, because the interrupt handler told us so.
                                          switch ( apds.readGesture() ) { // Get the gesture type.
                                            case DIR_UP: // Handle up stroke (Brightness increasing)
                                              if ( LastDimValue + BRIGHTNESS_INCREMENT > ( MAXDIMLEVELS - 1 ) ) {
                                                for ( int i = 0; i < MAX_LEVEL_REACHED_SIGNAL_COUNT; i++ ) {
                                                  analogWrite( LED_PIN, dimlevels[ 0 ] );
                                                  wait( MAX_LEVEL_REACHED_DELAY );
                                                  analogWrite( LED_PIN, dimlevels[ MAXDIMLEVELS - 1 ] );
                                                  wait(MAX_LEVEL_REACHED_DELAY );
                                                }
                                                LastDimValue = ( MAXDIMLEVELS - 1 );
                                              }
                                              else {
                                                LastDimValue += BRIGHTNESS_INCREMENT;
                                              }
                                              LastLightState = LIGHT_ON;
                                              SetCurrentState2Hardware();
                                              break;
                                            case DIR_DOWN: // Handle down stroke (Brightness decreasing)
                                              if ( LastDimValue - BRIGHTNESS_INCREMENT <= 0 ) {
                                                LastDimValue = 0;
                                              }
                                              else {
                                                LastDimValue -= BRIGHTNESS_INCREMENT;
                                              }
                                              if ( LastDimValue == 0 ) {
                                                LastLightState = LIGHT_OFF;
                                              }
                                              else {
                                                LastLightState = LIGHT_ON;
                                              }
                                              SetCurrentState2Hardware();
                                              break;
                                            case DIR_LEFT: // Handle left stroke. Turn lamp off
                                              LastLightState = LIGHT_OFF;
                                              SetCurrentState2Hardware();
                                              break;
                                            case DIR_RIGHT: // Handle right stroke. Turn lamp on
                                              LastLightState = LIGHT_ON;
                                              if ( LastDimValue == 0 ) { // @@Version 1.1 addition Slight modification. When the dimValue was 0, the light stayed off when turned on.
                                                LastDimValue = BRIGHTNESS_INCREMENT; // Just used the first Gesture dimming stage (2 times would be better for my taste though. Might change that in the future)
                                              }
                                              SetCurrentState2Hardware();
                                              break;
                                          }
                                        }
                                      }
                                      
                                      /**
                                         Handler for message send by the MySensor gateway.
                                      */
                                      void receive(const MyMessage &message) {
                                        if ( message.type == V_LIGHT ) { // Gateway reports a new Light state
                                          int lstate = atoi( message.data );
                                          if ( ( lstate < 0 ) || ( lstate > 1 ) ) {
                                            return;
                                          }
                                          LastLightState = lstate;
                                          if ( ( LastLightState == LIGHT_ON ) && ( LastDimValue == 0 ) ) {
                                            //In the case that the Light State = On, but the dimmer value is zero, then something (probably the controller) did something wrong,
                                            //for the Dim value to 100%
                                            LastDimValue = 100;
                                          }
                                      
                                          //When receiving a V_LIGHT command we switch the light between OFF and the last received dimmer value
                                          //This means if you previously set the lights dimmer value to 50%, and turn the light ON
                                          //it will do so at 50%
                                        }
                                        else if (message.type == V_DIMMER) { // Gateway reports new dimmer level. We'l adjust it to the new value
                                          int dimvalue = atoi( message.data );
                                          if ( ( dimvalue < 0 ) || ( dimvalue > 100 ) ) {
                                            return;
                                          }
                                          if ( dimvalue == 0 ) {
                                            LastLightState = LIGHT_OFF;
                                          }
                                          else {
                                            LastLightState = LIGHT_ON;
                                            LastDimValue = dimvalue;
                                          }
                                        }
                                        //Here we'll set the actual light state/level
                                        SetCurrentState2Hardware();
                                      }
                                      
                                      // Send current values to the PWM controlled MOSFET
                                      void SetCurrentState2Hardware() {
                                        if (LastLightState == LIGHT_OFF) {
                                          analogWrite( LED_PIN, dimlevels[0] );
                                        }
                                        else {
                                          analogWrite( LED_PIN, dimlevels[ LastDimValue - 1 ] );
                                        }
                                      
                                        //Send current state to the controller
                                        SendCurrentState2Controller();
                                      }
                                      
                                      // Report new values to the Gateway.
                                      void SendCurrentState2Controller()
                                      {
                                        if ((LastLightState == LIGHT_OFF) || (LastDimValue == 0)) {
                                          send(dimmerMsg.set(0));
                                        }
                                        else {
                                          send(dimmerMsg.set(LastDimValue));
                                        }
                                      }
                                      

                                      Note I didn't made any change to how the sketch functions. Some improvements can surely be done. But let's see if it works.

                                      A 1 Reply Last reply
                                      0
                                      • TheoLT TheoL

                                        @APL2017 I converted the MySensors 1.5 version to 2.x. It compiles but I can not test it since I don't have a hardware setup.

                                        Can you give it a try?

                                        /****************************************************************
                                          Title: MySensors enabled, gesture controlled lamp.
                                        
                                          V1.1 March 2016 by Theo
                                          v2.3 January 2021 by Theo (converted to MS 2.0)
                                        
                                          This lamp can be turned on/off, and dimmed by gestures. And it can be controlled by any Home Automation
                                          system, that can talk with MySensors.
                                        
                                          Supported gesture:
                                          1. Left to right stroke: turns lamp on
                                          2. Right to left stroke: turns lamp off
                                          3. Down to up stroke: increases brightness (When brightness is already at max, the lamp will blink - duration and blink count can be changed in the sketch)
                                          4. Up to down stroke: decreases brgihtness (When brightness level is at 0 the lamp is off)
                                        
                                          The gesture sensor ues in this Sketch is an APDS-9960 RGB and Gesture Sensor, sold by SparkFun. They can be found on eBay and Aliexpress as well.
                                          See Sparkfuns hookup guide for pin lay-out ( https://learn.sparkfun.com/tutorials/apds-9960-rgb-and-gesture-sensor-hookup-guide )
                                          IMPORTANT: The APDS-9960 can only accept 3.3V! Use bi direction level converter when using another Arduino than a Pro Mini 3.3V
                                        
                                          This Sketch is based upon the GestureTest exampl developped by,
                                          Shawn Hymel @ SparkFun Electronics on May 30, 2014. See https://github.com/sparkfun/APDS-9960_RGB_and_Gesture_Sensor
                                        
                                          The lamp itself is a white LED strip, controlled by an N channel MOSFET.
                                        
                                          Fore more details on the used hardware and libraries (see https://www.openhardware.io/view/50/Gesture-controlled-MySensors-Floor-lamp )
                                        
                                          Developed and test with MySensors release 1.5.4
                                        
                                          Revision history:
                                          31-02-2021 Version 2.2:
                                              - Sketch converted to MySensors 2.0+ (Not not tested)
                                          20-03-2016 Version 1.1:
                                              - set the brightness level to defined BRIGHTNESS_INCREMENT, when lamp is being turned on be a gesture and the current brightness level is 0.
                                                This was a little bug in previous version. It sometimes seemed that the APDS didn't work, but in some cases I had to increase brightness after
                                                I turned the lamp on.
                                              - cleaned up the code a bit
                                          19-03-2016 Version 1.0
                                        ****************************************************************/
                                        
                                        // Set the wait for ready to zero if you want the light the be operable even when the Gateway is off.
                                        //#define MY_TRANSPORT_WAIT_READY_MS 0
                                        
                                        
                                        // Enable and select radio type attached
                                        #define MY_RADIO_NRF24
                                        
                                        
                                        // Import libraries used by the Sketch.
                                        #include <SPI.h>
                                        #include <MySensors.h>
                                        #include <Wire.h>
                                        #include <SparkFun_APDS9960.h>
                                        
                                        // Constants declaration(s)
                                        #define APDS9960_INT                      2   // Needs to be an interrupt pin. We should be able to use the Arduino's pin 3 as well.
                                        #define LED_PIN                           3   // The led PWM pin, that drives the LED strip. This is the pin thats attached to the mosfet.
                                        #define MAXDIMLEVELS                     100  // The maximum number of dim levels. Domoticz supports 0-100 (we'll transalate thim in an array)
                                        #define BRIGHTNESS_INCREMENT             15   // Dimmer increment for gesture(s). Play with this value yourself. The amount of gesture controlled
                                        // dim levels is MAXDIMLEVELS / BRIGHTNESS_INCREMENT having 8 to 5 levels feels more natural to me.
                                        #define MAX_LEVEL_REACHED_DELAY          150  // Short blinking delay when increasing the dimmer while the dimmer is already at max
                                        // Had some troubles in the past with tha acurateness of the gw.wait on pro mini's. But that'll probably
                                        // not be noticeable with this short delay. Delay is in milliseconds
                                        #define MAX_LEVEL_REACHED_SIGNAL_COUNT   2    // The amount of blinks, when the max dim level already has been reached. It's just a way to let the user know
                                        // that the lamp can not be more brighter than the current brightness
                                        #define CHILD_ID_LIGHT                   1    // The child id of the Node. Only one Node on this sensor though. See MySensors documentation
                                        #define LIGHT_OFF                        0    // Constant indicating the lamp on state
                                        #define LIGHT_ON                         1    // Constant indicationg light off state
                                        #define SN "Gesture controlled lamp"          // Description of this sketch. 
                                        #define SV "2.2"                              // The version of the Sketch
                                        
                                        // Global Variables
                                        SparkFun_APDS9960 apds = SparkFun_APDS9960(); // Initialize a SparkFun_APDS9960 object. This does all the magic incl. i2c communication with the sensor.
                                        int isr_flag = 0;                             // interrupt flag, triggered when a gesture has been dectected. Used to detect gesture detection in the interrupt handler
                                        // the actual handling is done in the main loop. This allows is the keep the interrupt handler is lightweight is possible
                                        // which is a good practice. Otherwise you'll get some behaviour you don't expect.
                                        int LastLightState = LIGHT_OFF;               // The current lamp state. Wel'll turn it off for first time useage. The Sketch will query your Home Automation System for
                                        // the last value when it's being reboot.
                                        int LastDimValue = MAXDIMLEVELS;              // last known dim value (Only initial value. Value is retrieved from your HA system)
                                        
                                        /**
                                           Values could be calculated. But the sketch is small and storing in an Array is just faster. Otherwise we have to do calculations that incl Floats.
                                           Floats take up a lot of your arduino memory
                                        */
                                        int dimlevels[ MAXDIMLEVELS ] =  // PWM values used for translating home automation dimmer levels. This gives smoother transations
                                        { 0,   1,   2,   3,   4,   5,   6,   7,   8,   9,
                                          10,  11,  12,  13,  14,  15,  16,  17,  18,  19,
                                          20,  21,  22,  23,  24,  25,  26,  27,  28,  29,
                                          30,  31,  32,  35,  39,  42,  46,  49,  52,  56,
                                          59,  62,  66,  69,  73,  76,  79,  83,  86,  89,
                                          93,  96, 100, 103, 106, 110, 113, 116, 120, 123,
                                          126, 130, 133, 137, 140, 144, 147, 150, 154, 157,
                                          160, 164, 167, 171, 174, 177, 181, 184, 187, 191,
                                          194, 197, 201, 204, 208, 211, 215, 218, 221, 225,
                                          228, 231, 235, 238, 242, 245, 246, 250, 251, 255
                                        };
                                        
                                        /**
                                           Variables needed for setting up and communication with MySensors. These variables will handle all of the MySensors magic for you.
                                        */
                                        MyMessage lightMsg(CHILD_ID_LIGHT, V_LIGHT);
                                        MyMessage dimmerMsg(CHILD_ID_LIGHT, V_DIMMER);
                                        
                                        /**
                                           Initializing code. Basicly we'll setup MySensors communication and test if we can communicate with the gesture sensor. See comment in setup method for more details
                                        */
                                        void setup() {
                                          //  // Initialize NFR24L01+ radio for enabling MySensors );
                                          //  gw.begin(incomingMessage, AUTO, false);
                                        
                                        
                                          // declare output pin for PWM control of the MOSFET
                                          pinMode( LED_PIN, OUTPUT );
                                        
                                          // APDS Initialization code
                                          pinMode(APDS9960_INT, INPUT);   // Set interrupt pin as input. @@Note: this should be handled my the library. But it isn't
                                          attachInterrupt(0, interruptRoutine, FALLING);   // Initialize interrupt service routine. Basicly it'll call our interrupt routine
                                        
                                          if ( apds.init() ) { // Initialize APDS-9960 (configure I2C and initial values)
                                            // @@NOTE: original value is two. But it looks like the modern gesture sensor or more sensitive. 1 does it for me
                                            apds.setGestureGain( 1 );
                                          }
                                        
                                          if ( apds.enableGestureSensor(true) ) { // Start running the APDS-9960 gesture sensor engine. Sensor support more functions than gesture detection only.
                                            analogWrite( LED_PIN, 0 ); // Turn the lamp off.
                                          }
                                        }
                                        
                                        void presentation( ) {
                                          // Send the Sketch Version Information to the Gateway. Domoticz seems to ignore this. Don't know about the other HA systems.
                                          sendSketchInfo(SN, SV);
                                        
                                          delay( 50 ); // It can't hurt to add some delay. It gives the gateway some time to handle other messagess
                                        
                                          // Present the dimmable lamp is a child node to the HA system. We'll enable ACK communication.
                                          present(CHILD_ID_LIGHT, S_DIMMER, "floor lamp", true );
                                        
                                          delay( 50 ); // It can't hurt to add some delay. It gives the gateway some time to handle other messagess
                                        
                                          request( CHILD_ID_LIGHT, V_PERCENTAGE ); // Request current dimvalue from HA. The current value is being handled in the incomming method.
                                          delay( 50 ); // It can't hurt to add some delay. It gives the gateway some time to handle other messagess
                                          
                                          request( CHILD_ID_LIGHT, V_STATUS ); // Request current lamp state from HA. The current value is being handled in the incomming method.
                                          delay( 50 ); // It can't hurt to add some delay. It gives the gateway some time to handle other messagess
                                        
                                        }
                                        
                                        // Main loop. Does twoe things. Handle gestures if detected by the interrupt routine. And give the MySensors lib the oppurtunity to handle incomming messages.
                                        void loop() {
                                          if ( isr_flag == 1 ) {
                                            detachInterrupt(0);
                                            handleGesture();
                                            isr_flag = 0;
                                            attachInterrupt(0, interruptRoutine, FALLING);
                                          }
                                        }
                                        
                                        // interrupt handler. Is being triggered by the gesture sensor whenever a gesture has been detected. We've setup this up in the setup.
                                        void interruptRoutine() {
                                          isr_flag = 1;
                                        }
                                        
                                        // Determine gesture and handle accordingly.We'll ignore FAR and NEAR gestures. Do didn't feel natural to me anyway.
                                        void handleGesture() {
                                          if ( apds.isGestureAvailable() ) { // Check if there's a gesture available. Which should be, because the interrupt handler told us so.
                                            switch ( apds.readGesture() ) { // Get the gesture type.
                                              case DIR_UP: // Handle up stroke (Brightness increasing)
                                                if ( LastDimValue + BRIGHTNESS_INCREMENT > ( MAXDIMLEVELS - 1 ) ) {
                                                  for ( int i = 0; i < MAX_LEVEL_REACHED_SIGNAL_COUNT; i++ ) {
                                                    analogWrite( LED_PIN, dimlevels[ 0 ] );
                                                    wait( MAX_LEVEL_REACHED_DELAY );
                                                    analogWrite( LED_PIN, dimlevels[ MAXDIMLEVELS - 1 ] );
                                                    wait(MAX_LEVEL_REACHED_DELAY );
                                                  }
                                                  LastDimValue = ( MAXDIMLEVELS - 1 );
                                                }
                                                else {
                                                  LastDimValue += BRIGHTNESS_INCREMENT;
                                                }
                                                LastLightState = LIGHT_ON;
                                                SetCurrentState2Hardware();
                                                break;
                                              case DIR_DOWN: // Handle down stroke (Brightness decreasing)
                                                if ( LastDimValue - BRIGHTNESS_INCREMENT <= 0 ) {
                                                  LastDimValue = 0;
                                                }
                                                else {
                                                  LastDimValue -= BRIGHTNESS_INCREMENT;
                                                }
                                                if ( LastDimValue == 0 ) {
                                                  LastLightState = LIGHT_OFF;
                                                }
                                                else {
                                                  LastLightState = LIGHT_ON;
                                                }
                                                SetCurrentState2Hardware();
                                                break;
                                              case DIR_LEFT: // Handle left stroke. Turn lamp off
                                                LastLightState = LIGHT_OFF;
                                                SetCurrentState2Hardware();
                                                break;
                                              case DIR_RIGHT: // Handle right stroke. Turn lamp on
                                                LastLightState = LIGHT_ON;
                                                if ( LastDimValue == 0 ) { // @@Version 1.1 addition Slight modification. When the dimValue was 0, the light stayed off when turned on.
                                                  LastDimValue = BRIGHTNESS_INCREMENT; // Just used the first Gesture dimming stage (2 times would be better for my taste though. Might change that in the future)
                                                }
                                                SetCurrentState2Hardware();
                                                break;
                                            }
                                          }
                                        }
                                        
                                        /**
                                           Handler for message send by the MySensor gateway.
                                        */
                                        void receive(const MyMessage &message) {
                                          if ( message.type == V_LIGHT ) { // Gateway reports a new Light state
                                            int lstate = atoi( message.data );
                                            if ( ( lstate < 0 ) || ( lstate > 1 ) ) {
                                              return;
                                            }
                                            LastLightState = lstate;
                                            if ( ( LastLightState == LIGHT_ON ) && ( LastDimValue == 0 ) ) {
                                              //In the case that the Light State = On, but the dimmer value is zero, then something (probably the controller) did something wrong,
                                              //for the Dim value to 100%
                                              LastDimValue = 100;
                                            }
                                        
                                            //When receiving a V_LIGHT command we switch the light between OFF and the last received dimmer value
                                            //This means if you previously set the lights dimmer value to 50%, and turn the light ON
                                            //it will do so at 50%
                                          }
                                          else if (message.type == V_DIMMER) { // Gateway reports new dimmer level. We'l adjust it to the new value
                                            int dimvalue = atoi( message.data );
                                            if ( ( dimvalue < 0 ) || ( dimvalue > 100 ) ) {
                                              return;
                                            }
                                            if ( dimvalue == 0 ) {
                                              LastLightState = LIGHT_OFF;
                                            }
                                            else {
                                              LastLightState = LIGHT_ON;
                                              LastDimValue = dimvalue;
                                            }
                                          }
                                          //Here we'll set the actual light state/level
                                          SetCurrentState2Hardware();
                                        }
                                        
                                        // Send current values to the PWM controlled MOSFET
                                        void SetCurrentState2Hardware() {
                                          if (LastLightState == LIGHT_OFF) {
                                            analogWrite( LED_PIN, dimlevels[0] );
                                          }
                                          else {
                                            analogWrite( LED_PIN, dimlevels[ LastDimValue - 1 ] );
                                          }
                                        
                                          //Send current state to the controller
                                          SendCurrentState2Controller();
                                        }
                                        
                                        // Report new values to the Gateway.
                                        void SendCurrentState2Controller()
                                        {
                                          if ((LastLightState == LIGHT_OFF) || (LastDimValue == 0)) {
                                            send(dimmerMsg.set(0));
                                          }
                                          else {
                                            send(dimmerMsg.set(LastDimValue));
                                          }
                                        }
                                        

                                        Note I didn't made any change to how the sketch functions. Some improvements can surely be done. But let's see if it works.

                                        A Offline
                                        A Offline
                                        APL2017
                                        wrote on last edited by
                                        #36

                                        @TheoL Thank you so much for your efforts! The code works, I need to try to make gesture recognition a bit for stable (will replace module and maybe try different library) as well as reduce number of light levels as you suggested.

                                        TheoLT 1 Reply Last reply
                                        0
                                        • A APL2017

                                          @TheoL Thank you so much for your efforts! The code works, I need to try to make gesture recognition a bit for stable (will replace module and maybe try different library) as well as reduce number of light levels as you suggested.

                                          TheoLT Offline
                                          TheoLT Offline
                                          TheoL
                                          Contest Winner
                                          wrote on last edited by
                                          #37

                                          @APL2017 I'm working on a small library that handles a lot of those dimming features. We can always integrate it later on. But first let's try to make the gesture sensor stable. Then we can update the code on the website as well @mfalkvidd ?

                                          mfalkviddM 1 Reply Last reply
                                          0
                                          Reply
                                          • Reply as topic
                                          Log in to reply
                                          • Oldest to Newest
                                          • Newest to Oldest
                                          • Most Votes


                                          7

                                          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
                                          • MySensors
                                          • OpenHardware.io
                                          • Categories
                                          • Recent
                                          • Tags
                                          • Popular