Project Details
Material List
Quantity | Components |
---|---|
2 | Green 5mm LED |
8 | Red 5mm LED |
1 | Push button |
10 2 4 1 2 3 ft 1 | 220 ohms 1/4 w 12K ohms 1/4 w Galvanized nails Universal board Pieces of foam 3x3 inches Wires (at least 1/4 w) Scissors |
Quantity | Components |
---|---|
1 | White prime spray |
1 | Assorted colored papers or free paint paper samples |
1 | 3/4 transparent tape |
1 | Black gel pen |
Assembling the Moisture Sensors
Mechanical Assembly
Electrical Assembly
Assembling the Flower Face
Testing the Flower Face with the Software
// Author: Manoel Carlos Ramon
// email: manoel.c.ramon@intel.com
#define DEBUG 0
/* Pins that define if system is ON */
#define PIN_LEFT_EYE 10
#define PIN_RIGHT_EYE 11
/* Sensor switch button */
#define PIN_SWITCH_SYSTEM 13
void clear();
int current_sensor = 0;
int button_state = 0;
int array_happy_face[2][4] = {{1, 0, 0, 1}, /* line 1 */
{0, 1, 1, 0}}; /* line 0 */
int array_sad_face[2][4] = {{0, 1, 1, 0}, /* line 1 */
{1, 0, 0, 1}}; /* line 0 */
/* THE MOUTH - back view
_____________ led 0 - pin 6
| __________ led 1 = pin 7
| | _______ led 2 = pin 8
| | | ______ led 3 = pin 9
| | | |
O O O O line 1
0 0 0 0 line 0
^ ^ ^ ^
| | | |__ led 3 = pin 5
| | |______ led 2 = pin 4
| |________ led 1 = pin 3
|____________ led 0 = pin 2
*/
int lastButtonState = LOW; // the previous reading from the input pin
long lastDebounceTime = 0; ; // the last time the output pin was toggled
long debounceDelay = 500; // adjust this value if necessary to avoid flickering
void clear()
{
int pin = 0;
for (pin = 0; pin < 12; pin++)
{
digitalWrite(pin, LOW);
}
}
void drawMatrix(int array[2][4])
{
int line = 0;
int pin = 2;
int c = 0;
int level = LOW;
while (line < 2)
{
digitalWrite(line, LOW);
while (c <= 3)
{
level = array[line][c];
digitalWrite(pin, level);
c++;pin++;
}
c=0;
line++;
delay(10);
}
}
void setup() {
if (DEBUG) Serial.begin(9600);
// put your setup code here, to run once:
int pin = 0;
for (pin = 0; pin < 12; pin++)
{
pinMode(pin, OUTPUT);
delay(10);
}
// switch button
pinMode(PIN_SWITCH_SYSTEM, INPUT);
// turn off all leds
clear();
}
void checkButtonState()
{
// read the state of the switch into a local variable:
int reading = digitalRead(PIN_SWITCH_SYSTEM);
// check to see if you just pressed the button
// (i.e. the input went from LOW to HIGH), and you've waited
// long enough since the last press to ignore any noise:
// If the switch changed, due to noise or pressing:
if (reading != lastButtonState) {
// reset the debouncing timer
lastDebounceTime = millis();
}
if ((millis() - lastDebounceTime) > debounceDelay) {
// whatever the reading is at, it's been there for longer
// if the button state has changed:
if (reading != button_state) {
button_state = reading;
}
}
lastButtonState = reading;
return;
}
void loop() {
// reading the button state
checkButtonState();
if( button_state != lastButtonState)
{
// button pressed
current_sensor++;
if (current_sensor > 1) current_sensor = 0;
}
if (DEBUG) Serial.println(current_sensor);
if (current_sensor == 0)
{
//sensor 1 - only one LED on
digitalWrite(PIN_RIGHT_EYE, HIGH);
digitalWrite(PIN_LEFT_EYE, LOW);
drawMatrix(array_sad_face);
}
else
{
// sensor 2 - two LEDs ON
digitalWrite(PIN_RIGHT_EYE, HIGH);
digitalWrite(PIN_LEFT_EYE, HIGH);
//sad face
drawMatrix(array_happy_face);
}
}
Reviewing the Code
setup( ) function
setup()
function, you set the ports 2 to 9 (the mouth) and the ports defined by PIN_LEFT_EYE
and PIN_RIGHT_EYE
(the eyes) as output because they are the LEDs connections. PIN_LEFT_EYE
and PIN_RIGHT_EYE
are defined by the following code:#define PIN_LEFT_EYE 10
#define PIN_RIGHT_EYE 11
setup()
function is the port that determines which button is connected. Its represented by the definition PIN_SWITCH_SYSTEM
with port 13 by default./* Sensor switch button */
#define PIN_SWITCH_SYSTEM 13
loop( ) function
loop()
function checks the button state. If it is different from the previous state, that means the user pressed the button and the sensor selection must be changed.current_sensor
is zero (0
) and a sad face will be displayed using the LEDs. Note that only one eye, represented by the green LED connected to PIN_RIGHT_EYE
, is ON
, which means that when there is only one eye ON
, it’s sensor 1.ON
. In this case, the current_sensor
variable value is one (1
).drawMatrix( ) function
drawMatrix()
function is responsible for drawing the mouth according to the matrix passed as its argument.array_happy_face[][]
and array_sad_face[][]
integer arrays.int array_happy_face[2][4] = {{1, 0, 0, 1}, /* line 1 */
{0, 1, 1, 0}}; /* line 0 */
int array_sad_face[2][4] = {{0, 1, 1, 0}, /* line 1 */
{1, 0, 0, 1}}; /* line 0 */
1
means the LED must be turned ON
and 0
means OFF
. Considering this, you can see that the 1
s in array_happy_face[][]
form a smiling mouth and that they form a sad mouth in the array_sad_face[][]
.checkButtonState( ) function
checkButtonState()
function is responsible for determining whether the user pressed the button. For this, the checkButtonState()
implements the same logic used by the debounce example in the IDE (see Examples->02.Digital->Debounce
).debounceDelay
adjusts the button’s debounce interval. If, during your tests, you think the button is flickering, you can increase this interval.long debounceDelay = 500; // adjust this value if necessary to avoid flickering
Testing the Flower Face
ON
, as shown in Figure 8-10.
ON
, as shown in Figure 8-11.
ON
means sensor 1 and two eyes ON
means sensor 2.Running the Project
Calibration Procedure
soil_moisture.ino
. Just a few simply changes need to be made to the code.Defining the Connections
/* Moisture sensor - Analog Input */
#define ANALOG_MOISTURE_SENSOR_1 A0
#define ANALOG_MOISTURE_SENSOR_2 A1
int sensor_value = 0;
Setting the Boundary Values
#define DEBUG 1
sensor value:
” with the appropriate value. Make sure you are selecting the right sensor during this calibration.SOIL_ID_GOOD
to the appropriate value. In Listing 8-1, it was set to 350
, which determined if the soil is completely dried out or had enough moisture. The 350
value was tested in three different locations in the United States and in one location in Italy and worked very well for this demo. However, you should test and determine the best value for your soil and moisture level./* The analog reading boundary when soil is good */
#define SOIL_IS_GOOD 350
loop
function is changed so that it reads the current analog port selected by the push button, compares the value, and displays the right emotion in the flower face circuit, as shown in the following excerpt from Listing 8-1.void loop() {
// reading the button state
checkButtonState();
if( button_state != lastButtonState)
{
// button pressed
current_sensor++;
if (current_sensor > 1) current_sensor = 0;
}
// reading the sensor
switch (current_sensor)
{
case 0:
sensor_value = analogRead(ANALOG_MOISTURE_SENSOR_1);
// first sensor - one LED ON
digitalWrite(PIN_RIGHT_EYE, HIGH);
digitalWrite(PIN_LEFT_EYE, LOW);
break;
case 1:
sensor_value = analogRead(ANALOG_MOISTURE_SENSOR_2);
// second sensor - two LEDs ON
digitalWrite(PIN_RIGHT_EYE, HIGH);
digitalWrite(PIN_LEFT_EYE, HIGH);
break;
}
if (DEBUG)
{
Serial.print("current_sensor:");
Serial.println(current_sensor);
Serial.print(" sensor_value:");
Serial.println(sensor_value);
}
if (sensor_value >=SOIL_IS_GOOD)
{
drawMatrix(array_happy_face);
}
else
{
drawMatrix(array_sad_face);
}
}
loop()
function will call the function checkButtonState()
, which updates the variable button_state
. If button_state
is different than the previous state saved in the lastButtonState
variable, the current_sensor
variable changes and can assume two values—0
or 1
. The value 0
represents the first sensor and the value 1
represents the second one.switch
instruction will determine which sensor the user selected and call the analogRead()
function, which will read the analog port that corresponds to the connected sensor and load the value to the sensor_value
variable.0
) is selected, digitalWrite()
will turn ON
just one flower eye, because only one LED will be HIGH
, as shown here:digitalWrite(PIN_RIGHT_EYE, HIGH);
digitalWrite(PIN_LEFT_EYE, LOW
ON
because both LEDs will be HIGH
:digitalWrite(PIN_RIGHT_EYE, HIGH);
digitalWrite(PIN_LEFT_EYE, HIGH);
DEBUG
is defined as 1
, as explained previously.sensor_value
variable reports moist soil, the drawMatrix()
function will draw a smile in the flower face. Otherwise, a sad face is shown, as explained in the section called “Testing the Flower Face with Software” of this chapter.Showing This Project in a Fair
Ideas for Improving the Project
Increasing the Number of Sensors
Automatic Irrigation
Quantity | Components |
---|---|
1 | R1: 1K Ohm |
1 | D1: 1N4001 or 1N4004 |
1 | Q1: 2N2222A or BC548 |
1 | Relay |