Hi all!
First post ever!
To make this simple, I have built a board that has a DHT 1307 date time module with a SD Micro card reader (FAT32, 32gb) and a magnetic sensonr on a Nano v3 with 2 leds (10k ohms each).
The code is working and is checking every 10sec if the contact sensor changed state. If it did the system logs the datetime stamp with an "open"/"close" tag. Pretty simple.
The breadboard prototype was tested during a whole night without a hiccup.
The PCB board was working for a few hours and suddenly threw errors (I have the LED blink when there is an error writing to the file). I removed the card and saw I could still see the log up to the error. I powered the board again but the SD card would not initalize. Using <SD.h> v 1.2.4, SD.begin(10) (chipSelect is on pin 10) returned false.
I put the SD card in my laptop again and reformatted it. Works like a charm, going on 1hour.
Any idea what could cause the issue? The Arduino needs to be powered on for a whole 5 days at a time so this must be resolved.
Note the power source is not a AA battery, it is a 9V DC Powersupply. The reed switch is in reality a magnetic contact sensor.
This is the circuit FYI. I include it for context, I really do not thing it is a wiring issue, maybe aside from the power source that might trouble the SD Card. The PCB board is powering the Arduino with a DC Jack and a 9V Power Supply. Everything else is powered via the 5V Arduino Nano pin. This might be a suble difference with the prototype, in which the power supply was feeding this little power module that output 5V or 3V3 depending on the jumper wire setup. On the prototype everything was running of the rails with 5V... should not matter no?
Important part of the code (for simplicity)
// initialize the SD Card
pinMode(10, OUTPUT); // output, even if you don't use it
while (!SD.begin(10)) {
Serial.println("initialization failed!");
... blink to inform the user...
while (1);
}
Serial.println("initialization done.");
and here is the write function
// if available, open, write cLine to the file and close
myFile = SD.open("doorlog.csv", FILE_WRITE);
if (myFile) {
myFile.println(sLine);
myFile.close();
Serial.println("log is written");
return true;
} else {
// error trying to open the file
// could write to a different log file
Serial.println("log is not written");
.. blink the led this is where I get the error hours in...
return false;
}
I will check the connections on the PCB tomorrow morning. I plan to let it run during the night. I only check every 10sec, so I am not doing any type of fast writing on the card. I also .close() the filestream after each write to avoid losing any data if is power is cut.
I do not have enough experience with Arduino and feel I need to get outside help. I am building this for a friend and would like to give him something that works
If anybody thinks the whole code would be usefull, here is the full version
#include <Wire.h>
#include <DS3231.h>
#include <SPI.h>
#include <SD.h>
DS3231 clock;
RTCDateTime dt;
bool bDEBUGMODE = false; // FALSE when in production
bool bFirstAwake = true; // to log when powering up
int iCurrentState = 0; // 0 close, 1 open
int iLastState = 0; // 0 close, 1 open
const int sensor = 7; // door pin
File myFile;
const int chipSelect = 10;
const int redLED = 8;
void setup()
{
Serial.begin(9600);
Serial.println("Initialize the LEDs");
pinMode(redLED,OUTPUT);
Serial.println("Initialize the sensor");
pinMode(sensor,INPUT);
Serial.println("Initialize RTC module");
// Initialize DS3231
if (!clock.begin()) {
blinkled(redLED,2,1, true);
while (1);
}
// Send sketch compiling time to Arduino
//clock.setDateTime(__DATE__, __TIME__);
/*
Tips:This command will be executed every time when Arduino restarts.
Comment this line out to store the memory of DS3231 module
*/
// initialize the SD Card
pinMode(10, OUTPUT); // output, even if you don't use it
pinMode(chipSelect, OUTPUT); // The chipSelect pin you use should also be set to output
Serial.println("Initializing SD card...");
while (!SD.begin(chipSelect)) {
Serial.println("initialization failed!");
blinkled(redLED,3,1,false);
//blinkled(redLED,3,1, true);
//while (1);
}
Serial.println("initialization done.");
blinkled(redLED,1,5, false);
}
void blinkled(int pin,int times, int wait, bool nonStop){
int i = 0; // blink pin
digitalWrite(pin,LOW); // make sure it is off
do {
for (i=0;i<times;i++){
digitalWrite(pin,HIGH); // turn on
delay(wait*800); // wait
digitalWrite(pin,LOW); // turn off
delay(wait*800); // wait
}
delay(3000);
} while (nonStop);
}
boolean writeStandardLog(int iState) {
int MSG_BUFFER_SIZE = 50;
char msg[MSG_BUFFER_SIZE];
String sLine;
// construction datetime string
dt = clock.getDateTime();
char sDatetimeLog = "";
sLine = String(dt.year) + "/" + String(dt.month) + "/" + String(dt.day) + "," + String(dt.hour) + ":" + String(dt.minute) + ":" + String(dt.second);
// append door state
if (iState == 0){
sLine += ",close";
} else {
sLine += ",open";
}
Serial.print("Preparing to write ");
Serial.println(sLine);
// if available, open, write cLine to the file and close
myFile = SD.open("doorlog.csv", FILE_WRITE);
if (myFile) {
myFile.println(sLine);
myFile.close();
Serial.println("log is written");
return true;
} else {
// error trying to open the file
// could write to a different log file
Serial.println("log is not written");
blinkled(redLED,3,1, true);
return false;
}
}
void loop() {
int val;
val = digitalRead(sensor); // read the current state of the door
Serial.print("sensor says ");
Serial.println(val);
if (val == HIGH) {
Serial.println("door is closed");
iCurrentState = 0; // door is closed
} else {
Serial.println("door is open");
iCurrentState = 1; // door is open
}
if (bFirstAwake || (iLastState!=iCurrentState)) { // first time powering up or state change
Serial.println("Door movement or first rise detected, writing to card");
writeStandardLog(iCurrentState);
bFirstAwake = false; // don't write until reboot
}
iLastState = iCurrentState; // set the new current state
// wait 10sec before another measurement
delay(10000);
}