Robot Arm Software
Pages: 1 2
andym (447) 464 posts |
Does anyone know if the wimp-based Robot Arm software (as seen on ROOL’s stand at shows) for the Maplin Robot Arm is available anywhere? I do some work with an older group of tech users and they’ve just built the Robot Arm but could only control it from Windows. The Raspberry Pi install just didn’t work. It’d be great to sneak in a “RISC OS can do it easily” installation on the group’s Raspberry Pi. |
Andrew Conroy (370) 724 posts |
Hi, the wimp Robot Arm software on the ROOL stand was written by me! After seeing Neil Fazakerley demo the robot arm at the London Show in 2013 I went out and bought one, but then discovered that Neil hadn’t released the desktop software he was demoing. I got bored of waiting, so wrote my own. I haven’t released it publically because I didn’t want to tread on Neil’s toes as he was clearly there first. If you’d like a copy though, drop me a line to a.m.conroy@owlart.co.uk and I’ll send it through. Oddly, I was going to post and offer my robot arm and software to anyone who might have wanted it to demo at Recursion anyway! |
Jeffrey Lee (213) 6046 posts |
Of course the danger with that approach is that neither bits of software might ever get released, leading to more people creating (and potentially never releasing) their own versions! |
Neil Fazakerley (464) 124 posts |
The wimp version I wrote a few years ago had too many niggling issues to be sorted for general release. I gave up trying to fix them and chopped the whole thing down to a minimalist, single-tasking program called NanoArm for the RISC OS Pico release. I distilled it down to just half a screenful of Basic in the end. It’s out there if you want to try it. Recently though I heard that the makers of the Maplin arm have introduced a different PID in the latest firmware, which stopped my old program from working. So I’ve updated my original code to check for both old and new PIDs and cleaned up the screen presentation a bit. This version (NanoArm3) includes a ‘nudge’ mode, which is very useful for making tiny adjustments when you’re stacking lots of objects. The LED can be switched on and off and there’s even a readout of the current battery voltage, so you can see when it’s time for some fresh cells. REM NanoArm3 - a simple Maplin/OWI precision arm controller for Raspberry Pi RISC OS, Neil Fazakerley, Nov 2017. MODE MODE: OFF ON ERROR ON: CLS: REPORT: PRINT " at line ";ERL': PROCsend(0,0,0): SYS "OS_Byte",12,0: END PROCinit_usb val%=16: num%=0: r%=0: c%=0 SYS "OS_Byte",12,1: REM Sets fastest key repeat rate. SYS "ColourTrans_SetTextColour",(15<<24)+(200<<16)+(255<<8),,,128 COLOUR 0,0,0 GCOL 255,200,15 RECTANGLE FILL 300,1000,1200,880 PRINTTAB(30,22) "NanoArm 3" PRINTTAB(30,23) "---------" PRINTTAB(30,26) "A precision USB controller for those ubiquitous" PRINTTAB(30,28) "yellow and black Maplin/OWI robot arms" PRINTTAB(30,34) "Keys:" PRINTTAB(30,36) "1 - Grip";SPC(20);"> - Forward" PRINTTAB(30,38) "2 - Wrist";SPC(19);"> - Shift to 'nudge'" PRINTTAB(30,40) "3 - Elbow";SPC(19);"< - Reverse" PRINTTAB(30,42) "4 - Shoulder";SPC(16);"< - Shift to 'nudge'" PRINTTAB(30,44) "5 - Base";SPC(20);"ESC to quit" PRINTTAB(30,46) "6 – LED on/off" PRINTTAB(30,50) "Battery level: ";FNget_volts;+"v" PRINTTAB(58,54) "ELBOW active (1) " REPEAT WHILE INKEY(-104) AND NOT INKEY(-1): REM ">" byte%(num%)=val%*2: r%=1 PROCsend(byte%(0),byte%(1),byte%(2)) ENDWHILE WHILE INKEY(-103) AND NOT INKEY(-1): REM "<" byte%(num%)=val%: r%=1 PROCsend(byte%(0),byte%(1),byte%(2)) ENDWHILE IF INKEY(-103) AND INKEY(-1) THEN byte%(num%)=val%: r%=1 PROCsend(byte%(0),byte%(1),byte%(2)) t%=TIME: REPEAT UNTIL TIME>t%+2 ENDIF IF INKEY(-104) AND INKEY(-1) THEN byte%(num%)=val%*2: r%=1 PROCsend(byte%(0),byte%(1),byte%(2)) t%=TIME: REPEAT UNTIL TIME>t%+2 ENDIF IF r% THEN byte%(num%)=val%*3: r%=0 PROCsend(byte%(0),byte%(1),byte%(2)) t%=TIME: REPEAT UNTIL TIME>t%+14 ENDIF IF INKEY(-49) val%=1: num%=0: byte%(1)=0: c%=1: PRINTTAB(58,54) "GRIP active (1) " IF INKEY(-50) val%=4: num%=0: byte%(1)=0: c%=1: PRINTTAB(58,54) "WRIST active (2) " IF INKEY(-18) val%=16: num%=0: byte%(1)=0: c%=1: PRINTTAB(58,54) "ELBOW active (3) " IF INKEY(-19) val%=64: num%=0: byte%(1)=0: c%=1: PRINTTAB(58,54) "SHOULDER active (4)" IF INKEY(-20) val%=1: num%=1: byte%(0)=0: c%=1: PRINTTAB(58,54) "WAIST active (5) " IF NOT INKEY(-53) key6%=FALSE ELSE IF key6%=FALSE byte%(2)=NOT byte%(2): key6%=TRUE IF c% c%=0: PRINTTAB(30,50) "Battery level: ";FNget_volts;+"v " IF byte%(2) PRINTTAB(30,54) "LED on " ELSE PRINTTAB(30,54) "LED off" PROCsend(0,0,byte%(2)) UNTIL FALSE END DEF FNget_volts SYS "DeviceFS_CallDevice",1<<31,usb$,,receive_bmRbRwV%,receive_wIwL%,receive_buffer%,timeout% =receive_buffer%?0*2.4/100 DEF PROCsend(byte0%,byte1%,byte2%) send_buffer%?0=byte0%: send_buffer%?1=byte1%: send_buffer%?2=byte2% SYS "DeviceFS_CallDevice",1<<31,usb$,,send_bmRbRwV%,send_wIwL%,send_buffer%,timeout% ENDPROC DEF PROCinit_usb name$="OWI 535 'Robot Arm Edge'" device_number%=0: timeout%=100: device$="" DIM device_buffer% 255,send_buffer% 8,send_byte(8),receive_buffer% 8,byte%(8) send_bmRbRwV%=&40 OR (&06<<8) OR (&100<<16): send_wIwL%=3<<16 receive_bmRbRwV%=&80 OR (&06<<8) OR (&A00<<16) receive_wIwL%=2<<16 SYS "XOS_ReadVarVal","usb"+"$Device_00_00_00_1267_0000_-1*",device_buffer%,255,0,3 TO,,size% FOR index%=0 TO size%-1: device$+=CHR$(device_buffer%?index%): NEXT index% IF VAL(device$)=0 THEN SYS "XOS_ReadVarVal","usb"+"$Device_00_00_00_1267_0001_-1*",device_buffer%,255,0,3 TO,,size% FOR index%=0 TO size%-1: device$+=CHR$(device_buffer%?index%): NEXT index% ENDIF IF VAL(device$)=0 THEN PRINTTAB(10,20)'" **** Robot arm not found ****"': END usb$="USB"+device$ ENDPROCGive it a try, and let me know if you find any bugs. |
mikko (3145) 120 posts |
Good to see an update to this, Neil. I’ll try it out tonight. |
mikko (3145) 120 posts |
Hi Neil, There is a small bug. I’ve got a device id that doesn’t match the first pattern looked for: "$Device_00_00_00_1267_0000-1*" My id is of the type:
But the subsequent attempt to match the device id of that type fails because device$ has not been reset. The code works for me with this amendment: SYS "XOS_ReadVarVal","usb"+"$Device_00_00_00_1267_0000_-1*",device_buffer%,255,0,3 TO,,size% FOR index%=0 TO size%-1: device$+=CHR$(device_buffer%?index%): NEXT index% IF VAL(device$)=0 THEN device$="" SYS "XOS_ReadVarVal","usb"+"$Device_00_00_00_1267_0001_-1*",device_buffer%,255,0,3 TO,,size% FOR index%=0 TO size%-1: device$+=CHR$(device_buffer%?index%): NEXT index% ENDIF But rather than do two separate tests for the different device ids, this less less specific match works for both device id types above and should work for any new ids up to 9. SYS "XOS_ReadVarVal","usb"+"$Device_00_00_00_1267_000*",device_buffer%,255,0,3 TO,,size% FOR index%=0 TO size%-1: device$+=CHR$(device_buffer%?index%): NEXT index% |
Rick Murray (539) 13405 posts |
I have written a simple little script interpreter for the Maplin/OWI USB arm. https://www.heyrick.co.uk/blog/index.php?diary=20171226 YouTube video of it in action: https://www.youtube.com/watch?v=ZEBBz12pOSU Have fun! |
mikko (3145) 120 posts |
Excellent! Nice job, Rick. |
Norman Lawrence (3005) 171 posts |
I got one of these Robot Arms as a present for Christmas and this thread was just what I needed to control it with my RPi 3. Big thanks to Rick, Neil and Andrew for sharing your software. As always the question “what next?” comes to mind, perhaps some feedback control mechanism to avoid too much click click click at the end of the travel? |
Rick Murray (539) 13405 posts |
You’re welcome.
The idea that I had (and later discovered somebody has already done) was to drill small holes in one of the gears and use an optosensor like in the old mice (David Pilling suggested ITR9606), along with a small microswitch to detect the end of travel in one direction (the other end point can be known by calibrating how many gear turns from the ‘known’ side). As for the grip, measuring motor current may let us know when something has been gripped. The problems that come to mind are…
Just off the top of my head… That said, the original controller looks to be pretty simple. A clever USB interface IC and three motor controller ICs (two dual motor and one single motor – for the five motorised mechanisms). It’s a single layer board and it is – unbelievably – all driven from the same two batteries (yup, motors and microcontroller both!). That explains the electrolytics… Somebody skilled in making PCBs could make up a replacement. |
Norman Lawrence (3005) 171 posts |
Rick thanks for great suggestions. Fitting a micro switch sounds quite doable but fitting five optosensors into the gearboxes could be challenging and as you note slew in the gear mechanisms is an extra level of complication. I would have no idea about different controllers and the programming involved. My only observation would be that moving over to the GPIO pins would limit the Robot Arm to Pis whereas at the moment it should work on a wide range of RISC machines. Plenty to chew over. |
Andrew Conroy (370) 724 posts |
I looked at the possibility of adding tilt sensors to the arms, so you could monitor the angle of each section of the arm and so know where it was. You’d need something else for the rotation of the base though. I got as far as code to monitor I2C tilt sensors, but never developed it further. |
Rick Murray (539) 13405 posts |
That’s the conclusion I quickly reached.
That’s why I considered something like a Pi Zero (or older Pi1?) to replace the original controller. As it stands, we have one LED and five motors (bidirectional). Add to that at least four microswitches, eight if you want to accurately track both limits of movement. Then four opto sensors (or tilt sensing), and finally something to measure the grip (my idea was to monitor motor current to detect stalling). We can ignore battery voltage, this will surely be externally powered. |
Andrew Conroy (370) 724 posts |
I was thinking a pressure sensitive resistor on the pincers might work too :-) |
John Williams (567) 768 posts |
or how about a microswitch and a rubber pad of just-right resilience and thickness to allow for the desired grip-strength. The pad would also allow for a little over-run on the gripping after the switch had operated, so some measuring of the grip force would be necessary to select the compressible pad material and its thickness. Could an electronic kitchen scale be adapted, I wonder? |
Andrew Conroy (370) 724 posts |
That’s effectively what the pressure sensitive resistor is, isn’t it? |
John Williams (567) 768 posts |
Yes, but I’m talking there about calibrating an effectively simpler on/off control to the required grip, not making a kitchen scale! That is, choosing a weight and thickness of a suitably compressible material to permit the use of a microswitch. Once that is chosen the analogue calibration tool is no longer required! The chosen grip strength is set by the properties of the compressible pad, also taking into account any inertial over-run on the gripping motor mechanism! |
Rick Murray (539) 13405 posts |
Running the grip motors normally (not pulsed) takes about a second and a bit to go from fully open to fully closed. The pad is a piece of softish rubber. Hence I’m not entirely certain that it’s really viable to control grip “strength”. Just don’t pick up eggs… |
Norman Lawrence (3005) 171 posts |
Just noticed this article on the Arm Robot and they use potentiometers to create a feeback loop. http://www.instructables.com/id/Intro-and-what-youll-need/
Do you think that the Zero could replace the Arduino in the above article? |
Rick Murray (539) 13405 posts |
If using pots…does the Pi have enough ADC inputs to read them all? |
Neil Fazakerley (464) 124 posts |
I included current sensing for the gripper 3-4 years ago when I first demoed the arm’s driver prog at a Risc OS London Show. It works… some of the time. The problem is that all the motor gearboxes have clicking cog clutches built in, to prevent little hands driving the axes beyond their limits. The gripper uses this system to prevent it applying a crushing force to objects. The excess current signature is quite subtle though and varies with the state of the batteries. By the time the driver code has recognized the excess current flow, the motor’s clicking clutch has often already been triggered. Every time the clutch clicks, the grip is released slightly and then reapplied. That momentary release is often enough to drop the object. Eventually I removed the code as it wasn’t worth the effort to fix further and often left users confused with its lack of consistency. Regarding the batteries in the base. The arm does use all four batteries to carry out its tasks, but not quite in the way you’d expect. It uses all four batteries for weighted ballast to stop the arm tipping over when it’s doing extended lifts. Removing two of the batteries would not be a good idea unless you replaced them with similar weights. The extra two batteries can also form a useful spare set to switch to when the first two are run down. Incidentally, all four batteries are used for power in the manual control version – providing + and – power polarities to the controller’s switches for forward/reverse motor control. |
Norman Lawrence (3005) 171 posts |
The Pi does not have any ADC inputs but with suitable interface devices it can have sufficient. For example one I2C device from AB Electronics (costing 17 GBP with VAT) https://www.abelectronics.co.uk/p/69/ADC-Pi-Zero-Raspberry-Pi-Analogue-to-Digital-converter provides 8 inputs but can be piggy backed to provide up to 32 ADC input channels. @Neil Perhaps the idea of a pressure sensitive resistor would work for the gripper, what do you think? |
Rick Murray (539) 13405 posts |
There certainly isn’t much subtlety there. You can see the clutch problem in the first video (manual control) when I try to pick up the TED USB key.
Yes, I figured this out when I saw a video of a guy building the manual version. The controller was stupid simple, so I’m guessing the orange centre tap was treated as 0v, and the toggle switches would select +ve or -ve relative to the centre. For the grip, perhaps simplest is best? A simple microswitch. You’d still need to pulse the grip closed slowly to avoid gear clicks when the grip is ‘firm’ (in other words, running the motors normally until the switch is triggered then stopping is extremely unlikely to work reliably, if at all). |
Neil Fazakerley (464) 124 posts |
A quick scan of the various YouTube videos of this arm shows that all sorts of position sensors and switches have been schemed out and tested in recent years. To my mind, they all add too much weight and complexity to each axis and require a plethora of extra wires, plugs and interfaces for them to function. The most attractive qualities of this little arm are its ubiquity, cheap price, cross-platform simplicity (USB) and single-cable plug-and-go functionality. Whatever sensors or position aids are added, a main aim should be to retain as many of those qualities as possible. @Lawrence. Some kind of pressure sensor does seem an obvious area to look at. It would need to be simple and cheap though – I wouldn’t put it past the Chinese but I’m not aware of anything that fits the bill at the moment. |
Steve Pampling (1551) 7932 posts |
Any of the attempts done using two sheets of foil separated by a bit of foam as the sensor? |
Pages: 1 2