Lab 1 : Microcontrollers

Objective:

Develop an understanding of the function and purpose of microcontrollers by building and testing a simple autonomous robot. Using an Arduino Uno, control the motion of the robot by applying a PWM signal to a pair of Parallax servo motors through a program in the Arduino IDE. Learn how to assemble a well-structured robot and document progress in a Github repository.

Procedure:

The first part of the lab develops familiarity with the Arduino and Arduino IDE through a set of simple input/output tasks involving LEDs and potentiometers. The second part progresses to servo control and integration with the robot structure. We split into two groups to complete the first part and worked together on the second part.

Materials:

  • 1 Arduino Uno
  • 1 USB A/B cable
  • 2 Continuous rotation servos
  • 1 Pushbutton
  • 1 LED
  • 1 Potentiometer
  • Several resistors (kΩ)
  • 1 Solderless breadboard

Blinking LEDs:

We began with the “Blink” example sketch. In the Arduino IDE, we navigated to Files/Examples/01.Basic/Blink to find the code shown in "Code Snippet 1". After we compiled and loaded the sketch to the Arduino, the built-in LED on the Arduino began to toggle on and off as shown in the video 1 below.

											
	// the setup function runs once when you press reset or power the board
	void setup() {
	  // initialize digital pin LED_BUILTIN as an output.
	  pinMode(LED_BUILTIN, OUTPUT);
	}

	// the loop function runs over and over again forever
	void loop() {
	  digitalWrite(LED_BUILTIN, HIGH);   // turn the LED on (HIGH is the voltage level)
	  delay(1000);                       // wait for a second
	  digitalWrite(LED_BUILTIN, LOW);    // turn the LED off by making the voltage LOW
	  delay(1000);                       // wait for a second
	}

											
										

Code Snippet 1: Blinking Built-in LED

Video 1: Blinking Built-in LED

We then assembled a breadboard circuit with a red LED and 300-ohm resistor in series to protect our hardware, driven by the digital output from pin 13 on the Arduino. We modified the Blink sketch by setting pin 13 as a digital output instead of LED_BUILTIN as an output. We also sequentially set every digital pin as output to test all the pins.

Schematic 1: Blinking External LED

											
	// the setup function runs once when you press reset or power the board
	void setup() {
	  // initialize digital pin 13 as an output.
	  pinMode(13, OUTPUT);
	}

	// the loop function runs over and over again forever
	void loop() {
	  digitalWrite(13, HIGH);   // turn the LED on (HIGH is the voltage level)
	  delay(500);               // wait for a second
	  digitalWrite(13, LOW);    // turn the LED off by making the voltage LOW
	  delay(500);               // wait for a second
	}
											
										

Code Snippet 2: Blinking External LED

Working with Analog Outputs and Potentiometers:

Using a potentiometer, we created a manually adjustable voltage divider. When a voltage divider was created with the 300Ω resistor, an analog pin was used to read the varying voltage. As you can see in Video 2, the potentiometer’s analog voltage changed as we adjusted the voltage divider.

											
int a0pin= A0;         // define analog pin being used
int val=0;             // initialize voltage value that will be outputted to screen

void setup() {
pinMode(a0pin, INPUT); // initialize analog pin 0 as an input
  Serial.begin(9600);  // Set baud rate for serial data transmission
}

void loop() {
  val= analogRead(a0pin); // Read in voltage from analog pin 0
  Serial.println(val);    // Print voltage value on the Serial monitor
  delay(500);
}
											
										

Code Snippet 3: Reading Analog Output from Potentiometer

Schematic 2: Potentiometer Voltage Divider

Video 2: Potentiometer Voltage Divider Demo

Upon adding an LED to the circuit, we were able to control the brightness of the LED by controlling the voltage it received. To do this, the value of the potentiometer was taken using analogRead(pin), and mapped to a PWM output to create the effect of an analog output voltage on the digital pin, allowing the LED to change brightness.

											
int led = 9;    //Set pin 9 as LED
int a0= A0;     //Set analog 0 as potentiometer
int val=0;      //Initialize potentiometer voltage value
int dc=0;       //Initialize LED voltage value

void setup() {
  // Initialize LED, potentiometer, and serial connection
  pinMode(led, OUTPUT);
  pinMode(a0, INPUT);
  Serial.begin(9600);
}

void loop() {
  // Read voltage from potentiometer
  val= analogRead(a0);
  // Print potentiometer voltage
  Serial.println(val);
  // Map potentiometer voltage range to LED voltage range
  dc = map(val, 0, 1023, 0, 255);
  // Write voltage to LED
  analogWrite(9, dc);
}

											
										

Code Snippet 4: Potentiometer Changing Brightness of LED

Schematic 3: Potentiometer and LED

Video 3: Potentiometer Changing Brightness of LED Demo

Parallax Servos:

In order for our robot to move, we used Parallax Continuous Rotation Servos. To set the servos up, we added the Servo library to our existing code and modified our mapping function to map the potentiometer’s analog voltage to the servo’s input range, from 0 (full speed one direction) to 90 (stopped) to 180 (full speed the opposite direction). This enabled us to change the speed and direction of the servo manually through the potentiometer.

											
#include 
int a0= A0;    //Set analog 0 as potentiometer
int val=0;     //Initialize potentiometer voltage value
int dc=0;      //Initialize servo speed value
Servo servo;   //Initialize servo

//change servo speed by changing potentiometer output
void setup() {
  // Initialize servo, potentiometer, and serial connection
  servo.attach(9);
  pinMode(a0, INPUT);
  Serial.begin(9600);
}

void loop() {
  // Read voltage from potentiometer
  val= analogRead(a0);
  // Print potentiometer voltage
  Serial.println(val);
  // Map potentiometer voltage range to servo speed range
  dc = map(val, 0, 1023, 0, 180);
  // Write speed to servo
  servo.write(dc);
}
											
										

Code Snippet 5: Potentiometer Controlling Servo

Schematic 4: Potentiometer and Servo

Video 4: Potentiometer Changing Speed and Direction of Servo Demo

Robot Assembly:

We constructed our robot by attaching one Parallax servo to both the left and right sides of our chassis using 3D printed motor mounts. Wheels that meshed well with the splines on the output shafts of the servos were attached using a screw for each wheel. The ball bearing was attached to the rear of the frame using a standoff to extend the height of the assembly. A second chassis plate was mounted above the main chassis using the tall 3D printed brackets to allow a mounting point for the Arduino. A breadboard was placed on top of the lower chassis and the battery was mounted to the bottom of the frame between the servos using velcro. Figure 1 shows a top view of our robot and Figure 2 is a side view. Figure 2 includes other updates that we added to the robot in Milestone one such as traction for wheels and line sensors.

Figure 1: Top View of Robot

Figure 2: Side View of Robot

Driving the Robot Autonomously:

Once we assembled the robot, we programmed it to autonomously drive in a square by repeatedly moving forwards at full speed for a second then turning left 90 degrees as seen in Video 5 and Code Snippet 6.

											
#include 

// Initialize right and left servo
Servo rServo;
Servo lServo;

void setup() {
  // Attach servos: right to 10 and left to 11
  rServo.attach(10);
  lServo.attach(11);
}

void loop() {
  // continually drive forward then turn right, making a square
  goForward();
  turnLeft();
}

// goForward() drive forward for one second
void goForward() {
  rServo.write(0);
  lServo.write(180);
  delay(1000);
}

// turnLeft() turn left 90 degrees
void turnLeft() {
  rServo.write(0);
  lServo.write(0);
  delay(700);
}
											
										

Code Snippet 6: Autonomous Driving

Video 5: Autonomous Driving Demo