Why made this circuit, PWM-ing the tri-state pins. In data sheet they warned you. This way you are not able to dynamic brake, tristating them, and self induction energy gives spikes, because breaking the freewheel circuit.
All you need to drive is IN1 and IN2. IN1 - PWM non-inverting mode, IN2 - LOW, acts as a buck converter if PWM'ed. If Reversed IN1 - PWM inverting mode, IN2 - HIGH.
We use them in MiniSumo robots since 2008: 33886, 33887, 33932
And tried to find better Idea in controlling algorithm, but were not able to find any.
Here I present my methods for controlling the drivers:
void SetSpeed(signed int SpeedLeft, signed int SpeedRight){
//Constrain speed values
SpeedLeft=constrain(SpeedLeft, -100, 100);
SpeedRight=constrain(SpeedRight, -100, 100);
//Direction control
if(SpeedLeft >= 0){
//Clear OC1B on Compare Match, set OC1B at BOTTOM, (non-inverting mode)
TCCR1A = TCCR1A & 0b11101111;
digitalWrite(IN2, LOW);
}else{
//Convert negative to positive value
SpeedLeft=-SpeedLeft;
//Set OC1B on Compare Match, clear OC1B at BOTTOM, (inverting mode).
TCCR1A = TCCR1A | 0b00110000;
digitalWrite(IN2, HIGH);
}
if(SpeedRight >= 0){
//Clear OC0A on Compare Match, set OC0B at BOTTOM, (non-inverting mode)
TCCR1A = TCCR1A & 0b10111111;
digitalWrite(IN4, LOW);
}else{
//Convert negative to positive value
SpeedRight=-SpeedRight;
//Set OC1B on Compare Match, clear OC1A at BOTTOM, (inverting mode)
TCCR1A = TCCR1A | 0b11000000;
digitalWrite(IN4, HIGH);
}
//Mapping and correction of speed values
if(SpeedLeft>0) SpeedLeft=map(SpeedLeft, 1, 100, 38, 254);
if(SpeedRight>0) SpeedRight=map(SpeedRight, 1, 100, 30, 254);
//Output
analogWrite(IN1, SpeedLeft);
analogWrite(IN3, SpeedRight);
}
And if you get a Status Flag, toggle the D1 or EN/D2:
void StatusFlag(){
boolean driverStatus=digitalRead(SFA)&digitalRead(SFB);
if (driverStatus==LOW && driverState==HIGH){
Serial.print ("Fail Status: ");
Serial.print (digitalRead(SFA), BIN);
Serial.println(digitalRead(SFB), BIN);
Serial.println("DRIVERS_DISABLE");
DRIVERS_DISABLE();
Serial.println("DRIVERS_ENABLE");
DRIVERS_ENABLE();
}
#define DRIVERS_ENABLE() driverState=HIGH; digitalWrite(EN, driverState);
#define DRIVERS_DISABLE() driverState=LOW; digitalWrite(EN, driverState);