Posts Tagged ‘Tutorial’

Shakeable Dynamo Part 1: Why bother?

brother-battery

[ad#Google links]

First of all I have to start by condemning Brother Industries for what ultimately motivated me to build this basic prototype, allow me to explain and I apologise for the rant, the good stuff follows…

I read an article on the BBC news website (Vibration packs aim to replace batteries for gadgets) about a new type of battery developed by Brother that would require no external power source to charge it, just vibration from shaking it a few times. The aim being to replace batteries in low power applications such as TV remotes etc… thus removing alot of these batteries from the environment and ultimately saving energy.

A really nice, clean and elegant solution which could really benefit not only the developed world but for people in the developing countries. What a great company Brother Industries is until you read at the bottom of the article “There are no plans to commercialise the batteries as yet, according to Brother.”

Wait… So you’ve invented, or rather figured a way to not only replace millions of batteries in the common household, cutting down on waste and pollution providing free energy. But also a way to provide cheap portable power sources to people who can’t afford batteries, giving us as near as you’ll get to an ‘ever lasting battery‘!

And instead of rushing this to market, you do what… Nothing! Absolutely nothing. What a shame and a waste, I can’t help but feel that people at Brother have an interest in Duracell etc… as they obviously wouldn’t appreciate a battery that you don’t need to replace. It’s that kind of mindset of greed and ignorance that ruins the planet for the rest of us.

So this is leading somewhere, I assure you! I thought, how hard can this be to build my own – wouldn’t it be great to build a set of batteries that I could use to power my remote, wait wouldn’t it be even cooler to use this to power my Arduino? or even better build an interactive TV remote that you used like a wand to change channel with no power source needed. When you start imagining the potential applications and how this could revolutionise electronics and interactivity, its even more of a shame on Brother for doing nothing with this. Imagine Nintendo using this in their Wii remotes for instance? Imagine this being used to build a simple water tester… etc.

Anyway, here’s the start of it I’m going to show you how to build a basic dynamo with a bridge rectifier that converts our AC current to DC, and the size of it is not much bigger than an AA battery – it’s my first attempt and it turned out pretty well. It generates enough electricity to power an LED – doesn’t sound like much but when I figure out a condensing and charging circuit that’s when the fun starts – for which I’m hoping that you fine people of the web will help me out! :)

Ready to learn a bit about electro-magnetism and inductance?

Shakeable Dynamo Part 2: Building the initial dynamo
Shakeable Dynamo Part 3: How electromagnetic induction works
Shakeable Dynamo Part 4: Building the bridge rectifier

Arduino Robot Arm – LarryArm v0.1

Arduino-robot-arm

[ad#Google links]

I have constructed a basic Arduino robot arm using 3 servos that cost me £15 in total plus a couple of hours in time to build and it’s very simple that I think anyone can replicate and build this. I already had the Arduino Duemilanove ATMEGA328, some foamboard, tools and glue. The robot arm has 3 joints and moves in the X and Y dimensions – not the Z (although I will build this in subsequent versions). I’ve included some very basic Arduino robot arm code along with robot arm design / blueprints and measurements for you to download and build (on any material).

So firstly, I had a look around for robot arm kits that could be brought rather than fabricating the parts myself – I found the prices to be extremely prohibitive. I then looked at getting a design fabricated but most of the designs I’ve seen rarely give you or decent assembly instructions. I also looked at servo brackets and constructor sets but again whilst the odd piece is OK trying to get the parts for a robot arm is too expensive.

Where does this leave me, apart from being too poor to afford a robot arm kit? Well I thought how hard can it be to design and build my own robot arm? Surely I can do it for less and if it works I can publish the results and schematics rather than just a video of it working. So follow my below steps.

The first problem of designing your robot arm is how do you mount the servos? Most kits tend to use some kind of bracket that the servo is mounted into, the armature then mounted to this bracket. For a simpleton like me this seems like a lot of effort, my workshop skills not being that great and neither is my patience, I didn’t want to go down this route. After much thought I hit upon a simple idea, rather than build a bracket, how about altering the servo casing its self. They’re made from ABS plastic, they’re cheap and tough enough that drilling a hole to create a mounting peg should be easy, the drawing below shows where I added the bolt at the bottom, although measurements only show the nut the bolt is about 8mm in length – all depends on how thick your material is you’re using for the arm.

As you can see from the photos below, I take the base of the servo off and drill a hole in about the same position as the servo shaft at the top, this then allows me to place the servo directly into the armature using a bolt through the base of the servo so that it can turn freely in the arm without needing a bracket.

Robot Arm Servo Modification

 

Take the servo base off

 

Drill the servo base

 

Modded servo for arm

Arduino Robot Arm Design

 

Once this problem is overcome, the rest is easy. You can use my robot arm design below, click on the image to download the PDF:

Just print this off and stick it to the material that you’re cutting then cut the shapes out, if you’re using something more rigid than foamboard you won’t need the cross supports I added. I’ve also included a measurement of my servo in the diagram and remember to alter the measurements for the thickness of your material if needed (My foamboard was 5mm thick).

[ad#Google Ad in content]

Robot Arm Assembly Instructions

 

Robot arm

 

Robot arm parts

 

Assembling

 

Nearly finished robot arm

And as you can see from above the main arm gets assembled using nothing more than hot glue and my cutting isn’t even that neat. Here are the assembly steps:

1) Download and print my design
2) Glue the printouts to your material you wish to use
3) Cut all parts out
4) In joints B and D you’ll need to make a hole for the servo bolt to sit in – my drawings have this area marked as well as a larger circle for positioning the top of the servo
5) Now we fx the parts together, you’ll need to put the servos into joints A and C first, I used ht glue to fix the servo wheel to the arm, but you can screw it instead for a stronger fixing
6) With joints A and C in place we attach the joints B and D
7) Finally we attach joint A to a base so that we can counter weight the arm

