Ragazzi il problema non è stato risolto ma ci sono stati questi sviluppi:
Sono ripartito da zero e ho pensato che avevo necessità di leggere gli encoder nel miglior modo possibile e ho deciso quindi di usare due interrupt per la migliore lettura possibile (pin 2 e 3).
Mi riferisco ai problemi di "spazio" e Pin occupati... =(
Sono riuscito ad avere una lettura abbastanza pulita ma ho un dubbio:
Serial.print([b]angle*8.25[/b], 4);
ho osato correggere il valore in gradi che viene stampato a video moltiplicandolo per 8.25 secondo quanto dedotto da informazione pescate online...
We have 12 slits in encoder, and motor to encoder gear reduction is 10:32. So for 1 turn of output hub, encoders turns 48*10/32=15 turns, optical detectors sees 15*12=180 slits. Using both sides of slits gives nominal 360 ticks per turn resolution. Note that since we have a quadrature encoder, the maximum resolution is 720 ticks/turn
da qui: NXT® motor internals
Quando il mio counter segna 720---il valore in gradi che stampa il mio programma è 0.06118.25=0.5 e 0.5720 cioè alla tacca 720 mi dà 360°... almeno credo... sbaglio? a cosa è dovuta la necessità di una correzione?
//arduino uno---un motore lego nxt---un ponte H L293D;
//il motore lego ha 6 fili: nero e bianco x l'alimentazione e gli altri tre per la lettura l'encoder; giallo e blu sn i //segnali dell'encoder rosso è la massa dell'encoder e verde l'alimentazione 5v dell'encoder.
//Questo programma fa girare al max in un verso per testare il comportamento dell'encoder
#include <MotorNXT.h>
//MOTORE 1
int motorIN1 = 7;
int motorIN2 = 8;
int eneblePin = 9; //il ponte H controlla in pwm il motore
//VARIABILI ENCODER
volatile int position = 0;
volatile float angle = 0;
volatile float angle_previous = 0;
volatile float angle_post = 0;
MotorNXT motorNXT(motorIN1, motorIN2, eneblePin, 2, 3);
void setup() {
attachInterrupt(0, doEncoderA, CHANGE);
attachInterrupt(1, doEncoderB, CHANGE);
Serial.begin(115200);
pinMode(motorIN1, OUTPUT);
pinMode(motorIN2, OUTPUT);
pinMode(eneblePin, OUTPUT);
digitalWrite(eneblePin, LOW);
}
void loop() {
Serial.print("counter: ");
Serial.print(position, DEC);
Serial.print(" - ");
Serial.print("angle: ");
Serial.print([b]angle*8.25[/b], 4); // (x,4) stampa 4 cifre dopo la virgola
Serial.println(";");
digitalWrite(motorIN2, HIGH);
digitalWrite(motorIN1, LOW);
analogWrite(eneblePin, 255);
}
void doEncoderA(){ // interrupt 0 function
if (digitalRead(2) == HIGH) { // look for a low-to-high on channel A
if (digitalRead(3) == LOW) { // check channel B to see which way encoder is turning
position = position + 1;
}
else {
position = position - 1;
}
}
else { // must be a high-to-low edge on channel A
if (digitalRead(3) == HIGH) { // check channel B to see which way encoder is turning
position = position + 1;
}
else {
position = position - 1;
}
}
angle = 0.00105*position; // unit: radian
angle=angle*57.295; //unit:degree
}
void doEncoderB(){ // interrupt 1 function
if (digitalRead(3) == HIGH) { // look for a low-to-high on channel B
if (digitalRead(2) == HIGH) { // check channel A to see which way encoder is turning
position = position + 1;
}
else {
position = position - 1;
}
}
else { // must be a high-to-low edge on on channel B
if (digitalRead(2) == LOW) { // check channel B to see which way encoder is turning
position = position + 1;
}
else {
position = position - 1;
}
}
angle = 0.00105*position; // unit: radian
angle= angle*57.295; //unit:degree
}
Il problema mi si ripresenta seppur in forma diversa: invece che i due necessari per l'encoder (ho esaurito i pin di tipo digitale) , ora sono costretto a implementare un interruptsu di un pin analogico (sn tutti liberi) con la PinChangeInt per leggere la mia IMU MPU6050.
Non sto a ripostare tutto il codice, ma faccio riferimento a quello in due parti messo nei post precedenti. Il punto è che dopo la stampa di un solo valore esce dal loop e non stampa più; potrebbe essere un semplice problema di codice dovuto ad un errore mio dato che ho soltanto sostituito questo:
attachInterrupt(0, dmpDataReady, RISING); // the 0 points correctly to INT0 / D2
// -> if there is an interrupt from MPU-6000 to ATMEGA328, boolean mpuInterrupt will be made true
con questo:
#define PIN1 14 //voglio usare il pin A0
void quicfunc1() {
latest_interrupted_pin=PCintPort::arduinoPin;
interrupt_count[latest_interrupted_pin]++;
};
//e aggiungendo nel void setup() {
pinMode(PIN1, INPUT); digitalWrite(PIN1, LOW);
PCintPort::attachInterrupt(PIN1, &quicfunc1, RISING);
e dato che il programma funzionava perfettamente non capisco... ho provato anche con CHANGE...
(ho incluso la libreria)
E poi dato che stampa un valore corretto significa che un interrupt arriva, ma dopo non ne vengono chiamati altri può essere? Secondo voi dove sbaglio?