Saturday, May 17, 2014

Arduino Project Lesson Five: DC Motor Reversing

Overview

In this lesson, you will learn how to control both the direction and speed of a small DC motor using an Arduino and the L293D motor driver chip.
learn_arduino_overview.jpg
The project uses a pot to control the speed of the motor and a push button to control the direction.

Parts

To build the project described in this lesson, you will need the following parts.

Part

Qty

learn_arduino_dc_motor.jpg
Small 6V DC Motor 1
learn_arduino_L293d.jpg
L293D IC 1
learn_arduino_pot.jpg
10 kΩ variable resistor (pot) 1
learn_arduino_switch_click.jpg
Tactile push switch 1
learn_arduino_breadboard_half_web.jpg
Half-size Breadboard 1
learn_arduino_uno_r3_web.jpg
Arduino Uno R3 1
learn_arduino_jumpers_web.jpg
Jumper wire pack 1

An Experiment

Before we get the Arduino board to control the motor, we should experiment with the L293D motor control chip to get an idea how it works.
We can start by just using the Arduino to supply 5V to the motor.
learn_arduino_fritzing_pwr_only.jpg
Note which way the motor is spinning. You can do this by pinching the motor shaft between your fingers. Swap over the motor leads so that the motor lead that was going to +5V now goes to GND and vice-versa. The motor will turn in the opposite direction.
This gives us a clue as to how the L293D chip works. Its control pins allow us to do the equivalent of swapping over the motor terminals to reverse the direction of the motor.
Build up the breadboard as below. The Arduino is still just supplying power, but we can experiment manually with the control pins before we let the Arduino take over.
learn_arduino_fritzing_chip_only.jpg
The three pins of L293D that we are interested in are Pin 1 (Enable), Pin 2 (In1) and Pin 7 (In2). These are attached to either 5V or GND using the purple, yellow and orange jumper wires.
As shown above, the motor should be turning on one direction, let's call that direction A.
If you move Pin 1 (Enable) to GND the motor will stop, no matter what you do with the control pins In1 and In2. Enable turns everything on and off. This makes it useful for using a PWM output to control the motor speed. Reconnect Pin 1 to 5V so that the motor starts again.
Now try moving In1 (pin 2, yellow) from 5V to GND. In1 and In2 are both now connected to GND, so again the motor will stop.
Moving In2 from GND to 5V will cause the motor to turn in the opposite direction (direction B).
Finally, moving In1 back to 5V so that both In1 and In2 are at 5V will again cause the motor to stop.
The effect of the pins In1 and In2 on the motor are summarized in the table below:

In1

In2

Motor

GND GND
Stopped 5V GND Turns in Direction A GND 5V Turns in Direction B 5V 5V Stopped

Breadboard Layout

Now that we have got the hang of controlling the motor directly, we can let the Arduino manage the Enable, In1 and In2 pins.
When you build the breadboard, you need to ensure that the IC is the right way around. The notch should be towards the top of the breadboard.
learn_arduino_fritzing.png

Arduino Code

Load up the following sketch onto your Arduino.  

int enablePin = 11;
int in1Pin = 10;
int in2Pin = 9;
int switchPin = 7;
int potPin = 0;

void setup()
{
  pinMode(in1Pin, OUTPUT);
  pinMode(in2Pin, OUTPUT);
  pinMode(enablePin, OUTPUT);
  pinMode(switchPin, INPUT_PULLUP);
}

void loop()
{
  int speed = analogRead(potPin) / 4;
  boolean reverse = digitalRead(switchPin);
  setMotor(speed, reverse);
}

void setMotor(int speed, boolean reverse)
{
  analogWrite(enablePin, speed);
  digitalWrite(in1Pin, ! reverse);
  digitalWrite(in2Pin, reverse);
}

Pins are defined and their modes set in the 'setup' function as normal.
In the loop function, a value for the motor speed is found by dividing the analog reading from the pot by 4.
The factor is 4 because the analog reading will be between 0 and 1023 and the analog output needs to be between 0 and 255.
If the button is pressed, the motor will run in forward, otherwise it will run in reverse. The value of the 'reverse' variable is just set to the value read from the switch pin. So, if the button is pressed, this will be False, otherwise it will be True.
The speed and reverse values are passed to a function called 'setMotor' that will set the appropriate pins on the driver chip to control the motor.

void setMotor(int speed, boolean reverse)
{
  analogWrite(enablePin, speed);
  digitalWrite(in1Pin, ! reverse);
  digitalWrite(in2Pin, reverse);
}
Pins are defined and their modes set in the 'setup' function as normal.
In the loop function, a value for the motor speed is found by dividing the analog reading from the pot by 4.
The factor is 4 because the analog reading will be between 0 and 1023 and the analog output needs to be between 0 and 255.
If the button is pressed, the motor will run in forward, otherwise it will run in reverse. The value of the 'reverse' variable is just set to the value read from the switch pin. So, if the button is pressed, this will be False, otherwise it will be True.
The speed and reverse values are passed to a function called 'setMotor' that will set the appropriate pins on the driver chip to control the motor.

