Prezzemolo!

...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 :slight_smile:
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.