Armdroid 1

A blog covering the restoration work of a 1980's Colne Robotics Ltd. robotic arm called ARMDROID 1 and interfacing to modern day computer systems such as Raspberry Pi, Arduino, IBM PC, Mobile computing devices, and more... We'll also make use of rich development technologies on the way to build some truly exciting projects. Also now covering the Armdroid 1000 by D&M Computing Inc. and later LabVolt models.

Pages

Wednesday, 19 August 2015

For all of my projects I have used the standard digital output pins when connecting to the Armdroid's 8-bit parallel interface. But, what if you want to free up some of these pins in order to use external sensors, controls, or other devices...

The easiest way of getting more inputs and outputs is to use an "i/o port expander". This is a device that allows you to control a number of ports using data sent to the device. A port expander takes the data and controls the appropriate I/O pins.
This allows lots of sensors and devices, including the ability to control multiple Armdroids using only a few pins on the Arduino board.

The device I chose was the PCF8574A which has eight general purpose input/output pins controlled using I2C (pronounced I-squared-C). I2C is a serial communications protocol allowing ICs to swap data on the same two-wire bus - Serial Data Line (SDA) and Serial Clock Line (SCL).

There are other devices available supporting 16 ports (eg. MCP23017), or SPI buses (eg. MCP23S17) and are similar in usage. Although SPI (10Mhz) is faster than I2C (1.7MHz), for our purpose interfacing the Armdroid, it doesn't really make much difference

Pinouts

PCF8574A pinouts

The expanded I/O port are Pins 4-7 and 9-12 to be connected to the Armdroid interface D1-D8

Three address pins A0, A1, A3 determine the chips ID and must be wired to either +5v or GND.

The address of the PCF8574A is hard-coded to 0x38 by grounding A0, A1, and A2. I would recommend starting with these settings until you have something working.

Code

Surprisingly, the code changes to support the port expander in the
Armdroid Library are minimal thanks to C++ inheritance, and the Arduino
'Wire' library.

When designing the Armdroid library, flexibility was foremost, and it was always my intention to allow the library to be easily adapted for use in different projects.

To make this possible, core functionality was implemented in an abstract base class which can be derived into specialized classes. This base class doesn't actually have any knowledge how control the hardware, rather, its up to the derived classes to implement that. Another potential use in future might include supporting optimized versions for different Arduino boards.

This implementation adds a new member function ArmdroidPortExp::begin(uint8_t address) responsible for setting up the I2C hardware, and stores the supplied address of the port expander. We also take the opportunity to initialize the Armdroid interface at this point.

The virtual function ArmdroidPortEx::armdroid_write(uint8_t output) simply writes a byte to the port expander using the address supplied earlier. This is all done using the 'Wire' library that conveniently abstracts us from low-level I2C protocol/transmission details:

It wasn't possible to add this code to the library without introducing a dependency on the Wire library due to an 'oddity' with the Arduino IDE build mechanism. If you intend to make use of these extensions, you will need to first install the Armdroid-Arduino-Library, then follow the instructions to install Armdroid-Arduino-PortExp

Included with this library is a modified version of the AsyncDemo previously presented with the Asynchronous library enhancements.

Sunday, 9 August 2015

I've been making several enhancements to Armdroid Library to support Asynchronous operation. This means its now possible to drive all motors, and still do other processing at the same time - for example listening to the serial port for stop requests etc.

You may recall in my last post, when driving motors for very long durations, its simply not possible to interrupt things until all motors reached their target positions. This has been a limitation for sometime - and with hindsight, I really wish I had implemented the library slightly differently in the first place.

Advanced users will welcome these changes, although you can still use the existing drive methods which have been retained for compatibility with existing sketches/projects.

and complimented by the following control methods: ArmAsyncState getAsyncState()bool isRunning()bool Start(MTR_CHANNELS target)bool Pause()bool Resume()bool Stop()

To asynchronously drive motors, you must call driveMotorsAscynchronous() in your sketch loop() function. This handles timings and pulses stepper motors when ArmAsyncState = ASYNC_DRIVE_RUNNING. To enter this state, you call Start() with arguments to specify the target position for each motor channel.
Multiple calls to Start() are possible, but the current implementation does not wait for the existing target positions to be reached before running to new targets. This behavior was intentional as you can always implement a data structure to cache requests as necessary.

To cancel running motors at any time, call the Stop() method which cancels the asynchronous run request, and stops all motors dead.

Likewise, Pause()/Resume() allows you to pause and resume movements, but does not cancel the asynchronous run request.

The asynchronous extensions implements a simple state machine, so the ArmAsyncState enumeration has been provided to allow programmers to evaluate the state at any time.

To demonstrate the concept - the following example shows how to send commands over serial and allows users to cancel movements, at any time, no matter how lengthy the motor operations are.

You can send bytes to the Arduino from any software that can access the computer serial port.

