ADXL335 accelerometer with tft issues

Hello all,

I'm a senior electrical engineering student doing a project for a sensor suite to go on a gravity cart. I am using the ADXL335 accelerometer, Grove Air530 GPS, and am printing all of the sensor data on a Treedix 3.5” LCD TFT 320x480 Color Display. I have the GPS and accelerometer sensor data printing on my display, the problem comes with the vales of the accelerometer.

I have attached the accelerometer to analogue pins A3-A5 with Vcc on 3.3V and GND where it should be. I am using the ADXL335 library from Seeed Studio. The GitHub shows an updated version of the .h and .cpp files to include getAccelerometerX, Y, and Z that I am using to individually print these values when they change above a 0.1G threshold.

I added the updated code to my header and cpp file and changed the x y and z default pins from A0-A2 to A3-A5. I then ran the calibration example code to get the values to update the header file with and was off to the races. The Measure Acceleration example IDE code worked great. I had a resolution of +/- .05G, good'nuff.

I then tried to print the same data to the tft and the values are wildly off. Im getting X and Y axis outputs of 11G+ and a Z axis output of ~0.5G. I thought the issue might be with the updated library code I added, so I went back to their example Measure Acceleration and added some print lines using getAccelerationX() to compare with the output. The numbers were sometimes off, but never more than 0.02G or so.

I'm out of ideas on what else to check. I run the example Measure Acceleration and it gives great data. I use the same commands for my own code to print to the tft and it gives me crazy numbers. HUD.h is my own header file for the code below.

#include "HUD.h"

//HUD Constructor; Pass in a pointer to the LCD (tft) and the TinyGpsPlus (gps) instance; control location of data
HUD::HUD(MCUFRIEND_kbv* tft, TinyGPSPlus* gps, ADXL335* accelerometer) : speedLocation{50,200} , locationLocation{290,30} , signalLocation{5,300}, accelerationLocation{10,30} {
  this->tft = tft;
  this->gps = gps;
  this->accelerometer = accelerometer;
  this->previousSpeed = 0.0;
  this->previousLat = 0.0;
  this->previousLng = 0.0;
  this->previousAlt = 0.0;
  this->previousSats = 0;
  this->previousXaccel = 0.00;
  this->previousYaccel = 0.00;
  this->previousZaccel = 0.00;
  this->hasDrawnSpeed = false;
  this->hasDrawnLocation = false;
  this->hasDrawnConnected = false;
  this->hasDrawnAcceleration = false;
}

//Draw is the main HUD drawing function
void HUD::draw() {
  this->drawSpeed();
  this->drawLocation();
  this->drawSignal();
  this->drawAcceleration();
}
//------------------------------------------------------------------------------Create check to draw speed with no update / only with update
//
bool HUD::shouldDrawSpeed(){
  if (!this->hasDrawnSpeed){
    return true;
  }
  if (this->gps->speed.isUpdated()){
  double currentSpeed = this->gps->speed.mph();

   return (abs(currentSpeed - previousSpeed) > 0.01);
  }
  return false;
}

//------------------------------------------------------------------------------Create check to draw location with no update / only with update
bool HUD::shouldDrawLocation(){
  if (!this->hasDrawnLocation){
    return true;
  }
  if (this->gps->location.isUpdated() || this->gps->altitude.isUpdated() || this->gps->satellites.isUpdated()){
  double currentLat = this->gps->location.lat();
  double currentLng = this->gps->location.lng();
  double currentAlt = this->gps->altitude.feet();
  double currentSats = this->gps->satellites.value();

  bool latChanged = (abs(currentLat - previousLat) > 0.000001);
  bool lngChanged = (abs(currentLng - previousLng) > 0.000001);
  bool altChanged = (abs(currentAlt - previousAlt) > 0.01);
  bool satsChanged = (abs(currentSats - previousSats) > 0);

   return (latChanged || lngChanged || altChanged || satsChanged);
  }
  return false;
}

