Encoders no movimento simples de robot 2WD com PWM ajustado

 

Programa

demo_2wd_pwm_variable_encoders

#define serialSpeed 115200

#define bodyLeftMotorPwmRef 110
#define bodyRightMotorPwmRef 130

#define bodyLeftMotorPwmMin 90
#define bodyRightMotorPwmMin 110

#define bodyLeftMotorPwmMax 210
#define bodyRightMotorPwmMax 230

#define steeringFactor 0.9

// encoder type
#define bodyEncoderSJ01 true
#define bodyEncoderHC020K false
#define bodyEncoderLM393 false

#if bodyEncoderSJ01
#define bodyEncoderSignal CHANGE
#define bodyEncoderInputSignal INPUT
#endif
#if bodyEncoderHC020K
#define bodyEncoderSignal FALLING
#define bodyEncoderInputSignal INPUT_PULLUP
#endif
#if bodyEncoderLM393
#define bodyEncoderSignal RISING
#define bodyEncoderInputSignal INPUT
#endif

// motor one
#define enA 5
#define in1 4
#define in2 7
// motor two
#define enB 6
#define in3 8
#define in4 12

// LeftMotor
#define bodyLeftMotorEn enA
#define bodyLeftMotorForward in1
#define bodyLeftMotorBackward in2

// RightMotor
#define bodyRightMotorEn enB
#define bodyRightMotorForward in4
#define bodyRightMotorBackward in3

// encoder LeftMotor
#define bodyEncoderLeftInt 0
#define bodyEncoderLeftFunction bodyEncoderLeftCounter
#define bodyEncoderLeftPin 2 // A pin the interrupt pin
#if bodyEncoderSJ01
#define bodyEncoderLeftPinB 9 // B pin: the digital pin
#endif
#define bodyEncoderLeftSignal bodyEncoderSignal
#define bodyEncoderLeftInputSignal bodyEncoderInputSignal

// encoder RightMotor
#define bodyEncoderRightInt 1
#define bodyEncoderRightFunction bodyEncoderRightCounter
#define bodyEncoderRightPin 3 // A pin: the interrupt pin
#if bodyEncoderSJ01
#define bodyEncoderRightPinB 10 // B pin: the digital pin
#endif
#define bodyEncoderRightSignal bodyEncoderSignal
#define bodyEncoderRightInputSignal bodyEncoderInputSignal

#if bodyEncoderSJ01
byte bodyEncoderLeftPinLast;
boolean bodyEncoderLeftDirection; // the rotation direction
byte bodyEncoderRightPinLast;
boolean bodyEncoderRightDirection; //the rotation direction 
#endif

volatile signed long bodyEncoderLeftTotalPulses = 0;
volatile signed long bodyEncoderRightTotalPulses = 0;

unsigned long loopTimeStart = 0;

void setup() {
Serial.begin(serialSpeed); //Initialize the serial port

pinMode(bodyLeftMotorEn, OUTPUT);
pinMode(bodyLeftMotorForward, OUTPUT);
pinMode(bodyLeftMotorBackward, OUTPUT);
pinMode(bodyRightMotorEn, OUTPUT);
pinMode(bodyRightMotorForward, OUTPUT);
pinMode(bodyRightMotorBackward, OUTPUT);


#if bodyEncoderSJ01
bodyEncoderLeftDirection = true; //default -> Forward 
pinMode(bodyEncoderLeftPinB, bodyEncoderLeftInputSignal); 
#endif
attachInterrupt(bodyEncoderLeftInt, bodyEncoderLeftFunction, bodyEncoderLeftSignal);

#if bodyEncoderSJ01
bodyEncoderRightDirection = true; // default -> Forward 
pinMode(bodyEncoderRightPinB, bodyEncoderRightInputSignal); 
#endif
attachInterrupt(bodyEncoderRightInt, bodyEncoderRightFunction, bodyEncoderRightSignal);

delay(3000);

loopTimeStart = millis();

}

