💬 Gesture controlled MySensors, Floor lamp
-
Hello. Can somebody publish working code just for gesture and LED dimming with latest mySensors library? Thank you.
@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.
-
@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.
@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)
-
@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)
@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. -
@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. -
@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.
@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)); } } -
@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)); } }@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?
-
@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?
@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. -
@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. -
@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.
@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.
-
@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.
-
@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.
@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 ?
-
@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 ?
-
@mfalkvidd The mySensors site with all the build examples. The gesture control sensors is still in MySensors 1.x version