Posizione e velocità di un motore dc con encoder

Buongiorno,
ho un motore dc a spazzole (12V, 6W) con encoder incrementale calettato sull'albero. Il mio obiettivo è leggere i valori di posizione e velocità in determinati istanti di tempo per poi tracciare una caratteristica del motore. Ho scaricato la Quadrature Encoder Library, che tra gli esempi mi suggerisce il seguente codice:

#include <Encoder.h>
Encoder myEnc(5, 6);
void setup() {
  Serial.begin(9600);
  Serial.println("Basic Encoder Test:");
}

long oldPosition  = -999;

void loop() {
  long newPosition = myEnc.read();
  if (newPosition != oldPosition) {
    oldPosition = newPosition;
    Serial.println(newPosition);
  }
}

Non mi è chiaro perchè oldPosition venga inizializzata a -999.
Inoltre, se volessi leggere la velocità del motore, cosa dovrei implementare?
È sicuramente una domanda banale, ma sono alle prime armi.
Grazie.

1 - non conosco la libreria ma gli decoder si.
2 - penso che puoi inizializzare oldPosition anche con 0
3 - puoi leggere la velocità del motore cronometrando il tempo che intercorre tra oldPosition e newPosition (suppongo)
4 - devi sapere a quanti gradi corrispondono lo spostamento dalla lettura A dell'ancoder alla lettura B.
un po di matematica e "dovresti" essere in grado di ottenere quello che cerchi..

Sono mie supposizioni...

Io la butto sul piatto: mi sa che la libreria fa partire il conteggio da zero, inizializzare il valore vecchio permette di non perdere la prima lettura. Cmq basta provare

Standardoil:
Io la butto sul piatto: mi sa che la libreria fa partire il conteggio da zero, inizializzare il valore vecchio permette di non perdere la prima lettura. Cmq basta provare

Confermo, è così.
Per quanto riguarda la velocità? Non esiste una "funzione derivata", vero?

No, ma te la crei, cominci con fare la differenza tra due successive letture, se vuoi maggiore precisione per ogni lettura memrizzi il valore di millis e lo usi per fare la divisioni

Standardoil:
Io la butto sul piatto: mi sa che la libreria fa partire il conteggio da zero, inizializzare il valore vecchio permette di non perdere la prima lettura. Cmq basta provare

quindi può mettere il valore che vuole tranne che 0? ::slight_smile:

andreaven31:
Confermo, è così.
Per quanto riguarda la velocità? Non esiste una "funzione derivata", vero?

no. la velocità come ben sai è spazio/tempo
come suggerito prima, il tempo lo devi cronometrare con millis() tra oldPosition e newPosition.
per lo spazio devi sapere ogni quanti gradi l'encoder cambia da impulso A ad impulso B oppure quanti scambi ci sono in un giro completo.
ad esempio se ci sono 20 step in un giro e ci mette tot millis() per contarli saprai che il motore sta girando a Xrpm. calcolando la velocità di rotazione ne deriva il fatto che puoi sapere in ogni momento la posizione precisa dell'albero...
Ma attenzione: non ho aperto quella libreria ma sembra che comunque gestisca l'encoder tramite interrupts() che crea (che io sappia, prego i big di contraddirmi se dico una castronata) dei "problemi" con millis() e altre funzioni come ad esempio comunicazione seriale...
Ripeto prendi con le pinze questa mia affermazione...
EDIT: chiedo scusa. appena letto qua e la, non ci sono problemi per come è scritto il codice da te postato poiché andresti a gestire il cronometro al di fuori dell'attachInterrupt().

miky_police:
quindi può mettere il valore che vuole tranne che 0? ::)no. la velocità come ben sai è spazio/tempo
come suggerito prima, il tempo lo devi cronometrare con millis() tra oldPosition e newPosition.
per lo spazio devi sapere ogni quanti gradi l'encoder cambia da impulso A ad impulso B oppure quanti scambi ci sono in un giro completo.
ad esempio se ci sono 20 step in un giro e ci mette tot millis() per contarli saprai che il motore sta girando a Xrpm. calcolando la velocità di rotazione ne deriva il fatto che puoi sapere in ogni momento la posizione precisa dell'albero...
Ma attenzione: non ho aperto quella libreria ma sembra che comunque gestisca l'encoder tramite interrupts() che crea (che io sappia, prego i big di contraddirmi se dico una castronata) dei "problemi" con millis() e altre funzioni come ad esempio comunicazione seriale...
Ripeto prendi con le pinze questa mia affermazione...
EDIT: chiedo scusa. appena letto qua e la, non ci sono problemi per come è scritto il codice da te postato poiché andresti a gestire il cronometro al di fuori dell'attachInterrupt().

Tralasciando per un attimo la velocità, quel codice mi restituisce una serie di valori "0 1 0 1 0 1 0 1...". Il mio encoder ha 100 counts/giro. Come ottengo il valore rpm?
Dal datasheet non riesco a capire ogni quanti gradi l'encoder cambia tra i due impulsi, come da te suggerito.

andreaven31:
Tralasciando per un attimo la velocità, quel codice mi restituisce una serie di valori "0 1 0 1 0 1 0 1...". Il mio encoder ha 100 counts/giro. Come ottengo il valore rpm?
Dal datasheet non riesco a capire ogni quanti gradi l'encoder cambia tra i due impulsi, come da te suggerito.

o che misuri il tempo tra 2 impulsi (per giri bassi) oppure conti gli impulsi in un intervallo di tempo dato.

uwefed:
o che misuri il tempo tra 2 impulsi (per giri bassi) oppure conti gli impulsi in un intervallo di tempo dato.

E per gli 1010... consecutivi?

E visto che vuoi sapere anche la posizione assoluta devi anche contare gli impulsi e se il motore gira in entrambi i sensi anche la direzione. Devi avere un sensore che Ti da uno zero o home del movimento.
Ciao Uwe

miky_police:
ad esempio se ci sono 20 step in un giro e ci mette tot millis() per contarli saprai che il motore sta girando a Xrpm. calcolando la velocità di rotazione ne deriva il fatto che puoi sapere in ogni momento la posizione precisa dell'albero...

ovviamente mentre leggi quanto tempo passa tra un oldPosition e un newPosition li conti pure così sai la posizione assoluta...
::slight_smile:

Devi conoscere quanti impulsi per giro genera l'encoder. Supponi di misurare 300ms / giro (1200 impulsi) e cioe' il tempo che intercorre tra il primo e l'ultimo impulso dichiarato dal costruttore dell'encoder per una rivoluzione completa di 360 gradi. A questo punto la frequenza sara' 1/300ms=3,33 giri/sec che corrispondono a 1998 giri/minuto (rpm). Per la misura basta usare una sola fase dell'encoder, un interrupt esterno ad esempio sul fronte di salita, e un timer che viene fatto partire da zero e fermato alla fine del conteggio del numero di impulsi dichiarati per giro.