Tag Archives: Robot

Arduino Lego Robot – Update 2

Eyes and Brainz

In the past few days I’ve been busy installing the brain of my Arduino Lego robot, namely the Raspberry Pi, and making a mount for the Raspberry Camera to allow it to pan and tilt. If you haven’t read the first entry of my robot blog, you can do so here.

The Raspberry Pi is running Gentoo Linux, my favourite Linux distro. Installation was straightforward using the wiki and cross-compiling the software on my Gentoo desktop. The Arduino is connected directly to the Raspberry via USB and communicates over serial. All my robot code is done in Python (except for C++ for the Arduino), but since I’m still working on that I’ll focus on the mechanical parts in this blog update.

At this point the robot is basically completed mechanically.

I’ve installed the Raspberry Pi on top of the robot with some strategically placed Lego beams and axles. It sits just clear of the Arduino and its shield underneath it. The power supply for the Raspberry is a mobile phone power pack slung underneath the robot with rubber bands. The Arduino uses a 9V battery which also powers the 2 servo motors for the camera mount. Lastly, the robot Lego motors are powered by a Lego 9V (actually 7,2V) power pack on the back.

Underside view showing the battery pack for the Raspberry Pi and the 2 Lego motors.

I’m communicating with the robot via WiFi from either my desktop PC or laptop. At this time I just connect the Raspberry to my router but I’ll probably make a hotspot on my laptop to be able to take the robot out into the field. Since communications never leave the LAN I don’t experience too much lag and can easily pilot the robot in real time.

Camera mount

For the camera mount I chose not to use Lego parts as it would become too bulky and I couldn’t really find a way to attach the servos to them without having to modify the Lego parts. Only the lower servo is attached to Lego, for the upper servo I made a simple frame from some spare metal and attached that to the servo plastic arms. The camera is attached to the upper servo with double-sided tape.

Due to the limitations of the servos the camera rotates only +/- 50 degrees from center (up and down). I think the servos are good up till +/- 70 degrees but I prefer to keep a margin not to damage them. As of now the camera is controlled from the PC with the arrow keys in 10 degree increments and a key to recenter it. It works well, but I’ll probably look into programming a more fluid movement, possibly using a gamepad.

Front View

My next task will be modifying the code to show the live video feed within Pygame instead of a separate VLC window, and generally modifying and cleaning up my code. Especially the networking part needs a good look through.

Whenever I have something new to show I’ll write the next entry, but expect it to be focused on the software not the hardware. Oh, and I’ll soon make a video of the robot in action!

Arduino Lego Robot – Update 1

I’ve been building  an Arduino powered Lego tracked robot on and off for the past half year, and have finally come to the point where there’s something to show.

I didn’t take long to realize that I had to become proficient in programming and not just patch together other people’s code from the web, so I took a crash course in Python (using the excellent book Python Crash Course by Eric Matthes) and became familiar with C and C++ for the Arduino code.

