49713 Designing for the Internet of Things
· 16 members
A hands-on introductory course exploring the Internet of Things and connected product experiences.
When your plant appears to be sitting on your desk for a long period, it needs a vacation to somewhere with nice sunshine! ☀️🕶️
"I don't think that indoor plants need sunlight." "How much light does my plant really need?" "What does it mean by exposing to medium light?"
These are some misunderstandings and questions people might have. Actually, indoor plants also need to expose to the sunlight and environment outside the building periodically. Because it might be once a week or less often than that, people can easily forget to bring them outside!
"Take me on vacation" is a small unit that can be attached to any indoor plant plot. The unit keeps monitoring the amount of light a plant receives throughout a period of time quietly and only nudges its owner when it's time to get some sunlight.
There are three main features relating to bringing your beloved plant outside.
A. Light monitoring: to indicate when a plant stays in a place with not enough light for too long and needs to get sunlight.
B. Suggestion about the proper amount of light: to help the user provide the right amount of light to plants while bringing it outdoor, rather than guessing.
C. Fall detection: to protect the beloved plant from possible dangers while staying on vacation outdoor! (Be careful of dogs running around, the strong wind, and someone accidentally stepping on it!)
Scenarios
I initially approached the project by asking in which situation sensors or the ability to notify users from a distance become beneficial. Then I realized that sensors are better when the condition to be detected is "invisible" or cannot be precisely identified by human sense. Therefore, I decided to "monitor the amount of light throughout a period of time." Getting informed through a distance makes sense in situations when users and the plant are at different places. So, I came up with to detect a fall while the plant is brought elsewhere outside, such as a balcony, shared apartment desk, or in front of the house, etc.
I try to compromise between reminding and distracting users. Although reminders are important, it is not dramatically critical; therefore, I choose to use minimal feedback on the device. I utilize only a single LED to signals statuses(normal or abnormal), another RGB LED used only while users calibrating the proper amount of light and notification only when the plants need users to take action.
In the ideation process, I explored the availability of the sensors and came up with Photocell and Tile switch, which suits the most with the project's goal. For the output, besides LED and notifications, I also considered the Piezo Buzzer. However, I rejected using it since it tends to give too intrusive feedback for this context.
Most of the challenges occur with the sensor or switch that I have never used before, a tile switch. It happens to be too sensitive to any small movement; therefore, I learned more about the need to debounce, and the result is satisfactory. Another challenge is to give the right condition in publishing the event for IFTTT notification to avoid redundancy. I ended up by assigning them true or false in the "already announce" variable.
The overall process
1. Exploration
2. Plan and create the structure of code
3. Gradually complete the circuit and code, function by function
4. Link the device with the IFTTTT platform
5. Create the mock-up of the device from Lego
Part Lists
Modules
There are mains modules I used in this project: code, circuit and IFTTT platform. In the code, there are 2 main parts which are light monitoring and tilt monitoring as shown in the diagram below.
*Ideally, it should read the light value every hour, evaluate if the plant receives enough light per day and notify when there are several days in a roll without enough light. However, to make it practical in short demonstration, 15 seconds mean one whole day and the device will notify users after two days in a roll without enough light. (30 seconds in a roll in this demo)
** These requirements vary from different types of plants.
//Light Sensor
int photoCellPin = A0;
int photoCellReading = 0;
//Tilt Sensor
int tiltPin = D6;
int LEDstate = HIGH;
int tiltreading;
int tiltprevious = LOW;
long notetime = 0;
long debounce = 50;
//Monitoring LED
int ledPin = D2;
//Amount of light RGB LED
int redPin = D3;
int greenPin = D4;
int bluePin = D5;
#define COMMON_ANODE
//Time monitoring
int second = -1;
int totalday = 0;
int nolightday = 0;
int status = 0;
int hronvacation =0;
bool alreadyannounce_needvaca = FALSE;
bool alreadyannounce_backtowork = TRUE;
bool alreadyannounce_fall = FALSE;
void setup() {
//Variable display
Particle.variable("Light", &photoCellReading, INT);
Particle.variable("CurrentSecond", &second, INT);
Particle.variable("TotalDays", &totalday, INT);
Particle.variable("NoLightDaysInARoll", &nolightday, INT);
Particle.variable("PlantStatus", &status, INT);
Particle.variable("HourOnVacation", &hronvacation, INT);
Particle.variable("Tilt", &tiltreading, INT);
//Set up LED to be output
pinMode(ledPin, OUTPUT);
pinMode(redPin, OUTPUT);
pinMode(greenPin, OUTPUT);
pinMode(bluePin, OUTPUT);
//tilt sensor setup
pinMode(tiltPin,INPUT);
digitalWrite(tiltPin, HIGH);
digitalWrite(ledPin, LOW); //turn off monitoring LED
setColor(0, 0, 0); //turn off rgb led
}
void loop() {
//LIGHT MONITORING
photoCellReading = analogRead(photoCellPin);
second = Time.second();
//Monitoring Light level through a week
if(status == 0){
if(alreadyannounce_backtowork == FALSE){
Particle.publish( "Backtowork" );
delay(500);
alreadyannounce_backtowork = TRUE;
}
//pretend that every 15 seconds = 1 day
if (Time.second() == 0 || Time.second() == 15 || Time.second() == 30 || Time.second() == 45){
digitalWrite(ledPin, HIGH); //Monitoring LED blinks everytime it reads
delay(1500);
totalday++;
if(photoCellReading < 1500){
nolightday++;
}else{
nolightday = 0;
}
}else{
setColor(0, 0, 0); //turn off rgb led
delay(500);
}
if(nolightday >= 2){
status = 1;
alreadyannounce_needvaca = FALSE;
}
}
//The plant says I need a vacation
if(status == 1){
if(alreadyannounce_needvaca == FALSE ){
Particle.publish( "NeedVacation" );
delay(500);
alreadyannounce_needvaca = TRUE;
}
blink();
if(photoCellReading <= 1500){
setColor(0, 0, 255); //blue means too dim
delay(500);
}else if(photoCellReading > 1500 && photoCellReading < 3000){
setColor(0, 255, 0); //green means proper amount the plant needs :-)
hronvacation ++;
delay(1500);
if(hronvacation >=5){
status = 0;
alreadyannounce_backtowork = FALSE;
hronvacation = 0;
nolightday = 0;
}
}else if(photoCellReading >= 3000){
setColor(255, 0, 0); //red means too strong light
delay(500);
}
}
//TILT MONITORING
int switchstate;
tiltreading = digitalRead(tiltPin);
// If the switch changed, due to bounce or pressing...
if (tiltreading != tiltprevious) {
// reset the debouncing timer
notetime = millis();
}
if ((millis() - notetime) > debounce) {
// whatever the switch is at, its been there for a long time
// so lets settle on it!
//switchstate = tiltreading;
// Now invert the output on the pin13 LED
if (tiltreading == HIGH){
blink();
if(alreadyannounce_fall == FALSE){
Particle.publish( "Fall" );
delay(500);
alreadyannounce_fall = TRUE;
}
}else{
digitalWrite(ledPin, LOW);
alreadyannounce_fall = FALSE;
}
}
// Save the last reading so we keep a running tally
tiltprevious = tiltreading;
}
void blink (){
digitalWrite(ledPin, HIGH);
delay(500);
digitalWrite(ledPin, LOW);
delay(500);
}
void setColor(int red, int green, int blue){
#ifdef COMMON_ANODE
red = 255 - red;
green = 255 - green;
blue = 255 - blue;
#endif
analogWrite(redPin, red);
analogWrite(greenPin, green);
analogWrite(bluePin, blue);
}
Click to Expand
I would like to optimize the code to be able to use with the actual requirements for a particular plant such as to detect the light amount in every hour with a consideration of day and night, evaluate as a whole day if the plant gets enough light and notify in a realistic timeframe.
Another interesting area is to pull the specific data from the internet for each type of plant to ensure the precision and effectiveness of the device. The data mentioned are, for example, how many days the particular kinds of plants can thrive with dim light or how many lux of light is proper for this plant, etc.
I find myself enjoying the project very much. With the skills in this area, I have seen several opportunities to enhance users' "experiences" as I can utilize many more senses such as sound, motion, or light. I learned that, only with a set of sensors and output components, I could adapt and create various experiences. One sensor can be amazingly used in multiple ways. Lastly, after prototyping, I realized that user experience is very sensitive. People might think that to use an LED will be the same as any other device with a light. However, when I tried using my prototype, I suddenly noticed that every small factor matters (such as timing, how bright the LED is, the window material where the LED resides in, etc.) to deliver an experience for users.
A hands-on introductory course exploring the Internet of Things and connected product experiences.
When your plant appears to be sitting on your desk for a long period, it needs a vacation to somewhere with nice sunshine!
☀️🕶️
November 5th, 2019