Ciao a tutti.
Ho realizzato a scopo educativo un timer da cucina da 1 a 99 minuti o da 1 a 99 secondi (in tal caso più a scopo ludico) utilizzando il piccolo ma potente (se spremuto bene) ATtiny13, programmato tramite Arduino Uno (con caricato lo sketch «ArduinoISP») usando «Arduino as ISP (MicroCore)» come programmatore da impostare nell'IDE.
Lo sketch sfrutta appieno le potenzialità della MCU ATtiny13, usando addirittura il pin di RESET come input analogico per leggere quale pulsante è premuto: UP, DOWN o entrambi.
Appena acceso vengono testati i display accendendo tutti i led per un secondo.
Alla prima accensione il timer si imposta ad un valore di default di 10 minuti. È possibile regolare il tempo premendo il pulsante dx (=UP) o il pulsante sx (=DOWN). Una volta impostato il tempo voluto, bisogna premere entrambi i pulsanti per far partire il timer.
A questo punto viene visualizzato per due secondi il tempo impostato (questo per evitare che premendo prima un pulsante e poi l'altro il tempo non cambi, nel caso basta spegnere e riaccendere per impostare nuovamente), quindi i display si spengono (per risparmiare batterie) ed il timer inizia il conto alla rovescia.
Il tempo impostato viene memorizzato nella EEPROM, sicché alla prossima accensione verrà impostato di default.
Se si vuole sapere quanto tempo manca ancora alla fine del conteggio, basta premere un pulsante (qualsiasi, anche entrambi) che il display si accende per due secondi e mostra i minuti interi rimanenti.
A tempo scaduto il display mostra «--» e inizia la suoneria intermittente finché non viene spento.
Per la modalità timer da 1 a 99 secondi, bisogna a timer spento premere e tenere premuto DOWN (pulsante sx), quindi accendere il timer. Adesso si procede come di consueto coi pulsanti UP e DOWN a impostare il tempo, che stavolta saranno secondi. Quindi premendo entrambi i pulsanti inizia il count-down, a display sempre acceso scandito pure dal tic-tac-toc del buzzer. Anche in tal caso il tempo impostato verrà memorizzato sulla EEPROM.
Ovviamente se non si tiene premuto il pulsante DOWN all'accensione, il timer rimane impostato per minuti di default.
Allego schema elettrico, sketch e istruzioni essenziali pre programmare l'ATtiny13 via Arduino UNO.
Va detto che io uso dei display intelligenti BCD (che possiedono quindi internamente il «BCD to 7 segment decoder driver») che non costano poco (io li ho trovati per pochi euro ad una fiera campionaria), online si trovano per circa 10€ cadauno. Volendo risparmiare, si può usare un integrato CMOS 4511 come «BCD to 7 segment decoder driver» e due economici display 7 segmenti a catodo comune (FND500 ad esempio).
Spero di avervi stimolati ad usare questa simpaticissima ed economica MPU ATtiny13 (circa 0,30€ cadauna!).
Rimango a disposizione per aiuti o chiarimenti.
/*
ATtiny13 TIMER 1÷99 minutes - by KMZ Software 2021 - Copyleft p.i. Davide Cosciani - davidecosciani@gmail.com
Ver. 0.2.1
- A MCU juice !
- I used two BCD display HP 5082 7300 multiplexed by NPN BJT BC337, and two UP and DOWN buttons to set timer.
- By both button pressing the timer start. DOWN button pressed before power-up set the timer to count seconds instead the minutes.
- I drive a megnetic buzzer 16 ohm (bypassed by reverse 1N4148) by another BJT NPN BC337.
- The display blank during timer, but by pressing DOWN button the left time will be displayed.
- During seconds timer the display is every on.
- It runs from 3,3 to 5 Vdc, I use 3 AAA battery until its full discarge.
*/
#include <EEPROM.h>
#define BUZZER 0 // pin 5 buzzer 16 ohm
#define INGRESSO A0 // pin 1 ADC0 = time and start button
#define DESTRA HIGH
#define SINISTRA LOW
#define DISPLAY 4 // pin 3 HIGH = DX un. display; LOW = SX dec. display;
#define D 3 // pin 2
#define C 2 // pin 7
#define B 1 // pin 6
#define A 0 // pin 5
boolean secondi = false; // to count minutes it's default
byte i, kmz, minuti;
int attesa, premuto;
void mostra() {
i = kmz / 10;
if (kmz == 255) i = 10; // I use special code over 99 to hit display extra functions
if (kmz == 200) i = 11; // like display «BB» or «--» or blank « »
if (kmz == 100) i = 13;
digitalWrite(DISPLAY, SINISTRA);
digitalWrite(D, bitRead(i , 3)); // 1010 = 10 show «BB» lamp test
digitalWrite(C, bitRead(i , 2)); // 1011 = 11 show « » blank before timer
digitalWrite(B, bitRead(i , 1)); // 1100 = 12 show « »
digitalWrite(A, bitRead(i , 0)); // 1101 = 13 show «--» end timer
i = kmz % 10;
if (kmz == 255) i = 10;
if (kmz == 200) i = 11;
if (kmz == 100) i = 13;
digitalWrite(DISPLAY, DESTRA);
digitalWrite(D, bitRead(i , 3)); // 1010 = 10 show «BB» lamp test
digitalWrite(C, bitRead(i , 2)); // 1011 = 11 show « » blank before timer
digitalWrite(B, bitRead(i , 1)); // 1100 = 12 show « »
digitalWrite(A, bitRead(i , 0)); // 1101 = 13 show «--» end timer
// 1110 = 14 show « »
// 1111 = 15 show « »
}
void rimane() {
mostra();
delay(2000);
kmz = 200; // display off
mostra();
}
void inizia() {
EEPROM.write(0, minuti);
if (secondi) attesa = 2 * minuti;
else {
attesa = 120 * minuti;
kmz = minuti;
rimane();
}
while (attesa > 0) {
delay(500);
attesa--;
if (secondi) {
kmz = attesa / 2;
mostra();
}
if (!secondi && (analogRead(INGRESSO) > 340) && (analogRead(INGRESSO) < 710)) { // some button pressed
kmz = attesa / 120;
rimane();
attesa = attesa - 4; // subtracts lost time
}
}
kmz = 100;
mostra(); // show «--»
while (true) {
for (i = 0; i < 220; i++) {
digitalWrite(BUZZER, !digitalRead(BUZZER));
delay(1);
}
delay(100);
}
}
///////////////////////////////////////////////////////////////////////
void setup() {
pinMode(INGRESSO, INPUT);
pinMode(DISPLAY, OUTPUT);
pinMode(D, OUTPUT);
pinMode(C, OUTPUT);
pinMode(B, OUTPUT);
pinMode(A, OUTPUT);
delay(100);
if (analogRead(INGRESSO) > 340 && analogRead(INGRESSO) < 400) secondi = true; // set to count seconds, else minutes
kmz = 255;
mostra(); // show «BB»
delay(1000);
minuti = EEPROM.read(0);
if (minuti < 1 || minuti > 99) minuti = 10;
kmz = minuti;
mostra();
}
void loop() {
premuto = analogRead(INGRESSO);
if (premuto > 340 && premuto < 400) { // 340 = DOWN pressed 1,63V
minuti--;
if (minuti <= 0) minuti = 99;
kmz = minuti;
mostra();
}
if (premuto > 650 && premuto < 710) { // 680 = UP pressed 3,25V
minuti++;
if (minuti > 99) minuti = 1;
kmz = minuti;
mostra();
}
if (premuto > 480 && premuto < 540) inizia(); // 510 = BOTH pressed 2,50V
delay(200);
}
ATtiny13_TIMER.pdf (55.4 KB)