void loop() {
unsigned long loopTime = 0;

signed long steeringError = 0;
unsigned int bodyLeftMotorPwmOut = 0;
unsigned int bodyRightMotorPwmOut = 0;

// set direction
setBodyMotorLeftForward();
setBodyMotorRightForward();

// calculate pwm output
steeringError = abs(bodyEncoderLeftTotalPulses) - abs(bodyEncoderRightTotalPulses);

bodyLeftMotorPwmOut = bodyLeftMotorPwmRef - (steeringError * steeringFactor);
bodyRightMotorPwmOut = bodyRightMotorPwmRef + (steeringError * steeringFactor);

if(bodyLeftMotorPwmOut < bodyLeftMotorPwmMin) bodyLeftMotorPwmOut = bodyLeftMotorPwmMin;
if(bodyRightMotorPwmOut < bodyRightMotorPwmMin) bodyRightMotorPwmOut = bodyRightMotorPwmMin;

if(bodyLeftMotorPwmOut > bodyLeftMotorPwmMax) bodyLeftMotorPwmOut = bodyLeftMotorPwmMax;
if(bodyRightMotorPwmOut > bodyRightMotorPwmMax) bodyRightMotorPwmOut = bodyRightMotorPwmMax;

// set speed
analogWrite(bodyLeftMotorEn, bodyLeftMotorPwmOut);
analogWrite(bodyRightMotorEn, bodyRightMotorPwmOut);

// display info
//Serial.print(abs(bodyEncoderLeftTotalPulses)); Serial.print("\t");
//Serial.print(abs(bodyEncoderRightTotalPulses)); Serial.print("\t");
Serial.print((float)bodyLeftMotorPwmOut/10.0); Serial.print("\t"); // divided for scale display
Serial.print((float)bodyRightMotorPwmOut/10.0); Serial.print("\t"); // divided for scale display
Serial.print(steeringError); Serial.print("\t");
Serial.print(steeringError * steeringFactor); Serial.print("\t");
Serial.println("");

// end loop
loopTime = millis() - loopTimeStart; 
loopTimeStart = millis();
}


void bodyEncoderLeftCounter()
{
#if bodyEncoderSJ01
int Lstate = digitalRead(bodyEncoderLeftPin);
if((bodyEncoderLeftPinLast == LOW) && Lstate==HIGH)
{
int val = digitalRead(bodyEncoderLeftPinB);
if(val == LOW && bodyEncoderLeftDirection)
{
bodyEncoderLeftDirection = false; //Reverse
}
else if(val == HIGH && !bodyEncoderLeftDirection)
{
bodyEncoderLeftDirection = true; //Forward
}
}
bodyEncoderLeftPinLast = Lstate;

if(!bodyEncoderLeftDirection)
{
bodyEncoderLeftTotalPulses++;
} else {
bodyEncoderLeftTotalPulses--;
}
#else
bodyEncoderLeftTotalPulses ++;
#endif
}

void bodyEncoderRightCounter()
{
#if bodyEncoderSJ01
int Lstate = digitalRead(bodyEncoderRightPin);
if((bodyEncoderRightPinLast == LOW) && Lstate==HIGH)
{
int val = digitalRead(bodyEncoderRightPinB);
if(val == LOW && bodyEncoderRightDirection)
{
bodyEncoderRightDirection = false; // Reverse
}
else if(val == HIGH && !bodyEncoderRightDirection)
{
bodyEncoderRightDirection = true; // Forward
}
}
bodyEncoderRightPinLast = Lstate;

if(!bodyEncoderRightDirection)
{
bodyEncoderRightTotalPulses ++; 
} else {
bodyEncoderRightTotalPulses --; 
}
#else
bodyEncoderRightTotalPulses ++; 
#endif
}

void setBodyMotorLeftForward() {
digitalWrite(bodyLeftMotorForward, HIGH);
digitalWrite(bodyLeftMotorBackward, LOW);
}

void setBodyMotorRightForward() {
digitalWrite(bodyRightMotorForward, HIGH);
digitalWrite(bodyRightMotorBackward, LOW);
}

end