I'm currently working on a revised specification for the Armdroid Serial Protocol to include these changes and streaming modes. In the meantime, I've included this demonstration (AsyncDemo) in the examples directory.

Monday, 13 July 2015

Back during Easter Bytes at TNMOC, a visitor to the museum asked if it's possible to control the Armdroid on display using their Mobile Phone or Tablet Device... This got me thinking, and decided to hack something together for the following weekend...

If your interested in controlling your Armdroid using Wi-Fi or across the internet, here's how you can setup your own stand-alone, web-enabled Armdroid, using the Arduino Yun. When you're done, you'll be able to control your Armdroid using any web-browser, or control programmatically over the internet using Python or other scripting languages.

What exactly is the Arduino Yun you might be asking.... It's basically a combination of a classic Arduino Leonardo (based on the ATmega32U4 microcontroller) with a WiFi system-on-a-chip Atheros AR9331 running Linino (a MIPS GNU/Linux distribution based on OpenWrt). The two processing units are connected together using the Bridge library allowing you to combine the power of Linux with ease of Arduino.

OpenWrt supports REST services for clients and servers. REST is an acronym for "Representational State Transfer". It is a software architecture that exposes functionality through URLs. REST has gained widespread acceptance across the World Wide Web as a simple alternative to SOAP and WSDL-based web services. A nice introduction to the concepts behind REST can be found here.

This project implements an Armdroid REST API allowing functions of the robotic arm to be manipulated through URLs. I've prepared a simple web page that consumes this service to get you going, although you could easily interact with this from say, a Raspberry PI using the CURL library, etc.

The photographs above shows the project from Easter Bytes. In this arrangement, we configured the Yun's WiFi as a standalone Access Point - visitors would simply connect to this network using a Mobile Phone web-browser, then take control. This actually proved to be a real hit with many visitors to the museum, and was especially rewarding to get usability feedback from a 7-year old! (pictured)

You can see the simplicity of the set-up in the following photographs:

If you wish to use the sample web page, you'll need to prepare a memory card by creating the directory structure "arduino/www" which ensures the Yun will create a link to the SD card "/mnt/sd" path.

The REST API is structured around verbs and Armdroid functions - for example, you want to move the shoulder stepper motor x steps, you would simply issue an HTTP web request like http://arduino/armdroid/shoulder/position/x. Likewise, other Armdroid functions are described by their function - base, elbow, gripper etc.

If you wish to determine what is the current location for any stepper motor, you would use a URL such as http://arduino/armdroid/shoulder/position (without position value) and this will return in the response the offset counter for this channel.

The code begins by reading the client URL and tries to match the "position" command. If this is present, we can then determine if the URL is specifying a value representing the position in which to drive the motors, or alternatively, we'll simply report on the current position. If we do have a valid "position" command then we look to see if a speed has been specified. If this is not the case, the default (120 RPM) will be used instead.

If the command matches "sensor" then we have the ability to return the current sensor reading for the given channel.

In either case, after calling the Armdroid Library to perform the desired function, we send feedback to the client such as the new position after the operation completes.

Limitations

Yun's web server times-out after approximately 5seconds when performing lengthy Armdroid operations. This is mostly due to the design of the current Armdroid Library which is synchronous in operation, or blocking, when running motors for long periods of time. In this situation, a response doesn't get returned from the microcontroller before the web server gives up, and returns 500 (Internal Server Error) back to the client.

This isn't immediately obvious using the example web page, although can be easily demonstrated when browser debugging is enabled:

Fig 1. short base rotation (200 steps)

Issuing the request /arduino/armdroid/base/position/200 rotates the base stepper motor 200 steps resulting in HTTP status code 200 (OK) returned. You can see the reply includes our JSON response indicating the position (current offset counter) of this motor channel after performing the operation.

Now observe what happens when the request is made with 2000 steps:

Fig 2. lengthy base rotation (2,000 steps)

HTTP status code 500 is returned after 5seconds, and before the motor has finished running. By the time the motor reaches the target position, the connection no longer exists, no response is returned.

We'll revisit this when Asynchronous enhancements have been added to the library, but in the meantime, you can work around this by calling the API to retrieve the current position and wait if necessary until the previous operation has completed.

The sample web page included with the example is very basic... It serves purely as a demonstration only... if you want something with more sex appeal, you might want to look at DoJo or similar frameworks to create a richer experience.

Tuesday, 13 January 2015

Today, I'm going to share with you my Armdroid Remote Controller project, which was quickly hacked together for demonstrating the Armdroid 1 during a recent meeting of volunteers at TNMOC.

The circuit makes use of a single TSOP4838 IR receiver module along with some rather cleaver programming that decodes key presses and operates various Armdroid functions.

I'll be including the source code for this project as an example sketch in the forthcoming release of Armdroid Library on GitHub.

