Friday, August 1, 2014

Arduino restored, robot demoed at the hobby store

I got the Arduino board replacement on Wednesday, and everything worked out fine.  I can't tell if the ultrasonic range finder burned out a little or if it is just as crappy as it always was.  I won't bother replacing it, though.

It turns out that the new rubber tires I got from the hobby store are a little too grippy.  Because the tires require at least a little slippage when the robot turns (rotates), the robot can't turn at all because the tires simply don't slip on our floor.

So, last night, I decided to return to the hobby store to see if I could buy a different set of tires that maybe had better traction than the original tires but less traction than the ones I bought on Monday.  I also decided to bring in the robot, along with my old Airport Extreme Base Station and MacBook Pro, so I could give a demonstration.

I got there just before closing, which was at 7 PM.  A few customers came by to ooh and ah at the robot on the counter and ask questions, but extremely embarrassingly, I couldn't get the robot to run because I couldn't get it to connect to my base station.  My MacBook Pro was able to connect, and it could see that there were about a dozen other WiFi stations in the immediate area, so it must have been interference that was causing the Edimax WiFi dongle on the Raspberry Pi to have problems.

Then, right at closing time at 7 PM, the Raspberry Pi finally made contact.  I think the nearby Makerspace shop must have closed up and shut down its own WiFi access points, cutting down on interference.  There were only the three store staff people left in the store, but I was able to run the robot around a bit and show them how it worked.  I was also able to show them how the original tires slipped on the floor, so the guy who specialized in RC race cars was able to find a pair of racing tires that were softer than the original tires but harder than the tires he sold me earlier in the week.

I think the new tires will do nicely, but I also think that the best thing will be to switch tires depending on the surface the robot will drive on.

Monday, July 28, 2014

Burned out my Arduino Uno

Crap.

I took apart the robot to put some Velcro on the big battery today, and I had to disassemble the electronics to get inside.  When I reassembled it, I accidentally reassembled the wiring incorrectly, without noticing it, and I short-circuited the 5 V line to GND when I connected the ultrasonic range sensor.  A minute or so after I turned on the power, I smelled something like melting plastic.

I have some spare parts to test, but I'll likely have to order at least a new Arduino Uno.

-----

Update:  Based on my test with a spare Arduino Uno R2 board, it's just the Arduino Uno R3 board that burned out.  The Arduino Motor Shield R3 board seems fine, the Wireless SD shield wasn't really being used, the ultrasonic range sensor seems more-or-less fine, and the Raspberry Pi seems fine.  A test of the robot with the Arduino Uno R2 in place seems to indicate the function is normal, though I don't recall if the Arduino application had never said usbmodem as the serial port on the Raspberry Pi.  Regardless, it seems to upload properly to the Arduino.

The burned-out Arduino Uno R3 smells kind of funny, like melted epoxy.  I ordered a couple more from Amazon; they're about $8 cheaper than at Radio Shack.

-----

On a different note, I went to a local hobby store after work today and picked up a set of soft racing tires to replace the hard tires on the robot.  These fit the wheels, and they should provide better traction.

When I mentioned that I was using them for a robot, the guy who helped me find the tires asked me to bring the robot in to show him.  Unfortunately, he'll have to wait for me to rebuild it, now that the Arduino Uno has burned out.

New Demo Video


In this new demo video, I show my Raspberry Pi Arduino Robot approaching a cardboard box and scanning it with the ultrasonic range sensor, twice.  Unfortunately, I didn't properly save the first scan image file, so it doesn't show that the distance measured was ~10 inches from the range sensor.

Also demonstrated in the video is the onboard video, shown as an inset, picture-in-picture video.  The field-of-view isn't great.  I suppose I could angle it better, but when I drive the robot at home, it's on the floor, where its angle points sort of upward and looks okay.  Also, here, I could have adjusted the FOV electronically.  However, for privacy's sake, I was also trying to block out the view of the rest of the room.

After backing out, the robot had a power glitch (described below).  Power came back after I jostled the robot a bit, and then I drove it around a while.

Some notes:

-- I've been experiencing sporadic power loss to the motors whenever I run across bumpy surfaces.  If I pick it up or otherwise move it after it loses mobility, it often regains motor mobility.  I think I may have a loose wire somewhere inside the robot platform.  The battery pack is not secured inside, so if it slides around, a connection could loosen.  I think I'll tape some velcro to the battery pack and the bottom of the robot platform, so I can secure the battery pack.

-- The angular resolution of the ultrasonic range sensor is just awful, and I don't think I can buy another one that's any better.  Just looking over sensors in roughly the same price range on Amazon and Radio Shack, I think they're all almost exactly the same cheap/inexpensive design.  It's almost not worth using such fine step sizes on the stepper motor, and I thought I was using a relatively coarse step size to begin with.  I could try making some sort of collimation device for the sensors, but then I think I'd lose distance resolution.

-- 7/28/14 Update:  It turns out there are ultrasonic range sensors that are much cheaper than the Radio Shack range sensor, but most of these seem to use four pins instead of three.  At this point, I'd rather not have to figure out how to make use of the additional pin.

-- The robot itself is still not autonomous.  I still control it from my MacBook Pro via WiFi.  Now that the ultrasonic range sensor works, at least in a rudimentary way, I think it's time to build in some basic AI.  Collision-avoidance is the obvious first step, and since the angular resolution is so poor, I can make the sensor sweep faster by taking fewer steps.

-- You can also see from the video that the wheels slip a lot on some surfaces.  If I could buy tires with better traction or just a lot less slip, I could trust velocity estimates a bit more, and maybe I could program a little drive-to-destination AI, too.  That would be one advantage in using a Raspberry Pi as the brains of this robot over just using the Arduino alone.

-- If the Arduino plus Tamiya Tank platform robot was my version 1 robot, and if this is my version 2 robot, then maybe it's about time to consider a version 3 robot.  In addition to adding AI capability, I think it's time to consider additional physical capability.  I think I'm down to maybe only one or two remaining digital I/O pins on my Arduino stack.  I might be able to add another sensor, but I wouldn't be able to add another stepper motor, servo motor, or a robot arm (which, BTW, I have already assembled from a kit!).  So, to add more stuff, I would want to expand with more digital I/O pins.  One way to do that would be to add another Arduino stack.  But how?  A possibility might arise from the fact that I chose to go with USB as my means of communication between the Raspberry Pi and the Arduino, rather than using the GPIO ports as others have done.  If I can use a USB hub off the Raspberry Pi, then theoretically, I can communicate via USB with multiple Arduino boards, provided the Arduino serial libraries and the Raspberry Pi serial libraries allow for addressing through multiple USB devices.

-- Plus, if I go with expanded physical capabilities and multiple Arduinos and a USB hub, I'll definitely have to go with yet another, larger robot platform, one that can hold larger battery packs with much higher watt-hour ratings, which means the Arduino motor shields will have to drive relays rather than provide those voltages directly.  Then I can drive more powerful motors needed to drive the larger platform, but then the larger platform can hold my robot arm...


Tuesday, July 22, 2014

The range plot



After a little bit of tweaking, this is what the range plot looks like.  0 degrees is roughly straight ahead of the robot, and 90 degrees is to the left.  (Unless my memory has things reversed...)  In this scan, I'm sitting roughly in front of the robot as I'm testing out the scan, so you can see that I'm sitting roughly 20 inches in front of the robot at the height of the sensor (with the robot sitting on the table).

Unfortunately, it takes about 30 seconds or so to run through the scan and put up the plot in Python, and that's with a direct Ethernet connection to the already-slow Raspberry Pi.  Imagine how slow the response will be over wifi.  Still, it works, so that's something.  I suppose I could have bought a faster stepper motor, but I was going cheap -- <$4.  I had to tweak the delay time between steps and make the delay longer and longer, because shorter delay times caused the steps not to be always repeatable -- after multiple cycles, I ended up not returning to the same starting and stopping positions, which you don't want with a stepper motor.

Monday, July 21, 2014

Ultrasonic Range Sensor Scan Demo


Here's a video of the range sensor scanning back and forth.  I finished the code to do a twenty-one point scan across approximately 160 degrees or so in front of the robot and return a Python display of range points.  The display doesn't look all that great, in my opinion, but at least it shows if there's something pretty close to the robot.  I'll do a bit more tweaking, I guess.

Soon, I think, I'll put up more video.

Thursday, July 17, 2014

Ultrasonic range sensor in place


The proper 0.5 mm to 1/4 " shaft coupler arrived earlier this week.  The 2" stainless steel shaft that I had ordered was too tall, and the ultrasonic range sensor would have blocked the view of the Raspberry Pi camera, so I went out to Orchard Supply Hardware today and bought a package of 1/4" fluted wooden dowel pins and some wood screws.  I cut one of the pins in half, drilled a hole down the middle of each half, and then inserted one half in the shaft coupler, which I had already attached to the stepper motor.

I also bought a bunch of small circular PC boards (with solder pads) from Radio Shack, and I soldered -- rather poorly, unfortunately -- an 8-pin IC socket onto a small one, and I screwed this  PC board onto the wooden dowel pin.  Then I inserted the ultrasonic range sensor onto the IC socket on the stepper motor assembly.

You can see the photo of the assembly above.

I also remounted the Raspberry Pi camera onto the SD Card Shield with a longer standoff.  The SD Card shield doesn't really serve much of a purpose any more, other than to elevate the camera a bit higher and maybe... well, that's really about it.  I tried mounting the camera elsewhere on the top plate of the robot platform, but I couldn't really find a place I liked.

Now, I need to wire the ultrasonic range sensor with Arduino jumpers from the IC socket over to the SD Card shield, and I'll probably also use Arduino jumpers to connect the stepper motor to whatever pins are still available on the Arduino SD Card shield.  After that, I'll have to write new programs to control the stepper motor and to accumulate range data by sweeping in front of the robot and building a map of objects.

I still haven't bothered accounting for the pins, though.  This'll be really bad if it turns out I don't have enough available digital I/O pins.

Wednesday, July 9, 2014

Need to order a new shaft coupler

Got the wrong shaft coupler.  I should have ordered 5 mm instead of 3/16".  That's what I get from eyeballing the shaft OD with a ruler instead of measuring with a caliper.  Doh!

Sunday, June 29, 2014

Raspberry Pi Streaming Video

Before I forget:  Before a few days ago, I did imaging through the Raspberry Pi camera the following way:

I'd drive the robot a few feet.  Then I'd send a command to take a picture.  A picture would be sent back to me, and I'd take a look at it.  Then I'd dismiss the picture, and drive the robot a little bit more. And so on.

Tedious.

The whole thing was done via Python.  I couldn't figure out how to do streaming via Python.  So, following streaming instructions here, I set up streaming video via the from the Raspberry Pi camera to a web page.

Now, I get a live stream of the camera as I drive the robot, making it a more fun driving experience.

Unfortunately, it seems to have hosed the picamera Python library, so I don't have access vi Python.  Oh, well.  For now, I don't need or want it.  I'll have to see about reinstalling it or making it live side-by-side with streaming, if possible, if I want it back in the future.

Wednesday, June 25, 2014

Stepper motor arrived

Okay, the new stepper motor finally arrived, and I tried out the sample code linked by one of the reviewers.  It works fine, but some of the output pins used by the code are also used by the Arduino motor shield to control the motors.  I'll have to find unused pins and rewrite the stepper motor code.  I assume enough pins are available.  If not...

Now that I have the stepper motor, I have to come up with a way of mounting the ultrasonic range sensor to the motor.  First, I already attached the stepper motor to the top-front of the robot platform by reusing the long standoffs.  I tried moving the Arduino and the Raspberry Pi to another location on the top plate, but the holes really don't seem ideal for anything.  I wish the top plate had more holes for screws.

For attaching something to the stepper motor, I'll probably order this shaft coupler and this 1/4" rod. Then I'll have to find a flat platform or circuit board that can attach via 1/4" ID shaft collars or something similar, and I'll attach the range sensor to that board and wire it up to the Arduino stack.

I'm so used to looking through the McMaster-Carr catalog when ordering parts at work, but for this project, I'm looking through Amazon.com.

Friday, June 20, 2014

Waiting

No, I haven't abandoned this blog.  My next step was to add a stepper motor so I could sweep the ultrasonic sensor in a controlled fashion before the robot, in order to get a map of objects in the front.

I ordered a cheap stepper motor from Amazon.com some time ago, but the delivery time is very long.  I should get it in a couple of days... I hope.

Saturday, May 31, 2014

A new battery pack for my current robot.

I've been using the 6 AA battery holder that came with the Sainsmart 4WD robot platform for a few months now, and I've been wanting to get a beefier battery pack for more power.  Based on a comment from an Amazon.com buyer of the platform, I ordered the True Energy 9.6 V battery pack and charger from Amazon.com, and it arrived earlier today.  This evening, I went to Radio Shack and picked up a male/female pair of Molex connectors and a size M coax plug, so I could wire up the battery pack to feed through the shell of the robot platform for external recharging.

(I went by memory in selecting the size M coax plug, but fortunately, it's the right size.)


This photo shows the robot platform with the top taken off, showing the four motors attached to the wheels.  The left motors are wired together, and the right motors are wired together.


This is the top plate of the robot platform.  An Arduino Uno with a motor shield is attached to the front (left) of the plate with short standoffs.  The wireless SD shield (which I use mainly as a platform to hold a 16 pin socket) is not attached.  On the right is a small circuit board attached to the top plate with longer standoffs.  I usually velcro the Raspberry Pi and its battery pack here.


Here's the bottom side of the top plate, showing the 6 AA battery pack attached to the plate and wired to a two-position switch.  When the robot is jostled, sometimes a battery falls out of the holder.  In any case, it doesn't provide a lot of power.


So, here's the new battery pack, shown in green lying on the bottom of the robot platform.  The battery pack itself comes with a male molex connector that is used to attach to the charger.  Because this molex connector isn't quite compatible with the male and female molex connectors I got from Radio Shack, I disconnected the original molex connector and attached the Radio Shack male connector.  Then I wired the female molex connector to the coax socket and the two position switch (both of which were included with the Sainsmart 4WD robot platform).  If you look closely, you can trace out the wiring.

The new battery pack is intended to power both the Arduino stack and the robot motors.  In my initial test drive (without a full charge of the new battery), it's pretty swift.


Here's the top plate.  On the right of the "On" label, you can see the newly installed coax socket.



On these two photos, you can see the newly assembled robot charging.  On the left is the charger that came with the battery pack.  I used the male molex connector that I disconnected from the battery, and I wired it to the Radio Shack size M coax plug with a black and red pair of wires.

The Arduino wireless SD shield is shown at the top of the Arduino stack, with the Radio Shack ultrasonic range sensor kind of looking like a pair of eyes.  The Raspberry Pi and battery pack are velcro'd to the platform in back.  Also of note is a Belkin Retractable High Speed USB 2 Cable connecting the Raspberry Pi to the Arduino stack as well as a short USB cable (half disconnected) between the Raspberry Pi and the battery pack velcro'd beneath it.  I ordered both of these from Amazon.com to shorten cable length and reduce clutter.

This is a big thing to note:  A variety of Raspberry Pi -- Arduino robots described on the web use the GPIO ports on the Raspberry Pi to communicate with the pins on the Arduino.  To do so, since the two devices use 3.3 V and 5 V standard on their pins, the robot designers have to use an opto-isolator between the devices.  I don't see the advantage to this over using the USB ports on both devices and then using the serial communications packages in the libraries on both platforms to handle the communications.  It seems so much more straightforward to me to be able to send and receive ASCII code rather than control pins.

Finally, attached to the wireless SD shield by a standoff and encased in a clear plastic case behind the Radio Shack ultrasonic range sensor "eyes" is a Raspberry Pi Camera, attached also to the Raspberry Pi by its white flat ribbon cable.

-----

I still can't get the Raspberry Pi to act as a wifi access point to which I can log in.  So, I'm still forced to use my home WiFi network for communications.

I still can't get the Raspberry Pi camera to display photos directly from Python using show() (or image.show()), either over SSH or via a VNC connection.  (Actually, I'm not sure it works this way even when I use the Raspberry Pi directly connected to a monitor.)  Instead, I have to capture an image to a .jpg file and then use Python to make an external call to Image Viewer.  That works, but it feels pretty clunky.

