...e per completare l'esemplificazione degli sketch dedicati a prezzemolo:
**** RITARDO DI ACCENSIONE AL RIPRISTINO AC 230V ****
Indicato per apparecchiature (come motori, autoclavi, etc.) che potrebbero risentire degli sbalzi dovuti agli "assestamenti" di tensione durante un ripristino dell'energia elettrica dopo un blackout. Il ritardo è programmabile tramite dei jumper posti sugli ingressi.
Dato che mi ero scocciato di vedere sempre "millis()" piedi piedi, ho deciso che questa volta avrei usato un Timer...così, tanto per cambiare.
/*
* ** PREZZEMOLO ** APPLICAZIONE #3: RITARDO DI ACCENSIONE AL RIPRISTINO AC 230V
* ================================================================================
* Programma per generare un ritardo di n secondi prima dell'attivazione di un utilizzatore.
* Esempio tipico: attivazione di una POMPA con ritardo dopo un ripristino di corrente per evitare danneggiamenti.
* Hardware: nessuno. la posizione di jumper sulle porte determina i secondi di ritardo.
* Tempi:
* JP2 | JP1 | JP0 | Tempo = [valore] * SCALE_TIMER (2s)
* --------------------------
* 0 | 0 | 0 | 1s
* 0 | 0 | 1 | 2s
* 0 | 1 | 0 | 4s
* 0 | 1 | 1 | 6s
* 1 | 0 | 0 | 8s
* 1 | 0 | 1 | 10s
* 1 | 1 | 0 | 12s
* 1 | 1 | 1 | 14s
* Senza jumper sarà impostato automaticamente il valore massimo
*/
#define LED DDB3
#define TRIAC DDB4
#define LED_TOGGLE PORTB ^= (1 << DDB3)
#define JP0 0 // fpin 5 (SENS1)
#define JP1 1 // fpin 6 (SENS2)
#define JP2 2 // fpin 7 (ANALOG1)
#define SCALE_TIMER 2000 // costante di moltiplicazione del valore dei jumper in ms
unsigned volatile int tick;
unsigned volatile int delay_time;
void setup() {
cli();
TCCR0A &= ~(1<<WGM00); // Timer0 in modalità CTC
TCCR0A |= (1<<WGM01);
TCCR0B &= ~(1<<WGM02);
TCCR0A &= ~((1<<COM0A1) | (1<<COM0A0)); // porta OC2A (PB2) in toggle mode (pin fisico 5)
TCCR0B |= (1<<CS00) | (1<<CS01); // PRESCALER 64
TCCR0B &= ~(1<<CS02);
OCR0A = 124; // 1 ms (1000Hz)
TIMSK |= (1<<OCIE0A); // attiva interrupt (TIM0_COMPA_vect)
DDRB |= (1<<LED) | (1<<TRIAC); // PB3 e PB4 output (pin fisici 2, 3)
PORTB |= (1<<TRIAC); // uscita triac HIGH (dopo il delay diventa LOW)
DDRB &= ~((1<<DDB2) | (1<<DDB1) | (1<<DDB0)); // 3 input per la programmazione del delay (da 000 = 1s a 111 = 14s)
digitalWrite(JP2, HIGH); // pull UP dei tre ingressi
digitalWrite(JP1, HIGH);
digitalWrite(JP0, HIGH);
// programma valore del ritardo in base alla posizione binaria dei 3 ingressi (dip-switch)
delay_time = (((byte)digitalRead(JP2)<<2) | ((byte)digitalRead(JP1)<<1) | ((byte)digitalRead(JP0)<<0)) * SCALE_TIMER;
if (delay_time == 0) delay_time = 1000; // se dip-switch 000 allora ritardo = 1 secondo
sei(); // attiva interrupt (partenza timer)
}
/* Interrupt Service Routine (ISR) per CTC Match A */
ISR(TIM0_COMPA_vect) {
if (tick++ >= delay_time) { // aspetta n secondi
TCCR0B = 0; // ferma Timer (prescaler no clock)
PORTB &= ~(1<<TRIAC); // porta uscita triac a LOW per attivare il carico
}
else if (tick % 100 == 0)
LED_TOGGLE; // lampeggia LED con frequenza 5 Hz
}
void loop() {
// loop vuoto
}
E con questo credo di aver condiviso tutto il "prezzemolo" che avevo in casa ![]()
Non pubblicherò i programmini per ottenere "lampeggiatori" o "temporizzatori luce scala" perchè credo siano alla portata di chiunque.
E poi, in confidenza, non vedo l'ora di iniziare la sperimentazione con il componente LTSR 25-NP arrivato fresco fresco (http://media.digikey.com/pdf/Data%20Sheets/LEM%20USA%20PDFs/LTSR%2025-NP%20E.pdf) per tenere con precisione sotto controllo i consumi dell'impianto di casa, cercando di convincere un ATtiny84 a calcolare nel più breve tempo possibile la radice della media dei quadrati, per gli amici "RMS". Ma questa è un'altra storia...ops, un altro post.