Control the speed and direction of a DC Motor using a L293D.
These are my first steps in the creation of some application for my arduino board. This will detail the experiments with DC motor control.
Eventually a manual Xenon leveling system for my bike will be implemented.
First, my working setup:
[TBD: add picture of actual setup. Or someone tell me how to upload picture :-)]
Could someone share a link for this circuit?
The servo has been modified in such a manner that it can do a complete 360. And all internals have been removed.
Second, the source code.
//
// This code creates a PWM signal that rotates a motor iether left or right.
// PWN is used to reduce the voltage of the motor from 12V --> 5V
// This allows the power regulation for the digital part to be very small (and simple)
//
// Simple schematic:
//
// +-------+ VCC2=12V
// | L293D | VCC1=5V
// | |\ |
// MOTOR_DIR -------+-| >---+------[(M)]-----+
// | |/ | |
// | | |
// | |\ | |
// MOTOR_PWM -------+-| >---+----------------+
// | |/ |
// | |
// +-------+
#include <avr/interrupt.h>
#include <avr/io.h>
// Make pulse width as such that average voltage=5V
// Value 110 is experimantal.....
// For testing purposes the value can be divided by two (2)
#define MOTOR_SPEED 110/2
int LEDPIN =13;// Heartbeat led
int MOTOR_DIR =12;// Non PWM pin for direction control
int MOTOR_PWM =11;// PWM controlled pin.
int int_counter =0;
// We have ~32000 Overflows per second...
// Make led pulse to show its alive (heartbeat?)
ISR(TIMER2_OVF_vect){
int_counter +=1;
if(int_counter ==3200){
digitalWrite(LEDPIN, LOW);
}
if(int_counter ==32000){
int_counter =0;
digitalWrite(LEDPIN, HIGH);
}
};
// Turn the motor left.
// If the motor needs to turn right after this call,
// use motor_stop first!
void motor_left(){
// Set the pulse width
OCR2A=MOTOR_SPEED;
// Set the directional bit to the correct value
digitalWrite(MOTOR_DIR, HIGH);
// Set output to PWM
TCCR2A |=((1<<COM2A1)|(1<<COM2A0));
}
// Turn the motor right.
// If the motor needs to turn left after this call,
// use motor_stop first!
void motor_right(){
// Set the pulse width
OCR2A=MOTOR_SPEED;
// Set the directional bit to the correct value
digitalWrite(MOTOR_DIR, LOW);
// Set output to PWM (inverted of motor_left function)
TCCR2A |=((1<<COM2A1)|(0<<COM2A0));
}
// The following three commands should happen in the shortest time possible.
// TODO: So optimisation is needed!
void motor_stop(){
// Disconnect the PWM
TCCR2A &= ~((1<<COM2A1)|(1<<COM2A0));
// And put is all back to a safe 'LOW'
digitalWrite(MOTOR_DIR, LOW);
digitalWrite(MOTOR_PWM, LOW);
}
void setup(){
Serial.begin(9600);
CLKPR=0;
// Set the pins to output.
pinMode(LEDPIN, OUTPUT);
pinMode(MOTOR_DIR, OUTPUT);
pinMode(MOTOR_PWM, OUTPUT);
// And set these to a initial value to make sure.
digitalWrite(MOTOR_DIR, LOW);
digitalWrite(MOTOR_PWM, LOW);
// Use phase correct PWM Mode and set Output Compare mode
// Eventual PWM fequency will be ~30kHz, this is done to
// - minimize noise
// - minimize heat (suturation of motor --> L293=RIP)
I have chosen a very high frequency for the PWN output. The reasons for this are mentioned in the above source code.
The heartbeat can be removed by disabling the TOVF interrupt. Probably a lot of cycles are lost as a result of this heartbeat (20% ?)
Play around with the MOTOR_SPEED value. For me the value 110 worked ok.
More questions/additions needed. Let me know.
Title
Arduino Newsletter
We care about the privacy and personal data of our users.
To continue, please give us your consent:
Please confirm that you have read the privacy policy
Thank you for subscribing!
Curious to learn more?
Are you also a teacher, student, or professional that loves using Arduino in your day-to-day activities?
Then keep up-to-date with either our STEM or Professional monthly newsletters.
Arduino weekly newsletter (already subscribed)
Educators can benefit from the ever growing tech that shapes our environment through fun cool projects.
Why not awe your boss with highly innovative ways to help keep your enterprise connected at no extra cost?
Arduino Survey
We'd like to get to know you little better.
Please help us improve by answering this super short optional survey.