Controlling extension/retraction of P-type L12 Actuonix actuator using values from accelerometer

Hi everyone,

I need help with my project. I need an Actuonix L12 p type actuator to extend/retract a distance based on g force values detected from an accelerometer. The accelerometer I am using is a ADXL337.

The range of g-force values used is -0.5g to 0.5g where -0.5g the actuator is at 5mm, at 0g the actuator is at 25mm and at 0.5g the actuator is at 45mm.
I am wondering if anyone can help me create a code for this. I am very new to the world of Arduinos and haven't a great electrical knowledge so please bear with me on this. I have a code for detecting the g-force values pasted below which detects in one axis only for simplicity. The serial monitor in Arduino IDE displays the g-force only as I am only interested in the g-force values. I have tried this code and it works. I'm hoping that I can get the actuator to extend/retract based on the range of g-force values detected. Also if the g-force value exceeds the range I have mentioned, i'd like the actuator to extend/retract to the max (45mm) or min (5mm) distances depending on which side of the range it has exceeded.

Hopefully I havent made this sound too complicated. Any feedback or solutions is greatly appreciated. As i say I have very little experience with arduinos and hoping code can be added on top of the code I have provided if thats possible. Thanks :slightly_smiling_face:

int scale = 3; // 3 (±3g) for ADXL337, 200 (±200g) for ADXL377
boolean micro_is_5V = true; // Set to true if using a 5V microcontroller such as the Arduino Uno, false if using a 3.3V microcontroller, this affects the interpretation of the sensor data

void setup()
{
  // Initialize serial communication at 9600 baud
  Serial.begin(9600);
}

// Read, scale, and print accelerometer data
void loop()
{
  // Get raw accelerometer data for each axis
  int rawX = analogRead(A0);
  
  // Scale accelerometer ADC readings into common units
  // Scale map depends on if using a 5V or 3.3V microcontroller
  float scaledX; // Scaled values for each axis
  if (micro_is_5V) // Microcontroller runs off 5V
  {
    scaledX = mapf(rawX, 0, 675, -scale, scale); // 3.3/5 * 1023 =~ 675
  }

  // Print out scaled X accelerometer readings
  Serial.print("X: "); Serial.print(scaledX); Serial.println(" g");
  Serial.println();
  
  delay(200); // Minimum delay of 2 milliseconds between sensor reads (500 Hz)
}

// Same functionality as Arduino's standard map function, except using floats
float mapf(float x, float in_min, float in_max, float out_min, float out_max)
{
  return (x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min;
}

based on the example here for the actuator control, maybe something like this:
(Compiles, NOT tested!)

#include <Servo.h>

const int MinPos = 0, MaxPos = 180; //update min and max values as required
const float scale = 3.0; // 3 (±3g) for ADXL337, 200 (±200g) for ADXL377
boolean micro_is_5V = true; // Set to true if using a 5V microcontroller such as the Arduino Uno, false if using a 3.3V microcontroller, this affects the interpretation of the sensor data
int pos = 0;    // variable to store the servo position

Servo myservo;  // create servo object to control a servo

void setup()
{
  // Initialize serial communication at 9600 baud
  Serial.begin(9600);
  myservo.attach(9);  // attaches the servo on pin 9 to the servo object
}

// Read, scale, and print accelerometer data
void loop()
{
  // Get raw accelerometer data for each axis
  int rawX = analogRead(A0);
  
  // Scale accelerometer ADC readings into common units
  // Scale map depends on if using a 5V or 3.3V microcontroller
  float scaledX; // Scaled values for each axis
  if (micro_is_5V) // Microcontroller runs off 5V
  {
    scaledX = mapf(rawX, 0, 675, -scale, scale); // 3.3/5 * 1023 =~ 675
  }

  if(scaledX > scale){ //has exceeded the max range value
    myservo.write(MaxPos);              // tell servo to go to Maximum Position
    delay(30); //abitrarity delay. adjust accordingly to sufficient time for actuator movement to complete
  }
  else if(scaledX < -scale){ //has exceeded the min range value
    myservo.write(MinPos);              // tell servo to go to Minimum Position
    delay(30); //abitrarity delay. adjust accordingly to sufficient time for actuator movement to complete    
  }
  else{
    pos = map((int)(scaledX),-scale, scale, MinPos, MaxPos); //map accel range to servo range
    myservo.write(pos);              // tell servo to go to position in variable 'pos'
    delay(30); //abitrarity delay. adjust accordingly to sufficient time for actuator movement to complete
  }

  // Print out scaled X accelerometer readings
  Serial.print("X: "); Serial.print(scaledX); Serial.println(" g");
  Serial.println();
  
  delay(200); // Minimum delay of 2 milliseconds between sensor reads (500 Hz)
}

// Same functionality as Arduino's standard map function, except using floats
float mapf(float x, float in_min, float in_max, float out_min, float out_max)
{
  return (x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min;
}

hope that helps....

PS you probably will need to add another 'map' function to convert 'actuator displacement' to 'servo pos' :wink:

Hi, thanks for your help. I'll try it out.

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.