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