/** =======================================================
Greenhouse23
29-11-2015 Added Winsen MH-Z19 CO2 sensor
28-11-2015 lcd.clear was removed for less flickerin in LCD. Necessary area's overwritten by Spaces
21-11-2015 added hydroponics setting
19-11-2015 changed into once every 4 minutes
23-11-2015 log functie toegevoegd
measure soil moisture
if less than required value switch pump on
measure temperature
if less than required value switch on heating
measure humidity
if higher than desired value Switch on fan
Consider leaving fan on at night
http://www.quickgrow.com/gardening_articles/fans_air_movement.html
CO2 700-1400ppm atmosfeer is ca 395ppm
http://co2now.org/
http://www.omafra.gov.on.ca/english/crops/facts/00-077.htm
LCD commands:
lcd.setBacklight(LED_OFF);
lcd.noBacklight();
lcd.setBacklight(HIGH);
lcd.setBacklight(LOW);
lcd.clear();
lcd.home();
lcd.setCursor(positie, regel);
convert floats to strings:
float myFloat;
char buffer[5];
String s = dtostrf(myFloat, 1, 4, buffer);
But Serial.print() sends floats as strings too
========================================================= */
//sudo ln /dev/ttyS0 /dev/ttyACM9
/**********************************************************************
Import needed libraries
LiquidCrystal_I2C is from F. Malpertida
dht library http://arduino.cc/playground/Main/DHTLib Rob Tillaart
RTClib from Adafruit
If the library is in the sketch folder change #include <name> to
#include "name"
this tells the compiler to look in the sketch directory first.
***********************************************************************/
//---------------------------------------
#include <Wire.h>
#include <LiquidCrystal_I2C.h> //Malpertida
#include <dht.h> // Rob Tillaert
#include <RTClib.h> //Adafruit
/*************************************************************
Declare objects
RTC
DHT
LCD
**************************************************************/
//RTC_DS1307 rtc;
RTC_DS1307 RTC; //declare object RTC
dht DHT; //declare object DHT22
/**************************************************************
declare LCD data
set the LCD address to 0x27 for a 20 chars 4 line display
Set the pins on the I2C chip used for LCD connections:
addr, en,rw,rs,d4,d5,d6,d7,bl,blpol
***************************************************************/
//LiquidCrystal_I2C lcd(0x27, 2, 1, 0, 4, 5, 6, 7, 3, POSITIVE); // Set the LCD I2C address
LiquidCrystal_I2C lcd(0x27, 20, 4); // set the LCD address to 0x27 for a 16 chars and 2 line display
/**************************************************************
Declare pins )
***************************************************************/
//analogue pins
byte moisturePin = A0; //read soil moisture
byte levelPin = A1; //set level for irrigation
byte NTCPin = A2; // voor NTC if used
byte LDRPin = A3; // analog pin for LDR
// SDA
// SCL
//digital pins
byte DHT_Pin = 2; //Humidity sensor
byte SwitchButton = 3; // Make Switch
byte PushButton = 4; // PushButton
byte lightPin = 5; //Switches on light
byte fanPin = 6; //Switches fan
byte pumpPin = 7; //Switches pump
byte hotPin = 8; //Switches heater
byte buzPin = 9; //Switches buzzer
byte emptyPin = 10; //digital Pin10 guards waterlevel
byte CO2Pin = 11; // Winsen MH-Z19 PWM pin 9 pin 7 =gnd
byte spikePin = 12; //Digital Pin12 ->for intermittent switching of spike
byte signalPin = 13; // used for signal functions LED
/**************************************************************
Variables
***************************************************************/
volatile byte seconds;
byte push = 0; // contains the state of the pushbutton
byte sButton = 0; // contains the state of the throw switch
byte light; // contains the value for LDR reading
byte pump = 0; // contains the pump state
unsigned int moist = 0; // contains the soil moisture level
unsigned int irrigate = 0; // contains the set level for irrigation in case no potmeter
byte level = 0; // contains level of the waterlevel (HIGH or LOW)
int c; // contains the temperature reading
int CO2ppmRead = 0; // contains CO2 reading
boolean ready_to_read = 1; // is set every 4 minutes, it begins set in order to start with a measurement imemdiately
boolean hydro = 0; // no more moisture readings but just a 6 times a day irrigation
boolean hydroPump_flag = 0; // checks if pump was set according to a hydroponics scheme or because of measurement
boolean t_flag = 0;
boolean CO2Read_flag = 0;
// Constants
// these constants won't change:
const int sensorMin = 40; // LDR minimum, discovered through experiment
const int sensorMax = 1012; // LDR maximum, discovered through experiment
/* Definitions */
#define DHT22_PIN DHT_Pin // in fact a bit double
#define DS1307_I2C_ADDRESS 0x68 // each I2C object has a unique bus address, the DS1307 is 0x68
byte m = 0; // contains the minutes, refreshed each loop
byte h = 0; // contains the hours, refreshed each loop
byte s = 0; // contains the seconds, refreshed each loop
byte mo = 0; // contains the month, refreshes each loop
byte j = 0; // contains the year, refreshed each loop
byte d = 0; // contains the day (1-31)
byte dag = 0;// contains day of week (0-6)
byte incomingByte = 0;
byte meten = 243; //lcd char te printen bij meten ?? is of het kleiner of gelijk aan teken of 3/4 teken
int CO2ppmLimit = 340; // set lower CO2 value
/**************************************************************
Macro's/Defines
* ***********************************************************/
#define eersteRegel lcd.setCursor(0, 0)
#define tweedeRegel lcd.setCursor(0, 1)
#define pompAAN digitalWrite(pumpPin,HIGH)
#define pompUIT digitalWrite(pumpPin,LOW)
#define BAUD_RATE 115200
/*************************************************************
---------------- Define Special Characters-----------------
Create a set of new characters
0=fan
1=degree sign
2=termometer
3=waterdruppel / voor humidity
4=spikes / voor soil moisture
5=pump
6=up arrow
7=down arrow
//************************************************************/
const uint8_t charBitmap[][8] =
{
{
// fan wellicht char(248) gebruiken
B00000, // -----
B10001, // X---X
B01010, // -X-X-
B00100, // --X--
B01010, // -X-X-
B10001, // X---X
B00000, // -----
B00000 // -----
}
,
{
// degree wellicht char(223) gebruiken
B00110, // --XX-
B01001, // -X--X
B01001, // -X--X
B00110, // --XX-
B00000, // -----
B00000, // -----
B00000, // -----
B00000 // -----
// 0x6, 0x9, 0x9, 0x6, 0, 0, 0, 0
}
,
{
// termometer
B00100, // --X--
B01010, // -X-X-
B01010, // -X-X-
B01110, // -XXX-
B01110, // -XXX-
B11111, // XXXXX
B11111, // XXXXX
B01110 // -XXX-
}
,
{
// druppel
B00100, // --X--
B00100, // --X--
B01010, // -X-X-
B01010, // -X-X-
B10001, // X---X
B10001, // X---X
B10001, // X---X
B01110 // -XXX-
}
,
{
// moisture sensor
0b00100, // --X--
0b01110, // -XXX-
0b01010, // -X-X-
0b01010, // -X-X-
0b01010, // -X-X-
0b01010, // -X-X-
0b01010, // -X-X-
0b00000 // -----
}
,
{
//pomp
B01010, // -X-X-
B00100, // --X--
B00100, // --X--
B00100, // --X--
B11111, // XXXXX
B11111, // XXXXX
B11111 // XXXXX
}
,
{
// up arrow
0x0, 0x4, 0xE, 0x15, 0x4, 0x4, 0x4, 0x0
// -----
// --X--
// -X-X-
// X-X-X
// --X--
// --X--
// --X--
// -----
}
,
{
// down arrow - reservoir leeg
0x4, 0x4, 0x4, 0x4, 0x15, 0xE, 0x4, 0x0
// -----
// --X--
// --X--
// --X--
// X-X-X
// -X-X-
// --X--
// -----
}
};
//-------- end creation--------------
/************************************************************************************************************************/
/************************************************************************************************************************/
/************************************************************************************************************************/
void setup() {
/************************************************************
The timer is being set up in order to have a 4 minute
event in the ISR(TIMER1_COMPA_vect) routine for reading
of a sensor... should one wish that
************************************************************/
// initialize Timer1
cli(); // disable global interrupts
TCCR1A = 0; // set entire TCCR1A register to 0
TCCR1B = 0; // same for TCCR1B
// set compare match register to desired timer count:
OCR1A = 15624;
// turn on CTC mode:
TCCR1B |= (1 << WGM12);
// Set CS10 and CS12 bits for 1024 prescaler:
TCCR1B |= (1 << CS10);
TCCR1B |= (1 << CS12);
// enable timer compare interrupt:
TIMSK1 |= (1 << OCIE1A);
// enable global interrupts:
sei();
//---------------end timer initialisation *
//***********************************************************
Serial.begin(BAUD_RATE);
/************************************************************
Set up the RTC
*************************************************************/
#ifdef AVR
Wire.begin();
#else
Wire1.begin(); // Shield I2C pins connect to alt I2C bus on Arduino Due
#endif
RTC.begin(); // Start RTC
DateTime now = RTC.now();
DateTime compiled = DateTime(__DATE__, __TIME__);
// RTC.adjust(DateTime(2015, 11, 24, 21, 11, 0));
if (now.unixtime() < compiled.unixtime())
{
// Serial.println("RTC is older than compile time! Updating");
// following line sets the RTC to the date & time this sketch was compiled
// RTC.adjust(DateTime(F(__DATE__), F(__TIME__))); // be careful, this might not always be correct on codebender
}
//----Set sqw to 1 Hz---
// no practical function yet
Wire.beginTransmission(0x68);
Wire.write(0x07); //move pointer to SQW address
Wire.write(0x10); // sends 0×10 (hex) 00010000 (binary)
Wire.endTransmission();
//---end sqw-----
/*********************************************************
Set up the in and output pins
**********************************************************/
pinMode(levelPin, INPUT); // set level
pinMode(DHT_Pin, INPUT); // measures humidity
pinMode(emptyPin, INPUT); // measures reservoir
pinMode(SwitchButton, INPUT); // make Switch
pinMode(PushButton, INPUT); // PushButton
pinMode(spikePin, OUTPUT); // for alternative supply to spikes
pinMode(pumpPin, OUTPUT); // Output for Relay
pinMode(fanPin, OUTPUT); // Output for fan
pinMode(hotPin, OUTPUT); // Output for heater
pinMode(lightPin, OUTPUT); // Output for light
pinMode(buzPin, OUTPUT); // Output for buzzer
digitalWrite(pumpPin, LOW); // Pump off
digitalWrite(spikePin, LOW); // moisture sensor off
digitalWrite(fanPin, LOW); // fan Off
digitalWrite(hotPin, LOW); // heater off
digitalWrite(lightPin, LOW); // light Off
digitalWrite(buzPin, LOW); // buzzer off
/* Now LCD */
/*********************************************************
Set up LCD
initialize the lcd for 16 chars 2 lines
load the character definitions
print some messages and blink the backlight
*********************************************************/
lcd.begin(16, 2);
//upload defined characters to LCD
int charBitmapSize = (sizeof(charBitmap ) / sizeof (charBitmap[0]));
for ( int i = 0; i < charBitmapSize; i++ )
{
lcd.createChar ( i, (uint8_t *)charBitmap[i] );// zijn al geladen
}
//---------------end upload----------------
lcd.backlight();
// Print a message to the LCD.
lcd.setCursor(0, 0); // topleft
lcd.print("Greenhouse");
Serial.println("Greenhouse");
lcd.setCursor(0, 1); // regel 2
// ------- Quick 2 blinks of backlight -------------
flash(2);
// ------- Quick buzz--------------------------------
// buzz(1);
/*************************************************************
Start RTC
*************************************************************/
Wire.begin(); //needed for RTC, not for LCD
RTC.begin();
//RTC.writeSqwPinMode(SquareWave1HZ);// double?
//************************************************************
// Check buttons at startup *
//************************************************************
if (digitalRead(PushButton) == 0)
{
printLogTemp();
buzz(1);
}
}
/*----------------------------(end setup )---------------------*/
/************************************************************************************************************************/
/************************************************************************************************************************/
/************************************************************************************************************************/
/***************************************************************
Main loop
get and print Date/time
Check if the reservoir is full
Read soil humidity
Switch pump
Read Air Humidity and temperature
Read light
Display data
Switch heating on or off
Switch fan on or off
***************************************************************/
void loop() {
//Serial.println(seconds);
DateTime now = RTC.now(); //Get the current data
/*
Serial.print(now.day(), DEC);
Serial.print("-");
Serial.print(now.month(), DEC);
Serial.print("-");
Serial.print(now.year(), DEC);
Serial.print(" ");
Serial.print(now.hour(), DEC);
Serial.print(':');
printDigits(now.minute());
Serial.print(':');
printDigits(now.minute());
Serial.println();
*/
//--------------------------------------------------------
m = now.minute(); // contains the minutes, refreshed each loop
h = now.hour(); // contains the hours, refreshed each loop
s = now.second(); // contains the seconds, refreshed each loop
mo = now.month(); // contains the month, refreshes each loop
j = now.year(); // contains the year, refreshed each loop
d = now.day(); // contains the day (1-31)
dag = now.dayOfTheWeek(); // contains day of week (0-6)
//--------------------- ------------------------------
//------------end of RTC
if (Serial.available() > 0)
{
incomingByte = Serial.read();
switch (incomingByte)
{
case 63://?
printLogTemp();
break;
case 108: //l
logTemp(c);
break;
default:
break;
}
}
//-----------------------------------
/********************************************************************************
---------- 1. Check if there is enough water -------------
check if there is water
if not sound the buzzer
later in the program the pump will be disabled if water level too low
*********************************************************************************/
level = digitalRead(emptyPin); //Switch closed = empty
if (level == 0)
{
digitalWrite(buzPin, HIGH);
delay (50);
digitalWrite(buzPin, LOW);
delay(500);
}
/*********************************************************************************
------------2. Read the soil moisture content/switch pump----------------
First read the level set with P1 on the levelPin and store that in 'irrigate'
Then we read the soil humidity sensor.
We'll first have to set the spikePin to HIGH, in case that is used to feed
the sensor. After the reading we set it back)
If the value read ('moist') is smaller than what is considered dry ('irrigate')
then the pump should be switched on for a specific time.
This is done by indicating a higher treshhold for switching the pump off
Could be made conditional by testing the ready_to_read boolean
that is set every 4 minutes in order to spare the spikes
If Switchbutton in other position there is a steady 6x a day irrigation
* *
*********************************************************************************/
if (digitalRead(SwitchButton) == 0)
{
if (hydroPump_flag == 1) // check if pump was still on from a hydroponics action
// otherwise it may run for max 4 extra minutes
// a better option might be to just do a reading immediately after
// leaving hydro mode by setting ready_to_read oid
{
digitalWrite(pumpPin, LOW);
hydroPump_flag = 0;
}
irrigate = sample(levelPin);
if (ready_to_read == 1)
{
digitalWrite(spikePin, HIGH); // put voltage on the humidity sensor
digitalWrite(signalPin, HIGH); // geef optisch signaal dat er gemeten wordt
lcd.setCursor(13,1);
lcd.print(char(243));
digitalWrite(buzPin,HIGH);
delay(100); //wait a short while for the voltage to stabilize
moist = sample(moisturePin); //read soil humiditySensor
//
digitalWrite(spikePin, LOW);
digitalWrite(signalPin, LOW); // geeft optisch signaal dat er níet meer gemeten wordt
lcd.setCursor(13,1);
lcd.print(" ");
digitalWrite(buzPin,LOW);
if (moist <= irrigate)
{
pump = 1;
level = digitalRead(emptyPin); //Switch closed = empty
digitalWrite(pumpPin, level); // if the reservoir is empty a 0 will be written
}
if (moist >= irrigate + 5)
{
pump = 0;
digitalWrite(pumpPin, LOW); // prevents Jitter
ready_to_read = 0; // needed to read once every 4 min
seconds = 0; //reset the 4 minutes
}
}
}
else
{
Serial.println("hydro");
if (hydroPump_flag == 0) // Kan ook checken op 'pump==1'
{
digitalWrite(pumpPin, LOW); // zet de pomp af als deze aan was ivm meting
pump = 0;
}
/*****************************************************************************
schakel de hydroponics 6x dag
0,4,8,12,16,20 uur
checkt of een even nummer gedeeld door 2 nog steeds even is:
dwz het was deelbaar door 4
oneven nummers uitgefilterd in verband met afronding bij delen
of gebruik %4==0
* ***************************************************************************/
if ((now.hour() & 4) == 0) // is number dividable by 4
{
if (now.minute() == 0 && now.second() >= 30)
{
// hydroON();
digitalWrite(pumpPin, HIGH);
hydroPump_flag = 1;
pump = 1;
}
if (now.minute() == 2)
{
// hydroOFF();
digitalWrite(pumpPin, LOW);
hydroPump_flag = 0;
pump = 0;
}
}
}
/*********************************************************************************
3. test the DHT22 humidity/temp sensor-----------------
**********************************************************************************/
// Serial.print("DHT22, \t");
int chk = DHT.read22(DHT22_PIN);
switch (chk)
{
case DHTLIB_OK:
// Serial.print("OK,\t");
break;
case DHTLIB_ERROR_CHECKSUM:
Serial.print("Checksum error,\t");
break;
case DHTLIB_ERROR_TIMEOUT:
// Serial.print("Time out error,\t");
break;
default:
Serial.print("Unknown error,\t");
break;
}
/*********************************************************************************
4. Read LDR
no actions for the time being, but can be used to e.g. only irrigate at night
or to add artificial light to the day
**********************************************************************************/
light = Map(LDRPin);
/* ------------------Actions -------------------*/
/*********************************************************************************
5. DISPLAY DATA
Pushbutton not pressed: show measurements
Pushbutton pressed: show time
**********************************************************************************/
push = digitalRead(PushButton);
if (push == 1) // pushbutton not pressed
{
// lcd.clear();
lcd.setCursor(0, 0); // set cursor left on first line (line 0)
lcd.print(char(2)); // prints thermometer
lcd.print(" ");
lcd.print((float)DHT.temperature, 0);
lcd.print (char(1)); // prints degree sign
lcd.print("C");
lcd.print(" ");
lcd.print(char(3)); // droplet
lcd.print(" ");
lcd.print((float)DHT.humidity, 0);
lcd.print("%");
lcd.print(" ");
lcd.print (char(7 - level)); //prints up or down arrow (char 7 or 6)
if (level + pump == 2) // meaning there is water and pump switched on
{
lcd.print(" ");
lcd.print(char(5));
}
else
{
//lcd.setCursor(15,0);
lcd.print(" ");
}
if (digitalRead(SwitchButton) == 0) // normal operations
{
lcd.setCursor(0, 1); // set cursor left on line 1 (=2nd line)
lcd.print(char(4)); // spikes
lcd.print(" ");
lcd.setCursor(2, 1); // om gebruik van clear screen te vermijden
lcd.print(" ");
lcd.setCursor(2, 1);
lcd.print(moist);
lcd.print("/");
lcd.print(irrigate);
// lcd.print("=>");
// lcd.print((float)moist/irrigate);//integer kan contain no fraction so use the cast-operator to make it float
}
else // Hydroponics
{
lcd.setCursor(0, 1);
lcd.print("Hydroponics");
}
}
if (push == 0) // pushbutton pressed
{
lcd.clear();
lcd.setCursor(0, 0); //topleft
//--------------
DateTime now = RTC.now();
lcd.print(now.day(), DEC);
lcd.print('-');
lcd.print(now.month(), DEC);
lcd.print('-');
lcd.print(now.year(), DEC);
lcd.print(" ");
lcd.print(now.hour(), DEC);
lcd.print(':');
if (now.minute() < 10)
{
lcd.print("0");
}
lcd.print(now.minute(), DEC);
//---end rtc
lcd.setCursor(0, 1); // naar regel 2
lcd.print("light level: ");
int ldrRaw = map(analogRead(LDRPin), 0, 1024, 0, 100);
lcd.print(ldrRaw); lcd.print("%");
}
/**************************************************
now we measure temperature and air humidity *
and if necessary switch on heating or fan
temp kept at minimally 20 degrees
humidity is kept below 60%
**************************************************/
// ---------------5. Action on temperature ------
c = (DHT.temperature);
if (c <= 19)
{
// switch on heating
digitalWrite(hotPin, HIGH);
if (push == 1)
{
lcd.setCursor(12, 1);
lcd.print("*");
lcd.print(" ");
lcd.setCursor(14, 1);
lcd.print(seconds / 60);
}
}
else
{
digitalWrite(hotPin, LOW);
if (push == 1)
{
lcd.setCursor(12, 1);
lcd.print(" ");
lcd.print(" ");
}
}
//--------------6. Action on Humidity -----------
if (DHT.humidity >= 60)
{
// Switch on Fan
digitalWrite(fanPin, HIGH);
// print fan-sign only if pushbutton not pressed
if (push == 1)
{
lcd.setCursor(10, 1);
lcd.print(char(0)); // fan sign
}
}
else
{
digitalWrite(fanPin, LOW);
// print fan-sign only if pushbutton not pressed
if (push == 1)
{
lcd.setCursor(10, 1);
lcd.print(' ');
}
}
delay(500);
//Store temp every hour
if (m == 0 && t_flag == 0)
{
logTemp(c);
t_flag = 1;
}
if (m == 2 && t_flag == 1)
{
t_flag = 0;
}
//end dht
//end loop
// read the CO2 sensor, every hr on the hour
if (m == 0 && CO2Read_flag == 0)
{
CO2ppmRead = CO2ppm();
CO2Read_flag = 1;
}
if (CO2ppmRead < CO2ppmLimit)
{
digitalWrite(signalPin, HIGH);
CO2Read_flag = 0;
}
else
{
digitalWrite(signalPin, LOW);
}
//}
}
//------- End of Main program-----------
/************************************************************************************************************************/
/************************************************************************************************************************/
/************************************************************************************************************************/
//-------- Start of functions------------
int sample(int z)
/**********************************************************************
This function will read the Pin 'z' 5 times and take an average.
Afterwards it will be mapped to 8 bits by dividing by 4
Could ofcourse immediately divide by 20
***********************************************************************/
{
byte i;
int sval = 0;
for (i = 0; i < 5; i++)
{
sval = sval + analogRead(z);// sensor on analog pin 'z'
}
//sval = sval / 5; // average
//sval = sval / 4; // scale to 8 bits (0 - 255)
sval = sval / 20;
return sval;
}
/**********************************************************************
This function will flash the backlight a number of times
***********************************************************************/
void flash(byte y)
{
byte j;
for (j = 0; j < y; j++)
{
lcd.backlight();
delay(250);
lcd.noBacklight();
delay(250);
}
lcd.backlight(); // finish with backlight on
return;
}
/**********************************************************************
This function will sound the buzzer "u" times
***********************************************************************/
void buzz(byte u)
{
byte k;
for (k = 0; k < u; k++)
{
digitalWrite(buzPin, HIGH);
delay(200);
digitalWrite(buzPin, LOW);
delay(200);
}
return;
}
/****************************************************************************
This function will blink an LED a number of times for a specific duration
*****************************************************************************/
void ledblink(int times, int lengthms, int pinnum)
{
for (int x = 0; x < times; x++)
{
digitalWrite(pinnum, HIGH);
delay (lengthms);
digitalWrite(pinnum, LOW);
delay(lengthms);
}
}
/**********************************************************************
This function maps the LDR reading into nrs 0-3
***********************************************************************/
int Map(byte sens)
{
// read the sensor:
int sensorReading = analogRead(sens);
// map the sensor range to a range of four options:
byte range = map(sensorReading, sensorMin, sensorMax, 0, 3);
// do something different depending on the
// range value:
switch (range)
{
case 0: //
// Serial.println("dark");
// lcd.backlight();
break;
case 1: //
// Serial.println("dim");
// lcd.backlight();
break;
case 2: //
// Serial.println("medium");
// lcd.noBacklight();
break;
case 3: //
// Serial.println("bright");
// lcd.noBacklight();
break;
}
return range;
}
/**********************************************************************
This function adds a leading zero
***********************************************************************/
void printDigits(int digits) //this adds a 0 before single digit numbers
{
//if (digits >= 0 && digits < 10) {
if (digits < 10)
{
// lcd.print('0');
Serial.print('0');
}
//lcd.print(digits);
Serial.print(digits);
}
/**********************************************************************
This function adds a leading zero on LCDdewPointFast
***********************************************************************/
void printDigitLCD(int digits) //this adds a 0 before single digit numbers
{
//if (digits >= 0 && digits < 10) {
if (digits < 10)
{
lcd.print('0');
}
lcd.print(digits);
}
/**********************************************************************
This function converts Celsius to Fahrenheit
***********************************************************************/
float tempConvert(float celsius)
{
float fahrenheit = 0;
fahrenheit = (1.8 * celsius) + 32;
return fahrenheit;
}
/**********************************************************************
This function writes bytes to RTC non volatile RAM
***********************************************************************/
byte epromWrite(byte a, byte lstat)
{
a = a + 7;
Wire.beginTransmission(0x68);
Wire.write(a); // move pointer to RAM address
Wire.write(lstat); // send 1
Wire.endTransmission();
}
/**********************************************************************
This function reads bytes from RTC non volatile RAM
***********************************************************************/
byte epromRead(byte a)
{
a = a + 7;
byte lstat;
Wire.beginTransmission(0x68);
Wire.write(a); // move pointer to RAM address
Wire.endTransmission();
Wire.requestFrom(0x68, 1);
lstat = Wire.read();
//Serial.println(lstat);
return lstat;
}
/**********************************************************************
This is the timer interrupt function that sets a flag every 4 min
***********************************************************************/
ISR(TIMER1_COMPA_vect)
{
seconds++;
if (seconds == 240)
{
seconds = 0;
// leest elke 240 seconden (4 minuten) een sensor
//readSensor();
// moist=sample(moisturePin); //read soil humiditySensor
// of kies ervoor een flag te zetten
ready_to_read = 1;
}
}
/**********************************************************************
This function calculates dewpoint
***********************************************************************/
double dewPointFast(double celsius, double humidity)
{
double a = 17.271;
double b = 237.7;
double temp = (a * celsius) / (b + celsius) + log(humidity / 100);
double Td = (b * temp) / (a - temp);
return Td;
}
/**********************************************************************
This function will store hourly temperature in NVRam
* ********************************************************************/
void logTemp(int t)
{
byte bLSB = t & 0xFF;
//RTC.writenvram(h, bLSB);
updateNVRam(h, bLSB);// kies voor 'Update' ipv 'write'
}
/**********************************************************************
This function will retrieve stored temp values
* ********************************************************************/
void printLogTemp()
{
for (byte i = 0; i <= 23; i++)
{
Serial.print(i);
Serial.print(" ");
Serial.println(RTC.readnvram(i));
}
for (byte y = 0; y < 23; y++)
{
lcd.clear();
eersteRegel;
lcd.print(y);
lcd.print(" ");
lcd.print(RTC.readnvram(y));
tweedeRegel;
lcd.print(y + 1);
lcd.print(" ");
lcd.print(RTC.readnvram(y + 1));
delay(500);
}
delay(500);
}
/**********************************************************************
This function Updates the NVRam
* ********************************************************************/
void updateNVRam(byte a, byte data)
{
if (data != RTC.readnvram(a))
{
RTC.writenvram(a, data);
}
}
int CO2ppm()
/*********************************
Winsen MH-Z19
ppm=2000*(Th-2)/(TH+TL-4)
TH+TL=1000
* *******************************/
{
int ppm = pulseIn(CO2Pin, HIGH);
ppm = (2 * (ppm - 2));
return ppm;
}
//deelbaar door 5
boolean divideble5(byte x)
{
boolean d5 = 0;
if (x % 5 == 0)
{
d5 = 1;
}
return d5;
}
soil moisture
set moisture level
NTC
LDR
no water