Saturday, December 10, 2011

Quick test for servo characteristics

I got some new servos and wanted to see what their range and noise was like. Running a looping test is not very informative, and typing commands over and over is tedious. I like interactive stuff.

So I wrote up a quick program in Processing to allow you to use the  mouse or keyboard to set the angle of a servo on any pin. You just move the mouse within a white box to set the angle, or use keys for more fine control (if you're Michael J. Fox, for example). You move the mouse quickly up and down in the box to get an idea of how fast/responsive the servo is.

I hope someone finds this useful. The Processing PDE source file is pasted below. There's no code for Arduino, just the bitlash library.

Requires:
  • Arduino IDE
  • Bitlash Arduino library: a command-line-like interface to arduino functions and pins - http://bitlash.net/wiki/start - I used 1.1, there is also a new 2.0 RC4 which may be compatible.
  • Processing IDE - processing.org
 Caveats:
  • Only works for angles between 0 and 200. every servo I've ever used only has a range of at most 170 degrees, usually starting 5 - 20 degrees, ending 165 - 180 degrees. It's not hard to change if you have special servos. Using this program I have determined my new Dynam 34g servo's range to be 5-175 degrees, but I would limit it to 10-170 in order to avoid damaging them.
Possible improvements:
  • Allow individual, or simultaneous control of multiple servos; the standard arduino can control up to 8, and so the bitlash code only supports 8. The Mega can control more, but this requires a small change to the bitlash servo example. There are also shields and other things which can expand the servo control capabilities, which would require more extensive changes in bitlash; in fact with a large number, it might be worthwhile developing a custom protocol.
  • Put it in source control for shared access and versioning. Link to that instead of pasting source here. 
Source for ServoTestBitlash.pde:

/**
  * Quickly test servo min and max angles, speed, torque and noise, using Arduino with Bitlash library.
  *
  * 1. upload bitlash servo code to arduino (part of library examples).
  * 2. configure the variables below for the pin your servo is on, and serial port.
  * 3. run it.
  *
  * The angle is initialised to 90 degrees (roughly center).
  * Move the mouse cursor up and down in the white area to change the angle.
  * The current angle is shown at the top.
  * For more fine control, move the mouse off the screen and press W and S to increase and decrease the servo angle.
  *
  * Author: Joel Byrnes, December 2011.
  * email: arduino (at) adeptusproductions.com
  */

import processing.serial.*;

/***** modify this for your setup ******/

int servoPin = 9;
String serialPort = "/dev/tty.usbserial-A700eEtE";

/***** end modify part *****/

int pos = 90;
Serial port;
int lastMouseY;
  
void setup() {
  port = new Serial(this, serialPort, 57600);
  port.write("\n");
  setPos(servoPin, pos);

  size(350, 350);
  noStroke();
  frameRate(50);
}

void draw() {
  if (mouseY != lastMouseY) {
    if ((mouseY-50) < 0 || (mouseY-50) > 200) return;
    lastMouseY = mouseY;
    pos = mouseY - 50;
  }

  background(0);
  rect(50, 50, 250, 250);
  text("0", 10, 50);
  text("200", 10, 300);
  setPos(servoPin, pos);
}

void keyPressed() {
  if (key == 'w') {
    pos++;
  } else if (key == 's') {
    pos--;
  }
  else return;
 
  setPos(servoPin, pos);
}

void setPos(int pin, int position) {
  println(pos);
  text("angle: " + pos, 150, 25);
  port.write("servo(" + pin + "," + position + ")\n");
}

Monday, October 3, 2011

Augmented reality? Local Positioning System?

It occurred to me the car video would be a good target for augmented reality. I already have overlays, but you could insert location-based data over the video, for example the other cars, pit stops, navigation, maybe even explosions!

The trouble (as with any augmented reality system) is tracking distance, rotation, angle etc so as to place the augmented items correctly on screen. For a while I have been considering the idea of a LPS (local positioning system), like GPS, for accurate location of items in a small area. Fast compass measurements would also be necessary.


I recently attended a talk on lightweight java game library, which is mainly a simple, fast wrapper for OpenGL, so rendering objects is actually pretty easy :) Minecraft uses LWJGL.

Just thoughts, so far...

WiFi IP camera

While I haven't posted for a while, there was some fervent activity for a bit. My hackerspace comrade tjhowse found that there are cheap WiFi cameras you can get with an ARM processor and embedded ucLinux, which are in fact quite hackable. They also have pan-tilt stepper motors, but they have been geared way down so they are incredibly slow. Finally, they have decent IR leds so they can see in the dark; they are designed as controllable IP security cameras after all.

The innocent Wifi camera before being hacked.

The default web UI is quite decent.


I won't go into detail right now but the photo album is here and here are some threads on the topic:

http://groups.google.com/group/hackerspace_brisbane/browse_thread/thread/f5eae6b6d9922e00

http://groups.google.com/group/hackerspace_brisbane/browse_thread/thread/7336980c0f887d25

Added wires for serial connection and power.
Ultimately though, I found that:
  • The latency is actually quite low on a non-congested wireless network - as little as 35ms, which is quite adequate. 
  • The latency spikes a bit sometimes, not sure if this is congestion or CPU problems on the system
  • It is hard to connect up the Arduino over serial reliably, though I have basically solved that. 
  • It is great to have clear video without interference and static
  • However, the video is too slow. Framerate is uneven and low, and there is a significant delay - no good for what should be a fast-paced reflexive game. Not sure if this is due to CPU power, the capture device, or network problems.
So it was fun hacking it, and in fact I might keep it for data comms. Maybe remove the camera and just run the base board. That will require hacking the firmware, but that's a solved problem.

I was able to run the camera off the car's battery, through the Arduino's regulator! The reg got hot quickly though.

Thursday, June 2, 2011

Debug pin with software serial

I have been intending to re-purpose the hardware serial interface on the JeeNode to run IR comms, because being hardware and buffered it won't miss data if it's doing something else other than listening, as it would with any software serial library.

But at the same time, while doing development, I like to have debug output. Until I actually start doing the IR thing, I can still use the serial port for this. But I would like to keep that ready to do at any time. Or I can send them over the RF12, but I would like to reduce my wireless usage as much as possible, and not clutter up my UI's text window. Again, until I have multiple cars going, wireless contention isn't as much of an issue, but I prefer to do things properly the first time as long as it isn't going to be harder than fixing it later.

Then I thought, I could use software serial. It's slower and ties up the CPU, but I don't have a lot of or very frequent debug output, so it should be fine. Furthermore, I can just turn off debug output when it's not useful (mainly, when the car is moving around). I added #define and #if-#endif statements to turn the serial output on or off entirely, in a method like this (from memory):

#define DEBUG_ENABLED 1

void debugln(char[] msg) {
  #if DEBUG_ENABLED
  debugSerial.println(msg);
  #endif
}

So if I turn off DEBUG_ENABLED, then calls in the code such as debugln("Car ready") won't have any impact. And including a library should only take up some memory.

First I tried NewSoftSerial, which I have tested out before and decided was too slow (with Arduino and XBee). This caused my steering servo to freak out at the same interval as the messages being sent, no matter what pin I tried to use for debug. I also didn't see any serial output. I think the freak out was because NSS uses interrupts, which is probably shared with either that servo output (it's probably a PWM pin, I didn't check) or the RF12 code. I don't need or want an interrupt-enabled library because this is going to be used sparingly and only for output.

Side note: it's annoying that every such library demands you give it both an Rx and Tx pin. If I only want to send, why do I have to give it a receive pin?

So I tried out SoftwareSerial instead, which is part of the core Arduino library. It didn't cause any apparent problems with servo or RF12, but it also didn't seem to work at all. No matter what pin I chose, from a digital to an analog, or a few other pins on the JeeNode ISP or other headers which are not used at the moment, nothing came out. I set it to 4800 baud (9600 being the max anyway) but the LEDs didn't even light up. I added Serial.println after the debug and that was still outputting.

In short: is the RF12, Ports, or Servo library interfering with SoftwareSerial?

Update: it turns out you need to set the Tx pin to OUTPUT mode. I would have thought the library would do that, I really would.

So that started working, but then I had a problem with debugging just after sending a status update: the output was scrambled. I guessed that the rf12 library was sending and that was throwing off the serial timings. I asked on the JeeLabs forums if there was a way to fix it, and jcw himself (creator of Jeenode) replied. If you add a rf12_sendWait(1); after the sendStart command, it waits for the send to complete before returning to the program flow. That's a double-edged sword; You can guarantee your timings won't be thrown off by the background sending, but at the same time you delay returning to the program, I'm not sure for how long. If I want to keep the loop very tight, it might be a problem. I could also reduce the size of my sends as much as possible. But so far it seems ok.

Forum post is at http://forum.jeelabs.net/node/259

Now with pan/tilt mount

I thought of a quick and dirty way to test how the pan/tilt mount would work with the new car, without having to build the whole support and everything...



That tape is actually pretty sturdy... but I haven't driven it around much. At all actually. There isn't much room and it's late and the car is noisy. But it should be pretty awesome :)

This new car with its 7.2V battery (which after charging is like 8.5V) also means I can run the camera off the same battery, yay! So I don't need an extra battery holder for that. I will also add a MOSFET so that when I turn on the car, it allows current to the camera - so a single switch to turn everything on/off.

I'll record some video from the car camera when I am able to drive it around.

I also need to update that UI - I have the prototype pretty much done, I just have to do the work to put it into the app.

