Skip to content

Instantly share code, notes, and snippets.

@corinnas
Created October 13, 2010 17:04
Show Gist options
  • Save corinnas/624450 to your computer and use it in GitHub Desktop.
Save corinnas/624450 to your computer and use it in GitHub Desktop.
DC Motor and H-bridge
/*
* Back-n-forth robot
*
* A device that moves forward until it bumps into something,
* then backward until it bumps into something, and so on.
*
* Two DC motors are controlled by a single H-bridge.
*
* If the touch sensor on the front of the robot is closed,
* the robot will change direction to move backward.
*
* If the touch sensor on the back of the robot is closed,
* the robot will change direction to move forward.
*
* Created by Corinna Sherman
* September 25, 2010
*/
int enableSwitchPin = 8; // enable switch input pin to turn robot ON/OFF
int touchSensorPinF = 2; // touch sensor pin for sensor on front of robot
int touchSensorPinB = 3; // touch sensor pin for sensor on back of robot
int enablePin1 = 9; // H-bridge enable pin 1 (1,2EN)
int enablePin2 = 10; // H-bridge enable pin 2 (3,4EN)
int motorPin1 = 4; // motor 1 logic pin 1 on H-bridge (1A)
int motorPin2 = 5; // motor 1 logic pin 2 on H-bridge (2A)
int motorPin4 = 6; // motor 2 logic pin 1 on H-bridge (4A)
int motorPin3 = 7; // motor 2 logic pin 2 on H-bridge (3A)
void setup() {
// Initialize serial communication.
Serial.begin(9600);
// Set enable switch pin and touch sensor pins as input pins.
pinMode(enableSwitchPin, INPUT);
pinMode(touchSensorPinF, INPUT);
pinMode(touchSensorPinB, INPUT);
// Set other pins as output pins.
pinMode(enablePin1, OUTPUT);
pinMode(enablePin2, OUTPUT);
pinMode(motorPin1, OUTPUT);
pinMode(motorPin2, OUTPUT);
pinMode(motorPin3, OUTPUT);
pinMode(motorPin4, OUTPUT);
// Go forward by default.
goForward();
}
void loop() {
// If the switch is on, the motor turns in one direction.
if (digitalRead(enableSwitchPin) == HIGH) {
// Set enablePins to HIGH to turn on both motors.
Serial.println("go");
enable();
}
else {
Serial.println("stop");
disable();
}
if (digitalRead(touchSensorPinF)) {
goBackward(); // Front of robot has hit an obstacle, so robot will go backward.
} else if (digitalRead(touchSensorPinB)) {
goForward(); // Back of robot has hit an obstacle, so robot will go forward.
}
}
void enable() {
// Set enablePins to HIGH to turn on both motors.
digitalWrite(enablePin1, HIGH);
digitalWrite(enablePin2, HIGH);
}
void disable() {
// Set enablePins to LOW to turn off both motors.
digitalWrite(enablePin1, LOW);
digitalWrite(enablePin2, LOW);
}
void goForward() {
// Set right motor's direction
digitalWrite(motorPin1, LOW); // Set H-bridge 1A pin to low
digitalWrite(motorPin2, HIGH); // Set H-bridge 2A pin to high
// Set left motor's direction
digitalWrite(motorPin4, LOW); // Set H-bridge 4A pin to low
digitalWrite(motorPin3, HIGH); // Set H-bridge 3A pin to high
}
void goBackward() {
// Set right motor's direction
digitalWrite(motorPin1, HIGH); // Set H-bridge 1A pin to high
digitalWrite(motorPin2, LOW); // Set H-bridge 2A pin to low
// Set left motor's direction
digitalWrite(motorPin4, HIGH); // Set H-bridge 4A pin to high
digitalWrite(motorPin3, LOW); // Set H-bridge 3A pin to low
}
/*
* Phototrope
*
* A device with a light sensor that moves at a speed
* dependent on how much light it sees.
*
* Two DC motors are controlled by a single H-bridge,
* with the motor control inputs of the H-bridge
* connected to analog output (PWM) pins
* and the analog input for speed scaled to a range of 0-255.
*
* The brighter the light, the faster the device moves.
*
*
* Created by Corinna Sherman
* September 30, 2010
*/
int enableSwitchPin = 8; // enable switch input pin to turn robot ON/OFF
int touchSensorPinF = 2; // digital touch sensor pin for sensor on front of robot
int touchSensorPinB = 13; // digital touch sensor pin for sensor on back of robot
int lightSensorPin = 0; // analog input pin for photocell
int lightSensorValue = 0; // variable to hold the light sensor value
int maxLightSensorValue = 0; // variable to hold the maximum light sensor value
int minLightSensorValue = 0; // variable to hold the minimum light sensor value
int motorSpeed = 0; // variable to hold the device speed as a PWM in a range of 0-255
int enablePin1 = 9; // H-bridge enable pin 1 (1,2EN)
int enablePin2 = 10; // H-bridge enable pin 2 (3,4EN)
int motorPin1 = 3; // motor 1 logic pin 1 on H-bridge (1A) with PWM
int motorPin2 = 5; // motor 1 logic pin 2 on H-bridge (2A) with PWM
int motorPin4 = 6; // motor 2 logic pin 1 on H-bridge (4A) with PWM
int motorPin3 = 11; // motor 2 logic pin 2 on H-bridge (3A) with PWM
void setup() {
// Initialize serial communication.
Serial.begin(9600);
// Set enable switch pin and touch sensor pins as input pins.
pinMode(enableSwitchPin, INPUT);
pinMode(touchSensorPinF, INPUT);
pinMode(touchSensorPinB, INPUT);
// Set other pins as output pins.
pinMode(enablePin1, OUTPUT);
pinMode(enablePin2, OUTPUT);
pinMode(motorPin1, OUTPUT);
pinMode(motorPin2, OUTPUT);
pinMode(motorPin3, OUTPUT);
pinMode(motorPin4, OUTPUT);
// Disable motor by default until the speed is calculated in the loop function.
disable();
}
void loop() {
// Read value from light sensor.
lightSensorValue = analogRead(lightSensorPin);
// For light sensor calibration:
// Set the maximum light sensor value if the current reading exceeds the previous maximum.
// Else, set the minimum light sensor value if the current reading is less than the previous minimum.
if (lightSensorValue > maxLightSensorValue) {
maxLightSensorValue = lightSensorValue;
}
else if (lightSensorValue < minLightSensorValue) {
minLightSensorValue = lightSensorValue;
}
//Serial.println(lightSensorValue);
// Calculate the device's speed for analog output (pulse width modulation ranging from 0 to 255)
// using the current light level as seen by the light sensor
// as analog input (ranging from min light sensed to max light sensed).
motorSpeed = map(lightSensorValue, minLightSensorValue, maxLightSensorValue, 0, 255);
// Go forward by default.
goForward();
// If the switch is on, the motor turns in one direction.
if (digitalRead(enableSwitchPin) == HIGH) {
// Set enablePins to HIGH to turn on both motors.
Serial.println("go");
enable();
}
else {
Serial.println("stop");
disable();
}
// Check the touch sensors on front and back of robot.
if (digitalRead(touchSensorPinF)) {
goBackward(); // Front of robot has hit an obstacle, so robot will go backward.
}
else if (digitalRead(touchSensorPinB)) {
goForward(); // Back of robot has hit an obstacle, so robot will go forward.
}
}
void enable() {
// Set enablePins to HIGH to turn on both motors.
digitalWrite(enablePin1, HIGH);
digitalWrite(enablePin2, HIGH);
}
void disable() {
// Set enablePins to LOW to turn off both motors.
digitalWrite(enablePin1, LOW);
digitalWrite(enablePin2, LOW);
}
void goForward() {
// Set right motor's direction
analogWrite(motorPin1, 0); // Set H-bridge 1A pin to low
analogWrite(motorPin2, motorSpeed); // Set H-bridge 2A pin to a speed based on light level
// Set left motor's direction
analogWrite(motorPin4, 0); // Set H-bridge 4A pin to low
analogWrite(motorPin3, motorSpeed); // Set H-bridge 3A pin to a speed based on light level
}
void goBackward() {
// Set right motor's direction
analogWrite(motorPin1, motorSpeed); // Set H-bridge 1A pin to a speed based on light level
analogWrite(motorPin2, 0); // Set H-bridge 2A pin to low
// Set left motor's direction
analogWrite(motorPin4, motorSpeed); // Set H-bridge 4A pin to a speed based on light level
analogWrite(motorPin3, 0); // Set H-bridge 3A pin to low
}
/*
* Braitenberg Vehicle
*
* A device with two light sensors, each controlling one of two motors.
* When the left sensor sees more light, it drives the right motor faster
* so the vehicle turns to the left.
* When the right sensor sees more light, it drives the left motor faster
* so the vehicle turns to the right.
*
* Two DC motors are controlled by a single H-bridge,
* with the motor control inputs of the H-bridge
* connected to analog output (PWM) pins
* and the analog inputs for speed scaled to a range of 0-255.
*
* The brighter the light, the faster the device moves toward the light.
*
*
* Created by Corinna Sherman
* September 30, 2010
*/
int LEFT = 0; // index for lightSensorPins array corresponding to left sensor
int RIGHT = 1; // index for lightSensorPins array corresponding to right sensor
int CURRENT = 0;// index for lightSensorValues array corresponding to a given sensor's current value
int MIN = 1; // index for lightSensorValues array corresponding to a given sensor's minimum value
int MAX = 2; // index for lightSensorValues array corresponding to a given sensor's maximum value
int enableSwitchPin = 8; // enable switch input pin to turn robot ON/OFF
int lightSensorPins[] = {0, 1}; // analog input pins for photocells controlling left and right motors
// The outer array in the multidimensional array lightSensorValues
// holds sensor values for {leftSensorValues, rightSensorValues};
// Each inner array element is {currentSensorValue, minimumSensorValue, maximumSensorValue}
// for a given sensor.
int lightSensorValues[2][3] = {
{ 0,0,0 },
{ 0,0,0 }
};
int motorLSpeed = 0; // variable to hold the left motor's speed as a PWM in a range of 0-255
int motorRSpeed = 0; // variable to hold the right motor's speed as a PWM in a range of 0-255
int enablePinL = 9; // H-bridge enable pin 1 (1,2EN) to enable left motor
int enablePinR = 10; // H-bridge enable pin 2 (3,4EN) to enable right motor
int motorLPin1 = 3; // left motor logic pin 1 on H-bridge (1A) with PWM
int motorLPin2 = 5; // left motor logic pin 2 on H-bridge (2A) with PWM
int motorRPin1 = 6; // right motor logic pin 1 on H-bridge (4A) with PWM
int motorRPin2 = 11; // right motor logic pin 2 on H-bridge (3A) with PWM
void setup() {
// Initialize serial communication.
Serial.begin(9600);
// Set enable switch pin as input pin.
pinMode(enableSwitchPin, INPUT);
// Set other pins as output pins.
pinMode(enablePinL, OUTPUT);
pinMode(enablePinR, OUTPUT);
pinMode(motorLPin1, OUTPUT);
pinMode(motorLPin2, OUTPUT);
pinMode(motorRPin1, OUTPUT);
pinMode(motorRPin2, OUTPUT);
// Disable motor by default until the speed is calculated in the loop function.
disable();
}
void loop() {
// Get the current, minimum, and maximum light levels
// in the environment from the light sensors.
calibrate();
// Calculate the device's speed for analog output (pulse width modulation ranging from 0 to 255)
// using the current light level seen by the light sensor
// as analog input (ranging from min light sensed to max light sensed).
setMotorSpeed();
// Go forward by default.
goForward();
// If the switch is on, the motor turns in one direction.
if (digitalRead(enableSwitchPin) == HIGH) {
// Set enablePins to HIGH to turn on both motors.
//Serial.println("go");
enable();
}
else {
//Serial.println("stop");
disable();
}
}
// Calibrate the light sensors on the device.
void calibrate() {
calibrateLightSensor(LEFT);
calibrateLightSensor(RIGHT);
}
// Calibrate the light sensor with the given pin index into the lightSensorPins array.
void calibrateLightSensor(int pinIndex) {
// Read current value from the light sensor.
lightSensorValues[pinIndex][CURRENT] = analogRead(lightSensorPins[pinIndex]);
// For light sensor calibration:
// Set the maximum light sensor value if the current reading exceeds the previous maximum.
// Else, set the minimum light sensor value if the current reading is less than the previous minimum.
if (lightSensorValues[pinIndex][CURRENT] > lightSensorValues[pinIndex][MAX]) {
lightSensorValues[pinIndex][MAX] = lightSensorValues[pinIndex][CURRENT];
}
else if (lightSensorValues[pinIndex][CURRENT] < lightSensorValues[pinIndex][MIN]) {
lightSensorValues[pinIndex][MIN] = lightSensorValues[pinIndex][CURRENT];
}
}
void enable() {
// Set enable pins to HIGH to turn on both motors.
digitalWrite(enablePinL, HIGH);
digitalWrite(enablePinR, HIGH);
}
void disable() {
// Set enable pins to LOW to turn off both motors.
digitalWrite(enablePinL, LOW);
digitalWrite(enablePinR, LOW);
}
void goForward() {
// Set left motor's direction
analogWrite(motorLPin1, 0); // Set H-bridge 1A pin to low
analogWrite(motorLPin2, motorLSpeed); // Set H-bridge 2A pin to a speed based on light level
// Set right motor's direction
analogWrite(motorRPin1, 0); // Set H-bridge 4A pin to low
analogWrite(motorRPin2, motorRSpeed); // Set H-bridge 3A pin to a speed based on light level
}
void goBackward() {
// Set left motor's direction
analogWrite(motorLPin1, motorLSpeed); // Set H-bridge 1A pin to a speed based on light level
analogWrite(motorLPin2, 0); // Set H-bridge 2A pin to low
// Set right motor's direction
analogWrite(motorRPin1, motorRSpeed); // Set H-bridge 4A pin to a speed based on light level
analogWrite(motorRPin2, 0); // Set H-bridge 3A pin to low
}
// Set the speed variables for both left and right motors
// based on their corresponding light sensor readings
void setMotorSpeed() {
// Read current value from each light sensor.
lightSensorValues[LEFT][CURRENT] = analogRead(lightSensorPins[LEFT]);
lightSensorValues[RIGHT][CURRENT] = analogRead(lightSensorPins[RIGHT]);
// Calculate the motor speed for analog output (pulse width modulation ranging from 0 to 255)
// using the current light level as seen by the light sensor
// as analog input (ranging from min light sensed to max light sensed).
motorLSpeed = constrain(map(lightSensorValues[LEFT][CURRENT], lightSensorValues[LEFT][MIN], lightSensorValues[LEFT][MAX], 0, 255), 0, 255);
motorRSpeed = constrain(map(lightSensorValues[RIGHT][CURRENT], lightSensorValues[RIGHT][MIN], lightSensorValues[RIGHT][MAX], 0, 255), 0, 255);
//Serial.print("left sensor value = ");
//Serial.print(lightSensorValues[LEFT][CURRENT]);
//Serial.print(", right sensor value = ");
//Serial.println(lightSensorValues[RIGHT][CURRENT]);
//Serial.print("left motor speed = ");
//Serial.print(motorLSpeed);
//Serial.print(", right motor speed = ");
//Serial.println(motorRSpeed);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment