6V DC Motor with Encoder
Demo
with Mega & Adafruit Motor Shield
Price ~$10
Why mega is used : I need 4 interrupt pins for 2 motors (refer chart below)
Later, I noticed that I might not need to use 2 interrupt per motor. One pin per motor is enough since both values from each sensors are pretty similar unless you need extreme accuracy.
I used Adafruit Motor Shield to control motors, and cellphone power bank for power supply for motors & board.
Interrupt pins on 18, 19, 20, 21 (These are PhaseA, PhaseB on motor)
Both ends(1,6) will be the supply for motor power, connected to M1, M2.
I used 5V->3.3V convertor (Mega has 3V, but motor shield blocked it)
Screen result. Each 5 sec., speed increased, and so does the encoder counts.
Video
Code for Aduino Mega
#include "AFMotor.h"
// for encoder
void count_L1(void);
void count_L2(void);
void count_R1(void);
void count_R2(void);
int speedL = 0;
int speedR = 0;
// Variables shared by Interrupt functions should be "volatile" type
volatile int sensorV_L1 = 0;
volatile int sensorV_L2 = 0;
volatile int sensorV_R1 = 0;
volatile int sensorV_R2 = 0;
int interruptPinL1 = 18;
int interruptPinL2 = 19;
int interruptPinR1 = 20;
int interruptPinR2 = 21;
// define motor on channel 1 with 64KHz PWM
AF_DCMotor left_motor(1, MOTOR12_64KHZ);
AF_DCMotor right_motor(2, MOTOR12_64KHZ);
String s;
void setup() {
Serial.begin(9600);
Serial.println("2 x 6V DC Motor w/ Encoder");
speedL = 100; // max = 255
speedR = 100; // max = 255
// for encoder
attachInterrupt(digitalPinToInterrupt(interruptPinL1),count_L1,RISING);
attachInterrupt(digitalPinToInterrupt(interruptPinL2),count_L2,RISING);
attachInterrupt(digitalPinToInterrupt(interruptPinR1),count_R1,RISING);
attachInterrupt(digitalPinToInterrupt(interruptPinR2),count_R2,RISING);
}
void count_L1(){ sensorV_L1++; }; // interrupt function
void count_L2(){ sensorV_L2++; }; // interrupt function
void count_R1(){ sensorV_R1++; }; // interrupt function
void count_R2(){ sensorV_R2++; }; // interrupt function
void loop(){
left_motor.setSpeed(speedL);
right_motor.setSpeed(speedR);
left_motor.run(FORWARD);
right_motor.run(FORWARD);
// during delay, motor runs and
// encoder still counts using interrupt
delay(5000); // 5000 means 5 seconds
left_motor.run(RELEASE);
right_motor.run(RELEASE);
// Display result on com screen
s = " ";
s += speedL;
s += " : ";
s += sensorV_L1;
s += ", ";
s += sensorV_L2;
s += " \t";
s += speedR;
s += " : ";
s += sensorV_R1;
s += ", ";
s += sensorV_R2;
Serial.println(s);
// Clear the counts, since I am interesting only for
// the counts during 5 seconds delay.
sensorV_L1 = 0;
sensorV_L2 = 0;
sensorV_R1 = 0;
sensorV_R2 = 0;
// Change speed and limit the speed. 255 is max. I'm using speed for 100 ~ 200
speedL += 10;
if (speedL > 200) speedL = 100;
speedR += 10;
if (speedR > 200) speedR = 100;
}