Category: Hardware

Arduino vs Servos

The eyes on Exuro are basically 2 axis gimbals with a servo driving each axis. Never having built anything like this before, it was a bit of a learning experience. One of them was more of a re-learning experience in that I knew this but didn’t remember. On a small microcontroller board like an Arduino, there is a limited amount of power that can be drawn by anything connected to it.

In first working with the Arduino, I connected a single servo so that I could work through the initial hardware setup and some basic programming of the Arduino to make the servo arm move. Ground and power lines were connected to ground and +5v on the Arduino. The control line was connected to pin 9. It went pretty much as expected and was it was fun to see changes in software cause actions in the physical world.

Building on the initial success, I added a 2nd servo so I could start to see to the interactions and hardware layout needed to by the gimbals. Again, the ground and power lines were connected to the Arduino ground and +5v. Control was connected to pin 11. Mostly everything went smoothly but every once in a while, the Arduino would reset. It didn’t happen often so I didn’t spend much time tracing the problem. Until I added the 3rd servo. Ground and power lines were again connected to ground and +5v on the Arduino and the control line to pin 12.

With the 3rd connected and all 3 servos trying to move, the Arduino would reset. It would reset almost immediately after the servos started moving. I changed the code to only move 2 of the servos and things went back to working as expected. Every once in a while the Arduino would reset. But adding the 3rd would cause a reset every time. About this time it dawned on me that I might be trying to draw too much power through the Arduino.

So I dug through my collection of scrap wall warts till I found one that put out 5v at 2 amps. Since each servo wants around 0.5 amps, this should work. So I disconnected the power and ground lines for the 3 servos and connected them to the +5v and ground wires of the wall wart. I added a wire connecting the Arduino ground with the wall wart ground and powered up the Arduino. All three servos started moved their control arms back and forth without any more resets of the Arduino. Yippie!

Tags :

Arduino Switches

Part of the Exuro project includes the setup for a momentary contact switch that can be used to trigger the poofer. This way the system can either be run as a donation machine with the bill reader being used to trip the poofer or it can be manually controlled via a momentary contact switch.

My first attempt at connecting a switch was done by just connecting one switch terminal to ground and the other to the Arduino pin 2. The code was pretty straight forward:

int relay_state = LOW;
void toggle_relay()
  relay_state = !relay_state;
void setup() {
    attachInterrupt(0, toggle_relay, CHANGE); 

This had an number of unfortunate problems. The biggest one was that every once in a while the interrupt would be triggered all by itself . Without doing anything, the poofer relay would trigger. That wasn’t good. (The code for the poofer relay isn’t shown here.) It turns out that the problem was the electrical circuit. Since the switch was just connected between ground and pin 2, the wire running to the switch would act as an antenna and cause the hardware to think that the interrupt should be triggered. To resolve this problem, a 1k resistor was placed between pin 2 and ground. This ensured that the electrical signal traveling over the switch wire was stable.

The second annoying problem was that every once in a while an interrupt would be missed and the relay_state would be wrong. The toggle_relay code merely sets the relay_state to the inverse of what it was. That is if it’s a 1 then it becomes a 0 and if it’s a 0 then it becomes a 1. So if an interrupt is missed then the relay_state would be wrong and the poofer relay would be be the inverse of what it was supposed to be.

To resolve that, the toggle_relay code was changed to:

void toggle_relay()
  int val = digitalRead(2);
  if (val == LOW) {
    relay_state = LOW;
  } else {
    relay_state = HIGH;

This way the relay_state is always set to the state of the switch as read off pin 2. With these two changes, adding a 1k resistor and directly reading the pin, the system is much more stable and works as needed. Yea!

Many thanks to CTP for the pointer to using a resister to stabilize the switch.

Tags : ,

The Eyes, They be Moving!

Here’s a short video that shows the eyes on Exuro moving. You can see Mac moving around in the screen on the lower right of the video and the eyes moving to track the closest part of him. I’ll post more details soon but right now I’m just psyched that they’re moving and tracking pretty well!

Tags : , ,

Kinect, Python and Pushing Through

There’s tangent project that I’m working on that involves robotics, arduinos, kinect and fire. It’s a small robot called Exuro that has a pair of stainless steel eyes that are meant to track a person coming up to a donation box and when they make a donation, set off a small poofer. The idea is to track people using a kinect and have the eyes move as if they’re watching the closest person to the donation box. Working with an arduino to control external systems is pretty straight forward for me, it’s something that I’ve done before. But pulling sensor data from something like a kinect and interpreting the data is something I’ve never done. It’s rather intimidating. Processing video data at something like 30 frames per second, not something I’m used to do. But it sounds like fun!

There’s an open source driver to access the kinect called libfreenect that’s available from Included are wrappers for using the library from Python which most definitely my preferred programming language. That works.

Getting libfreenect to build on a Ubuntu 10.10 system was pretty straight forward. Just follow the instructions in the README.asciidoc file. Getting the Python wrappers to work took a bit more effort. cython is used to create the bindings between libfreenect and Python. Unfortunately, the version that’s currently included with Ubuntu 10.10 isn’t up to the task. Once I removed the Ubuntu and installed from the latest source, the Python bindings built and worked as just fine. I’m sure the fine folks maintaining Ubuntu will make a newer version available at some point, I’m just not willing to put this project on hold till they do 😉

There’s a few demo files that are included with the wrapper so you can start to play with the interface, library and the kinect data. Two of them, and, make for demo. The first opens two windows and shows a live video feed of the rgb camera in one and the depth camera in the other. The other demo shows a video of the depth camera but sweeps through the data showing what’s seen at different depths. These are really interesting demos to help wrap your head around what’s available from the kinect.

I got to wondering about the depth data and if there wasn’t a way to combine the two demos to be able to slide through the depth manually to see what’s there. The result is It allows you to slide along at any depth to see what’s there and then to contract or expand to see what’s around that depth. Here’s a sample video showing my hand pushing through a virtual wall:

The depth slider sets the focal point for what data to display and the threshold provides a +/- tolerance for how much data to display. A depth of 535 and a threshold of 0 would show just the data at 535 while a depth of 535 and a threshold of 6 would show the data from 529 thru 541.

It’s an interesting application to play with the gain a basic understanding of the data being returned and possible ways to use it. I’ve submitted a pull request on github to the maintainers of libfreenect to see if they’re willing to include it in the next release. Here’s hoping that they will.

There’s a lot more work I need to do for this project. The next steps will be to find the closest person in the data stream and calculate their location in the real world in reference to the location of the kinect. And I have almost no idea how to go about doing that. Time to read up on numpy and opencv

Tags : , , ,