ADXL377

Hello guys,

im using Adafruit ADXL377 shield and having a small trouble.

Im using the following code to adquire values from X,Y and Z and too scale them to ‘g’s’:

void loop()
{
 //Reset da array das coordenadas GPS
 memset(message,0,sizeof(message));

  readLocation();

  int rawX = analogRead(A0);
  int rawY = analogRead(A1);
  int rawZ = analogRead(A2);

  // Scale accelerometer ADC readings into common units
  // Scale map depends on if using a 5V or 3.3V microcontroller
  //float scaledX, scaledY, scaledZ; // Scaled values for each axis
  
    scaledX = mapf(rawX, 0, 1023, -scale, scale);
    scaledY = mapf(rawY, 0, 1023, -scale, scale);
    scaledZ = mapf(rawZ, 0, 1023, -scale, scale);

Serial.print("X: ");
  Serial.println(rawX);
  Serial.print("Y: ");
  Serial.println(rawY);
  Serial.print("Z: ");
  Serial.println(rawZ);
  Serial.println();

  // Print out scaled X,Y,Z accelerometer readings
  Serial.print("X: ");
  if(scaledX < 0) scaledX = -scaledX;
  Serial.print(scaledX);
  Serial.println(" g");
  Serial.print("Y: ");
  if(scaledY < 0) scaledY = -scaledY;
  Serial.print(scaledY);
  Serial.println(" g");
  Serial.print("Z: ");
  if(scaledZ < 0) scaledZ = -scaledZ;
  Serial.print(scaledZ);

    
  Serial.println(" g");
  Serial.println();


}

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;
}

The measures looks ok. the only trouble is always the first measure gets a peak like:

X: 16.6g
Y: 14g
Z: 25g

Why is that happening ?

khaoz87:
Hello guys,

im using Adafruit ADXL377 shield and having a small trouble.

https://www.adafruit.com/products/1413

Im using the following code to adquire values from X,Y and Z and too scale them to ‘g’s’:

void loop()

{
//Reset da array das coordenadas GPS
memset(message,0,sizeof(message));

readLocation();

int rawX = analogRead(A0);
  int rawY = analogRead(A1);
  int rawZ = analogRead(A2);

// Scale accelerometer ADC readings into common units
  // Scale map depends on if using a 5V or 3.3V microcontroller
  //float scaledX, scaledY, scaledZ; // Scaled values for each axis
 
    scaledX = mapf(rawX, 0, 1023, -scale, scale);
    scaledY = mapf(rawY, 0, 1023, -scale, scale);
    scaledZ = mapf(rawZ, 0, 1023, -scale, scale);

Serial.print("X: ");
  Serial.println(rawX);
  Serial.print("Y: ");
  Serial.println(rawY);
  Serial.print("Z: ");
  Serial.println(rawZ);
  Serial.println();

// Print out scaled X,Y,Z accelerometer readings
  Serial.print(“X: “);
  if(scaledX < 0) scaledX = -scaledX;
  Serial.print(scaledX);
  Serial.println(” g”);
  Serial.print(“Y: “);
  if(scaledY < 0) scaledY = -scaledY;
  Serial.print(scaledY);
  Serial.println(” g”);
  Serial.print("Z: ");
  if(scaledZ < 0) scaledZ = -scaledZ;
  Serial.print(scaledZ);

Serial.println(" g");
  Serial.println();

}

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;
}




The measures looks ok. the only trouble is always the first measure gets a peak like:

X: 16.6g
Y: 14g
Z: 25g

Why is that happening ?

That code doesn’t compile, print the raw x,y,z

Chuck.

Here what i receive in the serial:

X: 455
Y: 459
Z: 463

X: 22.09 g
Y: 20.53 g
Z: 18.96 g


X: 510
Y: 512
Z: 510

X: 0.59 g
Y: 0.20 g
Z: 0.59 g

Always the first measure has those peak g's why ?

khaoz87:
Here what i receive in the serial:

X: 455
Y: 459
Z: 463

X: 22.09 g
Y: 20.53 g
Z: 18.96 g


X: 510
Y: 512
Z: 510

X: 0.59 g
Y: 0.20 g
Z: 0.59 g

Always the first measure has those peak g’s why ?

Which Arduino are you using?

From AdaFruit’s website

This breakout comes with 3 analog outputs for X, Y and Z axis measurements on a 0.75"x0.75" breakout board. The analog outputs are ratiometric: that means that 0g measurement output is always at half of the 3.3V output (1.65V), -200g is at 0v and 200g is at 3.3V with full scaling in between.

