Posts Tagged ‘Arduino’
First custom PCB
This is my first working printed circuit board. I used the toner transfer method to draw the traces on the copper board. The purpose of this circuit board is to drive a stepper motor. This is a proof of concept for the final board version that will complete my equatorial mount project. The equatorial mount will be my first project in my new “Projects” section. I will begin with the conception and the making of this board.
I have designed the PCB using Fritzing, an open source circuit designer. You can find the project and the PDF of the circuit on my github. More details to come in the Projects section … hopefully in a few days.
I had a bit of troubles soldering the power connector because I drilled the holes too large. I’ll have to renew my stocks of small drill bits … I broke two 1/32″ bits while doing this board!
Keypad & LCD Display
While I was still trying to figure out what to do these 10 keypads, I received an LCD Display I ordered on eBay. It’s friday, I have no better idea than plug them both on an Arduino and code something.
I started from the circuit of the Keypad article and moved the wires connected to pins 7 & 8 to analog pins 0 & 1. There is no good reason to that shift except that it makes it easier to have the LCD wires all connected to the same side of the Arduino.
I will not go in details with the wiring since Limor Fried, founder of Adafruit Industries published an excellent demo on how to connect the display to an Arduino. This will require an additional 6 pins on your Arduino. I used the same pins as in the Lady Ada demo, 7, 8, 9, 10, 11 and 12.
Now let’s jump into the code. This is a very simple demo and you will not find anything mind blowing. The hard part has been coded for you in the LiquidCrystal library, included with the Arduino IDE.
Thanks for reading …
#include <Keypad.h>
#include <LiquidCrystal.h>
#include <Wire.h>
#define REDLITE 3
#define GREENLITE 5
#define BLUELITE 6
#define TITLE "KeyPad & LCD __"
#define READY "Ready ... "
#define EMPTY " "
// initialize the library with the numbers of the interface pins
LiquidCrystal lcd(7, 8, 9, 10, 11, 12);
// you can change the overall brightness by range 0 -> 255
int brightness = 255;
const byte ROWS = 4; //four rows
const byte COLS = 3; //three columns
char keys[ROWS][COLS] = {
{'1','2','3'},
{'4','5','6'},
{'7','8','9'},
{'*','0','#'}
};
//connect to the row pinouts of the keypad
byte rowPins[ROWS] = {2, 3, 4, 5};
//connect to the column pinouts of the keypad
byte colPins[COLS] = {6, 14, 15};
Keypad keypad = Keypad( makeKeymap(keys), rowPins, colPins, ROWS, COLS );
void setup()
{
// set up the LCD's number of rows and columns:
lcd.begin(16, 2);
// Print a message to the LCD.
lcd.print(TITLE);
lcd.setCursor(0,1);
lcd.print(READY);
brightness = 100;
Serial.begin(9600);
}
int index = 1;
char digits[2] = {' ',' '};
void loop(){
char key = keypad.getKey();
if (key != NO_KEY)
{
index = !index;
if(key == '*')
{
index = 1;
digits[0] = ' ';
digits[1] = ' ';
lcd.setCursor(0,0);
lcd.print(TITLE);
lcd.setCursor(0,1);
lcd.print(READY);
}
else if(key == '#')
{
// Animation
for(int i=0; i<15;i++)
{
lcd.setCursor(0,1);
lcd.print(EMPTY);
lcd.setCursor(i,1);
lcd.print(digits);
delay(100);
}
lcd.setCursor(0,1);
lcd.print(EMPTY);
lcd.setCursor(14,0);
lcd.print(digits);
index = 1;
digits[0] = ' ';
digits[1] = ' ';
lcd.setCursor(0,1);
lcd.print(READY);
}
else
{
digits[index] = key;
lcd.setCursor(0,1);
lcd.print(digits);
lcd.print(EMPTY);
}
Serial.println(key);
}
}
Cheap Keypad and Arduino
I just received a package of 10 flexible keypads I bought on eBay for 15.88$, shipping included. Having a keypad in your project opens so many possibilities, at 1.59$ each I think it’s a deal!
I found a keypad library for Arduino on the Arduino Playground. I made some minor modifications to the sample code they provide on that page. I changed the order of the rowPins and colPins arrays to match the order of the pins on my keypad. I also had to switch the # and the * to match my keypad.
There is however a bad side to this type of keypad … the number of pins required. This is a matrix type keypad that requires 7 IOs to run. For many projects, finding 7 IOs is simply not possible. There are two solutions to this problem. The most simple and most expensive one is to switch to the Arduino Mega. The cheap but more complex solution would be to use an IO port extender like the MCP23008.
#include <Keypad.h>
const byte ROWS = 4; //four rows
const byte COLS = 3; //three columns
char keys[ROWS][COLS] = {
{'1','2','3'},
{'4','5','6'},
{'7','8','9'},
{'*','0','#'}
};
byte rowPins[ROWS] = {2, 3, 4, 5}; //connect to the row pinouts of the keypad
byte colPins[COLS] = {6, 7, 8}; //connect to the column pinouts of the keypad
Keypad keypad = Keypad( makeKeymap(keys), rowPins, colPins, ROWS, COLS );
void setup(){
Serial.begin(9600);
}
void loop(){
char key = keypad.getKey();
if (key != NO_KEY){
Serial.println(key);
}
}
I think I will revisit my KidsClock project so I will not have to re-upload the program to change the wake up time or to switch to day light saving time. What would you do with a keypad and an Arduino? Leave your comment in the comment section of this post …
Tweetbot … the code
You can now find the code of the twitter robot on my github at: https://github.com/pchretien/tweetbot Feel free to fork … copying is not stealing! :)
Twitter Controlled Robot
I presented this project at the 28th Montréal Python meeting. I posted the slides of the presentation in my previous post here.
The objective of this project was to demonstrate the use of pyserial and XBee to wirelessly control a robot. This project was also my first attempt at using the Tweepy library. The requirements for the project were the following:
- The communication with he robot must be wireless
- The connection to the Twitter website is made by a separate computer using the Python library Tweepy
- The robot should move according to the messages it receives
- In addition to the movement, the robot should have a servo that indicate its direction
The code running in the Arduino is a very simple program. The micro-controller read on the serial port to get a char command. The commands are text integers. The robot moves according to the command it receives. You can find the code to drive the robot in my previous post Arduino Motor Controller Using an L293D Chip. The following loop() function of the Arduino program receives commands from a computer trough the serial port. Depending on the nature of the command, the robot will perform different actions.
void loop()
{
if ( Serial.available())
{
char ch = Serial.read();
switch(ch)
{
case '1': // forward
servo.write(90);
forward();
delay(RUN_DELAY);
stop();
break;
case '2': // backward
servo.write(90);
backward();
delay(RUN_DELAY);
stop();
break;
case '3': // right
servo.write(180);
right();
delay(TURN_DELAY);
forward();
delay(RUN_DELAY);
stop();
break;
//...
}
}
}
On the computer we are running a Python that connects to Twitter.com, read it’s messages and send commands to the robot that are related to the content of the messages.
import tweepy
import time
import serial
consumer_key=""
consumer_secret=""
access_token=""
access_token_secret=""
ser = serial.Serial('COM8', 19200, timeout=0)
# Initialize the tweepy API
auth = tweepy.OAuthHandler(consumer_key, consumer_secret)
auth.set_access_token(access_token, access_token_secret)
api = tweepy.API(auth)
api.update_status('Start listening at ' + time.strftime("%Y-%m-%d %H:%M:%S"))
print "Start listening at " + time.strftime("%Y-%m-%d %H:%M:%S")
print
# This is where we should send the command to the robot ...
def process_text(author, text):
print author
print text
print
if text.lower().find("cmd1") > -1:
ser.write('1')
if text.lower().find("cmd2") > -1:
ser.write('2')
if text.find("#mpr-bye") > -1:
quit = True
quit = False
lastStatusProcessed = None
lastMessageProcessed = None
while True:
for status in tweepy.Cursor(api.friends_timeline, since_id=lastStatusProcessed).items(20):
if lastStatusProcessed is None:
lastStatusProcessed = status.id
break
if status.id > lastStatusProcessed:
lastStatusProcessed = status.id
process_text(status.author, status.text)
for msg in tweepy.Cursor(api.direct_messages, since_id=lastMessageProcessed).items(20):
if lastMessageProcessed is None:
lastMessageProcessed = msg.id
break
if msg.id > lastMessageProcessed:
lastMessageProcessed = msg.id
process_text(msg.sender.name, msg.text)
if quit:
break
time.sleep(15)
api.update_status('Bye! ' + time.strftime("%Y-%m-%d %H:%M:%S"))
print "Bye!"
The Twitter anti-spam filter will block you to send twice the same tweet to someone. it is then difficult to use specific commands to control the robot since you can’t send it more than once.
The solution is to use common words as commands and to incorporate it into your tweets. That way you can send multiple variations of the same command simply by decorating the command with more text.
A video of the presentation should be available on my Youtube channel soon …
Montreal Python #28

