Linear actuators from Shift Automation - robust performance

Use an Arduino to read a linear actuator encoder

First posted on shiftautomation.com

Reading a linear actuator encoder with an Arduino

We previously wrote a step-by-step tutorial on how to control a linear actuator with an Arduino and relays, and discussed how you could add intelligence to your application by incorporating a micro controller such as an Arduino.  Our CH-Series linear actuator has a position feedback system so you can add more functionality to your application by reading the position of the actuator shaft.  Knowing the position of the shaft opens a very wide range of possibilities.

Hall Sensor Encoders

Just a recap of what Hall Sensor quadrature encoders are, in case you missed our article on linear actuator position systems.

A Hall Effect sensor is a non-contact sensor that detects a magnetic field.  In the application of Hall Effect sensors in a linear actuator, a circular magnet is placed on the motor shaft and two Hall Effect sensors are mounted near one another.  As the motor turns the sensors detect the pole of the magnet as it passes.   Because the sensors are offset, one will detect the pole of the magnet before the other which provides information on the rotational direction of the motor.

Hall Effect quadrature encoder

Connecting the Arduino to the linear actuator

 


(click to enlarge)

The CH-Series linear actuator has an encoder built in, providing four wires for the encoder.  The wire colors are red, black, yellow and white.

  • The red wire connects to Arduino +5V pin.
  • The black wire connects to Arduino ground pin
  • The yellow wire connects to Arduino pin 2
  • The white wire connects to Arduino pin 3

Rather than cycling back and forth as in the previous tutorial, I've added an input device to control the movement of the actuator.  I could have used a switch, but since I want to use a linear poteniometer (slider) in the  tutorial I thought I'd try something a little different.  I am using a linear potentiometer as a switch.  (For instructions on using two buttons or a SPDT switch see further down the page) In code I'm going to split it into three general areas; bottom-center-top.  By sliding the potentiometer to the bottom, center or top we can control the movement of the actuator.  It will be the same as using a latching rocker switch to control the actuator.

Here's how I've wired the linear potentiometer to the Arduino:


(click to enlarge)

Adding code for the linear potentiometer (switch)

In order for the Arduino to be able to take input from the linear potentiometer we have to read an analog value from the sensor.  By connecting the wiper (green line above) to A0 (analog pin 0) we can read that in code.

int potSwitch = analogRead(potPin);

  if (potSwitch > 700) {
    extendActuator();
  } else {
    if (potSwitch < 300) {
      retractActuator();
    } else {
      stopActuator();
    }
  }

 

Adding code for the encoder

To make use of the encoder you can write your own code to read the encoder and track the pulses.  I prefer to use an Arduino library that has already had a lot of development and testing done on it.  I've had great success with the PJRC encoder library. Follow the instructions there to install the library into Arduino.

Now we can take the code from our 'how to control a linear actuator with an Arduino and relays' tutorial and add to it.

Add the reference to the encoder library, create an encoder object, and initialize a variable for storing position:

 

#include <Encoder.h>
const int relay1 = 7;
const int relay2 = 6;
const int potPin = 0;

//Set up the linear actuator encoder
//On many of the Arduino boards pins 2 and 3 are interrupt pins
// which provide the best performance of the encoder data.
Encoder myEnc(2, 3); //   avoid using pins with LEDs attached
long oldPosition  = -999;

Next we enable serial output (debugging):

void setup() {
  pinMode(relay1, OUTPUT);
  pinMode(relay2, OUTPUT);
  Serial.begin(9600);
}

 

Then we add a bit of code in the loop function to debug print the position when it changes:

  //check the encoder to see if the position has changed
  long newPosition = myEnc.read();
  if (newPosition != oldPosition) {
    oldPosition = newPosition;
    Serial.println(newPosition);
  }

 Now we're ready to see the position change as the actuator cycles. Move the slider up, down and to the middle and the actuator should start stop and change direction as you use the switch.

Here's the complete code for reference.

#include <Encoder.h>
const int relay1 = 7;
const int relay2 = 6;
const int potPin = 0;

//Set up the linear actuator encoder
//On many of the Arduino boards pins 2 and 3 are interrupt pins
// which provide the best performance of the encoder data.
Encoder myEnc(2, 3); //   avoid using pins with LEDs attached
long oldPosition  = -999;

void setup() {
  pinMode(relay1, OUTPUT);
  pinMode(relay2, OUTPUT);
  Serial.begin(9600);
}

void loop() {

  int potSwitch = analogRead(potPin);

  if (potSwitch > 700) {
    extendActuator();
  } else {
    if (potSwitch < 300) {
      retractActuator();
    } else {
      stopActuator();
    }
  }

  //check the encoder to see if the position has changed
  long newPosition = myEnc.read();
  if (newPosition != oldPosition) {
    oldPosition = newPosition;
    Serial.println(newPosition);
  }
}

void extendActuator() {
  //Serial.println("extendActuator");
  digitalWrite(relay1, HIGH);
  digitalWrite(relay2, LOW);
}

void retractActuator() {
  //Serial.println("retractActuator");
  digitalWrite(relay1, LOW);
  digitalWrite(relay2, HIGH);
}

void stopActuator() {
  //Serial.println("stopActuator");
  digitalWrite(relay1, LOW);
  digitalWrite(relay2, LOW);
}

 

Let us know what you build, or if you have a request for another step-by-step. support@shiftautomtion.com


 

Don't have a linear potentiometer? Want to use two switches?

Here's an updated diagram and code:


(click to enlarge)

The code has not been tested, if you find it doesn't work just shoot us an email and we'll run through it.


#include <Encoder.h>
const int relay1 = 7;
const int relay2 = 6;
const int sw1Pin = 8;
const int sw2Pin = 9;

//Set up the linear actuator encoder
//On many of the Arduino boards pins 2 and 3 are interrupt pins
// which provide the best performance of the encoder data.
Encoder myEnc(2, 3); //   avoid using pins with LEDs attached
long oldPosition  = -999;

void setup() {
  pinMode(relay1, OUTPUT);
  pinMode(relay2, OUTPUT);
  pinMode(sw1Pin, INPUT_PULLUP);
  pinMode(sw2Pin, INPUT_PULLUP);
  Serial.begin(9600);
}

void loop() {

  int sw1State = digitalRead(sw1Pin); //Read the status of Switch1
  int sw2State = digitalRead(sw2Pin); //Read the status of Switch2

  if (sw1State == LOW) { //If switch1 is pressed
     extendActuator();
  } else {
     if (sw2State == LOW) { //If switch2 is pressed
        retractActuator();
     } else {   //NO SWITCHES pressed.
        stopActuator();
     }
  }
   
  //check the encoder to see if the position has changed
  long newPosition = myEnc.read();
  if (newPosition != oldPosition) {
    oldPosition = newPosition;
    Serial.println(newPosition);
  }
}

void extendActuator() {
  //Serial.println("extendActuator");
  digitalWrite(relay1, HIGH);
  digitalWrite(relay2, LOW);
}

void retractActuator() {
  //Serial.println("retractActuator");
  digitalWrite(relay1, LOW);
  digitalWrite(relay2, HIGH);
}

void stopActuator() {
  //Serial.println("stopActuator");
  digitalWrite(relay1, LOW);
  digitalWrite(relay2, LOW);
}

Copyright 2016 - shiftautomation.com