//------------------------------------------------------------------------------check to draw acceleration once
bool HUD::shouldDrawAcceleration(){
  if (!this->hasDrawnAcceleration){
    return true;
  }
  {
 
  float currentXaccel = this->accelerometer->getAccelerationX();
  float currentYaccel = this->accelerometer->getAccelerationY();
  float currentZaccel = this->accelerometer->getAccelerationZ();
  bool accelXchanged = (abs(currentXaccel - previousXaccel) > 0.1);
  bool accelYchanged = (abs(currentYaccel - previousYaccel) > 0.1);
  bool accelZchanged = (abs(currentZaccel - previousZaccel) > 0.1);

   return (accelXchanged || accelYchanged || accelZchanged);
 }
  return false;
}

//------------------------------------------------------------------------------Create drawSpeed method
void HUD::drawSpeed() {
  if (this->shouldDrawSpeed())
    {
      this->hasDrawnSpeed = true;

        // Get Current speed
        double currentSpeed = this->gps->speed.mph();
        int16_t speedboxWidth = 400;
        int16_t speedboxHeight = 90;

          //sec shes telling me a story

        // Print old speed in black
       // this->tft->drawRect((int16_t)(this->speedLocation.x - 10),(int16_t)(this->speedLocation.y - 60), speedboxWidth, speedboxHeight, CYAN);
        this->tft->setCursor(this->speedLocation.x, speedLocation.y);
        this->tft->setTextSize(2); 
        this->tft->setTextColor(BLACK);
        this->tft->setFont(&FreeMonoBold18pt7b); 
        this->tft->print(this->previousSpeed);
        this->tft->println(" mph");

        // Print in new color
        this->tft->setCursor(this->speedLocation.x, speedLocation.y);
        this->tft->setTextSize(2); 
        this->tft->setTextColor(CYAN);
        this->tft->setFont(&FreeMonoBold18pt7b); 
        this->tft->print(currentSpeed);
        this->tft->println(" mph");

        this->previousSpeed = currentSpeed;
        
    }
}

//------------------------------------------------------------------------------Create drawLocation method
void HUD::drawLocation() {
  if (this->shouldDrawLocation())
  {
      this->hasDrawnLocation = true;

        // Set current location values
        double currentLat = this->gps->location.lat();
        double currentLng = this->gps->location.lng();
        double currentAlt = this->gps->altitude.feet();
        double currentSats = this->gps->satellites.value();
        int16_t locationboxWidth = 190;
        int16_t locationboxHeight = 110;

        // Print location in black
        this->tft->drawRect((int16_t)(this->locationLocation.x - 10),(int16_t)(this->locationLocation.y - 25), locationboxWidth, locationboxHeight, WHITE);
        this->tft->setTextColor(BLACK);
        this->tft->setFont(&FreeSans12pt7b);
        this->tft->setTextSize(1);  
        this->tft->setCursor(this->locationLocation.x, this->locationLocation.y);
        this->tft->print("Lat: ");
        this->tft->println(this->previousLat,6);

        this->tft->setTextColor(BLACK);
        this->tft->setFont(&FreeSans12pt7b);
        this->tft->setTextSize(1);   
        this->tft->setCursor(this->locationLocation.x, this->locationLocation.y + 25);
        this->tft->print("Lng: ");
        this->tft->println(this->previousLng,6);

        this->tft->setTextColor(BLACK);
        this->tft->setFont(&FreeSans12pt7b); 
        this->tft->setTextSize(1);  
        this->tft->setCursor(this->locationLocation.x, this->locationLocation.y + 50);
        this->tft->print("Alt: ");
        this->tft->print(this->previousAlt,2);
        this->tft->println(" ft");

        this->tft->setTextColor(BLACK);
        this->tft->setFont(&FreeSans12pt7b); 
        this->tft->setTextSize(1);  
        this->tft->setCursor(this->locationLocation.x, this->locationLocation.y + 75);
        this->tft->print("Sats: ");
        this->tft->print(this->previousSats);

        // Print new values in white
        this->tft->setTextColor(WHITE);
        this->tft->setFont(&FreeSans12pt7b); 
        this->tft->setTextSize(1);  
        this->tft->setCursor(this->locationLocation.x, this->locationLocation.y);
        this->tft->print("Lat: ");
        this->tft->println(currentLat,6);

        this->tft->setTextColor(WHITE);
        this->tft->setFont(&FreeSans12pt7b); 
        this->tft->setTextSize(1);  
        this->tft->setCursor(this->locationLocation.x, this->locationLocation.y + 25);
        this->tft->print("Lng: ");
        this->tft->println(currentLng,6);

        this->tft->setTextColor(WHITE);
        this->tft->setFont(&FreeSans12pt7b); 
        this->tft->setTextSize(1);  
        this->tft->setCursor(this->locationLocation.x, this->locationLocation.y + 50);
        this->tft->print("Alt: ");
        this->tft->print(currentAlt,2);
        this->tft->println(" ft");

        this->tft->setTextColor(WHITE);
        this->tft->setFont(&FreeSans12pt7b); 
        this->tft->setTextSize(1);  
        this->tft->setCursor(this->locationLocation.x, this->locationLocation.y + 75);
        this->tft->print("Sats: ");
        this->tft->print(this->gps->satellites.value());

        this->previousLat = currentLat;
        this->previousLng = currentLng;
        this->previousAlt = currentAlt;
        this->previousSats = currentSats;
    }
}

