venerdì 25 gennaio 2019

Progetto Zero

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);

}

Nessun commento:

Posta un commento

Arduino logger low power

Alla fine ci sono riuscito La arduino MKR zero e' ormai da un mese che e' rimasta accesa sul tavolo...o meglio si attiva ogni minuto...