In case it helps, here is some code I wrote to test a board that I made simlar to yours. It is controlled by 4 buttons for Forward, Reverse, Stop and Emergency Stop (active braking). I also had an interrupt driven rev counter - just don't connect to these inputs and it won't matter at all.
#define STATE_DEBUG 1
#define SPEED_DEBUG 0
#define IN1 5 // input1 on L298
#define IN2 6 // input2 on L298
#define ENA 7 // enable A on L298
#define BUT_FWD 11 // forward
#define BUT_REV 10 // reverse
#define BUT_STOP 9 // stop
#define BUT_ESTOP 8 // e-stop
// RPM counter and ISR
#define PULSE 2 // pulse input from feeback device
#define PULSE_PER_REV 10 // pulses counted per revolution - this depends on the feeback device
#define RPM_CALC_INTERVAL 500 // milliseconds
volatile long pulseCount = 0; // pulse counter
unsigned int motorRPM; // calculated RPM
// Defines for command buttons
#define CMD_ESTOP 0
#define CMD_STOP 1
#define CMD_FWD 2
#define CMD_REV 3
volatile uint8_t Command = CMD_ESTOP;
// Motor constants
#define MIN_POWER 70 // PWM setting for minimum movement of motor
#define MAX_POWER 255 // PWM setting for maximum power to motor
// The current stater of the motor
#define MOTOR_BRAKE 0
#define MOTOR_STOP 1
#define MOTOR_RUN 2
#define MOTOR_PRE_RAMP_UP 3
#define MOTOR_RAMP_UP 4
#define MOTOR_PRE_RAMP_DOWN 5
#define MOTOR_RAMP_DOWN 6
#define DIR_UNDEF 0
#define DIR_FWD 1
#define DIR_REV 2
#define RAMP_UP_TIME 1000 // ms
#define RAMP_DOWN_TIME 1000 // ms
uint8_t motorState = MOTOR_BRAKE; // current state for the motor
uint8_t motorDirection = DIR_UNDEF; // current direction for the motor
uint16_t motorSpeedSP = MAX_POWER; // motor speed setpoint (MIN_POWER, MAX_POWER)
uint8_t motorSpeedCV; // motor speed current value
unsigned long timerRamp = 0; // timer to keep track of ramping time elapsed
#if STATE_DEBUG
#define StateTransition(S, N) { Serial.print(State2Str(S)); Serial.print(" -> "); S = (N); Serial.println(State2Str(S)); }
#else
#define StateTransition(S, N) S = (N);
#endif
const char* State2Str(uint8_t S)
{
switch (S)
{
case MOTOR_BRAKE: return("MOTOR_BRAKE");
case MOTOR_STOP: return("MOTOR_STOP");
case MOTOR_RUN: return("MOTOR_RUN");
case MOTOR_PRE_RAMP_UP: return("MOTOR_PRE_RAMP_UP");
case MOTOR_RAMP_UP: return("MOTOR_RAMP_UP");
case MOTOR_PRE_RAMP_DOWN: return("MOTOR_PRE_RAMP_DOWN");
case MOTOR_RAMP_DOWN: return("MOTOR_RAMP_DOWN");
}
return("???");
}
void setup ()
{
pinMode(IN1,OUTPUT);
pinMode(IN2,OUTPUT);
pinMode(ENA,OUTPUT);
pinMode(BUT_REV, INPUT);
pinMode(BUT_FWD, INPUT);
pinMode(BUT_STOP, INPUT);
pinMode(BUT_ESTOP, INPUT);
pinMode(PULSE, INPUT);
#if (STATE_DEBUG || SPEED_DEBUG)
Serial.begin(57600);
Serial.println("[L298 Motor Control Tester]");
#endif
// finally connect thre interrupt
attachInterrupt((PULSE == 2) ? 0 : 1, irqPulseCounter, RISING);
}
uint8_t ReadCommand(uint8_t cmdDefault)
{
// check change of state
if (digitalRead(BUT_ESTOP)) return(CMD_ESTOP);
else if (digitalRead(BUT_STOP)) return(CMD_STOP);
else if (digitalRead(BUT_FWD)) return(CMD_FWD);
else if (digitalRead(BUT_REV)) return(CMD_REV);
return(cmdDefault);
}
// IRQ and RPM routines
void irqPulseCounter()
{
pulseCount++;
}
void CalculateRPM()
{
static uint8_t lastState = MOTOR_STOP;
static unsigned long timerZero; // baseline of millis() function for current calculations
if (motorState == MOTOR_RUN) // is currently running
{
if (lastState == MOTOR_RUN) // and was running on the last call
{
if (millis()-timerZero < RPM_CALC_INTERVAL) return; // only calculate every CALC_INTERVAL ms
motorRPM = 1000 * (pulseCount / PULSE_PER_REV) / (millis() - timerZero);
}
// either has just started running or we need to reset for the calculation
pulseCount = 0;
timerZero = millis();
}
else // is not currently running
{
if (lastState == MOTOR_RUN) // and was running on the last call
motorRPM = 0;
}
lastState = motorState;
}
void SetSpeed(uint8_t direction, uint8_t speed)
{
if (direction == DIR_FWD)
{
digitalWrite(IN1, LOW);
analogWrite(IN2, speed);
digitalWrite(ENA, HIGH);
}
else
{
analogWrite(IN1, speed);
digitalWrite(IN2, LOW);
digitalWrite(ENA, HIGH);
}
}
void loop()
{
#if SPEED_DEBUG
Serial.print("R ");
Serial.print(motorRPM);
Serial.print(": S ");
if (motorDirection != DIR_UNDEF)
Serial.print(motorDirection == DIR_FWD ? "+" : "-");
Serial.print(motorSpeedCV);
Serial.print("\n");
#endif
Command = ReadCommand(Command);
if ((Command == CMD_ESTOP) && (motorState != MOTOR_STOP))
{
StateTransition(motorState, MOTOR_BRAKE);
}
switch(motorState)
{
case MOTOR_BRAKE:
digitalWrite(IN1,HIGH);
digitalWrite(IN2,HIGH);
digitalWrite(ENA,HIGH);
motorDirection = DIR_UNDEF;
motorSpeedCV = 0;
StateTransition(motorState, MOTOR_STOP);
break;
case MOTOR_STOP:
if ((Command == CMD_FWD) || (Command == CMD_REV))
{
motorDirection = (Command == CMD_FWD) ? DIR_FWD : DIR_REV;
StateTransition(motorState, MOTOR_PRE_RAMP_UP);
}
break;
case MOTOR_PRE_RAMP_UP:
motorSpeedCV = MIN_POWER;
timerRamp = millis();
StateTransition(motorState, MOTOR_RAMP_UP);
break;
case MOTOR_RAMP_UP:
if (millis()-timerRamp < RAMP_UP_TIME)
{
motorSpeedCV = MIN_POWER + (((motorSpeedSP-MIN_POWER) * (millis()-timerRamp)) / RAMP_UP_TIME);
}
else
{
motorSpeedCV = motorSpeedSP;
StateTransition(motorState, MOTOR_RUN);
}
SetSpeed(motorDirection, motorSpeedCV);
break;
case MOTOR_RUN:
if (Command == CMD_STOP)
{
StateTransition(motorState, MOTOR_PRE_RAMP_DOWN);
}
break;
case MOTOR_PRE_RAMP_DOWN:
timerRamp = millis();
StateTransition(motorState, MOTOR_RAMP_DOWN);
break;
case MOTOR_RAMP_DOWN:
if (millis()-timerRamp < RAMP_DOWN_TIME)
{
motorSpeedCV = motorSpeedSP - (((motorSpeedSP-MIN_POWER) * (millis()-timerRamp)) / RAMP_DOWN_TIME);
}
else
{
StateTransition(motorState, MOTOR_BRAKE);
}
SetSpeed(motorDirection, motorSpeedCV);
break;
}
CalculateRPM();
}