Ciao,
ho creato un piccolo countdown timer usando dei led ws2812 e un bottone per avviare il countdown.
Ho usato questa libreria: GitHub - inflop/Countimer: This is simple timer and counter Arduino library. che mi sembra buona e mi fornisce anche la possibilità di richiamare ogni tot una funzione che uso per aggiornare le luci che mostrano il tempo trascorso.
Lo sketch che sto usando è il seguente ed è la base di un progetto più ampio per la creazione di un tabellone segnapunti. Implementa anche una matrice di bottoni per la gestione di più eventi. Al momento l'unico utilizzato è il bottone P che serve a fare Start/Pause del timer.
#include <Keypad.h>
#include <Adafruit_NeoPixel.h>
#include "Countimer.h"
#ifdef __AVR__
#include <avr/power.h>
#endif
#define PIN 10
#define NUMPIXELS 50
#define BUZZER 11
Adafruit_NeoPixel pixels = Adafruit_NeoPixel(NUMPIXELS, PIN, NEO_RGB + NEO_KHZ800);
const byte ROWS = 3; //four rows
const byte COLS = 3; //four columns
//define the cymbols on the buttons of the keypads
char hexaKeys[ROWS][COLS] = {
{'L','l','P'},
{'O','o','S'},
{'T','t','M'}
};
byte rowPins[ROWS] = {3, 4, 5}; //connect to the row pinouts of the keypad
byte colPins[COLS] = {6, 7, 8}; //connect to the column pinouts of the keypad
int charLayout[10][15] = {
{1,1,1,1,0,1,1,0,1,1,0,1,1,1,1}, // zero
{1,1,1,0,1,0,0,1,0,1,1,0,0,1,0}, // one
{1,1,1,1,0,0,1,1,1,0,0,1,1,1,1}, // two
{1,1,1,0,0,1,1,1,1,0,0,1,1,1,1}, // three
{1,0,0,0,0,1,1,1,1,1,0,1,1,0,1}, // four
{1,1,1,0,0,1,1,1,1,1,0,0,1,1,1}, // five
{1,1,1,1,0,1,1,1,1,1,0,0,1,1,1}, // six
{0,1,0,0,1,0,0,1,0,0,0,1,1,1,1}, // seven
{1,1,1,1,0,1,1,1,1,1,0,1,1,1,1}, // eight
{1,1,1,0,0,1,1,1,1,1,0,1,1,1,1} // nine
};
//initialize an instance of class NewKeypad
Keypad customKeypad = Keypad( makeKeymap(hexaKeys), rowPins, colPins, ROWS, COLS);
// Initialize timer
Countimer tDown;
void toggleLocation(int loc, int ledState){
if(ledState==0){
pixels.setPixelColor(loc, pixels.Color(0,0,0)); //off
} else{
pixels.setPixelColor(loc, pixels.Color(255,0,0)); // red
}
}
void showNumber(int number){
for(int k=0;k<15;k++){
toggleLocation(k, charLayout[number][k]);
}
pixels.show();
}
void number_display(){
showNumber(tDown.getCurrentSeconds() % 10);
}
void buzz(){
showNumber(0);
Serial.println(tDown.getCurrentSeconds());
digitalWrite(BUZZER, HIGH);
delay(3000);
digitalWrite(BUZZER, LOW);
}
void setup(){
pixels.begin();
Serial.begin(9600);
tDown.setCounter(0, 0, 60, tDown.COUNT_DOWN, buzz);
tDown.setInterval(number_display, 1000);
pinMode(BUZZER, OUTPUT);
}
void loop(){
tDown.run();
char customKey = customKeypad.getKey();
if (customKey){
Serial.println(customKey);
switch (customKey){
case 'P':
tens = 0;
if (!tDown.isStopped() && !tDown.isCounterCompleted()) {
tDown.pause();
} else {
tDown.start();
}
break;
}
}
}
Ho notato una cosa piuttosto sgradevole sul conteggio del tempo: impostando il timer per il countdown di 60 secondi e avviando contemporaneamente il cronometro sul cellulare, mi trovo che il buzzer comincia a suonare pochi decimi di secondo prima dello scattare dei 59 secondi.
Il valore che vedo rappresentato sul mio pannello è 0, quindi il tempo, per arduino, risulta essere correttamente scaduto con un anticipo di ben 1 secondo.
Immagino che non si possa pretendere una gestione precisa del tempo da parte di arduino, ma 1 secondo ogni minuto diventa un problema per me che devo impostare il countdown a 7 o 10 minuti.
C'è qualche tipo di problema nel codice o nella libreria che ho scelto? Esistono librerie "migliori" o più "solide" di quella che ho utilizzato?
In alternativa che si può fare per migliorare la precisione in modo che arduino non si disallinei così rapidamente? (per esempio 1 secondo ogni 10 minuti è accettabile).
Grazie
Luca