Hi all,
I'm developing a program to monitor several digital sensor inputs and to datalog to an SD card when a trip is detected.
- Monitor digital inputs & make a flag if any input is not equal to a pre-determined 'normal' state
- Retrieve date/time info from DS1307 RTC
- Monitor duration of 'trip' using millis()
- Once sensor has returned to it's normal state, write the following information to the SD Card:
- Date & Time of trip
- Which sensor it was
- Duration of trip
Obviously, the Date/Time has to be collected as soon as a trip is detected along with which sensor it was, however the duration cannot be calculated until the trip has finished.
I've been playing with this for a little over 2 weeks now with limited success, originally I had issues with writing to the SD card (which works fine using the 1,2,3 example sketch) and have now given up and started from scratch.
My approach now is to compile strings which can be sent to the Serial Monitor as and when they occur, but can also be concatened together for sending to the SD card when the cycle is complete.
Using the Serial Monitor, it is clear that the strings are not being constructed correctly and remain as initialised ("").
I've attached my code below, i'm aware that there are gaps in it in other areas however this is a bare minimum for me to debug... would appreciate any feedback regarding my string construction issue.
As a side note, i've noticed that this uses an awful lot of memory (only just fits on a UNO and causes the Serial Monitor to display gibberish).
{ I HAVE REMOVED ALL THE CODE HERE WHICH SETS UP PIN SELECTION, ETC TO FIT IN THE POST }
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////
// *** PROGRAM VARIABLES *** //
///////////////////////////////
int sensor1_flag = 0;
int active_sensor = 0;
int timer_started = 0;
int write_enabled = 0;
unsigned long last_duration = 0;
unsigned long last_trip = 0;
String stringDateTime = "";
String stringSensor = "";
String stringDuration = "";
String dataString = "";
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
#include "Wire.h"
#define DS1307_I2C_ADDRESS 0x68
byte second, minute, hour, dayOfWeek, dayOfMonth, month, year;
#include <SPI.h>
#include <SD.h>
File Datalog;
// Convert normal decimal numbers to binary coded decimal
byte decToBcd(byte val)
{
return ( (val/10*16) + (val%10) );
}
// Convert binary coded decimal to normal decimal numbers
byte bcdToDec(byte val)
{
return ( (val/16*10) + (val%16) );
}
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Setup Code
void setup() {
pinMode(sensor1_pin, INPUT);
pinMode(chipSelect, OUTPUT);
Serial.begin(9600);
delay(500);
Serial.println("System Startup...");
Serial.print("Initialising RTC... ");
Wire.begin();
Serial.println("Done.");
Serial.print("Requesting current Date/Time from RTC... ");
updateTime();
Serial.println("Successful.");
second = 30;
minute = 21;
hour = 16;
dayOfWeek = 3;
dayOfMonth = 9;
month = 3;
year = 16; // 2 digit year
// Sets the DS1307 time: second, minute, hour, dayofweek, dayofmonth, month, year...
// setDateDs1307(second, minute, hour, dayOfWeek, dayOfMonth, month, year);
Serial.print("Initialising SD Card... ");
if (!SD.begin(chipSelect)) {
Serial.println("Initialisation failed!");
Serial.println("------------------------------------------------------------------------------------------");
return;
}
Serial.println("Successful.");
Serial.println("------------------------------------------------------------------------------------------");
}
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Sets the Date & Time
void setDateDs1307(byte second, byte minute, byte hour, byte dayOfWeek, byte dayOfMonth, byte month, byte year)
{
Wire.beginTransmission(DS1307_I2C_ADDRESS);
Wire.write(0);
Wire.write(decToBcd(second)); // 0 to bit 7 starts the clock
Wire.write(decToBcd(minute));
Wire.write(decToBcd(hour)); // If you want 12 hour am/pm you need to set
// bit 6 (also need to change readDateDs1307)
Wire.write(decToBcd(dayOfWeek));
Wire.write(decToBcd(dayOfMonth));
Wire.write(decToBcd(month));
Wire.write(decToBcd(year));
Wire.endTransmission();
delay(250);
Serial.println("Real Time Clock updated successfully.");
}
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Requests the Date & Time
void getDateDs1307(byte *second, byte *minute, byte *hour, byte *dayOfWeek, byte *dayOfMonth, byte *month, byte *year)
{
// Reset the register pointer
Wire.beginTransmission(DS1307_I2C_ADDRESS);
Wire.write(0);
Wire.endTransmission();
Wire.requestFrom(DS1307_I2C_ADDRESS, 7);
// A few of these need masks because certain bits are control bits
*second = bcdToDec(Wire.read() & 0x7f);
*minute = bcdToDec(Wire.read());
*hour = bcdToDec(Wire.read() & 0x3f); // Need to change this if 12 hour am/pm
*dayOfWeek = bcdToDec(Wire.read());
*dayOfMonth = bcdToDec(Wire.read());
*month = bcdToDec(Wire.read());
*year = bcdToDec(Wire.read());
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void updateTime()
{
byte second, minute, hour, dayOfWeek, dayOfMonth, month, year;
// retrieve data from RTC
getDateDs1307(&second, &minute, &hour, &dayOfWeek, &dayOfMonth, &month,
&year);
// DD/MM/YY
String Day = String(dayOfMonth, DEC);
String Month = String(month, DEC);
String Year = String(year, DEC);
// HH:MM:SS
String Hour = String(hour, DEC);
String Minute = String(minute, DEC);
String Second = String(second, DEC);
stringDateTime = String(Day + "/" + Month + "/" + Year + " " + Hour + ":" + Minute + ":" + Second + " ");
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void loop() {
// *** COMPARE INPUTS WITH THEIR NORMAL STATE & MAKE FLAG IF NOT *** //
sensor1_flag = digitalRead(sensor1_pin);
// *** SERIAL COMMS *** THIS SECTION CAN BE REMOVED ONCE PROVEN WORKING OK *** //
if (sensor1_flag == 1 && active_sensor == 0) {
updateTime();
last_trip = millis();
timer_started = 1;
active_sensor = 1;
}
if (active_sensor == 1 && sensor1_flag == 0 & active_sensor != 0) {
last_duration = (millis() - last_trip);
timer_started = 0;
active_sensor = 0;
write_enabled = 1;
}
stringDuration = String(last_duration + "ms");
// *** ASSEMBLE STRING FOR WRITING TO SD CARD *** //
switch (active_sensor) {
case 1: stringSensor = String(sensor1 + " ");
break;
case 2: stringSensor = String(sensor2 + " ");
break;
case 3: stringSensor = String(sensor3 + " ");
break;
case 4: stringSensor = String(sensor4 + " ");
break;
case 5: stringSensor = String(sensor5 + " ");
break;
case 6: stringSensor = String(sensor6 + " ");
break;
case 7: stringSensor = String(sensor7 + " ");
break;
case 8: stringSensor = String(sensor8 + " ");
break;
case 9: stringSensor = String(sensor9 + " ");
break;
}
dataString = String(stringDateTime + stringSensor + stringDuration);
// *** SD CARD COMMS *** //
if (write_enabled == 1) {
Datalog = SD.open("Datalog.txt", FILE_WRITE);
if (Datalog) {
Datalog.println(dataString);
Datalog.close();
} else Serial.println("Error communicating with SD Card!");
write_enabled = 0;
}
// *** TEMPORARY DEBUGGING CODE *** //
Serial.println(stringDateTime);
Serial.println(stringSensor);
Serial.println(stringDuration);
Serial.println(dataString);
delay(5000);
}
Thanks in advance.