Pages: [1]   Go Down
Author Topic: lettura Encoder in quadratura (veloce)  (Read 1509 times)
0 Members and 1 Guest are viewing this topic.
rovigo-ferrara
Offline Offline
Newbie
*
Karma: 0
Posts: 7
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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:
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:
digitalRead(2) ^ digitalRead(4) ? encoder0Pos -- :   encoder0Pos  ++ ;
con questa
Code:
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
Logged

Selvazzano Dentro - Padova
Online Online
Edison Member
*
Karma: 45
Posts: 1414
"Chi sa fa, chi non sa insegna"
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

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

Ettore Massimo Albani
Logged

Riva del Garda, TN / Forlì
Offline Offline
Edison Member
*
Karma: 8
Posts: 2246
Il piu' modesto al mondo
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

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.
Logged

Il nuovo forum italiano sull'elettronica: http://www.electroit.tk/ <--- Nuovamente online!

0
Offline Offline
Faraday Member
**
Karma: 31
Posts: 2908
Arduino rocks
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Così dovrebbe funzionare:
Code:
( 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.
Logged

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

rovigo-ferrara
Offline Offline
Newbie
*
Karma: 0
Posts: 7
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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

Code:
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
Logged

Riva del Garda, TN / Forlì
Offline Offline
Edison Member
*
Karma: 8
Posts: 2246
Il piu' modesto al mondo
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

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

Code:
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?
Logged

Il nuovo forum italiano sull'elettronica: http://www.electroit.tk/ <--- Nuovamente online!

Global Moderator
Italy
Offline Offline
Brattain Member
*****
Karma: 331
Posts: 22785
Logic is my way
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

@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/
Logged


rovigo-ferrara
Offline Offline
Newbie
*
Karma: 0
Posts: 7
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

@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???
Logged

Pages: [1]   Go Up
Jump to: