Go Down

Topic: Mouse-to-servo printer interface (Read 1 time) previous topic - next topic


Gotta write normal message before links...


Hello folks! I have fiddled with the AVR Studio and the Atmegas for some time, but i have to say the Arduino environment is so much faster to work with! I started making some general initializations of the basic interface devices (lcd for debugging, servos and a usb mouse) and put them together. It all took the entire weekend, something that would have taken weeks for me in the AVR Studio environment, thanks Arduino-developer-people!

However, i linked the PS/2 library to 3 RC Servos, writing to them in microseconds, did some patterns and scaling. The LCD is backlight controlled via PWM and has a LDR controlling the brightness (doesn't show too much in the video i'm about to put up soon) and added a pen to the outer servo arm. My original intention was to make a gripper holding the pen but i was lacking another servo. I did also have plans for reading a cutoff-current from the gripper to grab things with the right force, but that comes in time.

This is a project to test my own and the IDE's potential. The servo holder thingy was built in like 15-30 min, so nothing fancy. It is only a protorype of what to come.

Here are some pic's:

And the code:  
Code: [Select]
#include <Servo.h> //disables analogWrite() (PWM) functionality on pins 9 and 10
#include <ps2.h>
#include <LiquidCrystal.h>

#define ROT_START 2000
#define SHO_START 1000
#define ELB_START 1700

Servo servo_elbow;
Servo servo_rotbase;
Servo servo_shoulder;

// initialize the libraries with the numbers of the interface pins
PS2Mouse mouse(2, 1); //clk (right on usb), data (left on usb)
LiquidCrystal lcd(8, 7, 6, 5, 4, 3); //in order of physical LCD pins right to left

int bklghtPin = 11;    // LCD backlight pin 9
int ldrPin = 0;       //LDR analog pin 0
int light = 0;        
int regval = 0;
int testPin = 13;
int speakerPin = 9;

unsigned long last_rotbase = 0;
unsigned long last_shoulder = 0;
unsigned long last_elbow = 0;

void setup()
 pinMode(testPin, OUTPUT);
 // set up the LCD's number of columns and rows:
 lcd.begin(16, 2);
 lcd.print("SuperScreen 3000");
 light = analogRead(ldrPin);
 regval = light/4; //proportional conversion from 10 to 8 bit
 for(int fadeValue = 0 ; fadeValue <= regval; fadeValue +=3)
     analogWrite(bklghtPin, fadeValue);    
  digitalWrite(testPin, HIGH);  
  servo_rotbase.writeMicroseconds(ROT_START);   //init
  servo_shoulder.writeMicroseconds(SHO_START); //init
  servo_elbow.writeMicroseconds(ELB_START);   //init
  digitalWrite(testPin, LOW);  

void loop()
 MouseInfo mouseInfo;          //initiate mouse
 mouse.getData(&mouseInfo);    //initiate mouse
 last_rotbase = servo_rotbase.readMicroseconds();
 last_shoulder = servo_shoulder.readMicroseconds();
 last_elbow = servo_elbow.readMicroseconds();
 lcd.setCursor(0, 0);
 lcd.print("ROT: ");
 lcd.setCursor(4, 0);
 lcd.setCursor(8, 0);
 lcd.print("SHO: ");
 lcd.setCursor(12, 0);
 lcd.setCursor(0, 1);
 lcd.print("X: ");
 lcd.setCursor(4, 1);
 lcd.print(mouseInfo.x, DEC);            //speed of X, demonstrative
 lcd.setCursor(8, 1);
 lcd.print("ELB: ");
 lcd.setCursor(12, 1);
 if(mouseInfo.rightClick == 1)
  servo_shoulder.writeMicroseconds(((last_shoulder) - mouseInfo.y)); //från init, (1000 - 0)
  last_shoulder = servo_shoulder.readMicroseconds();
  last_elbow = servo_elbow.readMicroseconds();
  servo_shoulder.writeMicroseconds((SHO_START - (0.65*mouseInfo.cY))); //may need scaling
  servo_elbow.writeMicroseconds((last_elbow - mouseInfo.y));       //may need scaling  
 servo_rotbase.writeMicroseconds((ROT_START + mouseInfo.cX));    //don't fuxx with X!!!
 lcd_routine();  //make backlight adjust every 30 ms

void lcd_routine()
  light = analogRead(ldrPin);
  regval = light/4;
  analogWrite(bklghtPin, regval);

Greetings from Sweden and me, Henrik

I'll be glad to take comments and improvements. I know I am not the best programmer but...  :D Video is coming.