[ad#Google Ad in content]

Robot Arm Arduino Sketch and Circuit

 

Thats it. Now we just plug the servos into the Arduino board and control them with a simple sketch (below). For the circuit I used a breadboard to share the power supply to all the servos and the outside pin (normally white or orange) gets connected to a PWM pin on the Arduino board (9, 10 or 11 in this case)

The control of the servos and the circuit is no more complicated than my other Arduino servo projects

/*
LarryArm v0.1 Arduino Robot Arm test sketch to check servos and arm works.
*/

#include  

Servo shoulder;
Servo elbow;
Servo wrist;
int pos = 0;    

void setup()
{
  shoulder.attach(9);
  elbow.attach(10);
  wrist.attach(11);
} 

void loop()
{
  for(pos = 0; pos < 180; pos += 1)     {                                       shoulder.write(pos);       elbow.write(pos);     wrist.write(pos);     delay(15);            }    for(pos = 180; pos>=1; pos-=1)
  {
    shoulder.write(pos);
    elbow.write(pos);
    wrist.write(pos);
    delay(15);
  }
}

With that loaded in I got the following result, it worked but there were a couple of bugs. Turns out the servos are using more power than my USB port to te Arduino board can provide, so I’ll have to run the servos on a separate power supply. Also turns out that you get what you pay for, I brought the cheapest servos and they struggle to accurately write their position. For anyone wondering what that is on top of the arm its just the heaviest thing I could find near by to counter weight the robot arm.

Enjoy!

Arduino – Redefining the TV Remote

TVRemotes

We use them every day, but has no one got bored of pressing buttons on a stick, it’s far too much effort pressing buttons! Surely there are better ways to control a device? After doing some work with my Nikon camera using IR to control it, I wanted to do the same with other devices. Check out the video at the bottom of this post…

However, unlike the Nikon remote, my Samsung TV remote has many many buttons so each IR sequence sent from the remote will be different. This can be a problem when you want to decode the signals, which while not impossible I am lazy, so thankfully Ken Shirriff has built a library to do just that and while its built for TV remotes you can decode an IR signal to its raw pulses using it. Essentially the library senses IR and notes each pulse and gap between pulses, Kens library saves a lot of time and its well coded – I’ll cover the basics of it in a bit.

My idea is to capture the IR sequences and then using the Arduino send them by using different inputs other than buttons. My first idea is to use my SRF05 distance sensor (You can use any distance sensor) and the premise being that different distances from the sensor send different signals to the TV. So rather than pressing a button you just wave your hand above the sensor. Of course this is slightly limited but since I only have 5 channels (yep – only 5!) so it turned out to be quite feasible.

There are drawbacks to this of course – the main one being that you can only define so many actions in the sensors dectection range. But there is plenty of range to do the basics, power, sound and channel and by constantly measuring distances we can even say the direction of movement, up to down and vice versa, can have an effect on what signal to send. For example moving your hand closer to the sensor will change the channel down.

So first of all you may want to read some of my other tutorials/projects concerning IR and the SRF-05 and Sharp IR (it should also work well).
Arduino Nikon IR Intervalometer Camera Remote
SRF-05
– contains handy wiring diagram!
Arduino and Sharp GP2Y0A02 Infrared distance sensor

(Other Arduino projects and tutorials)

OK, next take a look at Ken Shirrifs IR library and guide here:
http://www.arcfn.com/2009/08/multi-protocol-infrared-remote-library.html

Arduino TV Remote Components

Arduino
Breadboard
IR Diode
3pin (NPN) Phototransistor/ IR receiver (
Radio Shack 276-640 IR receiver, Panasonic PNA4602, Vishay TSOP4838 – or just get one out an old mouse)
SRF-05 (or any distance measuring device e.g. Sharp IR GP2Y0A02)
Jumper wires

Oh and stating the obvious but you’ll also need a T.V with working remote to steal the signals from – course you can use other remotes (stereos etc..)

The circuits themselves are very very easy to build, an IR LED to pin 3, a IR receiver to pin 11 and the SRF-05 I’ve plugged into pins 2 and 4. I have all of them in one breadboard and it works very well (see below).

Using Kens Arduino TV Remote Library

If you download the library and then unzip it to your Arduino/Libaries directory (older versions, I think its Arduino/hardware/libaries). The library assumes that your phototransistor/ IR receiver is on digital pin 11 and your IR diode is on digital pin 3. Typically you want a IR receiver with a 38Khz range – they seem to work best for me.

How to get our TV infrared/ remote codes

First of all use Ken’s IRrecvDump example (should be in your examples menu) load this into your Arduino and begin to capture your remotes codes. My Samsung wasn’t recognised so I used the Raw codes – there’s plenty of documentation on Ken’s site for this – it’s really simple, even I could figure it out. You need to note how many pulses etc.. it decodes in the raw signal which helpfully is outputted e.g. Raw (68):

Now we process the codes slightly and put them in an array for each one now that we have our codes and the information we need to use them – since mine are in the raw format I need to clean them up slightly ready to be put in my code – just adding commas etc…

Now we can test the remote codes to make sure you can control your TV

Now using the IRsendDemo example, altering it my case to send the raw signal, we can test the codes to make sure that we can control the T.V – just use the basic sketch to send the codes which I edited slightly just to use an array for the raw code. You can check out the library files themselves to see the functions.

/*
 * IRremote: IRsendDemo - demonstrates sending IR codes with IRsend
 * An IR LED must be connected to Arduino PWM pin 3.
 * Version 0.1 July, 2009
 * Copyright 2009 Ken Shirriff
 * http://arcfn.com
 */

#include 

IRsend irsend;

// just added my own array for the raw signal
unsigned int powerOn[68] = {4450,4500,550,1700,500,1750,500,1750,500,600,550,600,500,600,550,600,500,600,550,1700,550,1700,550,1700,500,600,550,600,500,600,550,600,500,650,500,600,550,1700,500,650,500,600,550,600,500,600,550,600,500,600,550,1700,550,600,500,1700,550,1700,550,1700,550,1700,500,1750,500,1750,500};

void setup()
{
  Serial.begin(9600);
}

void loop() {

      // altered the code just to send/test my raw code
      irsend.sendRaw(powerOn,68,38);
      delay(100);

}

Add the distance sensor

This is actually the hardest bit and it’s not that hard really I just used my previous work and adapted it and wrote a few statements concerning the detected distance. You just have to spend some time debugging and getting your values right to ensure that your commands are only sent at the right time and that it doesn’t get confused. My code is still a little buggy if you’re not used to how to move your hand but it does work well once you’re used to it.

[ad#Google Ad in content]

/*
    http://luckylarry.co.uk
    Larrys alternative TV remote - oops no buttons!
    Sends signals to TV based upon sensor readings

    Makes use of Kens Shirriffs IRremote library
    An IR LED must be connected to Arduino PWM pin 3.
    Version 0.1 July, 2009
    Copyright 2009 Ken Shirriff
    http://arcfn.com

    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program.  If not, see .
*/

#include
IRsend irsend;

const int numReadings = 5;   // set a variable for the number of readings to take
int index = 0;                // the index of the current reading
int total = 0;                // the total of all readings
int average = 0;              // the average
int oldAverage = 0;           // the old average
int echoPin = 2;              // the SRF05's echo pin
int initPin = 4;              // the SRF05's init pin
unsigned long pulseTime = 0;  // variable for reading the pulse
unsigned long distance = 0;   // variable for storing distance

// setup my arrays for each signal I want to send
unsigned int powerOn[68] = {4450,4500,550,1700,500,1750,500,1750,500,600,550,600,500,600,550,600,500,600,550,1700,550,1700,550,1700,500,600,550,600,500,600,550,600,500,650,500,600,550,1700,500,650,500,600,550,600,500,600,550,600,500,600,550,1700,550,600,500,1700,550,1700,550,1700,550,1700,500,1750,500,1750,500};
unsigned int soundUp[68] = {4450,4500,550,1700,550,1700,500,1750,500,600,550,600,500,600,550,600,500,600,550,1700,550,1700,550,1700,500,650,500,600,550,600,500,600,550,600,500,1750,500,1700,550,1700,550,600,500,600,550,600,500,600,550,600,500,600,550,600,550,600,500,1700,550,1700,550,1700,550,1700,500,1750,500};
unsigned int soundDown[68] = {4400,4550,500,1750,500,1700,550,1700,550,600,500,600,550,600,500,600,550,600,500,1750,500,1750,500,1700,550,600,500,650,500,600,550,600,500,600,550,1700,550,1700,500,600,550,1700,550,600,500,600,550,600,500,600,550,600,500,600,550,1700,550,600,500,1750,500,1750,500,1700,550,1700,550};
unsigned int channelUp[68] = {4400,4550,500,1700,550,1700,550,1700,550,600,500,600,550,600,500,600,550,600,500,1750,500,1700,550,1700,550,600,500,600,550,600,500,650,500,600,550,600,500,1700,550,600,550,600,500,1700,550,600,500,650,500,600,550,1700,500,600,550,1700,550,1700,550,600,500,1700,550,1700,550,1700,550};
unsigned int channelDown[68] = {4450,4500,500,1750,500,1750,500,1700,550,600,500,650,500,600,550,600,500,600,550,1700,500,1750,500,1750,500,600,550,600,500,600,550,600,500,600,550,600,500,650,500,600,550,600,500,1700,550,600,500,650,500,600,500,1750,500,1750,500,1750,500,1700,550,600,500,1750,500,1750,500,1700,550};

void setup() {
  // make the init pin an output:
  pinMode(initPin, OUTPUT);
  // make the echo pin an input:
  pinMode(echoPin, INPUT);
  // initialize the serial port:
  Serial.begin(9600);
}

 void loop() {

    // loop for a number of readings on the SRF-05 to get an average to smooth the results. Much like all my other examples
    for (index = 0; index<=numReadings;index++) {
      digitalWrite(initPin, LOW);
      delayMicroseconds(50);
      digitalWrite(initPin, HIGH);
      delayMicroseconds(50);
      digitalWrite(initPin, LOW);
      pulseTime = pulseIn(echoPin, HIGH);
      distance = pulseTime/58;
      total = total + distance;
      delay(10);
   }
    // store the previous reading
    oldAverage = average;
    // store the current reading
    average = total/numReadings;
    // debug to check for spikes in the sensor etc..
    Serial.println(average);

    // now the fun part...
    // if my distance is less than 5...
    if (average <= 5) {
      Serial.println("Power Off");
      // use Kens IR library to send my signal (array, number of items in array, Khz)
      irsend.sendRaw(powerOn,68,38);
      // these delays depend on how long it take my device to recognise the signal sent and to act - I don't want to send signals that aren't getting read etc..
      delay(5000);
      // otherwise if my hand is higher
    } else {
      // check to see if my hand is in the registered space above the sensor
      if (average <=20 && average >=10 && oldAverage >=10) {
        // the below statement is our sensitive the readings are so if the current and previous readings are different with a tolerance of +/- 1 we can look at the direction of movement
        if ((average != oldAverage)
        && (average+1 != oldAverage)
        && (average-1 != oldAverage)) {
          // if the current reading is higher than the previous, then my hand is moving upwards
          if (average > oldAverage) {
            Serial.println("Channel Up");
            irsend.sendRaw(channelUp,68,38);
            delay(2000);
          } else {
            // otherwise if it is below then my hand is moving downwards
            if (average < oldAverage && oldAverage <=20) {               Serial.println("Channel Down");               irsend.sendRaw(channelDown,68,38);               delay(2000);                        }                  }          // otherwise my hand must be stationary so check where it is.         } else {           // if my hand is stationary between 10 and 15 cms away from the sensor           if (average >= 10 && average <=15) {             Serial.println("Sound down");             irsend.sendRaw(soundDown,68,38);           } else {             // if my hand is a bit higher up...             if (average >= 16 && average <=20) {               Serial.println("Sound up");               irsend.sendRaw(soundUp,68,38);             }           }         }         }     }        // clear our index and total for the next reading just in case     if (index >= numReadings)  {
      index = 0;
      total = 0;
    }
}

[ad#Google Ad in content]

Easy way to make Photo Canvas Box Frames

box frames

I like the idea of having canvas photo prints on the wall but I also have enough of an ego to think that I can take a photo good enough to warrant printing my own canvas. Also I think it’s a bit more personal too when it’s your own photo/ art.

I take alot of photos and never do anything with them, I always think about framing but to get the benefits you need to print big or do a series of panels, which is what I’ll be showing how to do along with a bit of printer/ photoshop advice. Just so you know Photoshop CS3 has some excellent tools for stitching photos together to make panoramas.

There are alot of shops that will print and box frame your photos on canvas for you and you can get canvas framing kits to help, so no worries if you don’t have a capable printer, it will probably just cost a bit more. I genuinely think anything over A3 you’ll want to pay to get printed anyway – because I doubt you’ll want to spend £1,000+ on an A2+ printer just to print one picture.

However, I am lucky enough to have worked for Epson so I own a Stylus Photo R1900. It’s fairly cheap I guess for what it can do but it’s limited to A3, so its just on the edge of the realm of large format printers. But doing your own framing is only cheap if you already have the printer – I doubt any decent shop will charge you more than £25 per A3 canvas print so don’t buy a printer specifically to do one print!

The right printer, media and ink

Whether using Epson printers or not to print canvas you need a decent printer and it’s all about the type of inks used, your average inkjet ink won’t stick to canvas and you need a printer that can also deal with thicker media and roll feeds. The R1900 can do that and it’s the cheapest one that you can get from Epson (around £400) – also look for the R1800, R2400 and R2880 as good ones to try. I would recommend the R800 but the smallest canvas roll you can get is A3 (13inches/ 330mm wide), there is a cheaper A3 one, the 1400 but don’t bother as its inks  (Claria) will just flake off canvas. Not sure about whats out there from Canon, HP etc… but I guess what I’m saying is check what your printer can do any decent manufacturer or shop should do you a test sample regardless.

Ok so you got the printer, now remember that I have worked for Epson, so please take what  I say as slightly biased and with a pinch of salt: Get the genuine Epson ink and media! (or the equivalent for your printer). You will honestly see the difference, in the case of the Epson stuff all the media is coated specifically for the inks and printer, so cheaper non-Epson paper/ canvas won’t work as well and you’ll see prints fade, smudge, chip off and blur – same for HP, Canon etc… If you use refills on these inkjets you’ll see the same kind of thing but you’ll also jam up your print heads – its the biggest cause of issues with the photo printers – that and continous ink feed systems. So if you use the shitty materials for this then expect the shitty results that’ll follow!

For the R1900 you’re talking about £95 for a full set of inks and £35-40 for the canvas roll. The £140 media outlay might seem high but this will let you do around 12 A3 panels, so works out about £10 per A3 panel with plenty of ink to spare to do other stuff, if like me you do A4 panels then I’ll easily get 20 on a roll – either way using this stuff is going to get you good results, even on auto settings. My only gripe with the R1900 is that it cains the inks so you have to be sure not to waste any prints – if I could, I would have the R2400/R2880.

Anyway so you get the idea: good printer, good media, good ink. Or just get your canvas printed by someone else – I’ll do it for you if you pay for the ink, media and postage!

Making the frames

Now you can spend some money and buy the wood, glue, tools etc… to make your own frames but you can get frames for around £2-3 for A4, maybe less (any good sources please let me know). Take a trip to your local wilkos, poundland etc… and find some existing box canvas prints (or cheap wooden photo frames). Check the dimensions to make sure your canvas will adequately cover the entire frame, the sides and some of the back for the best results, if you’re using a roll feed on the printer then the frame can be as long as you want just as long as the canvas can cover the frames width. I took a piece of canvas with me and a tape measure to ensure I got the best frames and odd looks from fellow consumers and store staff.

Pull out the canvas and staples

That’s it! Your frames are built – just strip off the existing canvas using some needle nose pliers and pull out the staples and you’ve got your frame ready in far less time and effort as constructing one yourself. Don’t worry about damaging the old canvas, chances are if you were cheap like me the picture on there was crap anyway.

3 A4 Frames for £9

Setting up to print your canvas
Whether or not you’re printing your canvas these instructions still apply. We need to create a template to help us print, crop and frame the canvas – please scroll down to the framing section to get an idea.

First measure up the width and height of the frame from edge to edge, now measure how thick  the frame is and finally measure the width of the wood used to make the frame.

For example my frame is 30 cm x 20cm, my frame thickness is 2cm and the width of each piece is 3cm. So my material needs to be at the very most 30cm x 40cm to get the best results. If you want to try and use as much canvas as possible for your print then just ensure that it covers the sides of the frame and around 1cm on the back to give you something to staple into and tension.

My printed area is going to be the area of the frame (30 x 20 cm) plus the sides, so that’s 34 x 24 cm.

For folding the canvas and getting a nice fit you’ll need to cut the corners off so make sure to add lines to your template. If you scroll down you’ll see why/ how this is done.

I used Photoshop CS3 to do my print templates but you should be able to  follow the steps and do this in any basic application that lets you draw a few guides and lines over a photo. I guess if you’ve got a decent photo printer then you’re using Photoshop – CS3 and onwards has a much better print interface.

Create a new document, from the measurements of the frame and make sure its at a minimum of 300 dpi resolution and use RGB colour.

Next show your rulers (CTRL + R) make sure you’re setup for mm or cm (Edit, menu then Preferences to change).

Drag guides to mark the sides of the frame.

Draw lines for cutting the corners off.

Create a white frame around the outside in a new layer – to save wasting ink on the material being stapled to the frame.

Now you can put your photo in this document for printing and it will be perfectly positioned for you. This works also if you’re doing multiple panels. I won’t go into colour correction here, I’ll assume that you’ve done all this.

Printing…

First to save wasting paper do a very small test print to make sure your print heads are aligned and nothing funky is happening in your images.

OK so we’re ready to print. You’ll need to first load the canvas roll typically at the back of the printer – this can be a pain to do as the printer won’t feed the roll unless its absolutely straight. To remedy this before clipping the canvas roll on the printer feed it first into the printer and press the roll button on your printer. It’s hit and miss but eventually it will take it, you just need to feed the paper in straight.

Now clip the roll on to the back of the printer and you’re ready to go. When printing you just need to set a few basic things, the media type (Watercolour paper – radiant white), to use the roll instead of sheet and to set the paper size to user defined (size of your document).

I always tick photo enhance and best photo options, also using the gloss optimiser. I leave the printer drivers to render the best colour conversion it can, generally few colours in my prints are out of the gamut. To get better results spend time playing with these setting but be prepared to waste some ink.

Click print and thats it. Once you’re done, press the roll feed button on the printer to feed the canvas out so you can cut it – the R1900 can attempt to cut the canvas but it’s  too thick. Once you’ve cut it (It only needs to be roughly straight) then press the roll feed button again to retract the leftover canvas ready for the next time – for doing panels I printed all of them and then cut the roll after the last print to save canvas.

3 panels printed

Framing your canvas

OK, you’ll need a staple gun with 6-10mm staples to do this. Its pretty easy to do and takes about 5-10 minutes per frame.

Cut off the corners

Remember the corner lines I added in my template first cut these off.

Mark the sides of the frame.

Now mark and measure in the depth of your frame on each side of your canvas, so on mine, I mark the edge at 2cm and at 22cm for example – you need these marks to make sure you get your frame in the right place.

Fold the canvas.

With the canvas face down fold back along the edge of the picture.

Staple the canvas to the frame

You should be able to line up the edges of your canvas with the frame, put in a staple to secure.

Pull the canvas tight, and staple the opposite side.

Fold the top

Tuck the corners in at the top and staple down, repeat at the bottom making sure to pull the canvas tight.

Finished stapling the frame

Finish off by stapling all sides down – can be as messy as you like, no one will see.

You should be left with a nice end result! :) Please feel free to ask if you need a hand or something explained – or if you want me to print your photos!

First box frame attempt

Tenacious D: Classico on the Bass Guitar

Classico on bass

Not so sure I’ve tabbed this 100% but it’s a start, Tenacious D’s Classico for the Bass guitar. Video at the bottom showing it being played.

It’s essentially parts from Bachs Bouree in E Minor, Beethovens Fur Elise and Mozarts Eine Kleine Nachtmusik. I’ve translated the notes as best I can on the bass but let me know if I’ve got it wrong, I’ve also done this in power tab as well here. Click the image below to see it a bit bigger and better quality.

I do apologise for the sound quality in the video below but through decent speakers you can actually hear the bass, shame about the hissing but its a good enough start.

Arduino: Controlling the Robot Arm

arduino processing robot arm pt2

So the arm is wired into Arduino as per the previous post, Arduino: Modifying a Robot Arm and hopefully this has worked. In this next part I alter the Arduino sketch slightly and write the first Processing sketch to test control of the arm – video at the bottom.

To control the robot arm we’ll be sending a byte value over the serial port and then reading that in the Arduino code. Depending upon the value sent different motors will be activated.

For the processing sketch I’ve made a few buttons for each motor and also coded the use of the keyboard for another control method. Using either arbitrarily moves the arms motors.

This sketch is the basis for all the further work as well as testing the arm, from this I will move to inverse kinematics as well as programming repeat actions for the arm to perform. Ultimately leading to the arm responding to sensors and other stimuli – eventually! (I have a lot to write up).

For a basic example of working with controlling Arduino using Processing please read my tutorial “Using Processing to Send Values to Arduino” which explains about sending data over the serial port.

The Arduino Sketch
Nothing much has changed from the sketch in the previous post, the main difference is that now you can see we’re reading values from the serial port and acting accordingly. All the logic happens in the Processing code.

/* controls each motor in an Edge Robotic Arm using data sent from 
    a Processing Sketch
    luckylarry.co.uk
 
*/
// set the output pins
// 14-18 are actually analog pins 0-4
int baseMotorEnablePin = 2;
int baseMotorPin1 = 3;                             
int baseMotorPin2 = 4;                           
int shoulderMotorEnablePin = 14;
int shoulderMotorPin1 = 15;                             
int shoulderMotorPin2 = 16; 
int elbowMotorEnablePin = 8;
int elbowMotorPin1 = 9;                             
int elbowMotorPin2 = 10;                           
int wristMotorEnablePin = 5;
int wristMotorPin1 = 6;                             
int wristMotorPin2 = 7; 
int handMotorEnablePin = 11;
int handMotorPin1 = 17;                             
int handMotorPin2 = 18; 
// set a variable to store the byte sent from the serial port
int incomingByte;

void setup() {
  // set the SN754410 pins as outputs:
  pinMode(baseMotorPin1, OUTPUT);
  pinMode(baseMotorPin2, OUTPUT);
  pinMode(baseMotorEnablePin, OUTPUT);
  digitalWrite(baseMotorEnablePin, HIGH);
  pinMode(shoulderMotorPin1, OUTPUT);
  pinMode(shoulderMotorPin2, OUTPUT);
  pinMode(shoulderMotorEnablePin, OUTPUT);
  digitalWrite(shoulderMotorEnablePin, HIGH);
  pinMode(elbowMotorPin1, OUTPUT);
  pinMode(elbowMotorPin2, OUTPUT);
  pinMode(elbowMotorEnablePin, OUTPUT);
  digitalWrite(elbowMotorEnablePin, HIGH);
  pinMode(wristMotorPin1, OUTPUT);
  pinMode(wristMotorPin2, OUTPUT);
  pinMode(wristMotorEnablePin, OUTPUT);
  digitalWrite(wristMotorEnablePin, HIGH);
  pinMode(handMotorPin1, OUTPUT);
  pinMode(handMotorPin2, OUTPUT);
  pinMode(handMotorEnablePin, OUTPUT);
  digitalWrite(handMotorEnablePin, HIGH);
  // start sending data at 9600 baud rate
  Serial.begin(9600);
}

void loop() {
  // check that there's something in the serial buffer
  if (Serial.available() > 0) {
    // read the byte and store it in our variable 
    // the byte sent is actually an ascii value
    incomingByte = Serial.read();
    // note the upper casing of each letter!
    // each letter turns a motor different way.
    if (incomingByte == 'Q') {
    digitalWrite(baseMotorPin1, LOW);   
    digitalWrite(baseMotorPin2, HIGH);  
    } 
    if (incomingByte == 'W') {
    digitalWrite(baseMotorPin1, HIGH);   
    digitalWrite(baseMotorPin2, LOW);  
    }
    if (incomingByte == 'E') {
    digitalWrite(shoulderMotorPin1, LOW);   
    digitalWrite(shoulderMotorPin2, HIGH);  
    } 
    if (incomingByte == 'R') {
    digitalWrite(shoulderMotorPin1, HIGH);   
    digitalWrite(shoulderMotorPin2, LOW);  
    }
    if (incomingByte == 'A') {
    digitalWrite(elbowMotorPin1, LOW);   
    digitalWrite(elbowMotorPin2, HIGH);  
    } 
    if (incomingByte == 'S') {
    digitalWrite(elbowMotorPin1, HIGH);   
    digitalWrite(elbowMotorPin2, LOW);  
    }
    if (incomingByte == 'D') {
    digitalWrite(wristMotorPin1, LOW);   
    digitalWrite(wristMotorPin2, HIGH);  
    } 
    if (incomingByte == 'F') {
    digitalWrite(wristMotorPin1, HIGH);   
    digitalWrite(wristMotorPin2, LOW);  
    }
    if (incomingByte == 'Z') {
    digitalWrite(handMotorPin1, LOW);   
    digitalWrite(handMotorPin2, HIGH);  
    } 
    if (incomingByte == 'X') {
    digitalWrite(handMotorPin1, HIGH);   
    digitalWrite(handMotorPin2, LOW);  
    }
    // if a O is sent make sure the motors are turned off
    if (incomingByte == 'O') {
    digitalWrite(baseMotorPin1, LOW);   
    digitalWrite(baseMotorPin2, LOW);  
    digitalWrite(shoulderMotorPin1, LOW);   
    digitalWrite(shoulderMotorPin2, LOW); 
    digitalWrite(elbowMotorPin1, LOW);   
    digitalWrite(elbowMotorPin2, LOW);  
    digitalWrite(wristMotorPin1, LOW);   
    digitalWrite(wristMotorPin2, LOW); 
    digitalWrite(handMotorPin1, LOW);   
    digitalWrite(handMotorPin2, LOW); 
    }
  }
}

[ad#Google Ad in content]

The Processing Sketch
I’ve drawn some fancy arrows for my buttons in this sketch but otherwise the code is pretty simple – if I press Q or q on the keyboard or if I press an arrow button then send the ascii value of Q (note the uppercase) over the serial port for the Arduino to pick up and turn the motor on. There is nothing here really complicated just a fair few lines of code for the user interface.

/* 
   Processing sketch that send a ascii byte character to Arduino which
   then subsquentally controls a motor
   luckylarry.co.uk
 
*/

// load the serial library for Processing
import processing.serial.*; 
// instance of the serial class
Serial port;
// values to store X, Y for each button
int M1LX, M1RX, M2LX, M2RX, M3LX, M3RX, M4LX, M4RX, M5LX, M5RX;
int M1LY, M1RY, M2LY, M2RY, M3LY, M3RY, M4LY, M4RY, M5LY, M5RY;
// stores the width/height of the box
int boxSize = 64;
// 2 new instances of my arrow class
// also set an array of coordinates for each arrow
arrow myRightArrow;
int[]rightArrowxpoints={30,54,30,30,0,0,30}; 
int[]rightArrowypoints={0,27,54,40,40,15,15};
arrow myLeftArrow;
int[]leftArrowxpoints={0,24,24,54,54,24,24}; 
int[]leftArrowypoints={27,0,15,15,40,40,54};
// set the font
PFont myFont;

void setup()  {
  // screen size of the program
  size(145, 455);
  // set the coordinates of each button box
  // base motor M1LX = Motor 1 Left X  etc..
  M1LX = 5;
  M1LY = 25;
  M1RX = 75;
  M1RY = 25;  
  // shoulder motor
  M2LX = 5;
  M2LY = 115;
  M2RX = 75;
  M2RY = 115;
  // elbow motor
  M3LX = 5;
  M3LY = 205;
  M3RX = 75;
  M3RY = 205;
  // wrist motor
  M4LX = 5;
  M4LY = 295;
  M4RX = 75;
  M4RY = 295;
  // hand motor
  M5LX = 5;
  M5LY = 385;
  M5RX = 75;
  M5RY = 385;
  
  // List all the available serial ports in the output pane. 
  // You will need to choose the port that the Arduino board is 
  // connected to from this list. The first port in the list is 
  // port #0 and the third port in the list is port #2. 
  println(Serial.list()); 
  // set the font to use
  myFont = createFont("verdana", 12);
  textFont(myFont);
  // Open the port that the Arduino board is connected to (in this case #0) 
  // Make sure to open the port at the same speed Arduino is using (9600bps)
  port = new Serial(this, Serial.list()[1], 9600); 
  // create the base arrow
  myRightArrow = new arrow(rightArrowxpoints,rightArrowypoints,7);
  myLeftArrow = new arrow(leftArrowxpoints,leftArrowypoints,7);
}

void draw() 
{ 
  background(0);
  noStroke();
  fill(150);
  // draw each box/ button with a label above each    
  text("Base Motor (Q/W)", 5, 5, 200, 75); 
  text("Shoulder Motor (E/R)", 5, 95, 200, 75);
  text("Elbow Motor (A/S)", 5, 185, 200, 75);
  text("Wrist Motor (D/F)", 5, 275, 200, 75);     
  text("Hand Motor (Z/X)", 5, 365, 200, 75);

  // start looking to see whats pressed and send a value
  // over the serial port
  if(keyPressed) {
    if (key == 'q' || key == 'Q') {
      port.write('Q');
    }
    if (key == 'w' || key == 'W') {
      port.write('W');
    }
    if (key == 'e' || key == 'E') {
      port.write('E');
    }
    if (key == 'r' || key == 'R') {
      port.write('R');
    }
    if (key == 'a' || key == 'A') {
      port.write('A');
    }
    if (key == 's' || key == 'S') {
      port.write('S');
    }
    if (key == 'd' || key == 'D') {
      port.write('D');
    }
    if (key == 'f' || key == 'F') {
      port.write('F');
    }
    if (key == 'z' || key == 'Z') {
      port.write('Z');
    }
    if (key == 'x' || key == 'X') {
      port.write('X');
    }
  } 
  // if no key is pressed check to see if the mouse button is pressed
  else if (mousePressed == true) {
    // check to see if the mouse is inside each box/ button if so send the value
    if (mouseX > M1LX-boxSize && mouseX < M1LX+boxSize && 
      mouseY > M1LY-boxSize && mouseY < M1LY+boxSize) {
        port.write('Q'); 
    } 
    else if(mouseX > M1RX-boxSize && mouseX < M1RX+boxSize && 
      mouseY > M1RY-boxSize && mouseY < M1RY+boxSize) {
        port.write('W'); 
    } 
    else if(mouseX > M2LX-boxSize && mouseX < M2LX+boxSize && 
      mouseY > M2LY-boxSize && mouseY < M2LY+boxSize) {
        port.write('E'); 
    } 
    else if(mouseX > M2RX-boxSize && mouseX < M2RX+boxSize && 
      mouseY > M2RY-boxSize && mouseY < M2RY+boxSize) {
        port.write('R'); 
    } 
    else if(mouseX > M3LX-boxSize && mouseX < M3LX+boxSize && 
      mouseY > M3LY-boxSize && mouseY < M3LY+boxSize) {
        port.write('A');   
    } 
    else if(mouseX > M3RX-boxSize && mouseX < M3RX+boxSize && 
      mouseY > M3RY-boxSize && mouseY < M3RY+boxSize) {
        fill(200);
        port.write('S');     
    }
    else if (mouseX > M4LX-boxSize && mouseX < M4LX+boxSize && 
      mouseY > M4LY-boxSize && mouseY < M4LY+boxSize) {
        port.write('D');     
    } 
    else if(mouseX > M4RX-boxSize && mouseX < M4RX+boxSize && 
      mouseY > M4RY-boxSize && mouseY < M4RY+boxSize) {
        port.write('F');  
    } 
    else if (mouseX > M5LX-boxSize && mouseX < M5LX+boxSize && 
      mouseY > M5LY-boxSize && mouseY < M5LY+boxSize) {
        port.write('Z'); 
    }
    else if(mouseX > M5RX-boxSize && mouseX < M5RX+boxSize && 
      mouseY > M5RY-boxSize && mouseY < M5RY+boxSize) {
        port.write('X');    
    }
    else {
      // if the mouse is pressed but not with in a box make sure nothings moving
      port.write('O');   
    } 
  } else {
    // no key or mouse press then make sure nothings moving.
    port.write('O');   
  } 
  
  // draw the buttons
  myRightArrow.drawArrow(80,30);
  myRightArrow.drawArrow(80,120);
  myRightArrow.drawArrow(80,210);
  myRightArrow.drawArrow(80,300);
  myRightArrow.drawArrow(80,390);
  myLeftArrow.drawArrow(10,30);
  myLeftArrow.drawArrow(10,120);
  myLeftArrow.drawArrow(10,210);
  myLeftArrow.drawArrow(10,300);
  myLeftArrow.drawArrow(10,390);
}

class arrow extends java.awt.Polygon { 
  /* our class is basically an instance of java.awt.Polygons and this class expects and array of X points, Y points and the number of 
     points in our shape. The variable names also have to be direct references to what this class expects, so xpoints, ypoints and npoints are all
     set/defined in the java class.
  */
  public arrow(int[] xpoints,int[] ypoints, int npoints) {
    // super invokes the java.awt.Polygon class
    super(xpoints,ypoints,npoints);
    
  } 
    // supply offsets to draw the arrow, means I don't need to set points for each one
    void drawArrow(int xOffset, int yOffset){
    fill(150);
    rect(xOffset-5, yOffset-5, boxSize, boxSize);
    fill(255);
    beginShape();
    for(int i=0;i

[ad#Google Ad in content]

Does it work?
Hopefully the sketch is working and you can control the arm via your computer. If not then first check that all motors are wired in properly and your batteries are not flat. If you arrow moves the arm the wrong way then you can either switch the motor pins on the circuit or change the Arduino sketch to alter the motors direction.

Calibrating the arm
We need to set start positions for the arm and note the positions and counts in order to later calculate the positions for the next parts of this work. This is where we'll look to more benefits of Arduino and possibly PID (Proportional, Integral, Derivative) control, PWM or someother way to get accurate positions for the motor. The only catch is each motor is in a gearbox so using an encoder or other device to measure motor rotations is not an option. But for now we can control our arm from the computer at least - check out the video below.


Arduino: Modifying a Robot Arm: How to wire up the robot arm to Arduino.

Arduino – Modifying a Robot Arm

Arduino robot arm

Essentially another tutorial involving controlling DC motors. In this post I’m going to first alter a robot arm I had built previously from a beginners kit so that it can be controlled from Arduino. Then I’m going to write a series of posts on different ways to control the robot arm using Processing and other things. You should be able to use all of what I write for work with other toys and motors.

To start with have a look at the robot arm, it’s an ‘Edge Robotic Arm Kit‘:

The kit is a basic construction one and costs about £30 which you can find in most gadget shops and web stores. You assemble a gear box for each motor/ joint in the arm, doesn’t take long to build (about an hour) and is controlled by a set of switches on a control box. The only thing to note here is we’re dealing with motors, not servos or stepper motors just bog standard DC motors. This means calculating positions isn’t going to be straightforward later on. The kit has 5 motors and 4 ‘D’ series batteries to power them and can lift about 100 grammes.

So this version has a controller attached that lets you move each motor by pressing a switch, the electrics are pretty basic and don’t allow much control or further input. I have seen other versions that allow you to plug it in to a computer via USB but you pretty much have the same controls.

In order for us to build our own controls/ interfaces and software we need to modify the arm to allow us to interface our microcontroller – in this case an Arduino board. The best way I think do this, since we want to control a motor going backwards and forward, is to use H-bridge chips – the L293D and SN754410 and wire each motor into a chip and then alter the power circuit to run these chips. Arduino can then digitally control the H-bridge chip to turn the motor on/off and change its direction.

You can see some other work I’ve done with motor DC motor control and I’ll be covering the same info throughout these posts.

Arduino Robot Arm Parts

3 H-bridge chips – I heavily recommend using the sn754410 chip but you can probably get away with the L293 series. Each chip can control 2 motors – 5 motors = 3 chips.
Arduino Deumilanova w/ ATMEGA328
Breadboard/ Prototyping board
Jumper/ Connector wires
Wire cutters/ strippers

Hacking the Robot Arm

I hope you’re not too precious about wanting to use the control unit again, thats the first thing to go! I did look at working with this but it doesn’t give the level of control that I want. Also I’ll be cutting and stripping the wires and removing the control circuit from the arm. The only permanent damage is done to the wires – basically cutting the plugs off of the wires, so you could always get new plugs if you wanted to revert it, although once I’ve shown you what can be done I don’t think you’ll mind.

Step 1
First we need to create our breadboard layout so we can plug in all the wires, we’re going to be using alot of pins on the Arduino, in fact I think I use pretty much all of them. You could reduce this using shift registers but for now its not an issue, although please follow the wiring diagrams as this layout gives the least hassle. Some pins e.g. digital pin 13 will make the motors move when the board is powering up so we want to avoid this.

First of all we need to put our H-Bridge chips on the breadboard. Make sure to put them in the center like illustrated. This means the 2 sides of the chip are isolated – it will not work otherwise!

Next using the above image and the following wiring diagram for the chip connect the ground and power for each chip leaving space for the motors and Arduino pins. Note that the red wires are connecting the rails together so the power will flow around the whole board! These chips will be using the battery power that runs the motors in the arm – the power will be plugged into the board, the Arduino pins are there to switch the chips on/ off etc… I’ve also got a table of outputs I’ve done for each pin on the H-Bridge chip, it’s the same for either the L293 series or SN754410, pin configuration diagram below. The numbers 1-16 also correspond to the numbers on the images of the circuit.

H-Bridge Pin Configuration

1 to pin on Arduino board
2 to pin on Arduino board
3 to motor1 (either + or -) it wont matter as its DC
4 to the gnd (-) rail on the breadboard
5 to the gnd (-) rail on the breadboard
6 to motor1
7 to pin Arduino
8 to power (+) rail.
9 to pin Arduino
10 to pin Arduino
11 to motor2
12 to GND (-) rail
13 to GND (-) rail
14 to motor2
15 to pin Arduino
16 to power (+) rail.

So you should have 3 chips on the board and be ready to add the motors and connections to Arduino.

Step 2
Now the circuit layout is complete we can start stripping down the arm. First remove the control unit and unscrew the panel above the battery pack – this should have all the motors plugged in to it. We’re going to systematically disconnect each motor plug, remove the plug, strip the wires a little bit and wire it on to the breadboard. When stripping the wires, remember to twist the exposed wires to prevent them becoming stranded – or solder pins to the wires.

Here’s the first motor in on the first chip:

Its important to remember which motor you’re plugging in to which chip but it’s not too much of an issue as with the software we’ll be writing later on we can work around this with our code, just so long as each motor is wired into a chip as above. Below is a list of my Arduino pins used.

Shoulder motor
chip 1, pin 1 to Arduino pin 14 (Analog pin o)
chip 1, pin 2 to Arduino pin 15 (Analog pin 1)
chip 1, pin 7 to Arduino pin 16 (Analog pin 2)
Base motor
chip 1, pin 9 to Arduino pin 2
chip 1, pin 10 to Arduino pin 3
chip 1, pin 15 to Arduino pin 4
Elbow motor
chip 2, pin 1 to Arduino pin 8
chip 2, pin 2 to Arduino pin 9
chip 2, pin 7 to Arduino pin 10
Wrist motor
chip 2, pin 9 to Arduino pin 5
chip 2, pin 10 to Arduino pin 6
chip 2, pin 15 to Arduino pin 7
Hand motor
chip 3, pin 9 to Arduino pin 11
chip 3, pin 10 to Arduino pin 17 (Analog pin 3)
chip 4, pin 15 to Arduino pin 18 (Analog pin 4)

You’ll notice that rather than refer to the motors as M1, M2, M3 as the kit does, I’m calling them something more meaningful as I think it makes them easier to identify – you should be able to figure out which motor is which from my description I would hope!

Second motor in:

You can see the battery power has been added. If you have any problems you can always connect one motor at a time and use a quick sketch to test the circuit is working and below is some simple codeto help you do that. For later tutorials this isn’t going to change much.

[ad#Google Ad in content]

int baseMotorEnablePin = 2;
int baseMotorPin1 = 3;
int baseMotorPin2 = 4;
int shoulderMotorEnablePin = 14;
int shoulderMotorPin1 = 15;
int shoulderMotorPin2 = 16;
int elbowMotorEnablePin = 8;
int elbowMotorPin1 = 9;
int elbowMotorPin2 = 10;
int wristMotorEnablePin = 5;
int wristMotorPin1 = 6;
int wristMotorPin2 = 7;
int handMotorEnablePin = 11
int handMotorPin1 = 17;
int handMotorPin2 = 18; 

void setup() {
  // set the motor pins as outputs:
  // set all chips to enabled state
  pinMode(baseMotorPin1, OUTPUT);
  pinMode(baseMotorPin2, OUTPUT);
  pinMode(baseMotorEnablePin, OUTPUT);
  digitalWrite(baseMotorEnablePin, HIGH);
  pinMode(shoulderMotorPin1, OUTPUT);
  pinMode(shoulderMotorPin2, OUTPUT);
  pinMode(shoulderMotorEnablePin, OUTPUT);
  digitalWrite(shoulderMotorEnablePin, HIGH);
  pinMode(elbowMotorPin1, OUTPUT);
  pinMode(elbowMotorPin2, OUTPUT);
  pinMode(elbowMotorEnablePin, OUTPUT);
  digitalWrite(elbowMotorEnablePin, HIGH);
  pinMode(wristMotorPin1, OUTPUT);
  pinMode(wristMotorPin2, OUTPUT);
  pinMode(wristMotorEnablePin, OUTPUT);
  digitalWrite(wristMotorEnablePin, HIGH);

}

void loop() {
    /*
    // SET either one to HIGH to turn the motor on.
    // e.g.
    digitalWrite(baseMotorPin1, LOW);
    digitalWrite(baseMotorPin2, HIGH);
    */
    digitalWrite(baseMotorPin1, LOW);
    digitalWrite(baseMotorPin2, LOW);
    /*
    // more motors here added.
    digitalWrite(shoulderMotorPin1, LOW);
    digitalWrite(shoulderMotorPin2, LOW);
    digitalWrite(elbowMotorPin1, LOW);
    digitalWrite(elbowMotorPin2, LOW);
    digitalWrite(wristMotorPin1, LOW);
    digitalWrite(wristMotorPin2, LOW);
    */

}

[ad#Google Ad in content]
Step 3
So now you should have all the motors wired to chips on the breadboard, now we just add the power to the board and we’re done – this is the power from the robot arm batteries, it can connect on either side of the breadboard as long as its connected to the power rails. Also remember to connect a wire from the GND rail on the breadboard to a GND pin on Arduino – there must be a common ground connection between Arduino and the H-bridge chips for this to work. Lastly Find a way to secure the Arduino and breadboard to the arm to minimise the risk of wires disconnecting, I just used some blu-tak (modelling clay etc..).

And here’s the final thing:

If you want to avoid the breadboard and make a more permanent circuit you should be able ot follow this, just make sure that the pins on each side of the H-Bridge are completely isolated from each other.

Onwards…
So thats it, the arm is ready to go – you can add your own switches and inputs to control this but we’re going  to have some fun writing software to control this arm in the next part to move each motor AND after that we’re going to be looking at using Inverse Kinematics and trigonometry to do some cool controlling of all the motors of the arm and to maybe start program tasks.

Oh, Inverse Kinematics basically means we can program the arm to go after a target moving all the motors in combination to do this – trust me it is very cool!

Arduino – Controlling the Robot Arm with Processing: Using Processing and my laptop to control the arm

Using Processing to Send Values using the Serial Port to Arduino

LEDs

In this write-up, I’ll show how to create a value in Processing and then send this value over the serial port to the Arduino. In the example I’m setting values of LEDs making them brighter or dimmed but this example can be extended to control other items – which I plan to do later!

Basically I’m going to set a value between 0 and 255 and then send this value to Arduino which will then use the analogWrite() function to alter the brightness of the LED using PWM (Pulse Width Modulation). I’ve already done a bit of work with LEDs and PWM.

For the communication between Processing and Arduino I’ll be using the serial port – in other work previously I’ve sent information from Arduino to Processing so this is how to do it the other way around. There are a couple of things to note though. Firstly when using Arduino to read a string from the serial port we have to look at it at a byte level, in my example it’s just easier to ignore using strings and send 1 character at a time and then store it in an array. Secondly when debugging your code you can’t read the serial values in Arduinos serial monitor as you’ll already be using the port in Processing so sometimes this can be trial and error although you can at least preview the values your sending in Processing.

Of course you can also extend this code to write values from Arduino back to Processing. There are already plenty of examples online of how to do serial port communication between Arduino and Processing and vice versa and setting an LED to on or off but I’ve done a few extra things to show some basic work with interaction and user interfaces to set the LEDs.

We’re going to set 3 LED’s – Red, Green and Blue and rather than just on or off we’ll be setting the PWM/ levels of brightness. Also the sketches deal with setting an RGB LED (RGBL) with the combined values.

I’ve written 2 visualisations to achive the above.

The first is a set of sliders like a mixing desk – when sliding a slider it will set the value of the LED it’s assigned to and the combined value will set the RGB LED. The second is a triangle shape that you can move around to create the colours, so where ever you drag each point of the triangle it will set the brightness of the LED accordingly.

The Arduino circuit and sketch is very simple and remains the same no matter which visualisation is used. So starting with the circuit…

Arduino Serial Parts

Arduino Deumilanova w/ ATMEGA328
Breadboard/ Prototyping board
Jumper/ Connector wires
3x LED (Red, Green, Blue)
1x RGB LED
6x 270 Ohm resistors

Arduino Serial Circuit

Very simple: 3 LEDs each with a common ground back to the Arduino board, the positive pins (the longer pin) has a 270 Ohm resistor between it and a connection to a digital pin. The RGB LED has 4 pins – 1 is for the power supply – some RGB LEDs instead may connect to GND so check before doing so. The other 3 pins each connect to a digital pin on the Arduino board.

LEDs

Arduino Serial Code – Receiving Values from Processing

The Arduino code is very simple as well – we set the the digital pins all as outputs, we setup the serial port we wish to use and then we read the values from the serial port and store them in an array, each item in the array corresponds to a value for an LED. There is a small catch however – it seems my RGB LED sees the value 255 as off and 0 as on so I have had to write some code to take this into account.

/* Sets LED values based on values sent on the serial port from Processing application.
   luckylarry.co.uk

*/

// create an array of LED pins - need to be the PWM digital pins
int ledPin[] = {9,10,11};
// an array to store the pins for the RGB LED
int RGBLpins[] = {3,5,6};
// array to store the 3 values from the serial port
int incomingByte[3]; 

void setup() {
  // initialize serial communication - make sure its the same as expected in the processing code
  Serial.begin(9600);
  // loop through and set the pins as outputs
  for (int i=0; i<3; i++) {
    pinMode(ledPin[i], OUTPUT);
    pinMode(RGBLpins[i], OUTPUT);
  }
}

/*  3 pins are stored in an array, 3 values from the serial buffer
are stored in an array, by looping through both we can light up the LEDs
using the values sent from the Processing sketch. NOTE: the values sent over
the serial port didn't seem to be in order, rather than RGB I got GBR so it
looks like it misses the first byte - so its just trial and error matching
the correct pin to the correct value.
*/

void loop() {
  // check to make sure there's 3 bytes of data waiting
  if (Serial.available() >= 3) {
    // read the oldest byte in the serial buffer:
    for (int i=0; i<3; i++) {
      // read each byte
      incomingByte[i] = Serial.read();
      // pass the value to each pin
      // analogWrite is used to write a value between 0 and 255 to the PWM pin.
      // lightup the separate LED's
      analogWrite(ledPin[i], incomingByte[i]);
      // seems that my RGB LED sees the values differently - it sees 255 as nothing and 0 as full colour!
      int val = 255 - int(incomingByte[i]);
      analogWrite(RGBLpins[i], val);
    }
  }

}

[ad#Google Ad in content]

Processing Sketch to Send Values via Serial Port to Arduino

Whilst both sketches visually look different they use pretty much the same methods. The main thing is that for each point, shape or item we wish to click and drag we rely on detecting where the mouse is, if its been clicked and if we're dragging the mouse. We can use Processings inbuilt functions mousePressed() and mouseDragged() but we still need to write conditional statements depending on where the mouse is.

To do this we can get the X and Y co-ordinates of the mouse using mouseX and mouseY and to compare these values we need to store the X and Y co-ordinates of any shape as variables - the easiest way is to use the PVector variable type which in its simplest use is an array that stores an X and Y value. Now we can mathematically compare the values and limit the movement of our shapes only moving when the mouse is in the correct area.

In the second sketch, the RGB triangle, I also wanted to test to make sure that the triangles points/vertices we're dragging remain inside a triangular area, to do this there is no Processing code as such its much easier to extend a class and use Javas polygon class (java.awt.Polygon) which will do all the work for us. In order to set the values we have to work out the distance we are from the original points, for which we can use the dist() method which allows us to draw a radius from a point and check to see how far our second point is from the original - we can also use this to create a circular detection area.

When getting the X, Y values from the mouse position we need to make sure these are converted to integers, for which we first use the round() method to convert our float to 1 decimal place and then use the int() method to cast the value as an integer. We also need integer values as it makes it much easier to send ints over the serial port as the libraries allow for these values.

The rest of the processing code is fairly straight forward we use text(), rect(), ellipse(), line(), fill() and stroke() functions to create our visualisation.

The only other thing to note is that in draw() method we always write the values to the serial port.

Visualisation One: RGB Sliders/ Mixing Desk
We have 3 sliders which each can set a value between 0 and 255, the Processing sketch writes each value separately to the serial port and displays the current mixed colour along with each slider value. You can download the sketch You can download the sketch here and try out the application below here and try out the application below. If you download the code please quickly do a find and replace to change //myPort to myPort - it's done just so you can see the app running in this webpage.

/*
    Code by Lucky Larry: www.luckylarry.co.uk

    RGB visualisation to control LED's by dragging sliders to define colour
    Copyright (C) 2009 Pete Dainty aka 'Lucky Larry'

    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program.  If not, see .

    Also makes use of gradient drawing code found at: http://processing.org/learning/basics/lineargradient.html

*/

// import the serial library to allow us to send data via the serial ports (USB in this case)
import processing.serial.*;
// create a new instance of the serial classes and assign it to 'myPort'
Serial myPort;
// create set of variables to store vector infomation (X nd Y co-oordinates)
PVector redSlider,greenSlider,blueSlider,whichSlider,lockSliders;
// create an arry to store the vectors of each slider
PVector sliders[];
// boolean value (true or false) to store if lock sliders button has been clicked
boolean locked;
// values needed for gradient code
int Y_AXIS = 1;
int X_AXIS = 2;
// setup our font
PFont myFont;

void setup() {
  // screen size
  size(300,315);
  // setup my font type and size
  myFont = createFont("verdana", 10);
  textFont(myFont);
  // specifiy the co-ordinates for each slider, the lock sliders button
  redSlider = new PVector(50,150);
  greenSlider = new PVector(110,150);
  blueSlider = new PVector(170,150);
  lockSliders = new PVector(12,27);
  // setup an array to store the values of each slider
  sliders = new PVector[] {redSlider,greenSlider,blueSlider};
  // smooth shapes
  smooth();
    /* define which port to use mine is COM10 and is 2nd in the array list.
       you can print out to the screen which ports are accessible by using this code line below
       set the baud rate to the same as in your Arduino code so mine is 9600
    */
    // println(Serial.list());
    myPort = new Serial(this, Serial.list()[1], 9600);
} // end setup

void draw() {
  // set background colour to grey in case the setGradient code fails
  background(50);
  // set outlines of shapes to be black
  stroke(0);
  /* creates a rectangle shape based up on X and Y co-ords,
     width and height, 2 RGB values to the colours to mix and which
     axis to apply the gradient.
  */
  color b1 = color(130, 130, 130);
  color b2 = color(70, 70, 70);
  setGradient(0, 0, width, height, b1, b2, Y_AXIS);
  // set the backgrounds of our slider columns
  color sliderGrad1 = color(120, 120, 120);
  color sliderGrad2 = color(50, 50, 50);
  setGradient(25, 20, 50, 275, sliderGrad1, sliderGrad2, Y_AXIS);
  setGradient(85, 20, 50, 275, sliderGrad1, sliderGrad2, Y_AXIS);
  setGradient(145, 20, 50, 275, sliderGrad1, sliderGrad2, Y_AXIS);
  noFill();
  rectMode(CENTER);
  // draw the outlines of each column and a guide line in the center
  rect(50,160,50,275);
  rect(110,160,50,275);
  rect(170,160,50,275);
  line(50,30,50,285);
  line(110,30,110,285);
  line(170,30,170,285);
  // loop through 25 times to produce 25 measurement lines and measurements
  for (int i=0; i<=25; i++) {
    stroke(30);
    // first column
    line(46,30+(i*10),54,30+(i*10));
    // second column
    line(106,30+(i*10),114,30+(i*10));
    // third column
    line(166,30+(i*10),174,30+(i*10));
    // right hand gauge and measurement numbers
    fill(40);
    stroke(40);
    line(196,30+(i*10),201,30+(i*10));
    text(Integer.toString(i*10),216,35+(i*10),25,25);
  }
  // draw the sliders - one for each item in the sliders array
  for (int i=0; i< mouseX &&
            sliders[i].x+20 > mouseX &&
            sliders[i].y-10 < mouseY &&
            sliders[i].y+10 > mouseY) {
              whichSlider = sliders[i];
            }
    }
    // check to see if the mouse is clicked inside the lock sliders button
    if (lockSliders.x-5 < mouseX &&
        lockSliders.x+5 > mouseX &&
        lockSliders.y-5 < mouseY &&
        lockSliders.y+5 > mouseY) {
          // if so then check the current state and set our boolean to the opposite value
          if(locked) {
          locked = false;
          } else {
          locked = true;
          }
       }
}

/* If the mouse is pressed and the value of whichSlider is not null - it will be null if the mouse is outside the slider area.
   Then look to see if the mouseY is in range, so we dont want it to exceed a scale of 255
   Then look to see if the sliders are locked, if they are then set all sliders to the mouse Y
*/
void mouseDragged() {
    if (whichSlider != null)
    {
        if(mouseY > 30 && mouseY < 287 ) {
          // set the Y value of the slider
          if(!locked) {
            whichSlider.y = mouseY;
          } else {
            for(int i=0; i<3; i++) {
              sliders[i].y = mouseY;
            }
          }
        }
    }
}

/* following gradient code taken from:
   http://processing.org/learning/basics/lineargradient.html
*/

void setGradient(int x, int y, float w, float h, color c1, color c2, int axis ){
  // calculate differences between color components
  float deltaR = red(c2)-red(c1);
  float deltaG = green(c2)-green(c1);
  float deltaB = blue(c2)-blue(c1);

  // choose axis
  if(axis == Y_AXIS){
    /*nested for loops set pixels
     in a basic table structure */
    // column
    for (int i=x; i<=(x+w); i++){
      // row
      for (int j = y; j<=(y+h); j++){
        color c = color(
        (red(c1)+(j-y)*(deltaR/h)),
        (green(c1)+(j-y)*(deltaG/h)),
        (blue(c1)+(j-y)*(deltaB/h))
          );
        set(i, j, c);
      }
    }
  }
  else if(axis == X_AXIS){
    // column
    for (int i=y; i<=(y+h); i++){
      // row
      for (int j = x; j<=(x+w); j++){
        color c = color(
        (red(c1)+(j-x)*(deltaR/h)),
        (green(c1)+(j-x)*(deltaG/h)),
        (blue(c1)+(j-x)*(deltaB/h))
          );
        set(j, i, c);
      }
    }
  }
}

[ad#Google Ad in content]

Visualisation Two: RGB Triangle
A bit more complex we have triangle this time to control the mixing of colours/ setting of values - it works the same way pretty much as the first one. The only real difference is how the mouse is detected and movement is limited to a triangle. You can download the sketch here and try out the application below. Like the previous sketch the downloadable version has the serial port code commented out so it will work in this webpage. Do a find and replace to change //myPort to myPort and that should sort it out.

/*
    Code by Lucky Larry: www.luckylarry.co.uk

    RGB visualisation to control LED's by dragging shapes to define colour
    Copyright (C) 2009 Pete Dainty aka 'Lucky Larry'

    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program.  If not, see .
*/

// import the serial library to allow us to send data via the serial ports (USB in this case)
import processing.serial.*;
// create a new instance of the serial classes and assign it to 'myPort'
Serial myPort;
// create set of variables to store vector infomation (X nd Y co-oordinates)
PVector areaPointA,areaPointB,areaPointC,pointA,pointB,pointC,pointDrag;
// create an arry to store the vectors of each point of our shape in this case a triangle
PVector[] rgbTriangle;
/* the next 3 lines uses a custom class at the bottom of this code.
   the class extends java.awt.polygon which means I can use this to create a triangle to test if the
   mouse is in side the shape. */
// new instance of our class
DragArea area;
// these lines specify the X value and Y value for each point of our triangle {xpoint1, xpoint2, xpoint3} etc..
int[]xpoints={152,23,284};
int[]ypoints={23,248,248};
// set 3 variables to store the colour values.
int R, G, B;
// setup our font
PFont myFont;
/* setup our background and variables */
void setup () {
    // screen size
    size(305,271);
    // setup my font type and size
    myFont = createFont("verdana", 12);
    textFont(myFont);
    // define our new instance of the custom class. (X points, Y points, Number of points in the shape) more info below by the class
    area = new DragArea(xpoints,ypoints,3);
    // define the area vectors - we use these to see how far our point is from its original source, needed to calculate the value between 0 and 255
    areaPointA = new PVector(152,25);
    areaPointB = new PVector(25,246);
    areaPointC = new PVector(280,246);
    // specifiy the starting co-ordinates for the triangle that we can move
    pointA = new PVector(152,40);
    pointB = new PVector(40,230);
    pointC = new PVector(265,230);
    // set the array with the new points.
    rgbTriangle = new PVector[]{pointA,pointB,pointC};
    // center our shapes
    ellipseMode(CENTER);
    rectMode(CENTER);
    // set smoothing for our shapes edges
    smooth();
    /* define which port to use mine is COM10 and is 2nd in the array list.
       you can print out to the screen which ports are accessible by using this code line below
       set the baud rate to the same as in your Arduino code so mine is 9600
    */
    // println(Serial.list());
    myPort = new Serial(this, Serial.list()[1], 9600);
} // end setup

/* begin our animation/ interaction */
void draw () {
    // set background to black
    background(50);
    // set the colours and positions of the large colour circles to indentify where red is 100% etc...
    // fill(R, G, B);
    fill(255,0,0);
    // ellipse(X co-ordinate, Y co-ordinate,width, height)
    ellipse(areaPointA.x, areaPointA.y, 15,15);
    fill(0,255,0);
    ellipse(areaPointB.x, areaPointB.y, 15,15);
    fill(0,0,255);
    ellipse(areaPointC.x, areaPointC.y, 15,15);
    // create our background triangle to show the area in which we can move.
    fill(100);
    beginShape(TRIANGLES);
      vertex(areaPointA.x,areaPointA.y);
      vertex(areaPointB.x,areaPointB.y);
      vertex(areaPointC.x,areaPointC.y);
    endShape();
    /* set the fill of our coloured triangle we work out the values by
       getting the current points co-ordinates and working out the distance
       from the original point. These distances are actually calculated on a
       circular area so it draws an elliptical area from the origin point from
       the 2 adjacent sides of the triangle. First set the values to our variables
       R, G, B and round them so that they'll be integers and parse them using the int() method
    */
    R = int(round(255-dist(areaPointA.x,areaPointA.y,pointA.x,pointA.y)));
    G = int(round(255-dist(areaPointB.x,areaPointB.y,pointB.x,pointB.y)));
    B = int(round(255-dist(areaPointC.x,areaPointC.y,pointC.x,pointC.y)));
    fill(R,G,B);
    /* we need to send this fill value to the Arduino to light up the LED's accordingly
       we do this by writing a value to the serial port.
       You can write values to the serial port using bytes, integers and chars.
       I'm going to send the 3 values separately and store them in an array on the Arduino
    */
    myPort.write(R);
    myPort.write(G);
    myPort.write(B);
    // create our RGB triangle from the draggable points
    beginShape(TRIANGLES);
      vertex(pointA.x,pointA.y);
      vertex(pointB.x,pointB.y);
      vertex(pointC.x,pointC.y);
    endShape();
    // create the drag handles for each point in the draggable shape.
    for (int i=0; i< mouseX &&
            rgbTriangle[i].x+5 > mouseX &&
            rgbTriangle[i].y-5 < mouseY &&
            rgbTriangle[i].y+5 > mouseY) {
              pointDrag = rgbTriangle[i];
            }
    }
} 

/* If the mouse is pressed and the value of pointDrag is not null - it will be null if the mouse is outside the handle area.
   We then do another check to see if our mouse pointer is inside our polygon area. In Processing we can use the .contains() method
   that we get from the custom class at the bottom to check if an XY value is inside the polygons area.
*/
void mouseDragged() {
    if ( pointDrag != null )
    {
      if(area.contains(mouseX,mouseY) ) {
        // set the XY values of the point we're dragging to the values of the mouse
        pointDrag.x = mouseX;
        pointDrag.y = mouseY;
      }
    }
} 

/* This doesnt look like much code but what we're doing is extending a class with another class.
   By extending our class with java.awt.Polygon we then inherit that classes methods to use as our own.
   Since Processing is based upon Java there are many classes that we can import to extend Processing.
   The functions of java.awt.Polygon can be found here: http://java.sun.com/j2se/1.4.2/docs/api/java/awt/Polygon.html
   This makes it much easier to do collision detection with shapes - Processing can handle rectangles and circles fine
   but for triangles this saves alot of effort.
*/
class DragArea extends java.awt.Polygon {
  /* our DragArea class is basically an instance of java.awt.Polygons and this class expects and array of X points, Y points and the number of
     points in our shape. The variable names also have to be direct references to what this class expects, so xpoints, ypoints and npoints are all
     set/defined in the java class.
  */
  public DragArea(int[] xpoints,int[] ypoints, int npoints) {
    // super invokes the java.awt.Polygon class
    super(xpoints,ypoints,npoints);
  }
}

[ad#Google Ad in content]