OB1 is a Service Droid I bought for experimenting with at home. I am not a professional programmer so I want to experiment more with relatively simple, Arduino compatible controllers before moving on to more powerful 32bit controllers. The Service Droid only has two 3DOF arms but they are reasonably strong for the robots size and quite good at manipulating things.
OB1 is powered by 7x AA Sanyo 2700mAh NiMh batteries wired in series to provide 8.4V. I use NiMh batteries because they maintain a relatively constant voltage for about 90% of the discharge cycle and they are easy to charge. I've added an extra cell to the original 6xAA battery holder that comes with the Rover 5 chassis because the minimum voltage for the Spider controller is 7V so 7.2V is cutting it pretty close.
Because the wires on the battery holders are a bit thin and only good for about 1A I replaced the wires with much thicker wire that is rated for about 5A. The simplest solution is to solder directly onto the terminals. It does melt the plastic so you need to hold the terminal and wire in place until the plastic cools and hardens again. Even if you do not hotglue the battery in place you should at least put some hotglue over the soldered terminals to prevent accidental short circuits and support the wire.
The power circuit is very simple, when the switch is in the off position it connects the battery to the 12V DC input to be trickle charged. A 15Ω, 2W resistor limits the average current to about 200mA and the diode prevents the charging LED from being powered by the battery.
The Service Droid kit comes with eight servos. The two shoulder servos are heavy duty metal geared servos with about 13Kg.cm of torque @ 8.4V. The other six servos are low power servos that I run directly from the Spider controller at 5V. All servos have ball bearings on their output shaft.
His brain is a DAGU Spider controller which is equivalent to an Arduino Mega 2560 but with a 3A switchmode power supply and servo headers as well as female header for each I/O pin.
OB1has a 2 motor, 2 encoder Rover 5 chassis driven by a Mini Driver robot controller. The Mini Driver uses the Rover 5 encoders to measure distance and control the robots speed. This allows the motors to maintain full torque even at low speeds. The Spider controls the Mini Driver via I²C. The Mini Driver reports back the battery voltage and encoder counts for measuring distance.
The ultrasound sensor on the head combined with the encoders allow the robot to navigate by a combination of obstacle avoidance, dead reckoning and mapping. An IR receiver is used to receive commands from a universal TV remote.
A bluetooth module allows the Spider controller to communicate with an Android phone that runs an app for voice recognition and speech. Once communication is established, the Spider sends the phone a list of words it's been programmed to respond to including the robots name. When the phone detects a sentence that starts with the robots name followed by words from the list it sends a dtring of numbers back to the robot indicating the words recognized. When the robot wants to say something it sends the phone a text string to be converted to speech.
Pincer Servo Modification:
My pincer doesn't have any switches or pressure sensors but by monitoring the voltage on the feedback pin as the servo closes I can determine when the servo has gripped an object. Once the servo cannot move any more I can stop the servo and prevent damage to the servo.I don't do this with the sweeper mechanism as it's spring loaded.
Before I start modifying the servo I use a bit of hotglue to hold the servo body to the gearbox. If you dont do this then you will end up with gears everywhere.
Now when we remove the screws only the top comes off. We can now access the pot without the servo falling apart.
The black duck servos have reasonably long wires inside which make it easy to remove the PCB and access the pot. Servos have an internal voltage regulator. The actual voltage varies depending on the brand. Typically the pots will have this regulated voltage (less than 5V) on one side, ground on the other and the center pin is a voltage relative to the position.
Using the tip of my soldering iron I melted a small indentation in the casing for the sensing wire to come through. This wire will go straight from the servo pot center pin to an analog input.
Now it's just a matter of soldering the sensor wire to the middle pin on the pot. You might need some tweezers to hold the wire in place while your soldering.
Now the PCB goes back into the servo with the sensor wire underneath.
Now the cover goes back on the servo and with the sensor wire connected to an analog input I get a reading of 135 when the pincer is fully closed and 415 when the pincer is fully open which give me better than 1° resolution. If I was using a 3.3V controller then I would have better than 0.5° resolution.
I wanted to add some short range object detection sensors on the grippers to help the robot align it's grippers with an object. The cheapest, simplest way is to use the same IR receiver used for receiving IR remote commands. These sensors have an open drain output that pulls low when the receiver detects modulated IR. My receivers are sensitive to 38kHz however you can get receivers configured for different frequencies.
My sensors consist of an IR LED transmitter (left) that is driven at 38kHz using the tone() command. A transistor is used to switch the IR LED which draws about 50mA when on. The Arduino outputs are only rated at about 40mA maximum. The receiver (right) has an indication LED wired in parallel so that regardless of the code, I can see if the receiver is detecting a signal. As I am using a Spider controller I have wired my circuit into a 3 pin servo header to save space and simplify wiring.
Here is the IR LED, receiver and indication LED on the pincer. Be careful not to encase the receiver with hot glue as the receivers can be easily damaged by excess heat. I fried my first attempt.
Here is the IR LED, receiver and indication LED on theSweeper assembly. Because of the close proximity between the IR LED and the receiver I had to use a bit of heatshrink tubing otherwise the receiver was on all the time.
Some adjustment of the angle between the LED and receiver may be required so I had the power on and the IR LED pulsing at 38kHz while I was glueing the parts in place so I could adjust the angle as the hotglue cooled.
Although the distance that these detectors will work at varies depending on the size and colour of the object they can both detect my hand a few centimeters in front of the gripper which is what I wanted just for aligning the gripper with an object I want to pick up.
Changing the angle between the LED and the receiver can increase the range a bit. Increasing the current through the IR LED will increase the range more. The PN100 transistor I am using will easily handle up to 500mA but you must be careful to make sure the LED will not burn out. Refere to the LED datasheet or limit the current to 100mA maximum.
I'm in the process of automating OB1. He's still mostly remote control right now as it makes it easier to test / debug each autonomous function. During my testing I found my code for the Mini Driver was not sending back the encoder counts and battery voltage. I've now updated the attached software for the Mini Driver.
I've added my current code (OB1.zip), it is far from complete but some functions may be useful for other Service Droid owners with a similar configuration.
I was working on code for using the ultrasound in conjunction with the IR sensors to locate and pick up and object but I found the coffee cup I was testing with could be detected over a fairly wide range as the head panned from left to right. I started to do some experiments with adding blinkers / blinders to the ultrasound. The blinkers are made from my business cards.
These worked well to narrow the field of detection horizontally without impeding the range of detection vertically. This makes it much easier for the robot to determine where the coffee cup was. Then I decided to experiment more.
Now I'm fitting a servo behind the ultrasound that will control the blinkers to limit the detection range either horizontally or vertically depending on what the robot is trying to detect. To help with debugging code I decided to install an LCD display. This way I can have raw data from sensors displayed without needing a serial link to the computer. Fortunately the body of the Servce Droid seems to be the perfect size for the LCD display :D
As you can see in this photo I've mounted the contrast pot and backlight current limiting resistor directly onto the LCD display and just used some hotglue to protect from accidental short circuits. It's not the most beautiful solution but it works. I've used some of the spare screws and brackets that come with the Service Droid kit to mount the display.
When I have more time I want to add a graphics display so I can generate a "radar" style view of what the robot is seeing. I'll have to move the bluetooth module over to the shoulder to make room.
As you can see, OB1 has quite a birds nest of wires inside him now. The ability to flip the front cover open really helps when accessing your controllers. I've now used almost all of the "plain" digital pins on the Spider now. Most of the remaining pins are either analog inputs, digital pins with PWM or comms ports.
Tried to finish my blinkers. Working at home with virtually no tools and only hotglue, cable ties and polymorph for materials so the end results were less than ideal. In the end I abandoned the upper and lower blinkers as I do not have a need for them yet and concentrated on getting the left and right blinkers working.
You can see in the photo below, the servo mount and some other small bits are polymorph. The transparent rod is part of a plastic frame thats been heated with a cigarette lighter and stretched / bent to suit my needs. The spring is from a pen and the flexible struts from the clear rod to the blinkers are offcuts from small cable ties.
I need to do some more testing to see how well the blinkers work. If they work well enough then I'll remake them and try to include vertical as well as horizontal blinkers.
Well that 16x2 LCD display was good for some debugging but now I want to "see" what the robot sees so I changed over to a small graphics display. The KXM1286J-4 is a white on blue 128x64 graphics display. These days there are lots of nice little graphics displays available but I just want a simple graphical representation of the signals from the ultrasound like a radar display.
It makes a neat little backpack and like the last display, I mounted it using spare brackets that came in the Service Droid Kit. I also angled it upward a bit so it was easier to read.
The Arduino Library I used was GLCDKS0108 written for LCD displays like this that use the KS0108 driver IC. After reading the instructions carefully I tried to reconfigure the pins used so I would not have to re-wire my robot. Unfortunately after a day of reading every file in the library I could not get the library to change from the default settings. I even deleted the config files all together and the code compiled as though the files still existed. So for now I have surrendered to the Gods of frustration and rewired the rest of the robot around the default pins used by the library.
I now have a simple radar style display setup on the graphics LCD. This is a great debugging tool when working with ultrasonic or infrared rangefinders. I've posted a video showing the first test at close range. I've actually got OB1 scanning the tabletop in front of him. He's looking down at about a 20°-30° angle. There are two semi circles drawn on the display. The small circle shows the range at 5cm. The large circle shows the range at 60cm.
My blinkers did not work as well as I hoped although I think this was due to the close range. Now that I have the display working I can do more experiments to try and increase the precision of the ultrasound. You can see in the video and the photo above that the beer is detected over an angle of about 15° even though in reality it probably only takes up about 5° of the robots field of view.
I recently tried to display the results of my IR gripper scan on the LCD display. Unfortunately everything that could go wrong did. One of my IR LEDs stopped working due to a solder joint breaking when I rewired the robot for the new display. The sweeper servo burned out in one direction because I didn't set the limits quite right and the IR sensor is getting some false readings it didn't get before, maybe due to the re-wiring.
Last but not least, my encoders seemed to loose accuracy on smaller distances. When trying to move just a few encoder counts at a time the counters would count but the wheel did not turn. It turned out this was because I was a bit lazy when I wrote my software for the Mini Driver.
I did not uses the quadrature function to measure direction. my code assumed direction based on what direction the motors were supposed to be going in rather than what they actually were. As a result, mechanical vibration and "bounce" from pulsing the motors was causing the encoder disc to go backwards and forwards by very small amounts. Just enough to trip an encoder sensor sitting between one region and another of the encoder disc.
I've now updated the code using my code in this tutorial and solved the problem. I've attached V1.2 of the code for anyone interested. OB1 can now maneuver with much better precision.
I always planned to use 7x 1.2V AA NiMh batteries (8.4V) but with work I never had time to add the extra cell. When the NiMh are first charged their voltage is higher than the 7.2V nominal voltage and the robot works fine on just 6 cells however after 10-15 minutes of run time the voltage drops down to 7.2V and then any dip in the voltage can cause the Spider controller to reset because the switch mode regulator needs at least 7V. Now with CNY holidays I finally added the 7th cell.
My original thinking was that the shoulder servos, which are powered directly from the batteries survive fully charged 2S LiPos (8.4V) so this should be OK. However, because the batteries have a higher voltage when freshly charged, according to OB1's battery monitor (built into the Mini Driver) the voltage after being trickle charged overnight peaks at 10V!
Considering the servos maximum rating is 7.2V, 10V is just too much and as a result, during testing I did have one servo fry even though it was not under load or even moving at the time. I had left the robot on just to watch the battery voltage slowly drop while I worked on the code.
I admit, I had already suggested to OrionBot that 2x or 3x 1N5401 3A diodes should be wired in series with the servo power to drop the voltage. These general purpose 3A diodes will drop the voltage by aproximately 0.7V - 0.8V depending on the current. This trick with the diodes is not the best solution but it is the cheapest and easiest which is why I mention it.
The best solution would be a 5A, LDO LM1084IT-ADJ adjustable regulator configured to supply 7V for the 2 shoulder servos. As this regulator will get hot and need a heatsink I am planning to use 1 for each shoulder servo. There is plenty of room in the shoulders and by having 1 for each servo the regulators will not get so hot and can use smaller heatsinks.