If someone could tell me how I could use my speaker with this (pin 9) setup I would be very happy!!!


That looks like alot of fun! Cant wait for the video!  :)
captain-slow.dk | non contagious!


Great job; but one thing is making me "cringe":

You have wires and cables wrapped around your power binding posts; now, I can't see if they are actually connected to any source of power - it kinda appears they aren't. Regardless, don't let this become a habit - binding posts for power should -never- have anything wrapped around them like that; if there were power, you can easily introduce shorts and possibly spurious signals, or apply power where you don't want it. All in all, it would lead to bad things (from transient errors - to fire!).

I will not respond to Arduino help PM's from random forum users; if you have such a question, start a new topic thread.


Another thing that could be awesome would be to make it write messages :)

Send it a short message, and it writes it. Maybe even with some "endless" paper (the stuff from printers) and make a device that could pull it a little forwards after each message...

oooooh (sorry, imagination is going crazy :P), maybe some kind of link to a webpage, place a webcam over, and let visitors write a message on the paper, and watch the printer write it.  ;D
captain-slow.dk | non contagious!


Apr 26, 2010, 12:40 am Last Edit: Apr 26, 2010, 12:43 am by Honk Reason: 1
BLD: those are great ideas! But my very prototypic platform is barely able to write with constant human control as it is, you'll see in the vid coming (uploading as we speak, 400mb into youtube :P ). Maybe I'll make a better stand for the servos in the future, then your ideas would be most possible! Especially if I recorded the movements of some specific letters. But that seems like very much more coding than mechanical work, and I am more in to mechanics/electronics than plain programming, but still a possibility!

cr0sh: I know what you mean... but I have a good explanation. The 7805 is a 2 amp one, getting extremely hot from using it, and the servos are quite slow with it. I then added an external battery pack via the posts, and the wires only coming in to the servo power line (I then disconnected the two wires coming in to it from the regulator of course!). So it was only a temporary solution. I also have no good connectors to the servos, hence the fried Hitech HS-55 (burned some transistors in it, and they are even smaller than usual SMD's!!).

So this was somewhat of a rush project. My imagination is also goind crazy and my head is aching of all new ideas im having. Thinking of getting some accelerometers/gyros and experiment. Then I have my ongoing humanoid experiment (animation on my youtube, I'll write the link as soon as it is uploaded)


Apr 26, 2010, 02:07 am Last Edit: Apr 26, 2010, 02:41 am by Honk Reason: 1
Bumping a little for the vids:



That looks like fun.

One suggestion on your sketch is to change the pins you use for the servos. There is a problem with the way digital write is implemented in the Arduino core that could cause jitter in the servos when these are connected to pins on the same port as the LCD.

You can read the technical details here: http://code.google.com/p/arduino/issues/detail?id=146

Probably the easiest way to reassign the pins is to wire the servos to the analog input ports  (which can also be used as digital outputs).  As you are only using three servos, you could attach them to pins 17,18 and 19 (analog pins 3,4,&5) so  analog ports 0,1 & 2 are available for input if you need them.


It is  ;)

However, thanks for the input! I notice quite much jitter on pin 16 (arduino pin 10) which is part of PORTB, that the other servos and part of the LCD also is connected to. The other two servos (the big ones) are calm as the night though, and I suspect the jitter is because of the crappy servo and might have something with my controling of it to do.

I will try reassigning the pins and see if I get rid of that servos' jitter anyways. If I proceed with this I am going to use a routine checking on every servos current via the analog pins, so then I gotta have those free.  


It can be tricky measuring servo current because hobby servos may only draw significant current when being pulsed, if you measure at the wrong time you may not get a meaningful reading.

What will your sketch do with the servo current values?


Hmm, I had not thought about that, but since the servos almost all the time is struggling to not "fall down"/keeping the pen up or whatever, there should always be a measurable current through them, and since it is pulsed, it might be as simple as filtering/buffering the current-to-voltage reading.

With the readings its primary task will be to sense endpoints, or unforeseen obstacles preventing the servos to move to the place I want, i.e protection.

The other thing I intend to do is sensing force in a gripper hand, so it will always grip an object until it has gone up to a specified current, which I hope will be proportional to the force on the object. That seems quite doable don't it?


Have a read through this thread: Sensing servo stress (load) , it discusses something similar.


Thanks for pointing me in a good direction!

Seems like I have some experimenting to do, and as I am pretty familiar with OP-amps/RC-filters from analog audio, I will probably incorporate that if I need when I try it out later. In some time I have planned to build a real model of my CAD:ed humanoid, and that will also need this kind of sensing.

Go Up