Oh, yes, and I've also started using a VNC connection to the Raspberry Pi.

-----

My next project is to attach the Radio Shack ultrasonic range sensor to a swivel platform attached to a stepper motor controlled by the Arduino stack.  Then I'll write an addition to the Arduino code to allow the range sensor to sweep in front of the robot and get a rudimentary range map of objects in front of the robot.  I've been playing with the pylab library in python, and it seems promising for this project.

Thursday, May 22, 2014

Tank code

Here's the Tank code, from when I used the Tamiya Tracked Vehicle Chassis as my platform.  (The Blink comments at the top just mean I recycled the code from an earlier LED test and forgot to remove the comment...)

/*
  Blink
  Turns on an LED on for one second, then off for one second, repeatedly.

  This example code is in the public domain.
 */

void setup()
{
  int i;  
  // initialize the digital pin as an output.
  // Pin 13 has an LED connected on most Arduino boards:
  pinMode(13, OUTPUT);
  
  // Right motor (with gearbox on rear)
  pinMode(3, OUTPUT);     // PWM, HIGH=fast, LOW=slow or off
  pinMode(9, OUTPUT);     // Brake, HIGH=brake, LOW=coast when PWM low
  pinMode(12, OUTPUT);    // Direction, HIGH=forward, LOW=reverse

  pinMode(8, OUTPUT);     // Brake
  pinMode(11, OUTPUT);    // PWM
  pinMode(13, OUTPUT);    // Direction

  //run_tank;  
  digitalWrite(9,HIGH);
  digitalWrite(8,HIGH);
  

  digitalWrite(12,LOW);
  delay(1000);
  digitalWrite(9,LOW);
  delay(1000);
  digitalWrite(3,HIGH);
  delay(5000);
  digitalWrite(9,HIGH);
  delay(1000);
  
  digitalWrite(12,HIGH);
  delay(1000);
  digitalWrite(9,LOW);
  delay(1000);
  digitalWrite(3,HIGH);
  delay(5000);
  digitalWrite(9,HIGH);
  delay(1000);


  digitalWrite(13,LOW);
  delay(1000);
  digitalWrite(8,LOW);
  delay(1000);
  digitalWrite(11,HIGH);
  delay(5000);
  digitalWrite(8,HIGH);
  delay(1000);
  
  digitalWrite(13,HIGH);
  delay(1000);
  digitalWrite(8,LOW);
  delay(1000);
  digitalWrite(11,HIGH);
  delay(5000);
  digitalWrite(8,HIGH);
  delay(1000);
  
  digitalWrite(9,HIGH);
  digitalWrite(8,HIGH);
  
}

void loop()
{
}

Nothing special, really.  With the digital pinMode settings to output, I set up the Arduino Uno and Motor shield to control the outputs to the motors.  After //run_tank, I turn on both brakes.  Then the right motor is set to reverse, the brake is released, the right motor is run (in reverse), and then the brake is applied.

Next, the right motor is set to forward, the brake is released, the right motor is run (forward), and then the brake is reapplied.

