49713 Designing for the Internet of Things
· 25 members
A hands-on introductory course exploring the Internet of Things and connected product experiences.
Found in DIoT 2018 2: Ambient Affect
This is an ambient object that displays water moisture level of your house plant with motion. The motion will represent a waving motion, like the plant i "waving for your attention," to remind you to water it when the moisture level of the soil is low.
Water Me! is a project that represents intimate personal data as motion in a semi-public space. When your house plant's moisture level is low (<200 reading in the soil moisture sensor), a motor turns that has a soft and long leaf like object attached to it. The resulting waving motion of the leaf like object is a display/signal that you need to water your plant or that you haven't been taking good care of your plant. This is semi-public, because it will be located wherever your house plant is located, and typically, a house plant is placed in a home space where anyone in that space could see it if you allowed them to enter it. It could also be placed in office plants and used for a similar reason.
To design and prototype an ambient object that represents whether you are taking care of your plant/if you need to pay more attention to you plant as motion in a semi-public space. The design should be non-intrusive, but obvious enough to be noticed and to help you make a positive behavior change. In this case, that positive behavior change is to pay attention to your plant by watering it.
http://0.lushome.com/wp-content/uploads/2015/03/green-ideas-interior-decorating-house-plants-3.jpg
//declaring integers
int val = 0;//variable to store soil value
int soil = A0;//Declare a variable for the soil moisture sensor
int soilPower = D7;//Variable for Soil moisture Power
//We wil use a digital pin to power this sensor, to prevent oxidation
//of the sensor as it sits in the corrosive soil.
//Setup function for the application
void setup()
{
pinMode(soilPower, OUTPUT);//Set D7 as an OUTPUT
digitalWrite(soilPower, LOW);//Set to LOW so no power is flowing through the sensor
//This function is used to get the soil moisture content
int readSoil()
{
digitalWrite(soilPower, HIGH);//turn D7 "On"
delay(10);//wait 10 milliseconds
val = analogRead(soil);
digitalWrite(soilPower, LOW);//turn D7 "Off"
return val;
}
Click to Expand
3. Then you will connect the soil moisture sensor to wifi and the particle cloud and crete variables that expose soil moisture as an integer in the cloud. You will also add in text to confirm that the soil moisture sensor is working. You will create a loop and inside read whether the soil moisture value is working and print a confirmation.
//declaring integers
int val = 0;//variable to store soil value
int soil = A0;//Declare a variable for the soil moisture sensor
int soilPower = D7;//Variable for Soil moisture Power
//We wil use a digital pin to power this sensor, to prevent oxidation
//of the sensor as it sits in the corrosive soil.
//Setup function for the application
void setup()
{
pinMode(soilPower, OUTPUT);//Set D7 as an OUTPUT
digitalWrite(soilPower, LOW);//Set to LOW so no power is flowing through the sensor
//connect to wifi and cloud
WiFi.on();
Particle.connect();
//Creates variables that are exposed through the cloud.
//You can request values from these using a variety of methods
Particle.variable("soil", &val, INT);
}
//loop for application (turn on motor when soil moisture is below 200)
void loop()
{
//display soil moisture to confirm is working
Serial.print("Soil Moisture = ");
//get soil moisture value from the readSoil function below and print it
Serial.println(readSoil());
delay(1000);//Take a reading every second
}
//This function is used to get the soil moisture content
int readSoil()
{
digitalWrite(soilPower, HIGH);//turn D7 "On"
delay(10);//wait 10 milliseconds
val = analogRead(soil);
digitalWrite(soilPower, LOW);//turn D7 "Off"
return val;
}
Click to Expand
4. Write the code for the motor, connect it to the cloud and display it as an integer variable there. Then add functionality of it into the loop. You will do this by declaring an integer for motor, setting motor as an output, setting the motor to off before the loop is read, and then activating the motor in the loop when the soil moisture sensor reads a level < 200. You will also create a variable for motor to be read in the cloud. All of this is written inline in the code below.
//declaring integers
int val = 0;//variable to store soil value
int soil = A0;//Declare a variable for the soil moisture sensor
int soilPower = D7;//Variable for Soil moisture Power
int motor = D1; // motor pin number
//We wil use a digital pin to power this sensor, to prevent oxidation
//of the sensor as it sits in the corrosive soil.
//Setup function for the application
void setup()
{
pinMode(soilPower, OUTPUT);//Set D7 as an OUTPUT
digitalWrite(soilPower, LOW);//Set to LOW so no power is flowing through the sensor
pinMode(motor, OUTPUT);//set D0 as an OUTPUT
digitalWrite(motor, LOW); //set motor off to start before read loop
//connect to wifi and cloud
WiFi.on();
Particle.connect();
//Creates variables that are exposed through the cloud.
//You can request values from these using a variety of methods
Particle.variable("soil", &val, INT);
Particle.variable("motor", &val, INT);
}
//loop for application (turn on motor when soil moisture is below 200)
void loop()
{
//display soil moisture to confirm is working
Serial.print("Soil Moisture = ");
//get soil moisture value from the readSoil function below and print it
Serial.println(readSoil());
delay(1000);//Take a reading every second
//This time is used so you can test the sensor and see it change in real-time.
//For in-plant applications, you will want to change this or increase it so
//you can take readings much less frequently.
//If your soil is too dry, turn on motor to rotate feather
//that notifies you with motion
if(readSoil() < 200)
{
Serial.println("Motor Running?");
// turn motor on if moisture level below 200
digitalWrite(motor, HIGH);
}
else
{
// turn motor off
digitalWrite(motor, LOW);
}
}
//This function is used to get the soil moisture content
int readSoil()
{
digitalWrite(soilPower, HIGH);//turn D7 "On"
delay(10);//wait 10 milliseconds
val = analogRead(soil);
digitalWrite(soilPower, LOW);//turn D7 "Off"
return val;
}
Click to Expand
//FINAL CODE
//declaring integers
int val = 0;//variable to store soil value
int soil = A0;//Declare a variable for the soil moisture sensor
int soilPower = D7;//Variable for Soil moisture Power
int motor = D1; // motor pin number
//We wil use a digital pin to power this sensor, to prevent oxidation
//of the sensor as it sits in the corrosive soil.
//Setup function for the application
void setup()
{
pinMode(soilPower, OUTPUT);//Set D7 as an OUTPUT
digitalWrite(soilPower, LOW);//Set to LOW so no power is flowing through the sensor
pinMode(motor, OUTPUT);//set D0 as an OUTPUT
digitalWrite(motor, LOW); //set motor off to start before read loop
//connect to wifi and cloud
WiFi.on();
Particle.connect();
//Creates variables that are exposed through the cloud.
//You can request values from these using a variety of methods
Particle.variable("soil", &val, INT);
Particle.variable("motor", &val, INT);
}
//loop for application (turn on motor when soil moisture is below 200)
void loop()
{
//display soil moisture to confirm is working
Serial.print("Soil Moisture = ");
//get soil moisture value from the readSoil function below and print it
Serial.println(readSoil());
delay(1000);//Take a reading every second
//This time is used so you can test the sensor and see it change in real-time.
//For in-plant applications, you will want to change this or increase it so
//you can take readings much less frequently.
//If your soil is too dry, turn on motor to rotate feather
//that notifies you with motion
if(readSoil() < 200)
{
Serial.println("Motor Running?");
// turn motor on if moisture level below 200
digitalWrite(motor, HIGH);
}
else
{
// turn motor off
digitalWrite(motor, LOW);
}
}
//This function is used to get the soil moisture content
int readSoil()
{
digitalWrite(soilPower, HIGH);//turn D7 "On"
delay(10);//wait 10 milliseconds
val = analogRead(soil);
digitalWrite(soilPower, LOW);//turn D7 "Off"
return val;
}
Click to Expand
We learned that it takes intentional, thoughtful design to create a product that displays sensitive information, but in a way that doesn't negatively impact the user or anyone else who may interact with the product.
In the future, we would start the process with a more purposeful ideation session around the many different options or areas we could explore to display sensitive information that haven't been explored yet. We are aware that products like Water Me! currently exist (like the Thirsty Light, https://www.amazon.com/Thirsty-Light-Original-Digital-Moisture/dp/B0017RXJUS). Though creating Water Me! was an educational experience for us, it could be even more exciting to tackle an issue or project concept that has not been robustly and/or successfully addressed.
Next steps for this project would be to connect the motor to multiple plants, to have the motor run at different speeds depending on the level of dryness (not just programmed to one level) and/or to attached the motor to the moisture sensor in a way that looks more like the original concept sketches we presented at the beginning of this documentation.
We faced two major challenges during this project and they are explained below:
1. Programming the if statement for the motor: Once we were able to get the soil moisture sensor (SMS) read and sending readings to the cloud, we had some difficulty figuring out how to get the motor to turn off and on when the moisture reading was below 200. This is partially because we were relying too heavily on documentation done by other people and because their projects were actually much different than ours. There isn't much documentation about how to program motors when information is read by a more complicated sensor like the SMS that we chose. Ultimately, we found a particle.io community project that was somewhat similar to ours and made sense to us (referenced below) and we manipulated the code to suit our needs.
2. Setting up the motor hardware: Online, we also found many different ways to set up the DC motor we used. We were able to power it and connect it to the cloud easily, but we had difficulty wiring it correctly so that it was not on all the time and could turn on and off per the commands sent to it by the SMS. Ultimately, our professor, Daragh Byrne, and TA, Roberto Andaya, guided us to resolve this issue by directing us to the transistor we should use TIP120 and a better way of wiring the motor, which is how it is wired in the fritzing diagram shown earlier in our documentation.
We received support and guidance from our professor, Daragh Byrne, and class TA, Roberto Andaya, and also referred to the below sources to complete this project.
To program of the soil moisture sensor and publish its data to the cloud, we referred and built upon code from this source: https://community.particle.io/t/soil-sensor-data-publish/21416
For setup of firmware for the motor, we referred to this source: https://www.hackster.io/adi1690/particle-photon-motor-control-c1fa6d
A hands-on introductory course exploring the Internet of Things and connected product experiences.
This is an ambient object that displays water moisture level of your house plant with motion. The motion will represent a waving motion, like the plant i "waving for your attention," to remind you to water it when the moisture level of the soil is low.
February 5th, 2018