Go Down

Topic: lettura Encoder in quadratura (veloce) (Read 1 time) previous topic - next topic

calzand

Buona Domenica a tutti,
ho scritto questo codice per conoscere la posizione di un encoder in quadratura
il canale A e connesso con il PIN 2 che richiama un interrupt ogni volta che cambia stato
il canale B e connesso con il PIN 4 per determinare la direzione

Code: [Select]
volatile int encoder0Pos = 0; // posizione attuale

void setup(){
  Serial.begin(57600);
  pinMode(2, INPUT);
  pinMode(4, INPUT);
  attachInterrupt(0, doEncoderA, CHANGE); // encoder A channel on interrupt 0 (arduino's pin 2)                       

}
void loop(){
  Serial.println(encoder0Pos);
  }

void doEncoderA() { // pin no 2
  digitalRead(2) ^ digitalRead(4) ? encoder0Pos -- :   encoder0Pos  ++ ; // se i due segnali sono uguali  decremente, altrimenti incrementa
//PIND & _BV(2) ^ PIND & _BV(4)  ?  encoder0Pos -- :       encoder0Pos  ++ ;
}


il codice funziona, ma per rendere la routine interrupt più veloce volevo cambiare questa riga
Code: [Select]
digitalRead(2) ^ digitalRead(4) ? encoder0Pos -- :   encoder0Pos  ++ ;
con questa
Code: [Select]
PIND & _BV(2) ^ PIND & _BV(4)  ?  encoder0Pos -- :    encoder0Pos  ++ ;
andando a leggere direttamente lo stato dei PIN
in questo caso girando l'encoder in un senso encoder0Pos diminuisce, girando nell'altro senso varia da 0 a 1 poi 0 poi 1 .......

Mi sfugge qualcosa? cosa non và?
grazzie a tutti

cyberhs

Non vorri sbagliare, ma se inserisci anche il pin 4 sotto interrupt avresti la moltiplicazione x4 della risoluzione dell'encoder.

Ettore Massimo Albani

superlol

prova a sostituire i _BV con 1<<

lo so è la stessa cosa ma mi pareva di aver letto che non si estende a tutti i chip o una roba simile.
Il nuovo forum italiano sull'elettronica: http://www.electroit.tk/ <--- Nuovamente online!

Così dovrebbe funzionare:
Code: [Select]

( PIND & _BV(2) ) ^ ( PIND & _BV(4) )  ?  encoder0Pos-- :  encoder0Pos++ ;


Se il risultato della operazione xor (^ or esclusivo) è vero viene eseguito il codice subito dopo il "?", se è falso viene eseguito il codice dopo il ":"

Lo xor risulta vero se solo uno dei due operandi è vero, ritorna falso se gli operandi sono entrambe identici, non importa se sono veri o falsi entrambe.

Ciao.
AvrDudeQui front end per avrdude https://gitorious.org/avrdudequi/pages/Home

calzand

o provato con le parentesi ma niente da fare.
l'unico sistema è cambiare CHANGE con FALLING

Code: [Select]
attachInterrupt(0, doEncoderA, FALLING );

però in questa maniera si ottiene una lettura 1X

deve esserci qualche problema di tempo di salita del segnale
grazie a tutti per le risposte

superlol


o provato con le parentesi ma niente da fare.
l'unico sistema è cambiare CHANGE con FALLING

Code: [Select]
attachInterrupt(0, doEncoderA, FALLING );

però in questa maniera si ottiene una lettura 1X

deve esserci qualche problema di tempo di salita del segnale
grazie a tutti per le risposte

hai provato mettendo delle resistenze di pullup?
Il nuovo forum italiano sull'elettronica: http://www.electroit.tk/ <--- Nuovamente online!

leo72

@calzand:
la funzione attachInterrupt, anche se sul reference c'è scritto diversamente, gestisce solo FALLING, RASING e LOW. Se vuoi usare lo stato CHANGE, devi usare la libreria PinChangeInt:
http://code.google.com/p/arduino-pinchangeint/

calzand


@calzand:
la funzione attachInterrupt, anche se sul reference c'è scritto diversamente, gestisce solo FALLING, RASING e LOW. Se vuoi usare lo stato CHANGE, devi usare la libreria PinChangeInt:
http://code.google.com/p/arduino-pinchangeint/



Questo non è vero sui pin 2 e 3 (INT0 e INT1) CHANGE funziona!
mettendo CHANGE conto sia i fronti di salita che di discesa e ottengo il doppio dei conteggi rispetto a FALLING o RISING
questo facendo la lettura con digitalRead

se faccio la lettura direttamente dal registro PIND & _BV(2) o PIND &(1<<PIND2) (che è la stessa cosa) funziona solo con FALLING (lettura 1x) e non con RISING e CHANGE.

Ho attivato le resistenze di PULL-UP interne ma non cambia niente.
Ho provato a scrivere codice direttamente da AVRstudio poi a caricare .hex nell'arduino, stesso comportamento.

digitalRead che altre operazioni fà oltre che a scrivere sulla porta???

Go Up
 


Please enter a valid email to subscribe

Confirm your email address

We need to confirm your email address.
To complete the subscription, please click the link in the email we just sent you.

Thank you for subscribing!

Arduino
via Egeo 16
Torino, 10131
Italy