void setMotor(int speed, boolean reverse)
{
  analogWrite(enablePin, speed);
  digitalWrite(in1Pin, ! reverse);
  digitalWrite(in2Pin, reverse);
}
Firstly, the speed is set, by using an analogWrite to the enable pin. The enable pin of the L293 just turns the motor on or off irrespective of what the in1 and in2 pins of the L293 are set to.
To control the direction of the motor, the pins in1 and in2 must be set to opposite values.
If in1 is HIGH and in2 is LOW, the motor will spin one way, if on the other hand in1 is HIGH and in2 LOW then the motor will spin in the opposite direction.
The '!' command means 'not'. So the first digitalWrite command for in1 sets it to the opposite of whatever the value of 'reverse' is, so if reverse is HIGH it sets it to LOW and vice versa.
The second digitalWrite for 'in2' sets the pin to whatever the value of 'reverse' is. This means that it will always be the opposite of whatever in1 is.

L293D

This is a very useful chip. It can actually control two motors independently. We are just using half the chip in this lesson, most of the pins on the right hand side of the chip are for controlling a second motor.
learn_arduino_L293D.jpg
A second motor would be attached between OUT3 and OUT4. You will also need three more control pins.
  • EN2 is connected to a PWM enabled output pin on the Arduino
  • IN3 and IN4 are connected to digital outputs on the Arduino
The L293D has two +V pins (8 and 16). The pin '+Vmotor (8) provides the power for the motors, and +V (16) for the chip's logic. We have connected both of these to the Arduino 5V pin. However, if you were using a more powerful motor, or a higher voltage motor, you would provide the motor with a separate power supply using pin 8 connected to the positive power supply and the ground of the second power supply is connected to the ground of the Arduino.


Saturday, May 10, 2014

Arduino Project Lesson Four; DC Motors

Overview

In this lesson, you will learn how to control a small DC motor using an Arduino and a transistor.
learn_arduino_overview.jpg
You will use an Arduino analog output (PWM) to control the speed of the motor by sending a number between 0 and 255 from the Serial Monitor.

Parts

To build the project described in this lesson, you will need the following parts.

Part

Qty

learn_arduino_dc_motor.jpg
Small 6V DC Motor 1
learn_arduino_transistor.jpg
PN2222 Transistor 1
learn_arduino_diode.jpg
1N4001 diode 1
learn_arduino_R-270-level.jpg
270 Ω Resistor (red, purple, brown stripes) 1
learn_arduino_breadboard_half_web.jpg
Half-size Breadboard 1
learn_arduino_uno_r3_web.jpg
Arduino Uno R3 1
learn_arduino_jumpers_web.jpg
Jumper wire pack 1

Breadboard Layout

When you put together the breadboard, there are two things to look out for.
Firstly, make sure that the transistor is the right way around. The flat side of the transistor should be on the right-hand side of the breadboard.
Secondly the striped end of the diode should be towards the +5V power line - see the image below!
The motor that comes with Adafruit Arduino kits does not draw more than 250mA but if you have a different motor, it could easily draw 1000mA, more than a USB port can handle! If you aren't sure of a motor's current draw, power the Arduino from a wall adapter, not just USB
learn_arduino_breadboard.jpg
The motor can be connected either way around.

Arduino Code

Load up the following sketch onto your Arduino.  

