And here is my code:
#include <Time.h>
#include <TimeAlarms.h>
#include <Wire.h>
#include <DS1307RTC.h>
#include <Ethernet.h>
#include <EthernetUdp.h>
#include <SPI.h>
#include <DHT.h>
#include <OneWire.h>
#include <DallasTemperature.h>
boolean DEBUG = true;
/************ ETHERNET/UDP ************/
EthernetClient client;
byte mac[] = { 0x0, 0x11, 0x95, 0x5A, 0x9E, 0x91 };
IPAddress ip(192, 168, 2, 21);
String pass = "password";
String data;
String host = "website.ca";
EthernetUDP Udp;
unsigned int localPort = 8888; // local port to listen for UDP packets
const char timeServer[] = "pool.ntp.org"; // NTP server
/************ TIME ************/
const int timeZone = 0; // UTC±00:00
tmElements_t tm;
/************ SENSORS ************/
const int ONE_WIRE_BUS_PIN = 7;
OneWire oneWire(ONE_WIRE_BUS_PIN);
DallasTemperature sensors(&oneWire);
DeviceAddress tankTemperatureSensor = { 0x28, 0x23, 0xBA, 0x0A, 0x06, 0x00, 0x00, 0xC9 };
#define DHTPIN 2
#define DHTTYPE DHT21
DHT dht(DHTPIN, DHTTYPE);
/************ RELAYS ************/
const int lightRelay = 25;
const int pumpRelay = 24;
const int RELAY_ON = HIGH;
const int RELAY_OFF = LOW;
/************ VARIABLES ************/
boolean lightOn = false;
boolean pumpOn = false;
void setup()
{
Serial.begin(9600);
pinMode(53, OUTPUT); // set the SS pin as an output (necessary!)
digitalWrite(53, LOW); // ? (not sure)
pinMode(4, OUTPUT); // SD select pin
digitalWrite(4, HIGH); // Explicitly disable SD
pinMode(10, OUTPUT); // Ethernet select pin
digitalWrite(10, LOW); // Explicitly enable Network
/************ ETHERNET/UDP ************/
Ethernet.begin(mac, ip);
/************ TIME ************/
SetRTCTime();
setSyncProvider(RTC.get);
Alarm.delay(2000);
// Verify if we have to start or stop the light at this time
if(hour() >= 10) {
StartLightRelay();
} else {
StopLightRelay();
}
TogglePumpRelay();
PostTemperatureAndHumity();
Alarm.alarmRepeat(8,00,0, SetRTCTime); // Everyday 4:00am (hour + offset => 4 + 4 = 8)
Alarm.alarmRepeat(10,00,0, StartLightRelay); // Everyday 6:00am (hour + offset => 6 + 4 = 10)
Alarm.alarmRepeat(0,00,0, StopLightRelay); // Everyday 8:00pm (hour + offset => 20 + 4 = 24)
Alarm.timerRepeat(30, PostStillALive);
Alarm.timerRepeat(300, TogglePumpRelay); // Every five minutes [300 seconds]
Alarm.timerRepeat(600, PostTemperatureAndHumity); // Every ten minutes [600 seconds]
/************ SENSORS ************/
sensors.begin();
sensors.setResolution(tankTemperatureSensor, 10);
/************ RELAYS ************/
pinMode(lightRelay, OUTPUT);
pinMode(pumpRelay, OUTPUT);
}
void loop() {
digitalClockDisplay();
Alarm.delay(1000); // wait one second between clock display
}
/* START - Light*/
void StartLightRelay() {
lightOn = true;
UpdateLightRelay();
}
void StopLightRelay() {
lightOn = false;
UpdateLightRelay();
}
void UpdateLightRelay() {
String lightState = lightOn ? "1" : "0";
postData("lightState=" + lightState, "lightState");
if( lightOn ) {
digitalWrite(lightRelay, RELAY_ON);
} else {
digitalWrite(lightRelay, RELAY_OFF);
}
}
/* END - Light*/
void TogglePumpRelay() {
pumpOn = !pumpOn;
String pumpState = pumpOn ? "1" : "0";
postData("pumpState=" + pumpState, "pumpState");
if( pumpOn ) {
digitalWrite(pumpRelay, RELAY_ON);
} else {
digitalWrite(pumpRelay, RELAY_OFF);
}
}
void PostStillALive() {
postData("", "still-alive");
}
void PostTemperatureAndHumity() {
float humidity = dht.readHumidity();
float temperature = dht.readTemperature();
if (isnan( temperature ) || isnan( humidity )) {
// Log a problem
// Serial.println("Failed to read from DHT");
}
char bufferHumidity[10];
dtostrf(humidity, 3, 1, bufferHumidity);
char bufferTemperature[10];
dtostrf(temperature, 3, 1, bufferTemperature);
postData("roomTemperature=" + (String)bufferTemperature + "&humidity=" + (String)bufferHumidity + "&tankTemperature=" + strTemperature(tankTemperatureSensor), "data");
}
boolean postData(String data, String action) {
if(action.length() > 0) {
if(data.length() > 0) {
data += "&";
}
data += "action=" + (action);
data += "&datetime=" + (String)getDatetime();
data += "&pass=" + (pass);
if(DEBUG) {
data += "&debug=true";
}
}
if( client.connected() ) {
Serial.println("Connected");
Alarm.delay(1000);
}
if ( client.connect( host.c_str(), 80) ) {
if( DEBUG ) {
Serial.println("Connected to " + host + "...");
}
client.print("POST /api/instance HTTP/1.1\n");
client.print("Host: "+ host +"\n");
client.print("Connection: close\n");
client.print("Content-Type: application/x-www-form-urlencoded\n");
client.print("Content-Length: ");
client.print(data.length());
client.print("\n\n");
client.print(data);
if( DEBUG ) {
Serial.println(data);
}
client.stop();
if( DEBUG ) {
Serial.println(F("disconnected"));
}
} else {
if( DEBUG ) {
Serial.println("Problem while connecting to " + host + "...");
Serial.println("connected : " + (String)(client.connected() ? "true" : "false") + "");
}
}
}
float getTemperature(DeviceAddress deviceAddress) {
sensors.requestTemperatures();
return sensors.getTempC(deviceAddress);
}
String strTemperature(DeviceAddress deviceAddress) {
float currentTemp = getTemperature(deviceAddress);
char buffer[10];
return dtostrf(currentTemp, 3, 1, buffer);
}
void SetRTCTime() {
Serial.println("SetRTCTime");
time_t time = ntpUnixTime(Udp);
if( time > 0 ) {
if (RTC.set(time)) {
Serial.println("Time set");
} else {
Serial.println("Error");
}
}
}
time_t getDatetime() {
if (RTC.read(tm)) {
return makeTime(tm);
} else {
if (RTC.chipPresent()) {
Serial.println("The DS1307 is stopped. Please run the SetTime");
Serial.println("example to initialize the time and begin running.");
Serial.println();
} else {
Serial.println("DS1307 read error! Please check the circuitry.");
Serial.println();
}
delay(9000);
}
}
void digitalClockDisplay()
{
if (RTC.read(tm)) {
//return tm.Hour;
Serial.print(tm.Hour);
printDigits(tm.Minute);
printDigits(tm.Second);
Serial.println();
}
}
void printDigits(int digits)
{
Serial.print(":");
if(digits < 10)
Serial.print('0');
Serial.print(digits);
}
/*-------- NTP code ----------*/
/*
* © Francesco Potortì 2013 - GPLv3 - Revision: 1.13
*
* Send an NTP packet and wait for the response, return the Unix time
*
* To lower the memory footprint, no buffers are allocated for sending
* and receiving the NTP packets. Four bytes of memory are allocated
* for transmision, the rest is random garbage collected from the data
* memory segment, and the received packet is read one byte at a time.
* The Unix time is returned, that is, seconds from 1970-01-01T00:00.
*/
time_t ntpUnixTime (UDP &udp)
{
static int udpInited = udp.begin(localPort); // open socket on arbitrary port
//const char timeServer[] = "pool.ntp.org"; // NTP server
// Only the first four bytes of an outgoing NTP packet need to be set
// appropriately, the rest can be whatever.
const long ntpFirstFourBytes = 0xEC0600E3; // NTP request header
// Fail if WiFiUdp.begin() could not init a socket
if (! udpInited)
return 0;
// Clear received data from possible stray received packets
udp.flush();
// Send an NTP request
if (! (udp.beginPacket(timeServer, localPort)
&& udp.write((byte *)&ntpFirstFourBytes, 48) == 48
&& udp.endPacket()))
return 0; // sending request failed
// Wait for response; check every pollIntv ms up to maxPoll times
const int pollIntv = 150; // poll every this many ms
const byte maxPoll = 15; // poll up to this many times
int pktLen;
for (byte i=0; i<maxPoll; i++) {
if ((pktLen = udp.parsePacket()) == 48)
break;
delay(pollIntv);
}
if (pktLen != 48)
return 0;
const byte useless = 40;
for (byte i = 0; i < useless; ++i)
udp.read();
unsigned long time = udp.read(); // NTP time
for (byte i = 1; i < 4; i++)
time = time << 8 | udp.read();
time += (udp.read() > 115 - pollIntv/8);
udp.flush();
return time - 2208988800ul;
}