interrupt con virtualwire

Ho un rx collegato al pin 3 di arduino, vorrei che quando riceve qualcosa si generasse un interrupt, come si può fare. Grazie

http://arduino.cc/en/Reference/AttachInterrupt

Ho letto grazie ma non riesco a farlo funzionare:

#include <avr/sleep.h>
#include <VirtualWire.h>
char rx[1];
void setup()
{
  vw_set_rx_pin(2);
  vw_setup(2000);
  Serial.begin(9600);
}

void wakeUpNow() 
{ 
}

void sleepNow() 
{
  ADCSRA = 0;   // disable ADC
  set_sleep_mode (SLEEP_MODE_PWR_DOWN);  
  sleep_enable();
  noInterrupts ();
  attachInterrupt (0, wakeUpNow, CHANGE);
  interrupts ();  
  sleep_cpu (); 

  sleep_disable();
  detachInterrupt (0);  
}
void loop()
{
  sleepNow();
  riceve();
    if (rx[0] == '1') 
    {
      tone(12,500)
       ........................
    }
    ............................
}
void riceve() 
{ 
  uint8_t buflen = 1 ;
  uint8_t buf[1];
  vw_rx_start();

  if(vw_get_message(buf, &buflen))
  {
    rx[0]=(char)(buf[0]);
    rx[1] = '\0'; 
  }
}

quando riceve un segnale dovrebbe risvegliarsi e se questo è uguale a ‘1’ dovrebbe suonare il buzzer…per poi tornare in sleep

come puó funzionare se attivi e poi disattivi l' interrupt?

attachInterrupt (0, wakeUpNow, CHANGE);
  interrupts ();  
  sleep_cpu (); 

  sleep_disable();
  detachInterrupt (0);

come puó funzionare se la funzione chiamata in caso di interrupt é vuota ( non fa niente)?

void wakeUpNow() 
{ 
}

Caio Uwe

grazie, ho provato a togliere interrupts (); e noInterrupts (); che dovrebbero abilitarli e disabilitarli, nella funzione wakeUpNow() ho inserito la funzione riceve(), che ho tolto nel loop. però continua a non funzionare.

