49713 Designing for the Internet of Things
· 16 members
A hands-on introductory course exploring the Internet of Things and connected product experiences.
A plant sings the Mario Song and update you on the light status during the day.
It has a photoresistor to detector light change of the environment around itself. It pushes notification to its owner in a 15-minute cycle during the day to let the owner know about the light condition around the plant. It also generates a log on Google sheet to collect light data throughout the day. This type of solution is best for the type of plans that are not in favor of bright conditions. It also connects with IFTTT so that the owner can receive notifications about the plant status.
First, I identified a few key features of the device. I thought about what signal it needs to give to the user and how the user would like to get notified when the plant needs more care. Then I decided to use the photoresistor to detect the light level and an LCD light screen that can show emojis that represent plant status based on light conditions. To make the plant more vivid, I added a piezo to have it generate a Super Mario song to the user.
I connected the sensors and the components on the board. During the process, I've been thinking about the essential parts of implementing a solution. However, when I try to connect the LCD screen to the breadboard with particle Argon, I found that it is hard to find a working library to make the LCD screen work. Due to the time constraint, I wasn't able to pursue that route. Then I decided to do something similar that can express the same idea. I eventually used LED light to indicate the two different ambient light status of the plant. I reuse the code that I wrote in the skill development practice. Here is a high-level step-by-step process:
/**
* Mario Secion BEGIN
*/
#include "pitches.h"
int melody[] = {
NOTE_E7, NOTE_E7, 0, NOTE_E7,
0, NOTE_C7, NOTE_E7, 0,
NOTE_G7, 0, 0, 0,
NOTE_G6, 0, 0, 0,
NOTE_C7, 0, 0, NOTE_G6,
0, 0, NOTE_E6, 0,
0, NOTE_A6, 0, NOTE_B6,
0, NOTE_AS6, NOTE_A6, 0,
NOTE_G6, NOTE_E7, NOTE_G7,
NOTE_A7, 0, NOTE_F7, NOTE_G7,
0, NOTE_E7, 0, NOTE_C7,
NOTE_D7, NOTE_B6, 0, 0,
NOTE_C7, 0, 0, NOTE_G6,
0, 0, NOTE_E6, 0,
0, NOTE_A6, 0, NOTE_B6,
0, NOTE_AS6, NOTE_A6, 0,
NOTE_G6, NOTE_E7, NOTE_G7,
NOTE_A7, 0, NOTE_F7, NOTE_G7,
0, NOTE_E7, 0, NOTE_C7,
NOTE_D7, NOTE_B6, 0, 0
};
//Mario main them tempo
int tempo[] = {
12, 12, 12, 12,
12, 12, 12, 12,
12, 12, 12, 12,
12, 12, 12, 12,
12, 12, 12, 12,
12, 12, 12, 12,
12, 12, 12, 12,
12, 12, 12, 12,
9, 9, 9,
12, 12, 12, 12,
12, 12, 12, 12,
12, 12, 12, 12,
12, 12, 12, 12,
12, 12, 12, 12,
12, 12, 12, 12,
12, 12, 12, 12,
9, 9, 9,
12, 12, 12, 12,
12, 12, 12, 12,
12, 12, 12, 12,
};
//Underworld melody
int underworld_melody[] = {
NOTE_C4, NOTE_C5, NOTE_A3, NOTE_A4,
NOTE_AS3, NOTE_AS4, 0,
0,
NOTE_C4, NOTE_C5, NOTE_A3, NOTE_A4,
NOTE_AS3, NOTE_AS4, 0,
0,
NOTE_F3, NOTE_F4, NOTE_D3, NOTE_D4,
NOTE_DS3, NOTE_DS4, 0,
0,
NOTE_F3, NOTE_F4, NOTE_D3, NOTE_D4,
NOTE_DS3, NOTE_DS4, 0,
0, NOTE_DS4, NOTE_CS4, NOTE_D4,
NOTE_CS4, NOTE_DS4,
NOTE_DS4, NOTE_GS3,
NOTE_G3, NOTE_CS4,
NOTE_C4, NOTE_FS4, NOTE_F4, NOTE_E3, NOTE_AS4, NOTE_A4,
NOTE_GS4, NOTE_DS4, NOTE_B3,
NOTE_AS3, NOTE_A3, NOTE_GS3,
0, 0, 0
};
//Underwolrd tempo
int underworld_tempo[] = {
12, 12, 12, 12,
12, 12, 6,
3,
12, 12, 12, 12,
12, 12, 6,
3,
12, 12, 12, 12,
12, 12, 6,
3,
12, 12, 12, 12,
12, 12, 6,
6, 18, 18, 18,
6, 6,
6, 6,
6, 6,
18, 18, 18, 18, 18, 18,
10, 10, 10,
10, 10, 10,
3, 3, 3
};
/**
* Mario Section END
*/
int speakerPin = D5;
// int forcePin = A2;//TODO:
// int forceReading = 0;//TODO
// create an array for the notes in the melody:
//C4,G3,G3,A3,G3,0,B3,C4
int song = 0;
int melody_song = 1;
int underworld_melody_song = 2;
//Define the pin for photo cell
int photoCellPin = A0;
int switchPin = A1;
//Create a variable to store light reading
int photoCellReading = 0;
//Define LED pin
int ledPinGreen = D2;
int ledPinBlue = D3;
int timer = 0;
void setup() {
pinMode(ledPinGreen, OUTPUT);
pinMode(ledPinBlue, OUTPUT);
pinMode(switchPin, INPUT_PULLUP); // sets pin as input
// Register a Particle variable for light reading
Particle.variable("light", &photoCellReading, INT);
}
void loop() {
photoCellReading = analogRead(photoCellPin);
int switchState = digitalRead(switchPin);
if (switchState == HIGH) {
sing(melody_song);
} else {
noTone(speakerPin);
}
if (timer <= 0) {
//collect data each 15 minute
timer = 60000*15;
Particle.publish("light_value", String(photoCellReading));
if (photoCellReading < 200) {
digitalWrite(ledPinBlue, HIGH);
digitalWrite(ledPinGreen, LOW);
} else {
digitalWrite(ledPinGreen, HIGH);
digitalWrite(ledPinBlue, LOW);
}
}
timer = timer - 1000;
delay(1000);
}
//A helper function that sing a sone
void sing(int s) {
// iterate over the notes of the melody:
song = s;
if (song == 2) {
// Serial.println(" 'Underworld Theme'");
int size = sizeof(underworld_melody) / sizeof(int);
for (int thisNote = 0; thisNote < size; thisNote++) {
// to calculate the note duration, take one second
// divided by the note type.
//e.g. quarter note = 1000 / 4, eighth note = 1000/8, etc.
int noteDuration = 1000 / underworld_tempo[thisNote];
tone(speakerPin, underworld_melody[thisNote], noteDuration);
// to distinguish the notes, set a minimum time between them.
// the note's duration + 30% seems to work well:
int pauseBetweenNotes = noteDuration * 1.30;
delay(pauseBetweenNotes);
// stop the tone playing:
tone(speakerPin, 0, noteDuration);
}
} else {
int size = sizeof(melody) / sizeof(int);
for (int thisNote = 0; thisNote < size; thisNote++) {
// to calculate the note duration, take one second
// divided by the note type.
//e.g. quarter note = 1000 / 4, eighth note = 1000/8, etc.
int noteDuration = 1000 / tempo[thisNote];
tone(speakerPin, melody[thisNote], noteDuration);
// to distinguish the notes, set a minimum time between them.
// the note's duration + 30% seems to work well:
int pauseBetweenNotes = noteDuration * 1.30;
delay(pauseBetweenNotes);
// stop the tone playing:
tone(speakerPin, 0, noteDuration);
}
}
}
Click to Expand
In the next step, I will improve the richness of the environmental information collected by the device that can help the plant to grow more. First, it will be a real plant instead of a mockup. Secondly, I will add more sensors to collect more information that is related to the plant's growth. Thirdly, the plant will be able to water itself with soil moisture data collected. There will be a more user-friendly dashboard for the owner to monitor the plant status. Also, I will use the LCD light to reflect the "plant emotion" based on collected environment data.
The most the challenges that I encountered is the complete complexity of implementing the LCD screen. It is extremely hard to find a working library that can be compatible with the screen in a short time. And It is also tough to make sure all the parts are working together without a freaking each other. In addition to that, the particleboard is very fragile, and it is very easy to break. I will definitely start early on this project to avoid any unexpected accidents that will prevent me from moving forward. Other than the point above, I also realized that the complexity of design on the board. Meeting all the feature requirements is not a one-step work. It is crucial to make sure thinking carefully before starting implementation.
The Super Mario Piezo Code
https://www.hackster.io/jrance/super-mario-theme-song-w-piezo-buzzer-and-arduino-1cc2e4
A hands-on introductory course exploring the Internet of Things and connected product experiences.
A plant sings the Mario Song and update you on the light status during the day.
November 7th, 2019