controlling DC motor with encoder


I have managed to steer a 12V DC motor with the use of one pot. I can control left and right turning and stop. I have used a L298N IC, some diodes, capaciters, a pot and lots of jumper wires.

Now I would like to read out the A B encoder which is in the motor and use a LCD display to display "motor turning left", "motor turning right" and "motor stop". I could use the pot value as input for the display but I will not learn from it and if the motor would be stuck it wouldn't be right anyway.

This is the motor I'm using:

I have looked for it but I can't find a code I can use as example code, can anybody help me get on the way?



This is the code for the encoder -> How to use USB Host Shield Hardware Manual Guide (Complete And Easy) - Circuits At Home .


Is this an interrupt code? I mean will it not miss any input from the encoder when looping through the code for the pot and L298N?

EDIT: Just read it isn't interrupt based, for direction it's no problem. In the future I would like to use it to determine position, after going to a micro switch after the Arduino is started, so the code will have to be adapted.


Hi mechatron, I looked at the link posted by felis and no, it is not interrupt driven, which is explained carefully in the article.

The problem with the code as used in the article is doing such a large Serial.print. There are ways round that, too.

Meanwhile back at your project, I'm just interested; So how much are you able to control the DC motor: Just full whack right/left or have you done speed control, too?


This is my code so far:

/* Using 1 potentiometer to control h-bridge
 * forward from zero to highest rpm
 * stop
 * reverse from zero to highest rpm
 * by Leo Groeneveld
int potpin2 = 2; // analog pin used to connect the potentiometer2
int val2;        // variable to read the value2 from the analog pin2
int pwmval2;     // variable to set the value of the PWM signal 
int pwmval3;     // variable to set the value of the PWM signal 

void setup()  { 
    pinMode(2, OUTPUT); // declare pin 2 to be an output:
    pinMode(3, OUTPUT); // declare pin 3 to be an output:
    analogWrite(2, 0);  // start with no output on PWMpin2
    analogWrite(3, 0);  // start with no output on PWMpin3

void loop()  { 
  val2 = analogRead(potpin2);       // reads the value of potentiometer2 (value between 0 and 1023) 
  if (val2 > 461 and val2 < 561) {  // dead-band
  analogWrite(2, 0);                // when in dead-band no signal to digital pin2
  analogWrite(3, 0);                // when in dead-band no signal to digital pin3
  if (val2 >= 0 and val2 <= 461) {      // motor rotating one direction
  pwmval2 = map(val2, 0, 461, 255, 0);  // motor rotating in one direction slow to highest rpm
  analogWrite(2, pwmval2);              // writes PWM value to digital pin2
  if (val2 >= 561 and val2 <= 1023) {      // motor rotating in other direction
  pwmval3 = map(val2, 561, 1023, 0, 255);  // motor rotating in other direction slow to highest rpm
  analogWrite(3, pwmval3);                 // writes PWM value to digital pin3
Serial.println(pwmval2, DEC);

I can control speed too.

I have taken an old printer apart and would like to be able to steer the printing head left and right to a certain position using a linear encoder but that’s also an A B type. The current motor is small and easy to experiment with.

In the future I would like to build a robot arm with a friend of mine and we would like to use a DC motor to rotate the whole arm and model servos for the other movements.

Thanks. Nice. Clean, simple and clear.

If you turn the pot QUICKLY it could have >0 on both pwm pins? I suspect it won't happen in this program, the Arduino is too fast, but it is a potential risk (edit:) especially if there is a loose connection to the pot or it is "noisy".

To mechatron: I wrote this code to demonstrate the technique - reading encoder using lookup table, hence no interrupts and lots of output. Once you understand how it works, modifying the code to work from an interrupt handler won't be too difficult.