Assignment:
The final weeks of the first year had us using our understanding of Arduino to attempt to build at small robot which could drive around and avoid obstacles in groups of three, while also sensing its range from things.
Due to time constraints, we didn’t make the entire robot. However, we did learn to code several parts of it; the Stepper Motor Wheels, LCD display and the range finder, Unfortunately we couldn’t get all these things working together in the time we had.
Stepper Motors:
In order for the robot to move around, it needed have some wheels. For this we used an electronic component called a “Stepper Motor” These are motors which will “Step” whenever there are given a signal from the Arduino. There are two kinds of stepper Motor, Unipolar and Bipolar, for this assignment we used unipolar Stepper Motors as they’re easier to code.
Our first job was to get the robot to move forward. To do this you need to understand waveform. The waveform of a stepper motor are basically the order it reads the Arduino signals. An example can be seen below. For our Robot, we’ll be using the code for Full Step.
Example Code:
In order to code the stepper motors, we made some adjustments to the basic “Blink” Example, details of which can be seen on on the “Embedded Programming” page.
The changes we need to make to this code involve changing the pinmode(LED_BUILTIN, OUTPUT) to control the Coils of the Stepper Motor. The Stepper Motor itself is connected to 4 of the Arduino’s digital pins, so the setup code should look like this.
// the setup function runs once when you press reset or power the board
void setup() {
// initialize digital pin Coil A as an output.
pinMode(13, OUTPUT);
// initialize digital pin Coil B as an output.
pinMode(12, OUTPUT);
// initialize digital pin Coil C as an output.
pinMode(11, OUTPUT);
// initialize digital pin Coil D as an output.
pinMode(10, OUTPUT);
}
The Robot will have two wheels, so another stepper motor needs to be connected to the other side, these motors will turn the opposite way from each other.
The next step is to alter the void loop section of the code. The waveform Chart above shows the change in the digitalWrite commands
void loop() {
digitalWrite(13, LOW);
digitalWrite(12, LOW);
digitalWrite(11, HIGH);
digitalWrite(10, HIGH);
delay(2);
digitalWrite(13, LOW);
digitalWrite(12, HIGH);
digitalWrite(11, HIGH);
digitalWrite(10, LOW);
delay(2);
digitalWrite(13, HIGH);
digitalWrite(12, HIGH);
digitalWrite(11, LOW);
digitalWrite(10, LOW);
delay(2);
digitalWrite(13, HIGH);
digitalWrite(12, LOW);
digitalWrite(11, LOW);
digitalWrite(10, HIGH);
delay(2);
}
This will allow one stepper motor to spin. In order to the robot to move, we need both the motors to spin in opposing directions. This involves reading the Full step bottom up. The code for that looks like this;
void loop() {
digitalWrite(13, LOW);
digitalWrite(12, HIGH);
digitalWrite(11, HIGH);
digitalWrite(10, LOW);
delay(2);
digitalWrite(13, LOW);
digitalWrite(12, LOW);
digitalWrite(11, HIGH);
digitalWrite(10, HIGH);
delay(2);
digitalWrite(13, HIGH);
digitalWrite(12, LOW);
digitalWrite(11, LOW);
digitalWrite(10, HIGH);
delay(2);
digitalWrite(13, HIGH);
digitalWrite(12, HIGH);
digitalWrite(11, LOW);
digitalWrite(10, LOW);
delay(2);
}
Bare in mind you need to use 4 different digital pins on the Arduino for this, so in this case Void Setup looks like this
Void Setup () {
pinMode(9, OUTPUT);
pinMode(8, OUTPUT);
pinMode(7, OUTPUT);
pinMode(6, OUTPUT);
}
So to get the robot to move forward, the full code will look like this;
void setup() {
pinMode(13, OUTPUT);
pinMode(12, OUTPUT);
pinMode(11, OUTPUT);
pinMode(10, OUTPUT);
pinMode(9, OUTPUT);
pinMode(8, OUTPUT);
pinMode(7, OUTPUT);
pinMode(6, OUTPUT);
}
Void Loop() {
//M1
digitalWrite(13, LOW);
digitalWrite(12, LOW);
digitalWrite(11, HIGH);
digitalWrite(10, HIGH);
delay(2);
//M2
digitalWrite(9, LOW);
digitalWrite(8, HIGH);
digitalWrite(7, HIGH);
digitalWrite(6, LOW);
delay(2);
//M1
digitalWrite(13, LOW);
digitalWrite(12, HIGH);
digitalWrite(11, HIGH);
digitalWrite(10, LOW);
delay(2);
//M2
digitalWrite(9, LOW);
digitalWrite(8, LOW);
digitalWrite(7, HIGH);
digitalWrite(6, HIGH);
delay(2);
//M1
digitalWrite(13, HIGH);
digitalWrite(12, HIGH);
digitalWrite(11, LOW);
digitalWrite(10, LOW);
delay(2);
//M2
digitalWrite(9, HIGH);
digitalWrite(8, LOW);
digitalWrite(7, LOW);
digitalWrite(6, HIGH);
delay(2);
//M1
digitalWrite(13, HIGH);
digitalWrite(12, LOW);
digitalWrite(11, LOW);
digitalWrite(10, HIGH);
delay(2);
//M2
digitalWrite(9, HIGH);
digitalWrite(8, HIGH);
digitalWrite(7, LOW);
digitalWrite(6, LOW);
delay(2);
}
Another method of coding the stepper motor is to use unassigned integers. This allows the motor to move both forwards and backwards. Everytime the loop completes i has +1 added to it. This keeps going until i = 200, where the loop will continue but the initeger returns to zero.
void setup() {
pinMode(13, OUTPUT);
pinMode(12, OUTPUT);
pinMode(11, OUTPUT);
pinMode(10, OUTPUT);
}
void loop() {
unsigned int i = 0;
while ( i < 200){
i=i+1;
//backwards
digitalWrite(13, LOW);
digitalWrite(12, HIGH);
digitalWrite(11, HIGH);
digitalWrite(10, LOW);
delay(2);
digitalWrite(13, LOW);
digitalWrite(12, LOW);
digitalWrite(11, HIGH);
digitalWrite(10, HIGH);
delay(2);
digitalWrite(13, HIGH);
digitalWrite(12, LOW);
digitalWrite(11, LOW);
digitalWrite(10, HIGH);
delay(2);
digitalWrite(13, HIGH);
digitalWrite(12, HIGH);
digitalWrite(11, LOW);
digitalWrite(10, LOW);
delay(2);
}
i = 0;
while ( i < 200){
i=i+1;
//forward
}
digitalWrite(13, LOW);
digitalWrite(12, LOW);
digitalWrite(11, HIGH);
digitalWrite(10, HIGH);
delay(2);
digitalWrite(13, LOW);
digitalWrite(12, HIGH);
digitalWrite(11, HIGH);
digitalWrite(10, LOW);
delay(2);
digitalWrite(13, HIGH);
digitalWrite(12, HIGH);
digitalWrite(11, LOW);
digitalWrite(10, LOW);
delay(2);
digitalWrite(13, HIGH);
digitalWrite(12, LOW);
digitalWrite(11, LOW);
digitalWrite(10, HIGH);
delay(2);
}
i = 0;
//Backwards
}
LCD Screen:
Another part of this robot we looked into for this was the LCD screens, or Liquid Crystal Displays.This is another component that needs to be connected to an Arduino. The connections for this part are;
- VCC to 5V (The red Wire)
- GND to GND (The Black Wire)
- SDA to A4 (The Blue Wire)
- SCL to A5 (The yellow Wire)
LCD’s can make use of open source downloadable libraries that need to be installed into the Arduino Environment. The one we downloaded, LiquidCrystal I2C.h allowed us to write messages on the LCD display;
Get the LCD I2C Library here: // https://bitbucket.org/fmalpartida/new-liquidcrystal/downloads
#include <LiquidCrystal_I2C.h> // set the LCD address to 0x27 for a 20 chars 4 line display // Set the pins on the I2C chip used for LCD connections: // addr, en,rw,rs,d4,d5,d6,d7,bl,blpol LiquidCrystal_I2C lcd(0x27, 2, 1, 0, 4, 5, 6, 7, 3, POSITIVE); // Set the LCD I2C address void setup() { Serial.begin(9600); // Used to type in characters lcd.begin(20,4); // initialize the lcd for 20 chars 4 lines, turn on backlight //-------- Write characters on the display ------------------ // NOTE: Cursor Position: Lines and Characters start at 0 // lcd.setCursor(Horizontal position,Line) lcd.setCursor(1,0); //Start at character 4 on line 0 lcd.print("Anime was a Mistake"); lcd.setCursor(1,1); //Next start at character 6 on line 1 lcd.print("And so was I"); delay(1000); delay(10000); // Wait and then tell user they can start the Serial Monitor and type in characters to // Display. (Set Serial Monitor option to "No Line Ending") lcd.setCursor(0,0); //Start at character 0 on line 0 lcd.clear(); //Clears the screen. lcd.print("Start Serial Monitor"); lcd.setCursor(0,1); lcd.print("Hello Happy people"); lcd.setCursor(0,2); lcd.print("How are you today?"); } void loop() { // when characters arrive over the serial port... if (Serial.available()) { // wait a bit for the entire message to arrive delay(100); // clear the screen lcd.clear(); // read all the available characters while (Serial.available() > 0) { // display each character to the LCD lcd.write(Serial.read()); }
Using the LCD as a Range Finder!
The final thing we attempted to do this week was to make the LCD show us the an ultrasonic sensor was from objects.
The Ultrasonic sensor is wired to the like this;
- Gnd to Gnd (The Black Wire)
- 5V to VCC (The Yellow Wire)
- Trigger to D8 (The Blue Wire)
- Echo to D7 (The red Wire)
The code for the Sensor is based of the Example Sketch “Ping” and looks a bit like this!
#define echoPin 7 // Echo Pin #define trigPin 8 // Trigger Pin #define LEDPin 13 // Onboard LED int maximumRange = 200; // Maximum range needed int minimumRange = 0; // Minimum range needed long duration; long distance; // Duration used to calculate distance void setup() { Serial.begin (9600); pinMode(trigPin, OUTPUT); pinMode(echoPin, INPUT); pinMode(LEDPin, OUTPUT); // Use LED indicator (if required) } void loop() { /* The following trigPin/echoPin cycle is used to determine the distance of the nearest object by bouncing soundwaves off of it. */ digitalWrite(trigPin, LOW); delayMicroseconds(2); digitalWrite(trigPin, HIGH); delayMicroseconds(10); digitalWrite(trigPin, LOW); duration = pulseIn(echoPin, HIGH); // Measures the length of a pulse on echoPin in microseconds //waits for the pin to go HIGH, starts timing, then waits for the pin to go LOW and stops timing. //Returns the length of the pulse in microseconds. //Calculate the distance (in cm) based on the speed of sound. distance = duration/58.2; if (distance >= maximumRange || distance <= minimumRange){ /* Send a negative number to computer and Turn LED ON to indicate "out of range" */ Serial.println("-1"); digitalWrite(LEDPin, HIGH); } else { /* Send the distance to the computer using Serial protocol, and turn LED OFF to indicate successful reading. */ Serial.println(distance); digitalWrite(LEDPin, LOW); } //Delay 100ms before next reading. delay(100); }
Future Progression;
We didn’t have time to combine the Motors with the LCD or the range finder, but in future i want to investigate sub-procedures to try and link these components and have the robot chose the correct action for the situation.