Tutorial number 3: Greenhouse control system.
In this example, we imagine out Arduino sitting in a greenhouse. It has a temperature sensor which is read by calling getTemperature(), and a soil humidity sensor which is read by calling getSoilHumidity().
Outgoing messages should be sent to 192.168.1.1 as follows:
- The temperature should be sent about once every minute in a message with the type "temp".
- The humidity should be sent once every five minutes in a message with type "humidity".
The Arduino should also respond to the following incoming messages:
- From: "house", Type: "Heater", Data: "On" - turns on a heater by calling turnOnHeater()
- From: "house", Type: "Heater", Data: "Off" - turns on a heater by calling turnOffHeater()
- From: "house", Type: "Water", Data: [integer] X - turns on sprinklers for X minutes by calling turnOnSprinklers() and then turns them off by calling turnOffSprinklers() X minutes later
- From: "house", Type: "Status", Data: - sends a message to the house node at 192.168.1.1 containing a quick summary of the status of the heater, sprinkler, soil humidity and temperature.
In addition to these messaging requirements, the control system should automatically shut off the heater if the temperature gets higher than 25 C, and shut off the sprinkler if the soil humidity rises above 90.
#include <Ethernet.h>
#include <SPI.h>
#include <TickTimer.h>
byte mac[] = { 0x90, 0xA2, 0xDA, 0x0D, 0x59, 0x20 };
IPAddress greenhouseIP(192, 168, 1, 101);
IPAddress houseIP(192, 168, 1, 1);
int ticks = 0;
TickTimer sprinklerTimer(turnOffSprinkler);
bool heaterIsOn = false;
bool sprinklerIsOn = false;
int greenhouseTemperature = 15;
int soilHumidity = 75;
void setup()
{
Serial.begin(9600);
Ethernet.begin(mac, greenhouseIP);
Mebm.
begin(
"greenhouse", 3);
delay(500);
Serial.println("setup() done, system running");
}
void loop()
{
delay(1000);
ticks++;
if (ticks % 30 == 0)
simulateEnvironment();
if (ticks % 60 == 0)
Mebm.
sendToIP(houseIP,
"temp", getTemperature());
if (ticks % (60*5) == 0)
Mebm.
sendToIP(houseIP,
"humidity", getHumidity());
if (getTemperature() > 25)
turnOffHeater();
if (getHumidity() > 90)
turnOffSprinkler();
sprinklerTimer.tick();
}
{
if (strncasecmp(message->
msgData,
"On", 48) == 0)
turnOnHeater();
else if (strncasecmp(message->
msgData,
"Off", 48) == 0)
turnOffHeater();
else {
Serial.print("handleHeaterMessage: message->msgData invalid: ");
}
}
{
int duration = atoi(message->
msgData);
turnOnSprinkler();
sprinklerTimer.set(60*duration);
}
{
Serial.println("handleStatusRequest()");
char desc[48];
memset(desc, 0, 48);
snprintf(desc, 48, "temp=%d, humidity=%d, heater=%d, sprinkler=%d",
getTemperature(),
getHumidity(),
heaterIsOn,
sprinklerIsOn);
}
void simulateEnvironment()
{
greenhouseTemperature += random(-3, 2);
if (heaterIsOn)
greenhouseTemperature += 3;
if (sprinklerIsOn)
soilHumidity += 5;
else
soilHumidity -= 1;
}
void turnOnHeater()
{
heaterIsOn = true;
Serial.println("heater on");
}
void turnOffHeater()
{
heaterIsOn = false;
Serial.println("heater off");
}
void turnOnSprinkler()
{
sprinklerIsOn = true;
Serial.println("sprinkler on");
}
void turnOffSprinkler()
{
sprinklerIsOn = false;
Serial.println("sprinkler off");
}
int getTemperature()
{
return greenhouseTemperature;
}
int getHumidity()
{
return soilHumidity;
}