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

}

giovedì 24 gennaio 2019

Wakeup Arduino da interrupt con ADXL345

Attenzione: per errore e' riportato che VCC del breakout di ADXL345 debba essere collegata a 5V mentre in realta' deve essere collegato a 3.3 V
----------------------------------------------------------------------

Questo post e' il gemello del precedente utlizzando pero' ADXL345
Il codice e' stato completamente ripreso da questo post 




Ho rimosso un po' di linee per rendere il codice piu' leggibile

In pratica se viene generato un interrupt di Inactivity l'arduino va in sleep. L'ADXL345 e' settato alla massima sensibilita' con una soglia di 75 ed un tempo prima di considerarsi inattivo di 3 secondi

---------------------------------------------------
#include <SparkFun_ADXL345.h>         // SparkFun ADXL345 Library
#include <LowPower.h>

ADXL345 adxl = ADXL345();             // USE FOR I2C COMMUNICATION


int interruptPin = 2;                 // Setup pin 2 to be the interrupt pin (for most Arduino Boards)
const int wakeUpPin = 2;                //For good accelaration return values I comment out this

void wakeUp()
{

}

void setup(){
  
  Serial.begin(9600);                 // Start the serial terminal
  Serial.flush();
  
  adxl.powerOn();                     // Power on the ADXL345
  adxl.setRangeSetting(2);           // Give the range settings
                                      // Accepted values are 2g, 4g, 8g or 16g
                                      // Higher Values = Wider Measurement Range
                                      // Lower Values = Greater Sensitivity

  adxl.setSpiBit(0);                  // Configure the device to be in 4 wire SPI mode when set to '0' or 3 wire SPI mode when set to 1
                                      // Default: Set to 1
                                      // SPI pins on the ATMega328: 11, 12 and 13 as reference in SPI Library 
   
  adxl.setActivityXYZ(1, 1, 1);       // Set to activate movement detection in the axes "adxl.setActivityXYZ(X, Y, Z);" (1 == ON, 0 == OFF)
  adxl.setActivityThreshold(75);      // 62.5mg per increment   // Set activity   // Inactivity thresholds (0-255)

  adxl.setInactivityXYZ(1, 1, 1);     // Set to detect inactivity in all the axes "adxl.setInactivityXYZ(X, Y, Z);" (1 == ON, 0 == OFF)
  adxl.setInactivityThreshold(75);    // 62.5mg per increment   // Set inactivity // Inactivity thresholds (0-255)
  adxl.setTimeInactivity(3);         // How many seconds of no activity is inactive?

  adxl.setTapDetectionOnXYZ(0, 0, 1); // Detect taps in the directions turned ON "adxl.setTapDetectionOnX(X, Y, Z);" (1 == ON, 0 == OFF)

  // Set values for what is considered a TAP and what is a DOUBLE TAP (0-255)
  adxl.setTapThreshold(50);           // 62.5 mg per increment
  adxl.setTapDuration(15);            // 625 μs per increment
  adxl.setDoubleTapLatency(80);       // 1.25 ms per increment
  adxl.setDoubleTapWindow(200);       // 1.25 ms per increment

  // Set values for what is considered FREE FALL (0-255)
  adxl.setFreeFallThreshold(7);       // (5 - 9) recommended - 62.5mg per increment
  adxl.setFreeFallDuration(30);       // (20 - 70) recommended - 5ms per increment

  // Setting all interupts to take place on INT1 pin
  adxl.setImportantInterruptMapping(1, 1, 1, 1, 1);     // Sets "adxl.setEveryInterruptMapping(single tap, double tap, free fall, activity, inactivity);" 
                                                        // Accepts only 1 or 2 values for pins INT1 and INT2. This chooses the pin on the ADXL345 to use for Interrupts.
                                                        // This library may have a problem using INT2 pin. Default to INT1 pin.
  
  // Turn on Interrupts for each mode (1 == ON, 0 == OFF)
  adxl.InactivityINT(1);
  adxl.ActivityINT(1);
  adxl.FreeFallINT(1);
  adxl.doubleTapINT(1);
  adxl.singleTapINT(1);
  
 attachInterrupt(digitalPinToInterrupt(interruptPin), ADXL_ISR, RISING);   // Attach Interrupt
  pinMode(wakeUpPin, INPUT); 

}

void loop(){

    attachInterrupt(0, wakeUp, RISING);
  int x,y,z;   
  adxl.readAccel(&x, &y, &z);       

  Serial.print(x);
  Serial.print(", ");
  Serial.print(y);
  Serial.print(", ");
  Serial.println(z); 
  
  ADXL_ISR();
}

void ADXL_ISR() {
  byte interrupts = adxl.getInterruptSource();
  
  // Free Fall Detection
  if(adxl.triggered(interrupts, ADXL345_FREE_FALL)){
    Serial.println("*** FREE FALL ***");
    //add code here to do when free fall is sensed
  } 
  
  // Inactivity
  if(adxl.triggered(interrupts, ADXL345_INACTIVITY)){
    
               Serial.flush();        
              adxl.InactivityINT(0);
              LowPower.powerDown(SLEEP_FOREVER, ADC_OFF, BOD_OFF);
  }
  
  // Activity
  if(adxl.triggered(interrupts, ADXL345_ACTIVITY)){
    Serial.println("*** ACTIVITY ***"); 
     
     adxl.InactivityINT(1);
     //add code here to do when activity is sensed
  }
  
  // Double Tap Detection
  if(adxl.triggered(interrupts, ADXL345_DOUBLE_TAP)){
    Serial.println("*** DOUBLE TAP ***");
     adxl.InactivityINT(1);
     //add code here to do when a 2X tap is sensed
  }
  
  // Tap Detection
  if(adxl.triggered(interrupts, ADXL345_SINGLE_TAP)){
    Serial.println("*** TAP ***");
    adxl.InactivityINT(1);
  } 
}

void blink() { 
}

Compaq Contura 4/25



Toshiba T3100 TS



Workstation Sun Ultra 10




Highscreen Colani Bluenote 243/1991

Piccolo museo dell'informatica Innocenti. 486  DX/33



Windows 95 in floppy 3 1/2

Piccolo museo dell'informatica: Windows 95 in floppy


Debugger integrato ESP32S3

Aggiornamento In realta' il Jtag USB funziona anche sui moduli cinesi Il problema risiede  nell'ID USB della porta Jtag. Nel modulo...