Sleep Power-Down e PCINT

Nella tabella 14.1 del manuale del mega328 c'è un numerino affianco al risveglio per interrupt. (3) Per Int1 e Int2, solo interrupt Livello.

Però nella descrizione del Power-Down c'è scritto che funziona il Pin Change.

Non capisco, si o no ?

Poi non capisco perchè ci sono tanti pin che possono essere change, ma solo 3 interrupt corrispondenti. PCINT0, PCINT1, PCINT2

x-giorgio-x: Poi non capisco perchè ci sono tanti pin che possono essere change, ma solo 3 interrupt corrispondenti. PCINT0, PCINT1, PCINT2

Perché sono a gruppi ... a te, una volta che è scattato l'interrupt, coprire quale pin del gruppo lo ha creato.

Per non impazzire, ti consiglio QUESTA libreria che gestisce tutti i tipi di interrupt.

Guglielmo

x-giorgio-x: Nella tabella 14.1 del manuale del mega328 c'è un numerino affianco al risveglio per interrupt. (3) Per Int1 e Int2, solo interrupt Livello.

Quella è una nota solo per Int0 ed Int1 ... e ti dice che le sole modalità che risvegliano la MCU sono quelle di livello (... e quindi non quelle di variazione) :

The External Interrupts can be triggered by a falling or rising edge or a low level.

Guglielmo

Lo sleep degli AVR ha diversi livelli di "coscienza" in funzione dei quali possono essere utilizzati vari eventi per il risveglio, minore è il consumo in sleep e minori sono gli eventi utilizzabili per risveglio, questo perché per risparmiare energia vengono spente selettivamente le varie periferiche non utilizzate. In pratica a seconda del livello di sleep è possibile usare solo alcuni eventi tra tutti quelli possibili, inoltre su i 328 solo i pint INT0 e INT1 dispongono di interrupt dedicati, con varie modalità di funzionamento, mentre per tutti gli atri pin è disponibile un solo interrupt per ogni port, in comune con tutti i relativi pin e gestisce solo il cambio stato, ecco perché hai solo 3 interrupt per tutti gli altri pin.

PCINTx = Pin Change Interrupt Request

Io devo svegliare la CPU con la variazione. Nella tabella c'è il numerino (3) Ma nella descrizione c'è scritto che PCINT sveglia. Uno dice si e uno no, sembrano in contraddizione.

Stai facendo confusione tra i pin INT0 e INT1, che hanno un loro interrupt specifico dedicato, e tutti gli altri pin per i quali c'è solo un singolo interrupt per ogni port attivo esclusivamente sul cambio stato. La nota 3 parla chiaramente di INT0 e INT1, non di PCINTx, ovvero dice che se stai usando i pin INT0 e INT1 il risveglio può avvenire solo tramite livello, HIGH o LOW, e non tramite cambio stato. Va da se che se non usi INT0 e INT1 e al loro posto usi il relativo PCINTx puoi ottenere il risveglio sul cambio stato anche su i pin per INT0 e INT1, ovvero i pin 2 e 3 di Arduino che fanno capo a PD2 e PD3 (PORT D pin 2 e 3) del Atmega 328P.

Dal data sheet.

an external level interrupt on INT0 or INT1, or a pin change interrupt can wake up the MCU

Sto provando ma non si sveglia.

PD2 - INT0 - PCINT18 PD3 - INT1 - PCINT19

li definisco così ?

attachInterrupt(2, VoidInt, CHANGE); attachInterrupt(3, VoidInt, CHANGE);

attachInterrupt(2, VoidInt, CHANGE);
attachInterrupt(3, VoidInt, CHANGE);

no, in quel modo non devi specificare il pin, ma l'INTX. Esempio

attachInterrupt(0, VoidInt, CHANGE);
attachInterrupt(1, VoidInt, CHANGE);

Oppure la sintassi corretta è

 attachInterrupt(digitalPinToInterrupt(2), VoidInt, CHANGE);
 attachInterrupt(digitalPinToInterrupt(3), VoidInt, CHANGE);

Così non andava.

PCICR |= (1 << PCIE1); // Attivo il pin change per PD2 e PD3
PCMSK2 |= (1 << PCINT18) | (1 << PCINT19);

Ma come hai detto tu ora si sveglia.
Grazie.

attachInterrupt(0, VoidInt, CHANGE);
attachInterrupt(1, VoidInt, CHANGE);