/*
Lesson Four; DC Motors We will start make Line Following Robot 

*/
int motorPin = 3;
void setup() 
{
  pinMode(motorPin, OUTPUT); 
  Serial.begin(9600); 
  while (! Serial); 
Serial.println("Speed 0 to 255"); 
  void loop()  
 
  if (Serial.available()) 
  { 
    int speed = Serial.parseInt(); 
    if (speed >= 0 && speed <= 255) 
    { 
      analogWrite(motorPin, speed); 
    } 
  } 
The transistor acts like a switch, controlling the power to the motor, Arduino pin 3 is used to turn the transistor on and off and is given the name 'motorPin' in the sketch.
When the sketch starts, it prompts you, to remind you that to control the speed of the motor you need to enter a value between 0 and 255 in the Serial Monitor.
learn_arduino_serial_monitor.jpg
In the 'loop' function, the command 'Serial.parseInt' is used to read the number entered as text in the Serial Monitor and convert it into an 'int'.
You could type any number here, so the 'if' statement on the next line only does an analog write with this number if the number is between 0 and 255.

Transistors

The small DC motor, is likely to use more power than an Arduino digital output can handle directly. If we tried to connect the motor straight to an Arduino pin, there is a good chance that it could damage the Arduino.
A small transistor like the PN2222 can be used as a switch that uses just a little current from the Arduino digital output to control the much bigger current of the motor.
learn_arduino_transistor.png
The transistor has three leads. Most of the electricity flows from the Collector to the Emitter, but this will only happen if a small amount is flowing into the Base connection. This small current is supplied by the Arduino digital output.
The diagram below is called a schematic diagram. Like a breadboard layout, it is a way of showing how the parts of an electronic project are connected together.
learn_arduino_schematic.jpg
The pin D3 of the Arduino is connected to the resistor. Just like when using an LED, this limits the current flowing into the transistor through the base.
There is a diode connected across the connections of the motor. Diodes only allow electricity to flow in one direction (the direction of their arrow).
When you turn the power off to a motor, you get a negative spike of voltage, that can damage your Arduino or the transistor. The diode protects against this, by shorting out any such reverse current from the motor.

Friday, May 9, 2014

Arduino Project Lesson Three; LCD Display Part Two

Overview

In this lesson, you will build on what we have learnt in lesson 11 and use a LCD display to show the temperature and light intensity.  
learn_arduino_overview.jpg
Light intensity is measured using the same photocell that you used in lesson 9.
To measure the temperature, you will use a temperature measurement chip. This device has just three leads two for 5V and GND and the third lead is connected directly to an analog input on the Arduino.

Parts

Part

Qty

learn_arduino_lcd.jpg
LCD Display (16x2 characters) 1
learn_arduino_pot.jpg
10 kΩ variable resistor (pot) 1
learn_arduino_R-1k-level.jpg
1 kΩ Resistor (brown, black, red stripes) 1
learn_arduino_resistor_LDR.jpg
Photocell (Light Dependent Resistor) 1
learn_arduino_transistor.jpg
TMP36 temperature sensor 1
learn_arduino_breadboard_half_web.jpg
Half-size Breadboard 1
learn_arduino_uno_r3_web.jpg
Arduino Uno R3 1
learn_arduino_jumpers_web.jpg
Jumper wire pack 1
The TMP36 looks just like the PN2222 transistor, but if you look at the flat side of the package body, you should see it labelled as a TMP36.

Breadboard Layout

The breadboard layout is based on the layout from lesson 11, so if you still have this on the breadboard it will simplify things greatly.
learn_arduino_fritzing.jpg
There are a few jumper wires that have been moved slightly on this layout. In particular, those near the pot.
The photocell, 1 kΩ resistor and TMP36 are all new additions to the board. The TMP36 has its curved face towards the display.

Arduino Code

The sketch for this is based on that of lesson 11. Load it up onto your Arduino and you should find that warming the temperature sensor by putting your finger on it will increase the temperature reading.
Also if you wave your hand over the photocell blocking out some of the light, the reading will decrease.

/* 
Lesson Three; Light and Temperature 
*/ 
#include <LiquidCrystal.h> 
int tempPin = 0; 
int lightPin = 1; 
//                BS  E  D4 D5  D6 D7 
LiquidCrystal lcd(7, 8, 9, 10, 11, 12); 
void setup()  
{ 
  lcd.begin(16, 2); 
} 
void loop() 
{ 
  // Display Temperature in C 
  int tempReading = analogRead(tempPin); 
  float tempVolts = tempReading * 5.0 / 1024.0; 
  float tempC = (tempVolts - 0.5) * 100.0; 
  float tempF = tempC * 9.0 / 5.0 + 32.0; 
  //         ----------------  
  lcd.print("Temp         F  "); 
  lcd.setCursor(6, 0); 
  lcd.print(tempF);
    // Display Light on second row 
  int lightReading = analogRead(lightPin); 
  lcd.setCursor(0, 1); 
  //         ---------------- 
  lcd.print("Light           ");  

  lcd.setCursor(6, 1); 
  lcd.print(lightReading); 
  delay(500); 
}

I find it useful to put a comment line above the 'lcd' command.


//                BS  E  D4 D5  D6 D7
 LiquidCrystal lcd(7, 8, 9, 10, 11, 12);



This makes things easier if you decide to change which pins you use.
In the 'loop' function there are now two interesting things going on. Firstly we have to convert the analog from the temperature sensor into an actual temperature, and secondly we have to work out how to display them.
First of all, let's look at calculating the temperature.
  int tempReading = analogRead(tempPin); 
  float tempVolts = tempReading * 5.0 / 1024.0; 
  float tempC = (tempVolts - 0.5) * 100.0; 
  float tempF = tempC * 9.0 / 5.0 + 32.0;
The raw reading from the temperature sensor is first multiplied by 5 and then divided by 1024 to give us the voltage (between 0 and 5) at the 'tempPin' analog input.
To convert the voltage coming from the TMP36 into a temperature in degrees C, you have to subtract 0.5V from the measurement and then multiply by 100.
To convert this into a temperature in Fahrenheit, you then have to multiply it by 9/5 and then add 32.
Displaying changing readings on an LCD display can be tricky. The main problem is that the reading may not always be the same number of digits. So, if the temperature changed from 101.50 to 99.00 then the extra digit from the old reading is in danger of being left on the display.
To avoid this, write the whole line of the LCD each time around the loop.

//         ---------------- 
lcd.print("Temp         F  "); 
lcd.setCursor(6, 0); 
lcd.print(tempF); 

The rather strange comment serves to remind you of the 16 columns of the display. You can then print a string of that length with spaces where the actual reading will go.
To fill in the blanks, set the cursor position for where the reading should appear and then print it.
Exactly the same approach is used for displaying the light level. There are no units for the light level, we just display the raw reading from the analog read. 

Arduino Project Lesson Two; LCD Display Part One

Overview
In this lesson, you will learn how to wire up and use an alphanumeric LCD display. 
learn_arduino_overview.jpg
The display has an LED backlight and can display two rows with up to 16 characters on each row. You can see the rectangles for each character on the display and the pixels that make up each character. The display is just white on blue and is intended for showing text.
In this lesson, we will run the Arduino example program for the LCD library, but in the next lesson, we will get our display to show the temperature and light level, using sensors.

Parts

To build the project described in this lesson, you will need the following parts.

Part

Qty

learn_arduino_lcd.jpg
LCD Display (16x2 characters) 1
learn_arduino_pot.jpg
10 kΩ variable resistor (pot) 1
learn_arduino_breadboard_half_web.jpg
Half-size Breadboard 1
learn_arduino_uno_r3_web.jpg
Arduino Uno R3 1
learn_arduino_jumpers_web.jpg
Jumper wire pack 1

Breadboard Layout

The LCD display needs six Arduino pins, all set to be digital outputs. It also needs 5V and GND connections.
learn_arduino_fritzing.jpg
There are quite a few connections to be made. Lining up the display with the top of the breadboard helps to identify its pins without too much counting, especially if the breadboard has its rows numbered with row 1 as the top row of the board. Do not forget, the long yellow lead that links the slider of the pot to pin 3 of the display. The 'pot' is used to control the contrast of the display.
You may find that your display is supplied without header pins attached to it. If so, follow the instructions in the next section.

Soldering Pins to the Display

The display needs 16 pins, so if your header strip is longer than that then break it off to the right length.
learn_arduino_lcd_kit.jpg
Then put the length of 16 header pins into the solder tabs on the display and starting at one end, solder each of the pins in place. It can be easier to put the long end of the pins into the breadboard so that the header pins are held straight.
If you do not do this, then solder one pin in first and then get the pins in straight, melting the solder on the pin before making any adjustment.
learn_arduino_soldering.jpg

Arduino Code

The Arduino IDE includes an example of using the LCD library which we will use. You can find this on the File menu under Examples → Liquid Crystal → HelloWorld.
This example uses different pins to the ones we use, so find the line of code below:

LiquidCrystal lcd(12, 11, 5, 4, 3, 2);
and change it to be:

LiquidCrystal lcd(7, 8, 9, 10, 11, 12);
Upload the code to your Arduino board and you should see the message 'hello, world' displayed, followed by a number that counts up from zero.
The first thing of note in the sketch is the line:

#include <LiquidCrystal.h>
This tells Arduino that we wish to use the Liquid Crystal library.
Next we have the line that we had to modify. This defines which pins of the Arduino are to be connected to which pins of the display.

LiquidCrystal lcd(7, 8, 9, 10, 11, 12);
The arguments to this are as follows:
Display Pin Name Display Pin Number Arduino Pin (in this example) RS 4 7 E 6 8 D4 11 9 D5 12 10 D6 13 11 D7 14 12
After uploading this code, make sure the backlight is lit up, and adjust the potentiometer all the way around until you see the text message
In the 'setup' function, we have two commands:

lcd.begin(16, 2);
lcd.print("hello, world!");
The first tells the Liquid Crystal library how many columns and rows the display has. The second line displays the message that we see on the first line of the screen.
In the 'loop' function, we aso have two commands:

lcd.setCursor(0, 1);
lcd.print(millis()/1000);
The first sets the cursor position (where the next text will appear) to column 0 & row 1. Both column and row numbers start at 0 rather than 1.
The second line displays the number of milliseconds since the Arduino was reset.