A tutt'oggi non avevo mai avuto la necessità/opportunità di usare un Interrupt per cui chiedo anticipatamente scusa per l'ingenuità della domanda.
Mi trovo a voler utilizzare un interrupt, non comandato da un pulsante, ma dalla ricezione di dati tramite HC-12.
In pratica all'arrivo di qualsiasi dato tramite HC-12 dovrebbe interrompere tutto e (per la prova di funzionamento) accendere un Led.
Qualcuno ha già avuto esperienze in tal senso? Nelle prove fatte mi pare di aver capito che il led lampeggia per un brevissimo istante (pochi millsecondi) e poi rimane spento.
In fase di sviluppo TX e RX sono collegati al PC, poi saranno autonomi
TX 2 e 3, RX 4 e 3
qualsiasi carattere va bene.
La necessità è dovuta al fatto che il programma RX completo è decisamente massiccio e la trasmissione non è continua, ma avviene ogni 41 sec. ca. per cui perdo alcune di queste.
dalla nostra esperienza se il programma è "pesante" la soluzione non è un interrupt, ma semplificare il programma
comunque la soluzione interrupt è semplice:
due strade
Io dico: collega il filo rx anche ad un altro pin di arduino, che abbia gli interrupt e abilita interrupt falling, se non hai pin con interrupt liberi cambia quelli della seriale software, che non hanno bisogni particolari
Fabio dice:
modifica la libreria della seriale software, che già usa gli interrupt change, per fare si che chiami la tua ISR
ma non siamo per nulla fiduciosi, se il programma è pesante la papera non galleggia
non ho mai capito perché se la Nano è elettronicamente praticamente uguale alla UNO serve avere un bootloader differente, addirittura due in concorrenza tra loro
Mah ... era nata con un bootloader (old bootloader) poi sostituito da Optiboot come sulla UNO. Se le compri oggi sono come la UNO, se compri cloni cinesi a basso costo, spesso montano ancora il vecchio bootloader.
Mai capito perché, inizialmente, ne hanno fatti due diversi ...
Guglielmo
P.S.: I cinesi, per queste cose, fanno solo copia/incolla ... hanno copiato la vecchia e continuano così Considera che i cloni cinesi del PicKit 3 (vecchio programmatore Microchip per i PIC) sono fatti con lo stampino e ... hanno tutti lo stesso numero seriale programmato dentro ... contrariamente agli originali, se cerchi di collegarne due alla stessa macchina, non riesci più a capire quale è uno e quale è l'altro
Lo pensavo anch'io! Ma non è così, normalmente viene visualizzato un orologio su 8 display a 7 segmenti, viene inoltre controllata la data e scritte eventuali variazioni su SD o EEPROM. Appena risolvo il tutto posterò il programma completo per eventuali suggerimenti su come migliorarlo.
il nostro vecchio responsabile qualità ci raccontava della nave copiata "sbagliata"
dai giapponesi, anche loro famosi agli inzi del secolo scorso per copiare senza remore
per farla breve avevavo comperato una nave da un cantiere occidentale, con la clausalo di ricevere tutti i disegni
il costruttore che aveva capito la gabola, ha allegato uan versione dei disegni con i calcoli di bilanciamento e galleggimento sbagliati
appena si sono messi a costrirle in proprio hanno dovuto tirarle sul dal fondo del bacino dove si è rovesciata
e lui ce la passava per veramente accaduta...
Fatto, sono riuscito ad accendere il led, ma al successivo invio dovrebbe spegnersi ... non lo fa. Allego programmi:
RX
/**
Test interrupt (su arduino NANO solo pin 2 e 3)
collegare un RX al pin 2
collegare un led al pin 13
*/
#include <SoftwareSerial.h>
SoftwareSerial mySerial(3, 4); // TX, RX
void setup() {
Serial.begin(9600);
mySerial.begin(9600);
pinMode(5, OUTPUT);
digitalWrite(5, LOW);
delay(300);
mySerial.begin(9600);
delay(200);
mySerial.println("AT+C005");
delay(200);
mySerial.println("AT+P8");
delay(200);
mySerial.println("AT+FU3");
delay(200);
digitalWrite(5, HIGH); // enter transparent mode
pinMode(13, OUTPUT);
}
volatile int stato = LOW; //volatile non può essere cambiata da altre parti di codice
void loop() {
attachInterrupt(digitalPinToInterrupt(2), cambia, FALLING);
if (mySerial.available()) {
Serial.println(stato);
delay(1000);
}
digitalWrite(13, stato);
}
/*
Funzione di gestione dell'interrupt: non riceve parametri e non
restituisce nulla.
Deve essere rapida e può usare solo variabili volatili e globali
*/
void cambia() {
stato = !stato;
// detachInterrupt(digitalPinToInterrupt(2));
}
TX:
#include <SoftwareSerial.h>
SoftwareSerial mySerial(3, 2); // TX, RX
void setup() {
// Open serial communications and wait for port to open:
Serial.begin(9600);
Serial.println("File: RX_TX_Prova_02_AT");
// set the data rate for the SoftwareSerial port
mySerial.begin(9600);
pinMode(5, OUTPUT);
digitalWrite(5, LOW);
delay(300);
mySerial.begin(9600);
delay(200);
mySerial.println("AT+C005");
delay(200);
mySerial.println("AT+P8");
delay(200);
mySerial.println("AT+FU3");
delay(200);
digitalWrite(5, HIGH); // enter transparent mode
}
void loop() { // run over and over
if (Serial.available()) {
mySerial.write(Serial.read());
}
}
Esattamente quello che pensavo, la trasmissione non si ferma potrei disattivare lo interrupt e riattivarlo nel proseguo del programma o rivedere lo stesso come suggerito da Guglielmo ..... ci devo pensare.
Se puoi spostare alcuni pin ed usare obbligatoriamente per il TX il pin 9 e per il RX il pin 8, allora invece della inefficiente SoftwareSerial potresti usare l'altamente ottimizzata AltSoftSerial (la installi dal Library Manager del IDE) che, tra l'altro, ha tempi di latenza molto più bassi e permette velocità molto più elevate.
Purtroppo non mi è possibile usarla in questo progetto in quanto ho saldato i PIN in quanto le parti funzionavano e smontare tutto è dannatamente complicato. Al momento mi resta solo da verificare la parte SD (HW e SW).