Invece di usare come al solito (e per comodita') un relay qui viene descritto come usare un transistor in funzione di interruttore. Il transistor in questione e' un 2N2222A (da non confondere con il P2N2222A dato che hanno la posizione dell'emettitore e del collettore invertiti)
Un pin digitale (il 13) e' collegato alla base del transistor per pilotare l'apertura o chiusura dell'interruttori (non dimenticarsi della resistenza)
Il transistor e' posizionato a valle dell'utilizzatore (qui semplificato con un led) ovvero sul lato GND
Si carica sull'Arduino lo sketch di esempio Blink
Ma perche' utilizzare un sistema cosi' complicato quando si potrebbe derivare la corrente dal pin13?? Perche' i pin digitali di Arduino possono erogare al massimo 45 mA e non possono quindi alimentare degli utilizzare piu' esigenti in termini di corrente
Per una trattazione piu' completa anche se introduttiva seguire questo link
lunedì 28 gennaio 2019
venerdì 25 gennaio 2019
MKR1000 Sleep Mode con Interrupt da RTC
Ho ripreso in mano anche la MKR1000 per testare le capacita' di sleep mode in rapporto ad Arduino Uno. La MKR1000 ha un processore completamente differente (un SAMD21 per la precisione) e integra un RTC per cui non ha bisogno di supporto esterno
Un paio di annotazioni
1) La MKR1000 non ha un pulsante di accensione e l'unico modo di spengerla e' staccare la batteria. Cio' e' abbastanza fastidioso
2) In un caso ho perso il controllo della scheda perche' non si vedeva il device tra i dispositivi USB. In questi casi si deve premere in modo ravvicinato nel tempo per due volte il pulsante di reset
3) Per minimizzare il consumo si deve esplicitamente spengere il modulo Wifi, questa operazione non viene eseguita dallo standbymode
4) Le alimentazioni, quando e' presente la sola LiPo, sono a 3.3V. La porta a 5V in alimentazione output e' disponibile solo quando c'e' un cavo USB che alimenta dall'esterno
Il trucco per impostate il risveglio da RTC e' simile a quello visto in questo post. Si setta un'allarme ad una certa ora, poi all'interno del codice di interrupt si setta il nuovo allarme nel futuro. In questo esempio gli allarmi sono spostati nel tempo di un minuto
(il codice e' stato ripreso da questo link originario e leggermente migliorato per le mie esigenze)
----------------------------------------------
#include <RTCZero.h>
#include <WiFi101.h>
RTCZero rtc;
bool matched = false;
int alarmMinutes = 15;
/* Change these values to set the current initial time */
const byte seconds = 0;
const byte minutes = 14;
const byte hours = 14;
/* Change these values to set the current initial date */
const byte day = 25;
const byte month = 1;
const byte year = 19;
void setup()
{
Serial.begin(9600);
WiFi.end();
rtc.begin();
rtc.setTime(hours, minutes, seconds);
rtc.setDate(day, month, year);
rtc.setAlarmMinutes(alarmMinutes);
rtc.enableAlarm(rtc.MATCH_MMSS);
rtc.attachInterrupt(alarmMatch);
}
void loop()
{
if (matched) {
matched = false;
printDate();
printTime();
Serial.println();
delay(1000);
alarmMinutes= (rtc.getMinutes()+1)%60;
rtc.setAlarmMinutes(alarmMinutes);
rtc.enableAlarm(rtc.MATCH_SS);
rtc.attachInterrupt(alarmMatch);
rtc.standbyMode(); // Sleep until next alarm match
}
}
void alarmMatch()
{
matched = true;
}
void printTime()
{
print2digits(rtc.getHours());
Serial.print(":");
print2digits(rtc.getMinutes());
Serial.print(":");
print2digits(rtc.getSeconds());
Serial.println();
}
void printDate()
{
Serial.print(rtc.getDay());
Serial.print("/");
Serial.print(rtc.getMonth());
Serial.print("/");
Serial.print(rtc.getYear());
Serial.print(" ");
}
void print2digits(int number) {
if (number < 10) {
Serial.print("0");
}
Serial.print(number);
}
Un paio di annotazioni
1) La MKR1000 non ha un pulsante di accensione e l'unico modo di spengerla e' staccare la batteria. Cio' e' abbastanza fastidioso
2) In un caso ho perso il controllo della scheda perche' non si vedeva il device tra i dispositivi USB. In questi casi si deve premere in modo ravvicinato nel tempo per due volte il pulsante di reset
3) Per minimizzare il consumo si deve esplicitamente spengere il modulo Wifi, questa operazione non viene eseguita dallo standbymode
4) Le alimentazioni, quando e' presente la sola LiPo, sono a 3.3V. La porta a 5V in alimentazione output e' disponibile solo quando c'e' un cavo USB che alimenta dall'esterno
Il trucco per impostate il risveglio da RTC e' simile a quello visto in questo post. Si setta un'allarme ad una certa ora, poi all'interno del codice di interrupt si setta il nuovo allarme nel futuro. In questo esempio gli allarmi sono spostati nel tempo di un minuto
(il codice e' stato ripreso da questo link originario e leggermente migliorato per le mie esigenze)
----------------------------------------------
#include <RTCZero.h>
#include <WiFi101.h>
RTCZero rtc;
bool matched = false;
int alarmMinutes = 15;
/* Change these values to set the current initial time */
const byte seconds = 0;
const byte minutes = 14;
const byte hours = 14;
/* Change these values to set the current initial date */
const byte day = 25;
const byte month = 1;
const byte year = 19;
void setup()
{
Serial.begin(9600);
WiFi.end();
rtc.begin();
rtc.setTime(hours, minutes, seconds);
rtc.setDate(day, month, year);
rtc.setAlarmMinutes(alarmMinutes);
rtc.enableAlarm(rtc.MATCH_MMSS);
rtc.attachInterrupt(alarmMatch);
}
void loop()
{
if (matched) {
matched = false;
printDate();
printTime();
Serial.println();
delay(1000);
alarmMinutes= (rtc.getMinutes()+1)%60;
rtc.setAlarmMinutes(alarmMinutes);
rtc.enableAlarm(rtc.MATCH_SS);
rtc.attachInterrupt(alarmMatch);
rtc.standbyMode(); // Sleep until next alarm match
}
}
void alarmMatch()
{
matched = true;
}
void printTime()
{
print2digits(rtc.getHours());
Serial.print(":");
print2digits(rtc.getMinutes());
Serial.print(":");
print2digits(rtc.getSeconds());
Serial.println();
}
void printDate()
{
Serial.print(rtc.getDay());
Serial.print("/");
Serial.print(rtc.getMonth());
Serial.print("/");
Serial.print(rtc.getYear());
Serial.print(" ");
}
void print2digits(int number) {
if (number < 10) {
Serial.print("0");
}
Serial.print(number);
}
Progetto Uno
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
----------------------------------------------------------------------
L'idea del progetto Uno e' avere un accelerometro che tramite un interrupt sveglia una Arduino Uno che tramite una radio per telemetria da droni invia un segnale ad un ricevitore remoto
Per risparmiare batteria il trasmettitore viene alimentato solo quando la Arduino si risveglia mediante un relay
I trasmettitori radio sono quelli indicati a questo link. Sono delle semplici radio che si comportano come delle seriali virtuali a 57600 e sono principalmente usati nell'ambito dei droni. Le radio vengono vendute a coppie per una comunicazione punto-punto ed una (o entrambe) hanno un connettore USB piu' un connettore a 6 pin...visto che vengono venduti per droni hanno dei cavi gia' predisposti per PixHawk o simili in alcuni casi e' difficile adattare i cavi per Arduino in modo semplice..se ne trovano alcuni come quello in foto che permettono l'inserimento dei pin
--------------------------------------------------------------------------
/* *********************************************
* SparkFun_ADXL345_Example
* Triple Axis Accelerometer Breakout - ADXL345
* Hook Up Guide Example
*
* Utilizing Sparkfun's ADXL345 Library
* Bildr ADXL345 source file modified to support
* both I2C and SPI Communication
*
* E.Robert @ SparkFun Electronics
* Created: Jul 13, 2016
* Updated: Sep 06, 2016
*
* Development Environment Specifics:
* Arduino 1.6.11
*
* Hardware Specifications:
* SparkFun ADXL345
* Arduino Uno
* *********************************************/
#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(57600); // Start the serial terminal
Serial.flush();
pinMode(7, OUTPUT);
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(10); // 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); // Read the accelerometer values and store them in variables declared above x,y,z
digitalWrite(7, HIGH);
delay(500);
Serial.print(x);
Serial.print(", ");
Serial.print(y);
Serial.print(", ");
Serial.println(z);
digitalWrite(7, LOW);
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() {
}
----------------------------------------------------------------------
L'idea del progetto Uno e' avere un accelerometro che tramite un interrupt sveglia una Arduino Uno che tramite una radio per telemetria da droni invia un segnale ad un ricevitore remoto
Per risparmiare batteria il trasmettitore viene alimentato solo quando la Arduino si risveglia mediante un relay
I trasmettitori radio sono quelli indicati a questo link. Sono delle semplici radio che si comportano come delle seriali virtuali a 57600 e sono principalmente usati nell'ambito dei droni. Le radio vengono vendute a coppie per una comunicazione punto-punto ed una (o entrambe) hanno un connettore USB piu' un connettore a 6 pin...visto che vengono venduti per droni hanno dei cavi gia' predisposti per PixHawk o simili in alcuni casi e' difficile adattare i cavi per Arduino in modo semplice..se ne trovano alcuni come quello in foto che permettono l'inserimento dei pin
--------------------------------------------------------------------------
/* *********************************************
* SparkFun_ADXL345_Example
* Triple Axis Accelerometer Breakout - ADXL345
* Hook Up Guide Example
*
* Utilizing Sparkfun's ADXL345 Library
* Bildr ADXL345 source file modified to support
* both I2C and SPI Communication
*
* E.Robert @ SparkFun Electronics
* Created: Jul 13, 2016
* Updated: Sep 06, 2016
*
* Development Environment Specifics:
* Arduino 1.6.11
*
* Hardware Specifications:
* SparkFun ADXL345
* Arduino Uno
* *********************************************/
#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(57600); // Start the serial terminal
Serial.flush();
pinMode(7, OUTPUT);
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(10); // 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); // Read the accelerometer values and store them in variables declared above x,y,z
digitalWrite(7, HIGH);
delay(500);
Serial.print(x);
Serial.print(", ");
Serial.print(y);
Serial.print(", ");
Serial.println(z);
digitalWrite(7, LOW);
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() {
}
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>
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
---------------------------------------------------
#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() {
}
----------------------------------------------------------------------
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() {
}
Iscriviti a:
Post (Atom)
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...
-
In questo post viene indicato come creare uno scatterplot dinamico basato da dati ripresi da un file csv (nel dettaglio il file csv e' c...
-
Questo post e' a seguito di quanto gia' visto nella precedente prova Lo scopo e' sempre il solito: creare un sistema che permet...
-
La scheda ESP32-2432S028R monta un Esp Dev Module con uno schermo TFT a driver ILI9341 di 320x240 pixels 16 bit colore.Il sito di riferiment...