After a few months of coding I’m finally at the point where it is all coming together. I’ve had the basic Lego robot built for months but never really programmed it to do anything other than running forward and stopping. The robot is built of parts from the Lego Crawler Crane kit (#42042), it’s basically the tracked base with some modifications like a motor for each track to allow steering. The motors are controlled via the Arduino (see my first blog entry), which in turn is controlled with a Python program on my PC via the serial monitor. The plan is to have a Raspberry Pi as the onboard PC, which in turn will be controlled via Wifi from another PC or laptop.

Back view of the robot
Top View

At the moment the robot is controlled with a simple Python program using the WASD keyboard keys, allowing forward and backward movement and turning. This works relatively well, with about a 1 second delay.

I took the video below when testing the serial communications; at that point I had only programmed forward movement.

I have attached the Arduino code below. It waits for a serial command to actuate the motors. If you intend to use this code yourself, be aware that some lines may be split because of the narrow WordPress theme format (should be fixed by now).

// Tank movement controlled via serial commands
// Works with Adafruit Motor Shield v.2.3
// Written by Kenneth Larsen, 2017

#include <Wire.h>
#include <Adafruit_MotorShield.h>
#include "utility/Adafruit_MS_PWMServoDriver.h"

// Create the motor shield object with the default I2C address
Adafruit_MotorShield AFMS = Adafruit_MotorShield();

// Select ports for motors: M1 - M4. 
Adafruit_DCMotor *Motor1 = AFMS.getMotor(1);
Adafruit_DCMotor *Motor2 = AFMS.getMotor(2);

String input; // input for Serial
int c = -20; // error correction
int FULLSPEED = 255;
int HALFSPEED = 126;

void setup()
 {
 Serial.begin(115200);
 AFMS.begin(); // create with the default frequency of 1,6KHz
 }

void moveForward()
// Define forward movement
{
 Serial.println("Moving forward...");
 uint8_t i;
 Motor1->run(FORWARD);
 Motor2->run(FORWARD);
 for ( i = 30 ; i < 255 ; i++ ) // accelerate slowly
 {
 Motor1->setSpeed(i);
 Motor2->setSpeed(i+c); 
 delay(10);
 }
 Motor1->setSpeed(FULLSPEED); // maintain max speed
 Motor2->setSpeed(FULLSPEED+c);
}

void moveBackward()
// Define backward movement
{
 Serial.println("Moving backward...");
 uint8_t i;
 Motor1->run(BACKWARD);
 Motor2->run(BACKWARD);
 for ( i = 30 ; i < 255 ; i++ ) // accelerate slowly
 {
 Motor1->setSpeed(i);
 Motor2->setSpeed(i+c); 
 delay(10);
 }
 Motor1->setSpeed(FULLSPEED); // maintain max speed
 Motor2->setSpeed(FULLSPEED+c);
}

void turnLeft()
// Define left turns
{
 Serial.println("Turning left...");
 Motor1->run(BACKWARD);
 Motor2->run(FORWARD);
 Motor1->setSpeed(HALFSPEED);
 Motor2->setSpeed(HALFSPEED);
}

void turnRight()
// Define right turns
{
 Serial.println("Turning right...");
 Motor1->run(FORWARD);
 Motor2->run(BACKWARD);
 Motor1->setSpeed(HALFSPEED);
 Motor2->setSpeed(HALFSPEED);
}

void stopMovement()
// Define stopping
{
 Serial.println("Stopping...");
 Motor1->run(RELEASE); // stop motors
 Motor2->run(RELEASE);
}

void loop()
{
 if (Serial.available() > 0)
 {
 input = Serial.readString();
 if (input == "forward")
 {
 moveForward();
 }
 if (input == "backward")
 {
 moveBackward();
 }
 if (input == "left")
 {
 turnLeft();
 }
 if (input == "right")
 {
 turnRight();
 }
 if (input == "stop")
 {
 stopMovement();
 }
 }
}

The Python code uses pygame to grab the keystrokes and send them to the Arduino via serial. I’ll split this program into two, one for the PC to send the commands and receive video, and another for the Raspberry Pi to forward the commands to the Arduino and send video directly from the Raspicam to the PC. This will be done over WiFi to make the robot completely cordless, and with better range than if I went with Bluetooth (and better security!).

# Serial control for Arduino robot
# Written by Kenneth Larsen, 2017
import serial, sys
import pygame

# Initialize pygame
pygame.init()
pygame.display.set_caption("Robot Control Center")
screen = pygame.display.set_mode((640,480))

# Initialize serial connection
try:
 ser = serial.Serial('/dev/ttyACM1', 115200)
except serial.serialutil.SerialException:
 try:
 ser = serial.Serial('/dev/ttyACM0', 115200)
 except serial.serialutil.SerialException:
 print("No serial connection found. Is the Arduino connected?\n")

# Define stop keys. Releasing any of these keys will cause the robot to stop
stopkeys = (pygame.K_w, pygame.K_a, pygame.K_s, pygame.K_d)

def quitprogram():
 """Handles program shut down."""
 print("Stopping robot and exiting...\n")
 # Stop motors
 ser.write(b'stop')
 sys.exit()

# Main loop
while True:
 screen.fill((255,255,255))
 for event in pygame.event.get():
 if event.type == pygame.QUIT:
 quitprogram()
 # Keyboard controls
 if event.type == pygame.KEYDOWN:
 if event.key == pygame.K_q:
 quitprogram()
 if event.key == pygame.K_w:
 ser.write(b'forward')
 print(ser.readline().decode('UTF-8'))
 if event.key == pygame.K_s:
 ser.write(b'backward')
 print(ser.readline().decode('UTF-8'))
 if event.key == pygame.K_a:
 ser.write(b'left')
 print(ser.readline().decode('UTF-8'))
 elif event.key == pygame.K_d:
 ser.write(b'right')
 print(ser.readline().decode('UTF-8'))
 elif event.type == pygame.KEYUP:
 if event.key in stopkeys:
 #if event.key == pygame.K_w or pygame.K_s or pygame.K_a or pygame.K_d:
 ser.write(b'stop')
 print(ser.readline().decode('UTF-8'))
 
 # Update display
 pygame.display.update()

This is just the initial programming of the robot. I’ve tried to keep everything as simple as possible to assure that it all works.

Next step will be to get the Raspberry Pi on the robot and connect the Arduino directly to it. I’m currently experimenting with sending live video from the Raspberry over Python. The next update will hopefully focus on this, with the robot controlled over WiFi from a laptop.

Part 2 is now available!

Arduino & Lego PF Motors

Working through the book Arduino Workshop by John Boxall I’ve finally come to the chapter describing how to build an Arduino Tank Robot. However, instead of buying a premade robot chassis I decided to make it out of Lego Technic instead, something I played a lot with as a child.

This presented me with some interesting challenges, first of all, how to interface the Lego Power Functions motors with the Arduino. Luckily, I’m not the first one doing this stuff, and I quickly found a great blog detailing how to cut the motor cables. As I didn’t want to permanently destroy the great Lego set I had just bought (the 42042 Crawler Crane), I bought some new cables and an extra motor from Lego.

Preparing the cables was easy: cut them, strip and tin the two outer wires for the battery pack (+9V and GND), and the two inner cables for the motors.

Jpeg
Cutting the cables (Lego fans should look away!)

To check if it all worked, I built a quick circuit with a TIP122 transistor according to this Arduino tutorial (though a bit simplified, I didn’t really need the switch). It worked perfectly, and I was able to control the motor speed with some simple PWM code. Next step was to run 2 motors off the Adafruit motor shield. As you can see in the video below, it all worked perfectly.

Jump on over to the first entry of how I built and programmed my Arduino Lego Robot: Arduino Lego Robot – Entry 1.

Jpeg
Arduino Lego Tank Robot