//------------------------------------------------------------------------------Create check to draw CONNECTED once
bool HUD::shouldDrawConnected(){
  if (!this->hasDrawnConnected){
    return true;
  }
  return false;
}


//------------------------------------------------------------------------------draw connection status
void HUD::drawSignal(){
        int16_t signalboxWidth = 300;
        int16_t signalboxHeight = 35;
  if (!this->gps->location.isValid()){
  
    // Print SIGNAL MESSAGE
       // this->tft->drawRect((int16_t)(this->signalLocation.x - 4),(int16_t)(this->signalLocation.y - 25), signalboxWidth, signalboxHeight, RED);
        this->tft->setTextColor(RED);
        this->tft->setFont(&FreeSans12pt7b);
        this->tft->setTextSize(1);  
        this->tft->setCursor(this->signalLocation.x, this->signalLocation.y);
        this->tft->println("SEARCHING FOR SIGNAL");

 // Print SIGNAL MESSAGE
        //this->tft->fillRect((int16_t)(this->signalLocation.x - 4),(int16_t)(this->signalLocation.y - 25), signalboxWidth, signalboxHeight, BLACK);
        this->tft->setTextColor(BLACK);
        this->tft->setFont(&FreeSans12pt7b);
        this->tft->setTextSize(1);  
        this->tft->setCursor(this->signalLocation.x, this->signalLocation.y);
        this->tft->println("SEARCHING FOR SIGNAL");

        // Print SIGNAL MESSAGE
       // this->tft->fillRect((int16_t)(this->signalLocation.x - 4),(int16_t)(this->signalLocation.y - 25), signalboxWidth, signalboxHeight, WHITE);
        this->tft->setFont(&FreeSans12pt7b);
        this->tft->setTextSize(1);  
        this->tft->setCursor(this->signalLocation.x, this->signalLocation.y);
        this->tft->println("SEARCHING FOR SIGNAL");
  }
    if (this->gps->location.isValid()){
    this->hasDrawnConnected = true;

//Print CONNECTED MESSAGE
        this->tft->fillRect((int16_t)(this->signalLocation.x - 4),(int16_t)(this->signalLocation.y - 25), signalboxWidth, signalboxHeight, BLACK);
        this->tft->drawRect((int16_t)(this->signalLocation.x - 4),(int16_t)(this->signalLocation.y - 25), (signalboxWidth - 140), signalboxHeight, WHITE);
        this->tft->setTextColor(GREEN);
        this->tft->setFont(&FreeSans12pt7b);
        this->tft->setTextSize(1);  
        this->tft->setCursor(this->signalLocation.x, this->signalLocation.y);
        this->tft->println("CONNECTED");
  }
}

