Ciao
faccio questa richiesta in altro modo, visto che in altro topic non ho avuto risposta, il titolo è più specifico e il codice è ridotto al minimo per la comprensione.
Utilizzo la libreria in oggetto su arduino nano per generare una freq. di 125 KHz, noto però diversi malfunzionamenti che spariscono se diminuisco la frequenza a circa 80 KHz.
Ho messo nel loop solo il lampeggio di un led, che utilizzando un delay funziona correttamente, ma se utilizzo millis non funziona (se abbasso la frequenza, millis funziona regolarmente).
Non ho notato interferenze nei timer, visto che millis lavora col timer0, mentre la libreria TimerOne sta utilizzando il timer1.
Qualcuno si è imbattuto in questi problemi? Test_TimerOne_Nano.ino (2.8 KB)
Ciao. Purtroppo non ho la minima idea di come risolvere il tuo problema...
Ti rispondo solo per "solidarietà"... Così la discussione torna in cima e qualcuno più ferrato magari la vede.
Ciao
ahhahahahha, grazie per la solidarietà purtroppo non trovo info nemmeno in rete, è strana questa cosa, visto che è pubblicato anche nel reference di arduino stesso; è specificato di non far fare tante cose alla funzione richiamata dall'interrupt perchè con tempi brevi non ci sarebbe il tempo di eseguirla, ma non mi pare ci siano tante cose da fare...
Vediamo se qualcuno ci capisce qualcosa
Ciao,
perchè voglio fare una cosa che non so fare
Ero felice di aver trovato un codice pronto, che utilizzava una libreria non di terze parti, perciò pensavo non avesse problemi; utilizzando il timer direttamente, oltre a impostarlo, non so nemmeno come fare la funzione collegata, devo andarmi a studiare il tutto e non sono sicuro di farcela.
Se partivo da una base funzionante, riuscivo sicuramente a modificarla ed adattarmela.
Se però non ci sono alternative mi metterò a studiare
Rieccomi,
aggiorno la situazione, ho seguito il consiglio di cotestatnt, non sapevo di quel calcolatore, addirittura forma il codice completo, bellissimo
Ho aggiustato un poco il codice e applicato usando il timer direttamente, ma con sorpresa la situazione è la medesima, stessi identici problemi che utilizzando la libreria.
A questo punto mi viene in mente che il codice nell'interrupt sia troppo grande, ma non saprei come calcolarlo e nemmeno come poterlo ridurre...
Allego il nuovo Sketch Timer1_Nano.ino (2.4 KB)
da quel che so tutte le variabili usate nelle ISR, od almeno quelle che modifichi in essa, devono essere qualificate con "volatile"; poi nella ISR fai una lettura ed una scrittura di un (due) PIN con i metodi digitalRead() e digitalWrite()...se proprio non puoi portarle nel loop() prova a fare la lettura e la scrittura diretta delle relative porte.
Mi sa che il problema di fondo è proprio questo. Per eseguire queste istruzioni, il micro impiega circa 4/5 microsecondi con un ATmega328 a 16Mhz
Per avere un segnale da 125Khz significa che la Interrupt Service Routine deve durare meno di 8uS ed è evidente che hai pochissimo margine.
Ciao,
pensavo era scomodo il codice quà, invece torna meglio? Forse per chi utilizza il telefono? Lo metto, nessun problema
Orso, posso provare a dichiarare le variabili come volatile, ma non ho capito il resto del discorso, scusami...
Se poi il problema è il tempo per eseguire le istruzioni, non saprei come fare (a parte il discorso che almeno da due siti diversi ho trovato questo sketch e pare che lo hanno utilizzato, quindi come??? Sono post vecchi, non so se il titolare risponde, posso provare)
Seconda cosa, a quanto ho capito, ogni impulso dell'onda a 125 KHz devo anche leggere l'impulso che ritorna e fare la lettura secondo la codifica Manchester, non avrei idea come farlo fuori dall'interrupt (il progetto è un lettore rfid)
Questo il codice ridotto al minimo per fare i test, ora provo con le var volatile:
#define ledr 13
#define maxBuf 50
#define streamBuf 50
byte inPin = 2; // ingresso dati
int lett; // ci salvo lettura del pin ingresso
int bitlenctr = 0;
int curState = 0;
int raw[maxBuf];
int rawZ[maxBuf];
int index = 0;
int indexZ = 0;
boolean lamp_on = false; // per sapere se led on
unsigned long lampeggio; // millis
void setup()
{
Serial.begin(19200);
setupTimer1();
pinMode(ledr, OUTPUT);
pinMode(inPin, INPUT);
digitalWrite(ledr, 1);
delay(500);
Serial.println("");
Serial.println("");
Serial.println("Test interrupt Timer1");
Serial.println("");
digitalWrite(ledr, 0);
delay(100);
lampeggio = millis();
}
ISR(TIMER1_COMPA_vect)
{
lett = digitalRead(inPin); // leggo l'ingresso
bitlenctr++; // aumento di 1 la var
if (lett != curState) //se il valore è diverso dal precedente
{
curState = lett; // salvo il valore in curstate
if (lett == 1) // se val è 1
{
if (index < maxBuf) // e se index è meno di 100
{
raw[index++] = bitlenctr; // salvo il valore
}
bitlenctr = 1; // assegno il valore 1 alla var
}
if (index > 1 && lett == 0) // se val è 0 e index magg di 1
{
if (indexZ < maxBuf) // e se indexZ è meno di 100
{
rawZ[indexZ++] = bitlenctr; // salvo il valore
}
bitlenctr = 1; // assegno il valore 1 alla var
}
}
}
void loop()
{
if ((millis() - lampeggio) >= 500) // tempo lampeggio
{
if (lamp_on == false) // se led spento
{
digitalWrite(ledr, HIGH); // accendo led
lamp_on = true; // avviso led on
}
else // se led acceso
{
digitalWrite(ledr, LOW); // spengo led
lamp_on = false; // avviso led off
}
lampeggio = millis(); // azzero millis
}
}
void setupTimer1()
{
noInterrupts();
// Clear registers
TCCR1A = 0;
TCCR1B = 0;
TCNT1 = 0;
// 125000 Hz (16000000/((1+1)*64))
OCR1A = 1;
// CTC
TCCR1B |= (1 << WGM12);
// Prescaler 64
TCCR1B |= (1 << CS11) | (1 << CS10);
// Output Compare Match A Interrupt Enable
TIMSK1 |= (1 << OCIE1A);
interrupts();
}
Si, avevo messo i link in un'altra discussione e non li ho messi quà, il progetto base è questo, in pratica un lettore di tag RFID, dal playground di arduino: Arduino Playground - DIYRFIDReader
L'ho modificato leggermente come spiega in questo sito: 125kHz | Azimuth
per poter leggere i tag ASK (trasmissione in modulazione di ampiezza) anzichè i tag FSK (trasmiss in modulazione di frequenza).
Sostanzialmente l'hardware è il solito, cambia leggermente il software per quanto riguarda la lettura del segnale ricevuto.
In pratica devo leggere l'impulso di risposta del tag, che dovrebbe seguire l'impulso generato da arduino e poi decodificare gli 0 e gli 1.
PS: ho dichiarato le variabili come volatile, ma non era quello il problema, anche perchè la volatile serve per avere stabilità del codice, ma sostanzialmente doveva funzionare comunque.
Spero di essermi spiegato bene