Using ADXL335 to control a servo

Hello I have a parallax servo from 0 to 180 that I am trying to use to respond to an accelerometer reading.

I converted the x and y axis accelerations to an angle and want the servo to go to that angle. It seems to work ok but the servo movement is very jerky.

Also, when the accelerometer changes are rapid, the servo will sometimes start jumping all over the place, then settle back at the angle. I am guessing it is because I am powering the servo from the arduino (I dont have a external power supply at the moment).

I attached my code. What can I do to make my servo response more fluid than jerky. I do not like the delay() at the end but without that command the servo is extremely jerky the higher the delay the better (1000 seems to work). Is there anything else I can do to make it more fluid with a punishing delay command?

My ultimate goal is to use the accelerometer and servo to keep something balanced at a certain angle.

#include <math.h>
#include <Servo.h>

Servo servo1;                     // servo control object

const int xpin = A0;                  // x-axis of the accelerometer
const int ypin = A1;                  // y-axis
const int zpin = A2;                  // z-axis (only on 3-axis models)
const float mz = .013986;         //g conversion factor for zaxis
const float bz = -4.88111;
int8_t c;                          //calculated angle

void setup()
{
 // initialize the serial communications:
 Serial.begin(9600);
 servo1.attach(9);
 
}
void loop()
{
 int servopos;
 int x = analogRead(xpin);  //read from xpin
 delay(1); //
 int y = analogRead(ypin);  //read from ypin
 //delay(1); 
 //int z = analogRead(zpin);  //read from zpin
 
 c = (atan((x*mz+bz)/(y*mz+bz)))*57296/1000; //calculate tilt in y axis from -90 to 90
 servopos = c+90;
 servo1.write(servopos);          
 delay(100);
}

Hi,
How are you powering your servo?
It should have its own power supply, the 5V on the arduino cannot supply the instantaneous currents that the servo draws when moving.

Can you please post a copy of your circuit, in CAD or a picture of a hand drawn circuit in jpg, png?

Thanks.. Tom.. :slight_smile:

I read that the arduino can power a single non load bearing servo, I do not have an external power supply at the moment. The servo only seems to act funky when it sweeps large angles (like 0 to 180). Otherwise I am not getting any voltage or current drops. Please see OP for more info..Thanks!

The circuit is very simple. Dont even need a diagram. I have:

1 Accelerometer
3.3V from arduino
Gnd (located next to 5v input)
A0, A1, A2 pin for x,y,z

1 Servo
5V from arduino
GND (located next to pin 13)
PWM pin 9

Almost 100% sure its because the servo is powered by usb and not externally. I am using a multimeter and the reference pin is measuring less than 4V when it starts acting erractic.

I also updated my code to add some troubleshooting and additional sensitivity checks.

#include <math.h>
#include <Servo.h>

Servo servo1;                     // servo control object
boolean setServo = false;         // Flag to change servo position
int acceleration = 90;            //initialize servo positon
int sensitivity = 5;             //If > 5, will require a larger movement before activating servos
int temp;                         //temporary calculations of servo - tiltangle

const int xpin = A0;                  // x-axis of the accelerometer
const int ypin = A1;                  // y-axis
const int zpin = A2;                  // z-axis (only on 3-axis models)
const float mz = .013986;         //g conversion factor for zaxis
const float bz = -4.88111;
int8_t c;                          //calculated angle from -90 to 90
int tiltangle;                      // from 0 to 180

void setup()
{
// initialize the serial communications:
Serial.begin(9600);
servo1.attach(9);

}
void loop()
{
setServo=false;
int x = analogRead(xpin);  //read from xpin
delay(1); //
int y = analogRead(ypin);  //read from ypin
//delay(1); 
//int z = analogRead(zpin);  //read from zpin

c = (atan((x*mz+bz)/(y*mz+bz)))*57296/1000; //calculate tilt in y axis from -90 to 90
tiltangle = c+90;
temp = (acceleration-tiltangle);
temp = abs(temp);

Serial.println(acceleration);

if(temp>sensitivity)
{
 acceleration = tiltangle;
 setServo=true;
}
if(acceleration >179)
{
 acceleration = 180;
}
if(acceleration <0)
{
 acceleration = 0;
}

if (setServo)  //Adjusts Servo Positions
 {
   servo1.write(acceleration);
 }
 
 delay(1);  //Tiny delay to reduce electrical noise.

}

Please can adjust the program for the two servo?