New car test through laptop

We took the new RC car for a spin with the UI and the camera. Buzz wanted to try out his own camera, which is much more expensive and better than mine, so we mounted it.

Camera mounted to car with additional rails... and tape. 

That's a true hack job there :) TJ suggested putting rails on it between the back and front shocks. We'll get around to actually cutting them to size, tapping and screwing them, but for now they're zip tied on. Then a plastic light cover is taped between the rods, and the camera, antenna and wires are taped down everywhere :)

You can also see the JeeNode at the front. It turns out to be really easy to control both steering, and throttle with an ESC, as they both just use standard servo control. It actually saves me 2 pins compared to the other car!

View from car camera


 Buzz took it for a spin. He was determined to try to drive it under the cars parked in the space. We taped a small flashlight to the front so we could see.


Unfortunately I didn't record any video footage from this. We were also still getting used to the fast car and the controls were twitchy; with just a slightly too-long keypress, I drove the car into a pole so hard the zip-tied rails slid forward out of the rear zip ties. Buzz got it stuck under a car. I tried to drive it outside which I knew was dangerous if I lost jeenode signal and therefore control. I lost both video and control signals at once momentarily, and Buzz went to get the car. He found it trying to reverse while hard up, and making a bad electronics smell. We're not entirely sure what made the smell, and everything still works, but I think it was probably the ESC - it's the only thing that was a bit warm.

I have been aware of the danger of driving out of signal for some time, because there's nothing stopping the car from continuing if it never gets the stop command. There's no way to detect a JeeNode signal in range except to receive data. It wasn't that much of a concern with the smaller car, and I was just careful. So now I have a really compelling reason, and I've done it - if the car hasn't received a command to go forward, reverse or stop for 250ms, it stops. This also requires a change to the UI to send an update every 150ms, just to keep it going if for example you hold down forward for over 250ms, where before there would be no need to send an update.

Wednesday, May 25, 2011

Fancy new UI

I've been working on dramatic improvements to the UI - position indicators, more gauges, and building in the support for a few features to come. Tell me if it looks familiar at all ;)


This would of course finally be full screen, with the video behind, and work in widescreen or 4:3.

Tuesday, May 24, 2011

New car! New control!


Bigger, faster, actually has suspension, proportional steering and throttle, and simplified electronics through an ESC - awesome :)
Also the battery is higher voltage (7.2V) so I should be able to run the camera off the same battery!
However, the canopy is very flimsy so I'll have to create a new mount for the camera + gun.

Oh and what's that behind it?....


It's an old set of steering wheel and pedals that I picked up for $10 at an op shop! It's for a PS2 or Xbox original, but as Xbox is just USB, at Hackerspace tonight I lopped off the end and after a lot of cursing about anti-standard wire colours, got it recognised as a USB device under Windows. Have yet to try Mac. How awesome will it be to drive that car with a proper wheel and pedals!

Thursday, March 10, 2011

JeeNode frequencies and signal quality

A question arose on the HackerSpace Brisbane mailing list about the supported frequencies of the JeeNodes. I was under the impression, in the vacuum of contrary information, that the units I had would work at least to some extent in all the supported frequencies (433, 868 and 915 MHz), although it is difficult to make a single radio that can do that. I was under this impression because I had tested such with the RF12demo on the units when I first unpacked them.

It turns out that because I bought them at the actual JeeLabs Shop, in Europe, I got the 868 MHz versions, rather than the 915 MHz version sold at Modern Device. This might be problematic.

Anyway, I did a number of tests to determine the suitability of each frequency with the modules I have.

Testing more thoroughly with the RF12demo again, I determined the following radio capabilities:

  • changing both to any of the 3 frequencies allows communication both ways (including ack)
  • changing one to 868 and the other 433 allows data 868 -> 433 but not the other way (and no ack reply)
  • sending from 915 cannot be received by either 868 or 433
This indicates all frequencies work, or at least some kind of shared delusion of using the same frequency.

Then I tested the relative signal quality of each frequency. I wrote a sketch that spams my car about every 50ms (it has an echo function for pinging and tests just like this) and reads the echo reply. I ran that on the USB JeeLink attached to my laptop used the highly scientific approach of walking around the house with it. I had it print out a dot for every send, and an R for every receive, so the ideal output looks like this:
.R.R.R.R.R.R.R.R.R.R.R.R.R.R.R.R.R.R
... and so on.
  • 915 was ok, in the same room it got all the packets, and I could get through two or three walls and still receive a significant number of packets.
  • 868 was awesome. I went all over the house and hardly dropped a packet. In fact I had to get the laptop halfway into the fridge before I started losing more packets than I sent! ...R...R.R.R.R....R..R... 
  • 433 was disappointing. It lost packets within the room and lost significant amounts just outside the door!