//------------------------------------------------------------------------------draw acceleration
void HUD::drawAcceleration() {
  if (this->shouldDrawAcceleration())
  {
      this->hasDrawnAcceleration = true;

        // Set acceleration values
        float currentXaccel = this->accelerometer->getAccelerationX();
        float currentYaccel = this->accelerometer->getAccelerationY();
        float currentZaccel = this->accelerometer->getAccelerationZ();
        int16_t accelerationboxWidth = 170;
        int16_t accelerationboxHeight = 90;

        // Print acceleration in black
        this->tft->drawRect((int16_t)(this->accelerationLocation.x - 10),(int16_t)(this->accelerationLocation.y - 25), accelerationboxWidth, accelerationboxHeight, WHITE);
        this->tft->setTextColor(BLACK);
        this->tft->setFont(&FreeSans12pt7b);
        this->tft->setTextSize(1);  
        this->tft->setCursor(this->accelerationLocation.x, this->accelerationLocation.y);
        this->tft->print("X accel: ");
        this->tft->println(this->previousXaccel);

        this->tft->setTextColor(BLACK);
        this->tft->setFont(&FreeSans12pt7b);
        this->tft->setTextSize(1);  
        this->tft->setCursor(this->accelerationLocation.x, this->accelerationLocation.y + 25);
        this->tft->print("Y accel: ");
        this->tft->println(this->previousYaccel);

        this->tft->setTextColor(BLACK);
        this->tft->setFont(&FreeSans12pt7b);
        this->tft->setTextSize(1);  
        this->tft->setCursor(this->accelerationLocation.x, this->accelerationLocation.y + 50);
        this->tft->print("Z accel: ");
        this->tft->println(this->previousZaccel);

          // Print new values in white
        this->tft->setTextColor(WHITE);
        this->tft->setFont(&FreeSans12pt7b);
        this->tft->setTextSize(1);  
        this->tft->setCursor(this->accelerationLocation.x, this->accelerationLocation.y);
        this->tft->print("X accel: ");
        this->tft->println(currentXaccel);

        this->tft->setTextColor(WHITE);
        this->tft->setFont(&FreeSans12pt7b);
        this->tft->setTextSize(1);  
        this->tft->setCursor(this->accelerationLocation.x, this->accelerationLocation.y + 25);
        this->tft->print("Y accel: ");
        this->tft->println(currentYaccel);

        this->tft->setTextColor(WHITE);
        this->tft->setFont(&FreeSans12pt7b);
        this->tft->setTextSize(1);  
        this->tft->setCursor(this->accelerationLocation.x, this->accelerationLocation.y + 50);
        this->tft->print("Z accel: ");
        this->tft->println(currentZaccel);

        this->previousXaccel = currentXaccel;
        this->previousYaccel = currentYaccel;
        this->previousZaccel = currentZaccel;
    }
}

Obviously, the scale and offset factors applied to the raw accelerometer data are wrong, but the posted code doesn't show how that is done.

See this tutorial for a simple six point correction (scroll down the page): Accelerometer Calibration II: Simple Methods | Chionotech

Thanks! While I read that, I'll link the short library that shows how were turning the raw data into something useful.

This is the library header

/*
 * ADXL335.h
 * Library for accelerometer_ADXL335
 *
 * Copyright (c) 2013 seeed technology inc.
 * Author        :   FrankieChu 
 * Create Time   :   Jan 2013
 * Change Log    :
 *
 * The MIT License (MIT)
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 * THE SOFTWARE.
 */
 
#ifndef __ADXL335_H__
#define __ADXL335_H__

#include <Arduino.h>
/*macro definitions of Analog read pins*/
#define X_AXIS_PIN A13
#define Y_AXIS_PIN A14
#define Z_AXIS_PIN A15

