OlfactIoTmaker: Commercial Diffusers Transformed Into IoT Devices
by giadaferrario in Circuits > Arduino
226 Views, 1 Favorites, 0 Comments
OlfactIoTmaker: Commercial Diffusers Transformed Into IoT Devices
The aim of this project is very simple, it is to enable some regular commercial diffusers to be controlled through buttons and wirelessly. The idea is to "hack" the diffusers and integrate a microcontroller able to connect to a common local network and receive control signals as well as be controlled by an external button.
In the following steps I'll show to how to do that.
Here the .ino file with the entire project code.
Downloads
Supplies
- 1 x Arduino Yun
- 3 x Glade Sense&Spray diffurers
- 2 x L293DNE motor drivers
- 4 x push buttons
- 4 x 10kohm resistors
- 1 x breadboard
- 1 x 5v - 2.0A in output adapter
- cables to be used with the breadboard
Open the Diffuser and Cut Unused Components
The first thing to do is open the diffuser and look inside it in order to understand how it works, what we need to keep, and what is useless for us and can be removed.
Opening the diffuser we can notice that it is composed by some gears, a dc motor that activates the gears, a button, and a movement sensor that through a small board send signals to the motor, and in the end there are also batteries.
For the purpose of this project the only things that we need to keep are the dc motor and gears. At this point we can cut the cables that go from the small board to the dc motor in order to remove the button, the sensor, and the integrated small board.
After that we can put back the gears and the dc motor in place, close the diffuser, and run out the dc motor cables (red for positive signal and black for ground) through the the little holes that are already present in the front of the diffuser.
This must be done for each diffuser.
Let's Move the Diffuser's Motors With Arduino
The main thing that the product must do is a perfume diffusion. There are two ways to send the signal for the perfume diffusion to diffusers. The first one is using buttons (explained in this Step), the second one sending an HTTP request to the Arduino through a browser (explained in Step 3).
To make a diffusion we need to be able to send signals to Arduino and Arduino must forward signals to diffusers' motors. First of all we need to set up 4 pins to control the buttons, setting them as input pins. We have 3 diffusers and 4 buttons because we want a button for each diffuser and one button that controls all of them.
pinMode(BTN1, INPUT);
pinMode(BTN2, INPUT);
pinMode(BTN3, INPUT);
pinMode(BTN4, INPUT);
What is explained from now for one motor it must be replicated for all of the three diffusers
Secondly, we need to fix 3 pins for each motor, one is for the 'Enable' signal and it must be set at the high level, the second one name it A and the third one name it B are used to control the rotation and the direction of the motor:
- A low and B low, the motor does not move
- A high and B low, the motor moves to the right
- A low and B high, the motor moves to the left
pinMode(MOTOR1_IN6, OUTPUT); # pin 6 for the motor 1
pinMode(MOTOR1_IN7, OUTPUT); # pin 7 for the motor 1
digitalWrite(ENABLE_1, HIGH); # enable for the motor 1
After have set all up, into the loop() method we need to check if a button is pressed and if yes we need to activate the corresponding engine. To do that we need to declare 3 global variables that maintain the state of the motor, if it has turned right/left or stop.
int state_right_1 = 0;
int state_left_1 = 0;
int state_stop_1 = 0;
This three variables are used to avoid that a motor can be reactivated even before finishing the previous diffusion, when the motor has rotated to the right the 'state_right_1' is set to 1, when it has stopped the the 'state_stop_1' is set to 1 and the 'state_right_1' is set to 0, and so on.
The flow to follow to the motor activation is: check if the button is pressed and if the motor is not active, if yes start the rotation to right (for 300ms), when the rotation to the right is finished stop for a small amount of time (in this case 50ms) and the start to rotate to the left for others 300ms that stop.
bool motor1_isNotActive = state_right_1 == 0 && state_stop_1 == 0 && state_left_1 == 0;
In order to activate more that motor at time and provide the possibility to activate a motor when another one is spraying we cannot use the delay(ms) function to keep track of the amount of time that the motor has rotating, since delay(ms) is a blocking function and it prevents the product from working properly. To avoid this problem we use millis(), a function that allows parallel activations keeping track of the time that has elapsed since the activation of the motor saving the motor activation instant in a variable (e.g, motor_1), declaring an interval (the time need by the motor to rotate in a direction), checking between the saved value, the current time instant and the fixed value if the motor has rotated for the fixed amount of time. If yes, it rotates in the other direction or stops, otherwise it continues to rotate in that direction.
Here a if check example:
if(millis() - motor_1 >= INTERVAL && state_right_1 == 1)
At this point, we need to replicate this for each motor of diffusers and we are able to control the perfume diffusions using buttons.
Let's Accept Request From the Browser
Now, we want to control our perfume diffusion remotely. To do that we need to use the Bridge library that simplifies communication between the two Arduino Yún processors, one receives the requests and forward them to the other one that is able to handle them.
We include the Bridge library and the related client-server:
#include <Bridge.h>
#include <BridgeClient.h>
#include <BridgeServer.h>
We declare globally the instance of the server:
BridgeServer server;
And in the setup() method we start the Bridge and the server:
Bridge.begin();
server.noListenOnLocalhost();
server.begin();
At this point, Arduino Yun after the boot is able to create its own Access Point, which we can connect to. It is visible to our Wi-fi network list as ArduinoYun-XXXXXXXXXXXX, we connect to it and we can set up a common network between us and Arduino going to 192.168.240.1 and configuring the network. Alternatively, we can use the Access Point created by the Arduino itself to communicate. In this project the second option is used.
To communicate with Arduino we need to use its IP address: 192.168.240.1 and a REST endpoint that it can recognise, /arduino.
At this stage, we what to send to our Arduino Yun these types of command, through the browser search bar:
- 192.168.240.1/arduino/on: to activate all the diffusers together
- 192.168.240.1/arduino/on/1: to activate the diffuser number 1
- 192.168.240.1/arduino/on/2: to activate the diffuser number 2
- 192.168.240.1/arduino/on/3: to activate the diffuser number 3
To accept the request and read the command in the loop() method, we use:
BridgeClient client = server.accept();
String command = client.readString();
After reading the string, we need to do some action to clean the string and parse it. This actions depends on what we want to send to Arduino. In our case we need to understand if the user want to activate a diffuser at time or if he want to activate all diffusers together. In addition we need to clean up the string since the 'Enter' that we push to send the request it is reported into the string as '\n'.
Let's Put All Together
Since we have the code to activate the diffusers in the both desired way, now we can put all the components together to the breadboard, as in the screenshot from my Tinkercad Circuit Design.
Enjoy!
Last step: enjoy the final result!
Thank you for reading this tutorial and if you replicate the project please share it with us here below :)