Note that this was all with unoptimised antennas. Default length of about 90mm. According to this talk page, 868 should be at 82mm (pretty close), and 433 at 165mm, which might explain its poor performance. I don't think 1/8 wave works very well. 
 
 

Car fully working with JeeNode

I pulled out the old RBBB Arduino clone, and hastily blue-tacked the JeeNode in its place. I left all the breadboard wiring in place in case it didn't work and I had to revert to the RBBB. But, success! It was a bit fiddly jumping all the wires from their otherwise neat ribbon cables into the JeeNode ports, but here it is:


The small ribbon cable with the black lead goes to the wheel motor controller, and the larger cable with red is for the pan/tilt servos, IR gun and has room for expansion.

So I've connected up everything, and it successfully goes forward, back, left, right, moves the camera, shoots and measures the battery voltage! Just as responsive as before! Only this time with better range! More on that in another post.

Saggy reprap parts :(

I often leave my stuff in the car, in the sun, while I'm at work, when I'm heading to HackerSpace Brisbane that evening. This must have happened on a particularly hot day:


The base of the pan/tilt mount is badly warped. The tilt doesn't work very well any more because the distance is greater, so you tilt up halfway and it starts going down again. Infinite sadness.

Do I put it on a flat surface and hit it with a hair dryer to get it back in shape? Do I just print a new part? I planned to design a new one with a support that went all around instead of just at the front. That should help with warping. Also a smaller base would be better, and the corners on this one catch on the servo wire, so it should be more rounded.

Tuesday, March 8, 2011

JeeNode working!

After quite a while porting my arduino code to use the jeenodes instead of serial/xbee, and figuring out which pins on the "ports" map to digital pin numbers, I got it to work! I can control the pan/tilt mount remotely! (that's all I've tried so far) And it's quite acceptably fast - in fact pings hover aound 54ms!

The main challenge with porting the code was that instead of just throwing data at the serial port and letting the xbees deal with it, I have to think about how to break it into packets, and which packets I really need to send and which I don't. There is also the issue of sometimes having to wait to send data, which might become a problem later. For now I have two methods, one says "send it now if you can, else drop it" and the other says "try to send forever". If the channel was tied up, it would just freeze up there. Obviously there will need to be some middle ground, if I run into problems.

I also had to write code for the JeeLink (the usb dongle, which is basically just a SMD AVR and antenna), to make it appear to be a plain serial connection for the frontend software. It was easiest if the frontend changed as little as possible (not at all, actually). In future it will be extended to provide the sender node ID and so on. This may probably become a central server node that directs all the traffic to the clients.

I had to figure out the mapping of pins to the existing arduino pins I was using so I could plug the servos into the right ports. Also there are only 4 digital and 4 analog-in ports provided on the JeeNode, so I was worried that I was already using all the pins I had available. I looked at the JeeNode diagram and the arduino diagram and painstakingly mapped it out. Basically the RF12 module steals 5 of my digital pins, two of them PWM. But some pins are mapped to the I2C and SPI/ISP connectors also available on the JeeNode, and to the INT pin on each Port. So I should be able to recover 3 digital pins, 2 of which are PWM, and two more analog-in pins. So that provides enough room for some additional things I want to do :)

Wednesday, February 2, 2011

Pan/tilt mount evolution

The first pan/tilt mount for the camera was just servos blutacked or polymorphed together (version 1). Then it was a tilt mount out of bent metal (version 2). Now I have designed and printed a mount on the Hackerspace Brisbane reprap!

Version 2:


Design of Version 3:



Installed:

Then with the old tilt mount.


And here are some images of the new tilt mount being assembled.

Design in OpenSCAD









Tuesday, February 1, 2011

JeeNodes

I've ordered 2x JeeNodes (v5) and a USB JeeLink, which I will test out as a replacement for the offboard XBee I'm using now. Combining a RBBB Arduino-compatible board and a radio, they are cheaper and hopefully also have better signal, more than the 2mW XBees I have. They didn't actually give me an option in the shop for the frequency I wanted (they come in 433, 800 and ~900 MHz versions, depending on your country's laws), but I'm hoping for 433 or 868 MHz versions, as I have heard bad things about 900 MHz, mainly because they share a common mobile phone frequency. I hope at the very least that they are all on the same frequency!

My original concerns about these devices were that they wouldn't be fast or efficient enough, but there wasn't much info available at that time. Since then I have gleaned that the radio comms run at 57600 baud and use interrupts, over the SPI interface, so it should be fast enough. That leaves the inbuild hardware serial for other purposes - IR comms!

Suddenly, an update!

It's been a reeeeaallllyy long time since I updated, but lots has happened recently. Here is a demo of the new fullscreen UI!

You should really watch it in max HD so you can see the text change.