#define ADC_AMPLITUDE 1024//amplitude of the 10bit-ADC of Arduino is 1024LSB
#define ADC_REF 3.28   //ADC reference is 3.28v
#define ZERO_X  1.11 //accleration of X-AXIS is 0g, the voltage of X-AXIS is 1.22v
#define ZERO_Y  1.09 //
#define ZERO_Z  1.36 //
#define SENSITIVITY 0.25//sensitivity of X/Y/Z axis is 0.25v/g

class ADXL335
{
private:
    void pinsInit();
    float scale;
public:
    void begin();
    void getXYZ(int16_t *x,int16_t *y,int16_t *z);
    void getAcceleration(float *ax,float *ay,float *az);
    float getAccelerationX();
    float getAccelerationY();
    float getAccelerationZ();
};

#endif

And this is the cpp file, both from Seeed Studio

/*
 * ADXL335.h
 * Library for accelerometer_ADXL335
 *
 * Copyright (c) 2013 seeed technology inc.
 * Author        :   FrankieChu 
 * Create Time   :   Jan 2013
 * Change Log    :
 *
 * The MIT License (MIT)
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 * THE SOFTWARE.
 */
 
#include <Arduino.h>
#include "ADXL335.h"

void ADXL335::pinsInit()
{
    pinMode(X_AXIS_PIN, INPUT);
    pinMode(Y_AXIS_PIN, INPUT);
    pinMode(Z_AXIS_PIN, INPUT);
}
void ADXL335::begin()
{
    pinsInit();
    scale = (float)SENSITIVITY*ADC_AMPLITUDE/ADC_REF;
}
void ADXL335::getXYZ(int16_t *x,int16_t *y,int16_t *z)
{
    *x = analogRead(X_AXIS_PIN);
    *y= analogRead(Y_AXIS_PIN);
    *z = analogRead(Z_AXIS_PIN);
}
void ADXL335::getAcceleration(float *ax,float *ay,float *az)
{
    int x,y,z;
    float xvoltage,yvoltage,zvoltage;
    getXYZ(&x,&y,&z);
    xvoltage = (float)x*ADC_REF/ADC_AMPLITUDE;
    yvoltage = (float)y*ADC_REF/ADC_AMPLITUDE;
    zvoltage = (float)z*ADC_REF/ADC_AMPLITUDE;
    Serial.println("voltage:");
    Serial.println(xvoltage);
    Serial.println(yvoltage);
    Serial.println(zvoltage);
    *ax = (xvoltage - ZERO_X)/SENSITIVITY;
    *ay = (yvoltage - ZERO_Y)/SENSITIVITY;
    *az = (zvoltage - ZERO_Z)/SENSITIVITY;
    
}
float ADXL335::getAccelerationX() {
    int x, y, z;
    float xvoltage, ax;
    getXYZ(&x, &y, &z);
    xvoltage = (float)x * ADC_REF / ADC_AMPLITUDE;
    ax = (xvoltage - ZERO_X) / SENSITIVITY;
    return ax;
}
float ADXL335::getAccelerationY() {
    int x, y, z;
    float yvoltage, ay;
    getXYZ(&x, &y, &z);
    yvoltage = (float)y * ADC_REF / ADC_AMPLITUDE;
    ay = (yvoltage - ZERO_Y) / SENSITIVITY;
    return ay;
}
float ADXL335::getAccelerationZ() {
    int x, y, z;
    float zvoltage, az;
    getXYZ(&x, &y, &z);
    zvoltage = (float)z * ADC_REF / ADC_AMPLITUDE;
    az = (zvoltage - ZERO_Z) / SENSITIVITY;
    return az;
}

This solved the issue for me! Big thanks!

I ended up following that six-point correction to find out the library was incorrect in its calculations. I made some raw measurements and made an excel spreadsheet to get better data averages. Added the changes necessary and getting a resolution of +/- .2G with a goal of .5G. Thanks again!

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