quando dici: come puó funzionare se la funzione chiamata in caso di interrupt é vuota ( non faniente? ma quando si risveglia non dovrebbe svolgere tutte le istruzioni del loop? per poi tornare in sleep? mi daresti il codice esatto? grazie

Il tuo codice è giusto, al max togli noInterrupts() prima di attachInterrupts e interrupts() subito dopo, che non servono. wakeUp è la funzione che il compilatore chiama quando arriva l'interrupt, può essere vuota se l'interrupt è usato solo per risvegliare il micro dallo sleep. Purtroppo va messa perché la funzione attachInterrupt la richiede e quindi non si può omettere tra i suoi parametri.

Piuttosto, sei sicuro sull'uso del pin 2, che è gestito da una libreria, come fonte di interrupt? Non potrebbe darsi che ci siano dei conflitti?

Prova il tuo sketch togliendo la VirtualWire e dando un piccolo segnale sul pin 2 per vedere se il micro si risveglia. Se si risveglia, il circuito è giusto e c'è incompatibilità fra la lib e l'uso dell'interrupt.

toglieno sleep_cpu sembra funzionare bene. ma quali sono le ultime librerie virtualwire? io uso la versione 1.20

Se togli sleep_cpu togli la messa in sleep del microcontrollore per cui il programma funziona ma senza sleep.

Ti passo questo link, leggilo bene. http://www.nongnu.org/avr-libc/user-manual/group__avr__sleep.html

leo72:
Se togli sleep_cpu togli la messa in sleep del microcontrollore per cui il programma funziona ma senza sleep.

Ti passo questo link, leggilo bene.
avr-libc: <avr/sleep.h>: Power Management and Sleep Modes

ho letto, fatto mille prove ma niente, e poi perchè sleep_bod_disable(); da errore ?

io ho seguito l’esempio che trovi:
http://playground.arduino.cc/Learning/ArduinoSleepCode
non so se cambia qualcosa ma sto usando un arduino micro: i pin di interrupt sono sempre 2 e 3… o mi sfugge qualcosa

cerco aiuto disperatamente

ho cambiato il modo che provoca l'interrupt e sembra funzionare, ho un contatto magnetico che lo provoca e poi trasmetto qualcosa... e funziona

void sleepNow() 
{
  ADCSRA = 0;   // disable ADC
  set_sleep_mode (SLEEP_MODE_PWR_DOWN);  
  sleep_enable();
  attachInterrupt (0, wakeUpNow, LOW); 
  sleep_mode (); 

  sleep_disable();
  detachInterrupt (0);  
}

set SLEEP_MODE_PWR_DOWN e poi lo applico con sleep_mode (); ma non trovo dettagli su cosa veramente vado a disabilitare, nel nenso in sleep_mode (); è compreso sleep_cpu (); ????

quindi il problema nasce quando l'interrupt lo deve provocare virtualwire. secondo voi in sleep_mode ricevo ma poi non risveglio oppure non ricevo proprio? perchè se almeno ricevessi potrei usare vw_have_message.... non saprei come ma almeno forse ci sarebbe una soluzione. come faccio a risolvere? sempre grazie

Se uso SLEEP_MODE_IDLE al posto di SLEEP_MODE_PWR_DOWN funziona. l'unico risparmio energetico che funziona

L'Arduini Micro è basato sull'Atmega32U4, non sull'Atmega328, quindi è simile alla Leonardo. Sulla Leonardo l'INT0 è sul pin 3, non sul pin 2: http://arduino.cc/en/Reference/AttachInterrupt

leo72: L'Arduini Micro è basato sull'Atmega32U4, non sull'Atmega328, quindi è simile alla Leonardo. Sulla Leonardo l'INT0 è sul pin 3, non sul pin 2: http://arduino.cc/en/Reference/AttachInterrupt

lo avevo letto, pin2 e attachinterrupt(0,fun,RISING) -->FUNZIONA se invece metto pin2 e attachinterrupt(1,fun,RISING) --> non funziona

Non voglio contraddirti però aprendo lo schema della Micro l'INT0 è effettivamente sul pin 3, quindi c'è qualcosa che non mi torna.

sto cercando di fare la stessa cosa ma con un attiny85, ma ho grossi problemi. ho comprato questo: http://www.robot-italy.com/it/tiny-avr-programmer.html per poterlo programmare facilmente.

da qui https://code.google.com/p/arduino-tiny/downloads/list ho scaricato arduino-tiny-0100-0017.zip che ho decompresso in documenti/arduino/hardware/attiny

aprendo l'ide ora vedo tutti i micro della famiglia attiny tra cui vari 85.

come faccio per impostarlo a 8 o 16 mhz? seguendo una guida trovata in rete faccio: da tipi di arduino scelgo attiny85 8 mhz(internal oscillator, bod disabled) da programmatore scelgo usbtinyIPS poi faccio scrivi bootloader

ma mi dice errore nella scrittura del bootloader: avrdude: initialization failed, rc=-1 Double check connections and try again, or use -F to override this check.

leo 72 mi servirebbe tanto un tuo aiuto. dovresti guidarmi passo passo. ti ringrazio

Faster, normalmente gli ATtiny 85 escono di fabbrica con i "fuse" settati per lavorare ad 1 MHz ... devi andarti a riprogrammare i "fuse" per cambiargli velocità, altrimenti credo avrai sempre problemi (la velocità che selezioni deve corrispondere alla reale velocità a cui lavora il chip) ...

QUI un esempio di "calcolatore per i fuse" che ti aiuta calcolarne i valori ... occhio che un errata programmazione dei "fuse" può bloccarti il chip e poi per sbloccarlo ti server un programmatore "High Voltage" ...

E poi ... quale "bootloader" vorresti caricarci ??? :astonished: Ho sempre programmato, e visto programmare, gli ATtiny85 con tecnica ISP ... mica sono degli ATmega ... e hanno solo 8 KBytes di memoria ... :roll_eyes:

Guglielmo

@Guglielmo: il core Tiny contiene dei bootloader farlocchi che servono solo a fare il setup dei fuse, operazione permessa con la nuova IDE 1.0.x anche sui Tiny. In pratica, facendo "Scrivi bootloader" altro non fai che fare appunto il setting dei fuse, senza realmente scrivere niente in Flash (il file .hex è vuoto). Quindi i passaggi seguiti sono giusti.

@Faster: lì c'è un errore ben preciso, una mancanza di collegamento fra il programmatore ed il chip. Come li hai collegati esattamente?

leo72: @Guglielmo: il core Tiny contiene dei bootloader farlocchi che servono solo a fare il setup dei fuse, operazione permessa con la nuova IDE 1.0.x anche sui Tiny. .....

Aha ... uno [u]sporco trucco[/u] quindi per nascondere quello che veramente occorre fare :D :D :D

Guglielmo

P.S. : Opinione personale ... uno che si avvicina a queste piccole MCU (... ma in realté a tutte), queste cose dovrebbe imparare a saperle "manipolare" ... così glie le si nascondono e non impara nulla ... :roll_eyes:

Sì, è uno "sporco trucco".

Concordo che certe cose andrebbe imparato farle a mano prima. ;)

leo72: @Guglielmo: il core Tiny contiene dei bootloader farlocchi che servono solo a fare il setupei fuse, operazione permessa con la nuova IDE 1.0.x anche sui Tiny. In pratica, facendo "Scrivi bootloader" altro non fai che fare appunto il setting dei fuse, senza realmente scrivere niente in Flash (il file .hex è vuoto). Quindi i passaggi seguiti sono giusti.

@Faster: lì c'è un errore ben preciso, una mancanza di collegamento fra il programmatore ed il chip. Come li hai collegati esattamente?

Utilizzo un usbtinyips, vedi il mio post precedente, inserisco attiny85 nell usbtiny che va alla porta usb del pc. Apro ide Arduino, seleziono quello descritto e esce l' errore, carico lo sketch blink, lampeggio led, cambio il pin da 13 a 0, ma non funziona. Caricamento terminato ma niente led spento. Come posso controllare se effettivamente ho cambiato i fuse?

leo72: Come li hai collegati esattamente?

Chiedevo i collegamenti fisici, ossia quali pin hai collegato con quali.