Playing with Picomotors

arduino

I’ve written about slip-stick motors before here and I’ve now purchased a couple from ebay to play with.

I acquired both 30nm and 100nm resolution Picomotors and a Picomotor 8701 driver. This post documents the process on getting them up and running.

This is the 30nm resolution motor:

picomotor

It’s kind of seen better days. The case is coming off and I wrapped teflon tape round it to hold it together. It does work however!

Slip-stick motors work using the difference in motion caused by static and dynamic friction. It’s rather neat and you can read more about it here. But it means they only require a single piezo stack give clockwise and anti-clockwise rotation. Giving you 30-100nm resolution over ~25mm travel.

slipstick

The 8701 driver didn’t come with a power supply, but luckily it’s quite well documented (local copy). It requires +12,-12 and 5V supplies. It also used an old DIN type connector. Unfortunately I didn’t have one knocking around so had to make do with board pins. Hopefully the one I’ve ordered from China will turn up in the new couple of weeks, same goes for the 15pin input signal connector.

func

For the moment I’m running it off a bunch of lab supplies, but will probably put together something more permanent at some point:
power

Driving the motor is pretty straight forward. There’s a 5v “step” input pin (which triggers on the negative edge), and a direction pin. The motor can be driven at upto 1KHz. Initially I drove it using a function generator:

control

Finally I knocked a quick Arduino Sketch together to drive to motor over serial (code below):

arduino


void setup()
{
  // start serial port at 9600 bps and wait for port to open:
  Serial.begin(9600);
  while (!Serial) {
    ; // wait for serial port to connect. Needed for Leonardo only
  }

  pinMode(8, OUTPUT);
  pinMode(9, OUTPUT);
}

int cspeed = 1;
void do_steps(int dir,int dspeed) {

  digitalWrite(9,dir);
  for(int n=0;n<dspeed;n++) {
    digitalWrite(8,1);
    delay(1);
    digitalWrite(8,0);
    delay(1);
  }

}

void loop()
{
  // if we get a valid byte, read analog ins:
  if (Serial.available() > 0) {
    // get incoming byte:
    int in = Serial.read();
    
    if(in == 'W') {do_steps(1,cspeed); Serial.print("S");}
    if(in == 'S') {do_steps(0,cspeed); Serial.print("S");}
    if(in == 'P') {cspeed++; Serial.print(cspeed); Serial.print("\n");}
    if(in == 'L') {cspeed--; Serial.print(cspeed); Serial.print("\n");}
  }
}