//first calibrate dry sensor value and pure water. We might want to consider calibrating under extremely dry conditions if we want more accuracy in drier values.
const int dry = 560; // value for dry sensor
const int wet = 305; // value for wet sensor
const int chipSelect = 4;
const byte pinStop = 2;
const byte pinStart = 3;
const byte ledStop = 5;
const byte ledStart = 6;
#include "RTClib.h"
#include <SPI.h>
#include <SD.h>
RTC_DS3231 rtc;
char daysOfTheWeek[7][12] = {"Sunday", "Monday", "Wednesday", "Thursday", "Friday", "Saturday"};
// SD CARD READER
File myFile;
// Date and time
DateTime now;
// Moisture data
struct moisture_type {
int Percent;
int Raw;
};
moisture_type Moisture;
boolean DoWriting = true;
void setup() {
Serial.begin(9600); //com enable
pinMode(pinStart, INPUT_PULLUP);
pinMode(pinStop, INPUT_PULLUP);
pinMode(ledStop, OUTPUT);
pinMode(ledStart, OUTPUT);
delay (1000);
if (!rtc.begin ()) {
Serial.println ("couldn't find RTC");
Serial.flush();
while (1);
}
if (rtc.lostPower()) {
Serial.println("RTC lost power, let's set the time!");
rtc.adjust(DateTime(F(__DATE__), F(__TIME__)));
}
Serial.print("Initializing SD card...");
// see if the card is present and can be initialized:
if (!SD.begin(chipSelect)) {
Serial.println("card failed, or not present");
// don't do anything more:
while (1);
}
Serial.println("card initialized.");
// When time needs to be re-set on a previously configured device, the
// following line sets the RTC to the date & time this sketch was compiled
// rtc.adjust(DateTime(F(__DATE__), F(__TIME__)));
// This line sets the RTC with an explicit date & time, for example to set
// January 21, 2014 at 3am you would call:
// rtc.adjust(DateTime(2014, 1, 21, 3, 0, 0));
myFile = SD.open("test.txt", FILE_WRITE);
}
void loop() {
static unsigned long lastMeasurement = 0;
if (millis()-lastMeasurement >= 1000 && DoWriting) {
lastMeasurement = millis();
now = rtc.now();
getMoistureData();
PrintTo(Serial);
WriteToSD();
}
handleSerialCommands();
handleButtons();
if (myFile) SetWritingLED(true);
else SetWritingLED(false);
}
void SetWritingLED(boolean state){
digitalWrite(ledStop, !state);
digitalWrite(ledStart, state);
}
void handleSerialCommands(){
if (Serial.available()){
char c = Serial.read();
if (c == 'p') PrintSD();
if (c == 's') {
DoWriting = false;
Serial.println("Stopped Writing to SD");
myFile.close();
}
if (c == 'w') {
DoWriting = true;
Serial.println("Start Writing to SD");
}
}
}
void handleButtons(){
if (StopButtonReleased()) {
DoWriting = false;
Serial.println("Stopped Writing to SD");
myFile.close();
}
if (StartButtonReleased()) {
DoWriting = true;
Serial.println("Start Writing to SD");
}
}
void WriteToSD(){
if (!myFile) myFile = SD.open("test.txt", FILE_WRITE);
if (myFile) {
PrintTo(myFile);
}
// if the file didn't open, print an error:
else {
Serial.println("error writing to test.txt");
}
}
void getMoistureData(){
Moisture.Raw = analogRead(A1);
Moisture.Percent = map(Moisture.Raw, wet, dry, 100, 0);
}
void PrintTo(Stream &stream){
stream.print (now.year(), DEC);
stream.print ("/");
stream.print (now.month(), DEC);
stream.print ("(");
stream.print (daysOfTheWeek[now.dayOfTheWeek()]);
stream.print (")");
stream.print (now.hour(), DEC);
stream.print (":");
stream.print (now.minute(), DEC);
stream.print (":");
stream.print (now.second(), DEC);
stream.print (",");
stream.print(Moisture.Raw);
stream.print(",");
stream.print(Moisture.Percent);
stream.print(",");
stream.println("%");
}
void PrintSD(){
String s = "-> ";
if (myFile) myFile.close();
File PrintFile = SD.open("test.txt");
if (PrintFile) {
while (PrintFile.available()) {
char c = PrintFile.read();
if (c != 10) s += c;
else {
Serial.println(s);
s = "-> ";
}
}
PrintFile.close();
}
}
boolean StopButtonReleased(){
static byte lastState = HIGH;
static unsigned long lastChange;
static byte released = false;
byte state = digitalRead(pinStop);
if (lastState != state) lastChange = millis();
if (millis() - lastChange > 30) {
if (!state) released = true;
}
lastState = state;
if (released && state) {
released = false;
return true;
}
return false;
}
boolean StartButtonReleased(){
static byte lastState = HIGH;
static unsigned long lastChange;
static byte released = false;
byte state = digitalRead(pinStart);
if (lastState != state) lastChange = millis();
if (millis() - lastChange > 30) {
if (!state) released = true;
}
lastState = state;
if (released && state) {
released = false;
return true;
}
return false;
}