USART_RX_vect con Arduino

Ciao Ragazzi, volevo chiedervi una strana cosa in cui mi sono imbattuto pochi giorni fa. Ho scritto un'applicazione che fa uso della porta seriale di arduino e volevo intercettare l'interrupt quando ricevo un dato. Ovviamente il compilatore da errore, e da quanto ho capito le librerie dell'ambiente di sviluppo già usano questa funzionalità bloccandola quindi all'utente. Corregetemi se sbaglio ovviamente!!! Esiste un modo per far funzionare l'interrupt della seriale?

Ciao, dipende da che errore ricevi e da come hai tentato di intercettare e cosa.

Mi pare di capire hai usato le macro ISR, se si allora bisognerebbe vedere nelle librerie cores di arduino, io ricordo di averla vista definita nei sorgenti ma quale se Rx o Tx non ricordo.

Come mai ti serviva la tua routine di interrupt?

se ci fai caso i pin non hanno un'interrupt singolo, ma ci sono 3 registri interrupt per tutti i pin. Se ti metti in "ascolto" del registro che comprende i pin seriali, riesci a intercettare gli interrupt, per ricavare il pin di interrupt basta un poco di algebra booleana sullo stato dei pin (anch'esso in un registro) rispetto all'interrupt precedente Parlo per esperienza personale :)

Vi posto un codice stupidissimo giusto per capirci. Quando intercetto un byte in ingresso scrivo “ACK”.

#include <avr/interrupt.h>

void setup(void)
{
sei();
}

void loop(void)
{
}

ISR(USART_RX_vect)
{
Serial.println(“ACK”);
}

Ovviamente non funzione, il compilatore resta in copilazione ma da subito da errore:

java.lang.NullPointerException at processing.app.debug.Compiler.compile(Compiler.java:75) at processing.app.Sketch.build(Sketch.java:1412) at processing.app.Sketch.compile(Sketch.java:1203) at processing.app.Editor$44.run(Editor.java:1807) at java.awt.event.InvocationEvent.dispatch(InvocationEvent.java:209) at java.awt.EventQueue.dispatchEvent(EventQueue.java:597) at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:269) at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:184) at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:174) at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:169) at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:161) at java.awt.EventDispatchThread.run(EventDispatchThread.java:122)

il codice che uso (modificato al volo per i pin che ti servono, non ho testato se funziona), estrapolato a sua volta da BIRONPILOT V59, di ciskje

#define MASKPCINT16 (1<<0)
#define MASKPCINT17 (1<<1)
voi setup(){
   PCICR |= (1 << PCIE2); //activate interrupt on pin register 2
   PCMSK2 = (1 << PCINT16) | (1 << PCINT17);// unmask digital pin0 and pin1
}

byte _oldbit=0, _newbit, _changed;
ISR(PCINT2_vect) {
  _newbit=PIND; //read the stato of the pin
  _changed=_newbit^_oldbit; //find what pin has changed
  if (_changed&MASKPCINT16){//if digital PIN0 has changed
    if (_newbit&MASKPCINT16) {
       //PIN0 now is high
    }else{
       //PIN0 now is low
    }
  }
  if (_changed&MASKPCINT17){//if digital PIN1 has changed
    if (_newbit&MASKPCINT17) {
       //PIN1 now is high
    }else{
       //PIN1 now is low
    }
  }
  _oldbit=_newbit;//save actuale state of pin
}

Ok, questo codice va sicuramente bene, ma mi permette solo di smascherare gli interrupt sul pin state change e non sulla ricezione dell'intera parola sulla seriale. Mi spiego meglio, io per determinare la ricezione con questa soluzione dovrei usare un contatore il che significa un continuo richiamo a interrupt,se nel codice uso più di un interrupt, ad esempio sull'ADC ottengo come risultato un codice inefficiente. Al contrario invece usando l'interrupt su parola ricevuta io passo 1 volta soltanto invece che le 10 minime necessarie nel codice sopra descritto.

ahhh capito... bhe visto che l'errore di compilazione dello sketch che hai postato non sembra essere da parte del compilatore ma da parte dell'IDE, secondo me dovresti provare a compilare i codice a mano. C'è un file di impostazioni di arduino, in cui puoi impostare un paio di variabili in modo che stampi i comandi al compilatore e ad avrdude, così li puoi fare anche a mano (compilazione e upload) certo è un pò sbatti ma a occhio e croce il NullPointerException sembra proprio un bug dell'IDE

edit: che poi a me da errore:

core.a(HardwareSerial.cpp.o): In function global constructors keyed to rx_buffer': ~/arduino-0021/hardware/arduino/cores/arduino/HardwareSerial.cpp:115: multiple definition of__vector_18' sketch_feb23a.cpp.o:sketch_feb23a.cpp:16: first defined here collect2: ld returned 1 exit status

quindi che è una doppia definizione. secondo me una bella soluzione è, visto che hardwareSerial è una classe, estenderla e fare l'overloading del metodo che ti interessa. Ovviamente poi dovrai richiamare anche il metodo della superclasse perchè le cose funzionino normalmente