ich:
es geht nicht ohne Multitasking -
wenn du einen Lego Encodermotor besitzt, probier es aus -
mit Lesen von nur 1 QE: geht es,
kommt ein 2. dazu: keine Chance.
Der Grund:
zwischen den einzelnen Encoder-Lesefunktionen müssen zu viele andere Aktionen erledigt werden, und bis das nächste Mal der QE ausgelesen werden kann, wurden schon zu viele Signale übersehen.
#define MAXMOTORS 2
#define OUT_A 0
#define OUT_B 1
// set motor pins
#define pinmenc0A 2
#define pinmenc0B 3
#define pinmot0d1 4
#define pinmot0d2 5
#define pinmot0pwm 6
#define pinmenc1A 7
#define pinmenc1B 8
#define pinmot1d1 9
#define pinmot1d2 10
#define pinmot1pwm 11
long motenc[MAXMOTORS]={0,0},
oldenc[MAXMOTORS]={0,0};
byte pinmotdir[MAXMOTORS][2]={ {pinmot0d1, pinmot0d2},
{pinmot1d1, pinmot1d2} };
int pinmotpwm[MAXMOTORS]={pinmot0pwm, pinmot1pwm};
//------------------------------------------------------------------------------------
// read encoder: "Entnommen aus http://www.meinDUINO.de"
int8_t altAB = 0;
// 1/1 Auflösung
//int8_t schrittTab[16] = {0,-1,1,0,1,0,0,-1,-1,0,0,1,0,1,-1,0};
// 1/4 Auflösung
int8_t schrittTab[16] = {0,0,0,0,0,0,0,-1,0,0,0,0,0,1,0,0};
//----------------------------------------------------------------------------------------
int8_t readEncoder(int pinA, int pinB) {
altAB <<= 2;
altAB &= B00001100;
altAB |= (digitalRead(pinA) << 1) | digitalRead(pinB);
return(schrittTab[altAB]);
}
//-----------------------------------------------------------------------------------------
void idle(unsigned int ms) {
for (int t=0; t<(ms*5); ++t) { // to be adjusted !
motenc[0] += readEncoder(pinmenc0A, pinmenc0B);
motenc[1] += readEncoder(pinmenc1A, pinmenc1B);
if( motenc[0] != oldenc[0] ) oldenc[0] = motenc[0];
if( motenc[1] != oldenc[1] ) oldenc[1] = motenc[1];
delayMicroseconds(100);
}
}
//-----------------------------------------------------------------------------------------
//-----------------------------------------------------------------------------------------
inline void motoroff(byte motnr) {
digitalWrite( pinmotdir[motnr][0],LOW);
digitalWrite( pinmotdir[motnr][1],LOW);
analogWrite(pinmotpwm[motnr],0);
}
//-----------------------------------------------------------------------------------------
inline void motorcoast(byte motnr) {
digitalWrite( pinmotdir[motnr][0],LOW);
digitalWrite( pinmotdir[motnr][1],LOW);
analogWrite(pinmotpwm[motnr],0);
}
//-----------------------------------------------------------------------------------------
inline void motoron(byte motnr, int power) {
if(power>0) {
digitalWrite( pinmotdir[motnr][0],HIGH);
digitalWrite( pinmotdir[motnr][1],LOW);
}
else
if(power<0) {
digitalWrite( pinmotdir[motnr][0],LOW);
digitalWrite( pinmotdir[motnr][1],HIGH);
}
else
if(power==0) {
digitalWrite( pinmotdir[motnr][0],LOW);
digitalWrite( pinmotdir[motnr][1],LOW);
}
power = abs(power);
if(power>254) power=254;
analogWrite(pinmotpwm[motnr],power);
}
//-----------------------------------------------------------------------------------------
//-----------------------------------------------------------------------------------------
void setup(){
pinMode(pinmot0d1,OUTPUT);
pinMode(pinmot0d2,OUTPUT);
pinMode(pinmenc0A,INPUT_PULLUP);
pinMode(pinmenc0B,INPUT_PULLUP);
pinMode(pinmot0pwm,OUTPUT);
pinMode(pinmot1d1,OUTPUT);
pinMode(pinmot1d2,OUTPUT);
pinMode(pinmenc1A,INPUT_PULLUP);
pinMode(pinmenc1A,INPUT_PULLUP);
pinMode(pinmot0pwm,OUTPUT);
Serial.begin(115200);
}
//----------------------------------------------------------------------------------------
void loop(){
// motor 0 + motor 1
for (int i=0; i<255; i+=5){
motoron(0, i);
motoron(1, i);
motenc[0] += readEncoder(pinmenc0A, pinmenc0B);
motenc[1] += readEncoder(pinmenc1A, pinmenc1B);
if( motenc[0] != oldenc[0] ) oldenc[0] = motenc[0];
if( motenc[1] != oldenc[1] ) oldenc[1] = motenc[1];
Serial.print(motenc[0]); Serial.print(" - "); Serial.println(motenc[1]);
idle(100);
}
motoroff(0);
motoroff(1);
idle(10);
motenc[0] += readEncoder(pinmenc0A, pinmenc0B);
motenc[1] += readEncoder(pinmenc1A, pinmenc1B);
if( motenc[0] != oldenc[0] ) oldenc[0] = motenc[0];
if( motenc[1] != oldenc[1] ) oldenc[1] = motenc[1];
Serial.print(motenc[0]); Serial.print(" - "); Serial.println(motenc[1]);
idle(500);
for (int i=0; i>-255; i-=5){
motoron(0, i);
motoron(1, i);
motenc[0] += readEncoder(pinmenc0A, pinmenc0B);
//motenc[1] += readEncoder(pinmenc1A, pinmenc1B);
if( motenc[0] != oldenc[0] ) oldenc[0] = motenc[0];
if( motenc[1] != oldenc[1] ) oldenc[1] = motenc[1];
Serial.print(motenc[0]); Serial.print(" - "); Serial.println(motenc[1]);
idle(100);
}
// ohne bremsen
Serial.print(motenc[0]); Serial.print(" - "); Serial.println(motenc[1]);
idle(500);
}
Rabenauge:
Dafür gibts Interrupts. 8)
:?:
das klingt hoffnungsvoll -
dann zeig doch mal bitte, wie das geht, damit man keine Impulse an den digipins der Encoder (2/3 + 7/8) übersieht und daraus auch den Encoderstand korrekt berechnen kann!