If you are usings a standard 5V UNO, and the Sensor is flat on a surface.

Z axis Raw should read: 339
X Axis Raw should read: 338
Z Axis Raw should read: 338

The Sensor outputs 0.00825 V per G. so Zero G is 1.65V, one G positive is 1.65825

If you are using a 3.3V Micro, and the sensor is flat on a surface:

Z axis Raw should read 514 = (1.65825/3.3)*1024
X axis Raw should read 512 =(1.65/3.3)*1024
Y axis Raw should read 512 = (1.65/3.3)*1024

Those first reading are way out. Post your actual, compiling code, and maybe I can find what is wrong.

base on your numbers, you are using a 3.3v Arduino. You probably need to null the sensor.

the 510 reading looks to be the 0g level.

Instead of:

g=mapf(raw,0,1023,-200.0,200.0);

try

int temp = abs(raw-510); // zero is 510
g=mapf(temp,0,510,0.0,200.0);
if(raw<510) g=-g;

Chuck.

Im using a arduino mega 1280, using exactly this conection:

How do i null the sensor ?

khaoz87:
Im using a arduino mega 1280, using exactly this conection:

How do i null the sensor ?

Read the Sensor at a known acceleration. (i.e. not moving, fixed orientation) Y:512, X:510, Z:510

Calculate an offset from:
Sensor is lying with Y axis pointed away from EARTH Therefore Y Axis should read 1g
X and Z axes are parallel to the surface of Earth therefore they should read 0g

So I pick raw Sensor Value of 510 as 0g. That is what my previous example code did.

My corrections have those assumptions, If the sensor is oriented in a different manner, you will have to change my coding.

Also, you might have to create a specific null value fore EACH axis. Just orient the Sensor such that the axis under question is measuring Zero g. Then use that value for your ‘nulling’ value for that axis.

uint16_t nullAxis(uint8_t axisPin){
Serial.print("Orient Sensor such that ");
switch(axisPin){
   case A2 : Serial.print('Z');
     break;
   case A1 : Serial.print('Y');
     break;
   case A0 : Serial.print('X');
     break;
   default : Serial.print(" Unknown AXIS. Aborting")'
     return 0; // out of range value
   }
 Serial.print(" axis is Horizontal.\n");
bool goodRead=false;
uint16_t reading, avgReading;
uint8_t cnt=0;
while(!goodRead){ // Stay in loop until reading stabilizes.
  reading = analogRead(axisPin);
  cnt++;
  avgReading += reading;
  if(cnt>60){
    avgReading = avgReading - (avgReading/cnt);
    cnt--;
    }
 if(cnt==60)&&(avgReading/cnt==reading)) goodRead = true;
 }
return reading;
}

uint16_t zZero,yZero,xZero;


void NullSensor(){
do{
  zZero = nullAxis(A2);
  while(zZero==0);
do{
  yZero = nullAxis(A1);
  while(yZero==0);
do{
  xZero = nullAxis(A0);
  while(xZero==0);
}

void readNulledSensor(uint16_t* Z, uint16_t* Y, uint16_t* X){
*Z=(512+analogRead(A2))-zZero;
*Y=(512+analogRead(A1))-zZero;
*X=(512+analogRead(A0))-zZero;
}

void setup(){
Serial.begin(9600);
nullSensor();
}

uint16_t maxZ,maxY,maxX;
uint16_t minZ=1024,minY=1024,minX=1024;
unsigned long timeout=0;

void loop(){
uint16_t z,y,x;
readNulledSensor(&z,&y,&x);

if(z>maxZ)maxZ=z;
if(y>maxY)maxY=y;
if(x>maxX)maxX=x;

if(z<minZ)minZ=z;
if(y>minY)minY=y;
if(x>minX)minX=x;


char ch[100]; // message buffer
if(millis()-timeout>1000){ // every second print reading
   sprintf(ch,"Max Z=%d Max Y=%d Max X=%d\n",maxZ,maxY,maxX);
   Serial.print(ch);
   sprintf(ch,"Min Z=%d Min Y=%d Min X=%d\n",minZ,minY,minX);
   Serial.print(ch);
   sprintf(ch,"Current:\n Z=%d Y=%d X=%d\n",z,y,x);
   Serial.print(ch);
   minX=1024;minY=1024;minZ=1024;
   maxX=0; maxY=0; MaxZ=0;
   timeout = millis(); // start next timeout
   }

}

Chuck.