GPS ad alimentazione solare con registrazione dati su SD Card e sleep mode ed attivazione programmabile tramite orologio interno
Componenti:
Arduino Uno
SeedStudio Solar Charger Shield
Data recoder shield
RTC DS3231
GPS con uscita seriale
Lipo 10.000 mAh
Pannello solare 6V
SD Card 2Gb
Il rele' deve essere collegato nella configurazione NA (normalmente aperto)
La seriale del GPS e' collegata direttamente alla seriale dell'Arduino perche' usare una SoftwareSerial crea problemi con la modalita' Sleep
Tra i vari aggiustamenti che ho fatto al programma c'e' anche un ridimensionamento dell'array del buffer. Con un buffer da 200 byte il programma si compilava, veniva lanciato su Arduino ma la IDE segnalava che il poco spazio di memoria rimasto libero (un centinaio di bytes) poteva rendere il programma instabile....in effetti durante l'esecuzione il buffer veniva riempito con caratteri a caso e con pezzi della memoria. Ridimensionato il buffer il problema e' scomparso
------------------------------------------------------------------------------
#include <RTClibExtended.h>
#include <Wire.h>
#include <LowPower.h>
#include <stdlib.h>
#include <avr/interrupt.h> // library for interrupts handling
#include <avr/sleep.h> // library for sleep
#include <avr/power.h> // library for power control
// SD Card headers
#include <SPI.h>
#include <SD.h>
#define wakePin 2 //use interrupt 0 (pin 2) and run function wakeUp when pin 2 gets LOW
RTC_DS3231 rtc; //we are using the DS3231 RTC
int contatore;
const unsigned int dim_buffer = 100;
int SerialData[dim_buffer];
const int chipSelect = 10;
char incomingByte = 0; // for incoming serial data
char filen[10];
String filename;
char filenb[10];
String filenameb;
DateTime now;
//-------------------------------------------------
void wakeUp()
{
}
//------------------------------------------------------------
void setup() {
pinMode(7, OUTPUT);
delay(3000);
// Inizializzazione SD
if (!SD.begin(chipSelect)) {
//Serial.println("Card failed, or not present");
while (1);
//if (!sd.begin(chipSelect)) {
//Serial.println("Card failed, or not present");
//while (1); Serial.begin(9600);
}
delay(3000);
//Set pin D2 as INPUT for accepting the interrupt signal from DS3231
pinMode(wakePin, INPUT);;
//Initialize communication with the clock
Wire.begin();
rtc.begin();
rtc.adjust(DateTime(__DATE__, __TIME__)); //set RTC date and time to COMPILE time
delay(500);
now = rtc.now();
//clear any pending alarms
rtc.armAlarm(1, false);
rtc.clearAlarm(1);
rtc.alarmInterrupt(1, false);
rtc.armAlarm(2, false);
rtc.clearAlarm(2);
rtc.alarmInterrupt(2, false);
rtc.writeSqwPinMode(DS3231_OFF);
delay(1000);
}
//------------------------------------------------------------
void loop() {
Serial.begin(9600);
while (!Serial) {
}
Serial.println("inizio");
digitalWrite(7, HIGH);
now = rtc.now();
sprintf(filen, "%02d%02d%02d%02d.txt", now.month(), now.day(), now.hour(), now.minute());
String filename(filen);
delay(2500);
Serial.println(filename);
File dataFile = SD.open(filename, FILE_WRITE);
for (uint32_t i = 0; i <= 4000; i++) {
contatore = 0;
while (contatore < 98)
{
if (Serial.available() > 0) {
SerialData[contatore] = Serial.read();
//dataFile.print(char(Serial.read()));
contatore++;
//Serial.print(char(SerialData[contatore-1]));
//dataFile.print(" ");
//Serial.println(contatore);
}
}
if (dataFile) {
for (int s = 0; s < contatore - 1; s++) {
Serial.print(SerialData[s]);
Serial.print(" ");
Serial.print(char(SerialData[s]));
if (SerialData[s] != 255) {
dataFile.print(char(SerialData[s]));
Serial.println(" I");
}
else
{
Serial.println("E");
}
}
}
//dataFile.write(SerialData,197);
memset(SerialData,0,sizeof(SerialData));
}
dataFile.close();
Serial.println("Finito");
// salva la tensione della batteria
sprintf(filenb, "%02d%02d%02d%02d.bat", now.month(), now.day(), now.hour(), now.minute());
String filenameb(filenb);
File dataFileb = SD.open(filenameb, FILE_WRITE);
if (dataFileb) {
String bat = String(analogRead(A0), DEC);
dataFileb.println(bat);
dataFileb.close();
}
// spenge antenna GPS
Serial.end();
digitalWrite(7, LOW);
delay(500);
now = rtc.now();
DateTime nextAlarm = now + TimeSpan(0, 4, 0, 0);
delay(3000);
rtc.setAlarm(ALM1_MATCH_HOURS, nextAlarm.minute(), nextAlarm.hour(), nextAlarm.second()); //set your wake-up time here
rtc.alarmInterrupt(1, true);
delay(3000); // wait for console
attachInterrupt(0, wakeUp, LOW); //use interrupt 0 (pin 2) and run function wakeUp when pin 2 gets LOW
LowPower.powerDown(SLEEP_FOREVER, ADC_OFF, BOD_OFF); //arduino enters sleep mode here
detachInterrupt(0); //execution resumes from here after wake-up
//When exiting the sleep mode we clear the alarm
rtc.armAlarm(1, false);
rtc.clearAlarm(1);
rtc.alarmInterrupt(1, false);
delay(3000);
}