And then I do the two steps on the left motor, before finally setting both brakes.

I suppose I could have put the same code in loop().  Mainly I put it in setup() out of habit.

However, I found this approach pretty unsatisfactory.  Without sensors providing any feedback, there's no way for the robot to find its way around a room or other obstacle course, so all of the motion has to be preprogrammed.  With the hardware I had available at the time, with no wireless communication to the Arduino, that writing a new program, picking up the tank and attaching the Arduino to the computer, and uploading the program before setting the tank back on the floor and pressing the button to restart the device.

There simply was no remote control or even limited robot intelligence and autonomy.

I needed something better.

(I'll put up a schematic of the wiring for this tank robot later, when I get around to it.)

Tuesday, May 20, 2014

The old robot platform and the new robot, as of 5/20/14


Here's a photo of the two platforms.  On the right is the Tamiya tank platform (Tracked Vehicle Chassis kit) with the Tamiya Universal Plate and the Tamiya L/R Independent 4 speed Double Gearbox.


Previously, I had mounted the Arduino Uno and the Arduino Motor Shield on the Tamiya platform, along with a couple of 9V batteries in parallel.  I'd then program the Arduino to drive the tank via the motor shield with a preset list of commands (forward, rotate left, rotate right, reverse, etc.).

When I later bought the Raspberry Pi, I thought of using the Raspberry Pi as the brains of the robot, with its larger memory potentially allowing more programming flexibility than is available on the Arduino as well as the fact that the RPi is an actual computer (if a small, cheap, and low-powered one) as opposed to a micro controller, like the Arduino.  In order to do this, I needed a bigger platform to accommodate the additional parts.

So, on the left is my current robot.  It uses a Sainsmart 4WD aluminum robot platform.  The right and left side motors are connected in parallel on each side, so the four wheels aren't really independent.  I use 6 AA batteries to provide the motor power.  At the front of the robot (right, in the photo) is the Arduino Uno (mounted by standoffs to the top plate), an Arduino motor shield, and a wireless SD shield, on which is mounted a Radio Shack ultrasonic distance sensor.

At the end of the robot (left, in the photo), on a small platform attached by standoffs attached to the top plate, is the Raspberry Pi (model B) and Mophie Juicepack battery pack for iPhone that I use to power the Raspberry Pi.  The RPi also has an Edimax USB WiFi adapter and a Raspberry Pi Camera Module, mounted in a case that is mechanically attached to the wireless SD shield on the Arduino stack.  The RPi assembly is strapped with a velcro strap to the raised platform.  The battery pack feeds power to the RPi via a USB-micro-USB cable, and the RPi talks to the Arduino Uno via a USB cable, rather than the GPIO RPi pins to the Arduino pins that several other people use.

I'll go into more detail later on the assembly and programming of this robot.  For now, it's not autonomous.

However, as of this evening, I was able to sit at my MacBook Pro and use the WiFi network to drive the robot around my house by moving a little and then viewing the camera image after subsequent moves to see where the robot was located.  So that was fun.

Starting the blog

I've been working on a robot hobby for about a year and a half.  My inspiration has been the Mars rovers that JPL has successfully landed on Mars.

It started out as an Arduino stack running on a Tamiya tank platform, but it has recently evolved into a Raspberry Pi connected to an Arduino stack via USB and mounted onto a Sainsmart robot platform, all communicating with my MacBook Pro via my in home WiFi network.

This project has proceeded in fits and starts for over a year, mainly in a few minutes stolen here or there or an hour or so on an occasional weekend.  It has been slow because I have a family and a job -- you know, a real life beyond the hobby.  And it's not even my main hobby.

Actually, what is my main hobby? ...

Anyway, I thought I'd start recording my work on a blog, since I don't really have notes of my progress to date.  And then -- and this is the important part -- I'd make this blog public, in case anyone stumbles across it, finds something useful, and maybe -- if I can figure this out -- leave some feedback.