Today at 18:30h, I’ll make a short presentation at the 28th edition of the Montreal Python. I’ll present my PyGame Wireless Game Controller and a robot controller by the web.
More details about the presentation on the Montreal Python Website:
http://montrealpython.org/2012/03/montreal-python-28-lithographic-lobotomy/
You can get the slides of the presentation here:
https://docs.google.com/presentation/d/1KTqljkl-fSZyuhXonCrQN10HsEFdp5AsavMEvj8bdRU/edit#slide=id.p
Parametric Arduino Case
When you make a project using an Arduino board, you often need a case to attach the Arduino onto your project. This small project is my first attempt to make such a case that can be adapted to all my projects.
To make it parametric I am using the OpenScad application. OpenScad is an open source 3D modeling software that allows you to model your objects using a dedicated scripting language. Because your object is made out of code, it is easy to make designes that are defined by configurable parameters.
Following is the code of the arduino case. As you will see at the top of the listing, many variables are defined so that you can adapt the object to your needs.
arduino_width = 54;
arduino_length = 69;
arduino_usb_width = 13;
arduino_usb_height = 15;
arduino_usb_x = 9.5;
arduino_power_width = 9.5;
arduino_power_height = 15;
arduino_power_x = 3.5;
wall_thickness = 2;
wall_height = 7;
bottom_thickness = 1;
side_shoulder = 6;
difference()
{
// Exterior box
cube([arduino_width+(2*wall_thickness),
arduino_length+(2*wall_thickness),
wall_height+bottom_thickness],
center=true);
// Interior recess
translate([0,0,bottom_thickness/2.0])
cube([arduino_width,
arduino_length,
wall_height],
center=true);
// Bottom hole
cube([arduino_width-(2*side_shoulder),
arduino_length-(2*side_shoulder),
wall_height+bottom_thickness],
center=true);
// USB hole
translate([-1*((arduino_width/2.0)-(arduino_usb_width/2.0)-arduino_usb_x),
-1*(arduino_length/2.0)-(wall_thickness/2.0),
-1*(wall_height/2.0-arduino_usb_height/2.0)+bottom_thickness/2.0])
{
cube([arduino_usb_width,
wall_thickness,
arduino_usb_height],
center=true);
}
// Power hole
translate([((arduino_width/2.0)-(arduino_power_width/2.0)-arduino_power_x),
-1*(arduino_length/2.0)-(wall_thickness/2.0),
-1*(wall_height/2.0-arduino_power_height/2.0)+bottom_thickness/2.0])
{
cube([arduino_power_width,
wall_thickness,
arduino_power_height],
center=true);
}
}
Visit my page on Thiniverse to get more details about this project. I invite you to explore this huge repository of objects. The future of 3D printing is great and this site is there to lead the way.
Arduino Motor Controller Using an L293D Chip
Controlling DC motors is at the heart of many robotic projects. Servo motors are sexy but DC motors are cheap and a lot more useful to control wheel based robots. In this article I’ll display a “robot shield” circuit that allows you to use cheap motors to drive your robot.
Wiring
This shield has been built on top of the Adafruit Prototype Shield. Using the prototype shield makes it much simpler to develop a custom Arduino shield. You can get one from Adafruit here.
The assembly is powered by a 6V battery connected to the Vin pin of the Arduino and to the voltage regulator input pin. The voltage regulator output is connected to pin 9 (Vcc2) of the chip to power the motors. The Arduino 5V pin is connected to pin 16 of the controller to power the internal logic. Make sure to use a proper heat sink on the voltage regulator and on the chip (pins 4,5,12,13) if you plan to power the robot with a higher voltage source.
The L293 current driver chip amplifies the input signal received on pins 2, 7, 10 and 15 to outputs pins 3, 6, 11 and 14. This allows us to take a low power signal from our circuit and transform it into a higher power signal for the motors. Using these 4 input/output the L293 can drive two motors forward and backward.
Motor #1 is connected to pins 3 and 6 and motor #2 is connected to pins 11 and 14. To drive motor #1 you apply 5V on pin #2 and 0V on pin #7. To drive the same motor in opposite directions you apply 5V on pin #7 and 0V on pin #2. You can use the same technique to drive motor #2 with pins 10 and 15.
Speed can be controlled by sending a logical pulse to the L293 “enable input” pins. Pin #1 drives the speed of motor #1 and pin #9 of motor #2. The best way to do this is by using the Arduino PWM outputs on pins 9, 10 and 11. In this example, the Arduino pin #10 is connected to the L293 pin #1 and the Arduino pin #11 is connected to the L293 pin #9.
Speed And Direction
There are two methods to control the direction of a wheeled robot. One is to build a direction mechanism similar to cars where the wheels are oriented in the direction you want the robot to go. This method involves complex mechanisms and requires more space for the robot to maneuver.
The alternate method is to drive left and right wheels in opposite directions allowing the robot to make a sharp 360 degrees turn. This method requires no additional mechanism and is much simpler to implement by using a micro-controller. However, this method assumes that both motors are running at the same speed, which is often not the case with cheap motors.
This code shows how to control direction using the L293 chip with an Arduino board.
...
void backward()
{
digitalWrite(MOTOR_1A, LOW);
digitalWrite(MOTOR_1B, HIGH);
digitalWrite(MOTOR_2A, LOW);
digitalWrite(MOTOR_2B, HIGH);
checkDistance = 1;
}
void forward()
{
digitalWrite(MOTOR_1A, HIGH);
digitalWrite(MOTOR_1B, LOW);
digitalWrite(MOTOR_2A, HIGH);
digitalWrite(MOTOR_2B, LOW);
checkDistance = 0;
}
void right()
{
digitalWrite(MOTOR_1A, LOW);
digitalWrite(MOTOR_1B, HIGH);
digitalWrite(MOTOR_2A, HIGH);
digitalWrite(MOTOR_2B, LOW);
checkDistance = 0;
}
void left()
{
digitalWrite(MOTOR_1A, HIGH);
digitalWrite(MOTOR_1B, LOW);
digitalWrite(MOTOR_2A, LOW);
digitalWrite(MOTOR_2B, HIGH);
checkDistance = 0;
}
void stop()
{
digitalWrite(MOTOR_1A, LOW);
digitalWrite(MOTOR_1B, LOW);
digitalWrite(MOTOR_2A, LOW);
digitalWrite(MOTOR_2B, LOW);
checkDistance = 0;
}
...
For example, the Tamiya double gearbox includes two low cost DC motors. The gearbox is amazing for small robotic projects but heading straight with these motors can be much more difficult than expected.
This is where the L293 chip comes to the rescue. This chip can control both the direction and the speed of the motors. To control the speed of the motors you connect the two PWM digital outputs of the Arduino micro-controller to the enable input pins 1 and 9 of the chip. As explained in the datasheet: “When an enable input is high, the associated drivers are enabled and their outputs are active and in phase with their inputs”.
You are now able to adjust the motor speeds by changing the PWM output value of the enable input of the faster motor. PWM outputs range from 0 to 255 so, to slow down a motor by a ratio of 10% you should set the associated PWM output to 230. Trial an error is the only way to get that done and make your robot head in a straight line.
void setup()
{
...
pinMode(10, OUTPUT); // To L293 pin #1
pinMode(11, OUTPUT); // To L293 pin #9
analogWrite(10, 185); // Faster motor at 72% of its full speed
analogWrite(11, 255); // Slower motor at 100% of its full speed
...
}
What’s Next
In a future article we will see how to use the shield to drive a simple Robot controlled by an infrared remote control. This project will pack together many tutorials published on this blog. If you have worked with the L293 chip to control motors, let us know in the comment section below.
Wireless Arduino/XBee Game Controller
For this project, I keep the same controller as in the previous post but, instead of controlling a servo motor through a second Arduino, I will use it as a game controller.
The game will be played on my desktop computer. Since I am not very good at writing games, I downloaded the PyGame library. This framework comes with tons of samples so I decided to hack one of these samples and replace the keyboard input with my controller. You move the tank left and right by turning the game controller in the vertical position. You can fire bombs by switching the controller horizontally.
The code and the circuit of the game controller are the exact same setup as in my previous post. What I’ll demonstrate here is how to implement a receiver in this Python game.
You will need to connect an XBee wireless module to your computer using a USB adapter board. This will create a new communication port, in our case COM8.
The idea is to replace the keyboard with the data coming from the controller through the serial port. To maintain compatibility with the original version, I decided to simply override the keyboard values with the wireless controller commands.
The first step is to load the proper modules and open a connection through the serial port. I will use two global variables to replace the keyboard commands: one for the firing command and the other for the tank direction.
#
# Serial port communication with the Arduino/XBee
#
import serial
import thread
arduinoFiring = 0
arduinoDirection = 0
ser = serial.Serial('COM8', 19200, timeout=0) # Change COM[number] for ttyUSB[number]
Once this is defined, we need to override the keyboard values. To replace the spacebar fire command, we override the value with:
firing = keystate[K_SPACE] firing = arduinoFiring # <-- Override the keyboard with the game controller data
To replace the arrows direction commands, we are add the following lines:
direction = keystate[K_RIGHT] - keystate[K_LEFT] direction = arduinoDirection # <-- Override the keyboard with the game controller value
Finally, we have to feed these two values with the data received from the game controller. The best way to do this is by starting a new thread to listen on the serial port, read incoming data and convert it to game usable values.
def processArduino(buffer):
global arduinoFiring
global arduinoDirection
if len(buffer) == 0:
return
if buffer[0] != '<':
return
if buffer[len(buffer)-1] != '>':
return
tokens = buffer[1:len(buffer)-1].split(':')
if len(tokens) < 4:
return
for i in range(4):
if len(tokens[i]) == 0:
return
#print(buffer)
c = int(tokens[0])
x = int(tokens[1])
y = int(tokens[2])
z = int(tokens[3])
if y > 550:
arduinoDirection = 1
elif y < 450:
arduinoDirection = -1
else:
arduinoDirection = 0
if z > 575:
arduinoFiring = 1
else:
arduinoFiring = 0
def readArduino():
buffer = ''
while 1:
b = ser.read()
while b:
if b == '<':
buffer = ''
buffer += b
if b == '>':
processArduino(buffer)
b = ser.read();
def main(winstyle = 0):
...
thread.start_new_thread(readArduino, ())
We have two functions here. The readArduino() function is the thread entry point that contains the code reading on the serial port. A buffer is built of bytes received from the game controller. When the ‘<’ character is read, the buffer is cleared to receive a new command. When the character ‘>’ is received, the command stored in the buffer is processed.
The data is processed in the function processArduino(buffer). The data buffer is received as a parameter. The function reads the three axis and the compass values. Then, it determines if the direction is -1, 0 or 1 and if the tank fires a bomb. The values of the axis range from 400 to 600. The constants used in the function to determine the position of the controller can be adjusted to match your game requirements.















