Go Down

Topic: Linear Actuator PWM position control w/ FIO (Read 4758 times) previous topic - next topic


Hello! I'm working with an array of Firgelli L12 linear actuators (http://firgelli.com/products.php?id=41), 12 volts, integrated control option, 100 mm stroke length, and I'm trying to control the stroke position through PWM from an Arduino Fio. We're using the Fio with an XBee Series 1 wireless module because we want to be able to control the actuator extension lengths wirelessly using Grasshopper + Firefly. So far, setting up the Fio to talk to Firefly has gone relatively smoothly, but I'm having a funny issue with how the PWM signal maps to position. When I tested the actuator with my Uno, the relationship between signal and length was fairly straightforward (analogWrite 0 = fully retracted, analogWrite 255 = fully extended 4"). However, when I try the same code with the Fio, it will only extend to 3" with a signal of 255 instead of the full 4".

I think this is an issue of signal frequency; I adjusted the PWM signal frequency in my test code because the actuator requires a 1 kHz square wave using this example: http://www.arduino.cc/playground/Code/PwmFrequency. This worked on the Uno no problem. I know that the Uno's clock speed is 16 MHz while the Fio's clock speed is 8 MHz, so (I believe) the frequency on each of the pins should be half of what's listed for the 16 MHz boards. Unfortunately, in that case, it seems like none of the standard dividers would provide a 1kHz wave. I tinkered with the test code a bit and found that whether I'm controlling the actuator with a signal of ~2000Hz or ~500Hz, the actuator is still only going out to 3" at the highest signal. I'm posting my test code below:

Code: [Select]

#define BAUDRATE 57600

void setup() {
  setPwmFrequency(3, 8); //1953.125Hz?
  setPwmFrequency(5, 64);//488.2813Hz?
  setPwmFrequency(10, 64);//1953.125Hz?


void loop() {
  analogWrite(3, 255); //should be at 4" extension, instead at 3"
  analogWrite(5, 255);
  analogWrite(10, 255);
  delay(15000); //the delays are so long because of the travel time of the actuator
  analogWrite(3, 1); //returns to more or less 0"
  analogWrite(5, 1);
  analogWrite(10, 1);

void setPwmFrequency(int pin, int divisor) {
  byte mode;
  if(pin == 5 || pin == 6 || pin == 9 || pin == 10) {
    switch(divisor) {
      case 1: mode = 0x01; break;
      case 8: mode = 0x02; break;
      case 64: mode = 0x03; break;
      case 256: mode = 0x04; break;
      case 1024: mode = 0x05; break;
      default: return;
    if(pin == 5 || pin == 6) {
      TCCR0B = TCCR0B & 0b11111000 | mode;
    } else {
      TCCR1B = TCCR1B & 0b11111000 | mode;
  } else if(pin == 3 || pin == 11) {
    switch(divisor) {
      case 1: mode = 0x01; break;
      case 8: mode = 0x02; break;
      case 32: mode = 0x03; break;
      case 64: mode = 0x04; break;
      case 128: mode = 0x05; break;
      case 256: mode = 0x06; break;
      case 1024: mode = 0x7; break;
      default: return;
    TCCR2B = TCCR2B & 0b11111000 | mode;

I've tried tinkering with the frequency divider and the baud rate and nothing will get it to fully extend. Does anyone have any ideas of what I'm doing wrong? I'm not an EE, so please excuse my poor grasp of basic electric principles.


Are you using the blue wire (Voltage Input Signal) or the white wire (RC input signal)?

If you are using the blue wire, how do you get the 5v signal when the FIO running at 3.3v?
Send Bitcoin tips to: 1G2qoGwMRXx8az71DVP1E81jShxtbSh5Hp


I think you maybe hit upon my problem - I am using the blue lead and I completely neglected to take into account the voltage difference between the Fio and the Uno. I guess I'll have to look at other options for control or change the board we're using, but the wireless integration with the Fio is so nice.


If you use the white wire (RC input) you can probably use the Servo library.  Even though the FIO runs at 3.3v the signal is probably high enough to activate the 5V input.  Use writeMicroseconds(1000) for full in and writeMicroseconds(2000) for full out.  Values between 1000 and 2000 should give intermediate positions.

Send Bitcoin tips to: 1G2qoGwMRXx8az71DVP1E81jShxtbSh5Hp


I tried using the writeMicroseconds command and it seems to work very well! Thanks for your help, you saved me a lot of frustration and head-banging!

Go Up

Please enter a valid email to subscribe

Confirm your email address

We need to confirm your email address.
To complete the subscription, please click the link in the email we just sent you.

Thank you for subscribing!

via Egeo 16
Torino, 10131