The project works surprisingly well, although movements to preset positions are made point-2-point (P2P), which is slightly different to continuous path movements. This is after all, a demonstration, although could be easily extended to support waypoints and recording/playback of movements.

I've been using an old Sky remote control handset, you'll need to change the scan codes to match your hardware, although instructions will be included how to do this.

Connecting an infrared receiver module is relatively simple, the sensor output is connected to a spare digital input on the microcontroller.

ArmdroidShield (version 1) utilizes pins 2-9 for connecting to the Armdroid's 8-bit parallel interface, so pin 10 was chosen for this purpose, along with +5V and Gnd connections. There are many common IR receiver modules available. Check the datasheet for your device to ensure that you connect it correctly.

The software works by decoding the IR signals to digital pulses that correspond to buttons on the remote. A scan code lookup table is then used to assign Armdroid functions to key presses. This table uses function pointers to simplify the program logic, also included are methods for Rolling/Pitching the Gripper, along with routines for calculating target offsets when moving to new positions.

Saturday, 15 November 2014

The restoration of TNMOC's Armdroid is getting closer to completion, and attention has shifted towards designing suitable displays for the robot at the museum.

Initial displays are likely to be Arduino based, and in time, we'll probably add other historical computers into the mix. In the meantime, something I had not given much thought about, was what to do with my 'temporary' breadboard interface that's been used over the past year, a more permanent solution is however needed.

So, a couple of weeks ago, I decided to design a PCB to be called.... wait for it.... ArmdroidShield !

Having a purpose made PCB will of course be more reliable, and better suited to a harsher museum environment. The goal was to keep things flexible - perhaps we'll use these at a future Summer/Winter Bytes and students can design other Armdroid-based control systems, so making the board using a Shield design, was an obvious choice.

This was my first attempt at designing a double-sided PCB. Fortunately, the design doesn't require many components, so from start to finish - 2hrs including inspection of final design, and correcting contacts positioned too close together.

The PCB arrived the following week directly from the fabricator, and as you can see the results are pretty good:

The shield has been designed around the Arduino R3 header standard making it compatible with the following products:

Arduino Uno (Revision 3)

Arduino Leonardo

Arduino Yun

Arduino Ethernet

Arduino Tre & Arduino Zero (when available)

It's a very simple board, really just an adapter - only Digital Pins 2 through to 9 are utilized, along with common grounds.

The tricky bit was soldering the Stackable Headers and keeping everything properly aligned, but with perseverance, got there in the end.

Tuesday, 16 September 2014

Finally, the original proximity sensors have been refitted to my Armdroid, and a new wiring harness completes the installation work. As you may recall, they had been removed earlier when diagnosing tight-spots in the mechanics.

Machining new aluminum spaces was probably the most time consuming part. The original spaces were in bad shape and had a tendency to rub on the reduction pulleys with the timing belts, this caused friction and as result, performance suffered.

The sensors are aligned perfectly to reduction gearing. Setting up can be tricky - a multimeter comes in handy for testing, and making position adjustments.

All sensors have been positioned within a millimeter of reduction gearing, and more importantly, no longer make any physical contact.

The new 6-core wiring harness, connecting the four sensors mounted on the rear support bar, front-mounted gripper sensor, and Base position sensor was installed:

The hand sensor is still a mystery, see previous post Magnet Madness
For now, accepting the fact this won't do anything useful, have purposefully left disconnected and will decided later what I'm doing here.

Update: Its a shame Colne Robotics didn't invest in designing a decent gripper tension feedback mechanism similar to that employed in the Microbot MiniMover-5 triggering a micro-switch contact under tension, or the gripper is completely closed.

Pictured to right - TNMOC/Armdroid showing sensor installed under Right-Hand Wrist function. Not convinced this is correct either, sure, it will work, but leaves the Left-Hand Wrist monitored by only one sensor.

Another grey area in the instructions is chassis grounding - prototype models had their 7805 voltage regulator bolted to the chassis which grounds the circuit to the metal work. Later, single-interface models do not do this, so a chassis ground cable was included in my wiring. This will allow me to easily switch between interface circuits.

Tracing the circuit, the majority of the 14-pin header for the feedback sensors are ground connections.
Also, note, in Input Mode, the port address line D2 (header pin 8) is spare - no connection

This configuration is likely to change, but these are my current assignments:

Armdroid 1S

Armdroid 1000

About Me

...is a professional software engineer with interests in embedded systems, mobile technologies, electronics, robotics, and all things geeky!

I was an early developer of Windows CE, building the first ETL monitoring application for Pocket PC and Windows Mobile devices. I now practice in Android development for mobile apps, and find this a far superior platform. On the desktops, I have experience of pretty much every technology you can imagine...

I hold one Patent in the United States, and have further filings pending in the United Kingdom.

Volunteer at The National Museum of Computing (TNMOC), located at Bletchley Park, helping to look after the collection of historic computers & robots.