I am happy to be able to show you my work again. This time I built a gesture-controlled Arduino lamp.
This project took me a lot of time, which I always have a shortage of.
The first version of the luminaire I built very quickly, and it worked fine on my breadboard, but when I brought it permanently into the enclosure, this is where it all started. After searching on the internet I’ve found lots of complaints about APDS9960 sensor problems, but no solutions for these problems. Little by little, I spent my time studying the datasheet of this sensor and understanding its functionality. But finally, it worked, and I could write a stable working code. So everything is in order.
The main emphasis in this luminaire I made not on the visualization and on the control of gestures. All other functions are secondary.
The lighting fixture is turned on by gesture to the left or right, as well as you can turn it on and a gesture to yourself, but it is not very convenient. Then with gestures to the left and right, you can flip through the lighting effects. If you start flipping to the right, the lamp will first change its colors from white to red, including all the primary colors and transitions between them.
If we flip to the left after turning on the lamp, we will see dynamic lighting effects such as “Fire”, “Matrix” and “Light”, “Matrix”, “Lava Lamp”, “Rainbow”, “Confetti”, “Sparks”, “Fire Lamp”. If you need to go back to a normal lamp, you can turn the lamp off with a gesture away from you and on with any of the three gestures instead of flipping.
Turning it off is done with a gesture away from you.
The brightness is adjusted by a gesture of approaching and moving away from the sensor. First, you bring your hand as close as possible to the sensor and then raise it sharply upwards. The luminaire goes into brightness adjustment mode. Bringing the palm closer and further away from the sensor, you need to find the appropriate brightness and fix your hand for a couple of seconds to store the brightness value. When the brightness is saved, the luminaire will let you know about it by smoothly turning off the light and then turning it on with a new brightness level.
I have not paid much attention to visual effects because I plan to make a second version of the Wemos D1 mini controller lamp. In which I plan to bring everything to perfection. For the same reason, for now, I only use one LED strip consisting of four WS2812B strips instead of four.
This is actually the main problem of the LED lamp. The interrupts in APDS9960 have a life of their own and can be triggered by anything, e.g., EM interference or a person near the sensor, pulsation of the power supply, and maybe something else.
At first, I tried to correct the problem by changing the hardware. Filtering of the power supply did not help. Even with a 18650 battery, the sensor still continued to live its life. I tried switching the INT signal terminating resistor to +5V. Also, it was no success.
As I studied it, I realized what causes false interrupt triggers. The main problem is the occasional reflection of the IR signal. The manufacturer recommends covering the sensor and everything around it with a black rubber coating. I don’t have that paint and didn’t bother with it. It could probably reduce the number of false positives a bit, though.
I wrote code that filters out all the random triggers but ran into another problem. When an interrupt is triggered, the gesture’s information is not transmitted on the I2C bus instantly but has a certain delay. And if the power supply due to the addressable LED strip is noisy, then the transfer time will always be different, taking into account these disturbances. I had to take this fact into account and rewrite the gesture detection code.
If you do not use the interrupt from the sensor in the code, then there is no problem with detecting the gesture. But in this case, we lose multitasking. If the lamp has a dynamic effect, then this requires a looping code, which is always executed all the time, and to get the controller out of the loop, we need to use interrupts.
In order to improve the stability of gesture recognition, the library also had to reduce the sensitivity of the receiver. To do this, in the file SparkFun_APDS9960.h replace the line:
if( ! setLEDBoost(LED_BOOST_300) )
if( !setLEDBoost(LED_BOOST_150) )
I chose experimentally a current of 50mA, which makes the gestures most stable, and I don’t need to burden the infrared LED with 100mA.
I also made the mistake of placing the microcontroller on the bottom of the lamp and the top cover’s gesture sensor. Because of this, I had to use 30 cm long wires to connect Arduino and apds9960. Which also added extra instability to the sensor. In the end, I overcame all these problems with the software.
I use the charger from my smartphone to power the device, with an output voltage of 5V and a current of 2A. But in fact, the light with the white light on at maximum brightness does not consume more than 1.3A. For this reason, any power supply with an output current of at least 1.3A will do.
Any other voltage step-down converter can replace the dc-dc mini360 stabilizer with an output current of at least 150mA.
I do not use a logic level converter in the circuit below, but it is my personal decision. Therefore I take no responsibility in advance if you fail sensor APDS9960 connected without a TTL level converter.
Be sure to check the gesture sensor for jumpers. They are marked in red in the picture below. If they are missing, you should use a soldering iron to apply and heat solder to these contact tracks until a homogeneous drop is formed. Now the Chinese deliver these sensors without jumpers. Without these jumpers, the operation of the sensor is not guaranteed.
Sketch for the Arduino
The code is divided into two parts. The first part contains the basic code that works with the sensor, and the second part contains the code for all the light effects.
APDS9960_INT – input for external interrupt. Arduino Nano and UNO have only two such inputs, 2 and 3.
PIN – Here, you need to specify the output to the LED strip. You can specify any digital pin to which the ws2812b strips are connected.
NUM_PIX – here you specify the number of addressable LEDs in the strip used.
range – error limit from 0 to 10. If you fix your hand over the sensor for 2 seconds when adjusting the brightness, the readings should be saved, but if the readings are not saved, then gradually increase the error limit.
Luminaire looks better live than on the video. Now, all who have seen it in my place, asking to build them the same. At the moment, I wouldn’t say I like the way the brightness control works, but I am working on it. No promises soon, but the next version of the light is already in development.
Thanks for reading this article to the end! If you still have questions, you can ask in the comments below the article. No registration is required.