Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save john212/8179059c61c05dcda565 to your computer and use it in GitHub Desktop.
Save john212/8179059c61c05dcda565 to your computer and use it in GitHub Desktop.
Using a 3-Axis Accelerometer to Measure Inclination In X-Axis and Display Angle on ST7735 TFT LCD
/**************************************************
Using a 3-Axis Accelerometer to Measure Inclination
(X-Axis Only) and Displaying Result on a 138x160 TFT LCD
by J. Cantlin
Januaty 2, 2015
***************************************************/
/**************************************************
Description of Program
A 3-Axis accelerometer is used to measure the angle
of incline compared to a resting position (horizontal to floor).
The sensor is an ADXL335 made by Analog Devices, it is
a +- 3g x,y,z 3-axis accelerometer. The algortihm for determining
the angle of incline is from an Analog Devices data
sheet. Reference: Analog Devices Application Notes:
"Using an Accelerometer for Inclination Sensing" - AN-1057 Rev. 0
http://www.analog.com
This program writes to the ST7735 TFT Dispay.
TFT LCD = Thin Film Transistor Liquid-Crystal Display, a type of
advanced LCD display that uses thin-film transistors.
***************************************************/
/**************************************************
TFT LCD Display
The ST7735 used is from Sainsmart.com The ST7735R is a single-chip
controller/driver for the 262K-color, graphic type TFT LCD.
This 1.8 in. display has a resolution of 128x160 pixels.
The interface is SPI. It includes an SD card which is not used
in this sketch.
TFT LCD library
https://www.arduino.cc/en/Reference/TFTLibrary
This library enables an Arduino to communicate with the TFT LCD screen.
The TFT library extends the Adafruit GFX, and Adafruit ST7735 libraries that
it is based on. The GFX library is responsible for the drawing routines,
while the ST7735 library is specific to the screen type used with the Arduino TFT.
The TFT library relies on the SPI library for communication with the screen and SD card,
and needs to be included in all sketches. The onboard SD card uses the SD library.
Hardware SPI is used in this sketch.
***************************************************/
/*********************************************************************
SPI - Serial Peripheral Interconnect Protocol
The 4 signal lines are:
– clock (SCLK), from the bus master to all slaves; all the SPI signals are synchronous to this clock signal
– A data line from the master to the slaves, named MOSI (Master Out-Slave In)
– A data line from the slaves to the master, named MISO (Master In-Slave Out)
– slave select (or chip select) (SSx/CSx) for EACH slave, to select the slave the master communicates with
Arduino hardware supports SPI as follows:
- Uno: MOSI Pin 11, MISO Pin12, SCK Pin 13, SS Pin 10
- Mega: MOSI Pin 51, MISO Pin50,SCK Pin 52, SS Pin 53
- Note: MISO not needed for read only LCD, Only one SPI so SS not required.
The DC pin (data/command) is used to select between command mode (low) and data mode (high).
SPI Libraries:
Must include SPI.h and "begin" the SPI using SPI.begin() in setup. This initializes
the SPI bus by setting SCK, MOSI and SS to outputs, pulling SCK and MOSI LOW and
SS HIGH.
***********************************************************************/
/*********************************************************************
Summary of ST7735 TFT LCD Pins Used:
The board is a "raw" board, not the Adafruite breakout board.
Looking at board from back, pins at bottom, starting from
righmost pin, Vcc:
---TFT Pins--- ---Arduino Digital Pins---
Vcc = 3 to +5vdc ==>+5vdc
Gnd = Ground ==>Grouund
SCL = TFT Clock ==>Arduino Pin 13 (defined in hardware)
SDA = TFT MOSI (MISO n/a for TFT) ==>Arduino Pin 11 (defined in hardware)
DC = TFT data/command mode selector ==>Arduino Pin 9
RES = RESET ==>Arduino Pin 8
CS = TFT chip select ==>Arduino Pin 10 (must be an OUTPUT)
---SD Card Pins---- ---None SD Card Not Used---
MISO = common to all SPI devices
SCLK = common to all SPI devices
MOSI = common to all SPI devices
CS = SD chip select
***********************************************************************/
/*********************************************************************
The analog "zero" readings for the x, y, and z axis were determined.
The x,y axes are in the horizontal plane, if you place the breakout
board flat on the table, the x axis will be defined as + to the right
and - to the left. The y axis will be defined as + away from you and
- towards you. The z axis is in the vertical plane and the z axis
will be defined as + up and - down. When flat, the g forces versus
measured analog readings for the sensor were:
+x = 0g = 262 analog reading for x-axis use 326+-66. 326=zero g
-x = 0g = 392 analog reading
+y = 0g = 263 analog reading for y-axis use 325+-66. 326=zero g
-y = 0g = 395 analog reading
+z = 0g = 286 analog reading for x-axis use 351+-67. 350=zero g
-z = 1g = 418 analog reading
***********************************************************************/
/**********************************************************************
The map funtion "maps" one range of values to another:
map(value, fromLow, fromHigh, toLow, toHigh).
The constrain function will limit the range to a specified minimum and maximum:
constrain(x, min, max).
To contrain the analog sensor reading from say 260 to 392 and map them to
-1 g to 1 g" for the x, y axis and 1 g to -1 g for the z axis.
(example) constrain(valX, 326,392);
(example) map(valX,260,392,0,66) //mapping uses integer values only.
Since the map function does not work with floats, a user defined
funtion called mapf is used to replace map. Reference:
http://dm.risd.edu/pbadger/PhysComp/index.php?n=Code.MapConstrain
*********************************************************************/
/**************************************************
Summary of Arduino Uno Analog Pins Used:
A0 = ADXL335 X-axis Sensor
A1 = ADXL335 Y-axis Sensor
A2 = ADXL335 Z-axis Sensor
A3 =
A4 =
A5 =
***************************************************/
/**************************************************
Summary of Arduino Uno Digital Pins Used:
00 =
01 =
02 =
03 =
04 =
05 =
06 =
07 =
08 = RESET pin of TFT ==> use any pin
09 = DC pin of TFT Data/Command Mode Select ==> use any pin
10 = CS pin of TFT Circuit Select ==> use any pin
11 = MOSI pin of TFT ==>defined in hardware SPI
12 =
13 = SCLK pin of TFT ==>defined in hardware SPI
***************************************************/
/*********************************************************************
Do NOT use these "includes" with #include TFT.h:
#include <Adafruit_GFX.h> // Core graphics library
#include <Adafruit_ST7735.h> // Hardware-specific library
***********************************************************************/
#include <SPI.h> //Serial Peripheral Interconn lib for high speed drive of TFT LCD.
#include <TFT.h> //TFT library to drive TFT displays.
#include <SD.h> //Library for accessing SD card.
#include <math.h> //Auduino code library for math operations
/* Define pins used with SPI and TFT LCD
MOSI 11 defined in hardware SPI which is being used, do not define here
SCLK 13 defined in hardware SPI which is being used, do not define here*/
#define TFT_RESET 8 //can also connect to Arduino reset, use pin 0
#define TFT_DC 9
#define TFT_CS 10
// initialize the library with the TFT LCD pins.
// TFT(pin10, pin9, pin8) = (CS, DC, RESET) for SPI Hardware configuration on Arduino Uno
Adafruit_ST7735 TFTscreen = Adafruit_ST7735(TFT_CS, TFT_DC, TFT_RESET);
/***********************************
TFT Display Analog Value and Shapes
This example for an Arduino TFT screen reads
the value of an analog sensor on A0, and
displays the value on the screen.
https://www.arduino.cc/en/Tutorial/TFTDisplayText
************************************/
//declare global variables uses for reading acceleration and finding angles
float valX, valY, valZ; //raw analog values for x, y, and z axis readings.
float accX, accY, accZ; //analog readings converted to acceleration, in g's.
float angleX, angleY, angleZ; //angle of inclination with x, y, and z axis.
float absAngleX, absAngleY, absAngleZ; //positive incline angles
void setup()
{//****start setup function block****
// initialize the serial port, if needed remove comments
Serial.begin(9600);
// Initialize (begin) the ST7735S 1.8" TFT
TFTscreen.initR(INITR_BLACKTAB); // initialize a ST7735S chip, black tab
//constrain analog x, y, z readings to actual measured ranges
constrain(valX,268,401); //updated 12-31-2015
constrain(valY,268,401); //updated 12-31-2015
constrain(valZ,292,427); //updated 12-31-2015
// clear the screen and set the background color
TFTscreen.background(0, 0, 0); //(r,g,b) where (0,0,0) = black
//set screen text parameters
TFTscreen.stroke(255,255,255); //(r,g,b) where (255,255,255) = white
TFTscreen.setTextSize(1); //1 = small
}//****endof setup function block****
void loop()
{//****start infinite loop****
//read the accelerometer x, y, and z axis values
valX = analogRead(0); // read analog input pin A0
valY = analogRead(1); // read analog input pin A1
valZ = analogRead(2); // read analog input pin A2
delay(10); // short delay to allow readings to stabilize
//map the analog sensor readings to a g value between -1 g to + 1 g
//to match the values in AN-1057, the z readings were reversed.
accX = mapf(valX,268.0,401.0,-1.0,+1.0); //user defined mapf function
accY = mapf(valY,268.0,401.0,-1.0,+1.0); //user defined mapf function
accZ = mapf(valZ,292.0,427.0,+1.0,-1.0); //user defined mapf function
//calculate the angle of inclination with each axis.
angleX = atan2(accX,(sqrt(pow(accY,2)+pow(accZ,2))))*(180/PI);
angleY = atan2(accY,(sqrt(pow(accX,2)+pow(accZ,2))))*(180/PI);
angleZ = atan2((sqrt(pow(accX,2)+pow(accY,2))),accZ)*(180/PI);
//use fabs() "f"loating point absolute value vs abs()
absAngleX = fabs(angleX);
absAngleY = fabs(angleY);
absAngleZ = fabs(angleZ);
//Draw the initial side of the angle, that is, the x-axis
TFTscreen.stroke(0, 255, 0); // set the stroke color to blue
TFTscreen.line(0, TFTscreen.height()/2, TFTscreen.width(), TFTscreen.height()/2); // draw the line
delay(1000);
//find endpoints of line starting at origin = (0, TFTscreen.height()/2)
//convert angle to integer
//CAUTION: watch out for radians vs degrees!
int intAngleX = (int) angleX; //angleX is in degrees
float radAngleX = angleX * (PI/180);
float tanRadAngleX = tan(radAngleX);
float deltaY = ((TFTscreen.width())*(tanRadAngleX));
int intDeltaY = (int) deltaY;
int endY = ((TFTscreen.height())/2)- intDeltaY;
//Draw the terminal side of the angle, that is, the angle of inclination to the x-axis
TFTscreen.stroke(255, 0, 0); // set the stroke color to red
TFTscreen.line(0, TFTscreen.height()/2, TFTscreen.width(), endY); // draw the line
delay(2000);
TFTscreen.background(0,0,0); // clear the screen before starting again
delay(2000);
/********************************************************************/
//Print data used for testing and debugging - comment out as needed.
// Serial.print("analog readings for x, y, z: ");
// Serial.print(valX, DEC); // print the acceleration in the X axis
// Serial.print(" "); // prints a space between the numbers
// Serial.print(valY, DEC); // print the acceleration in the Y axis
// Serial.print(" "); // prints a space between the numbers
// Serial.println(valZ, DEC); // print the acceleration in the Z axis
//
// Serial.print("accX ");
// Serial.println(accX,DEC);
// Serial.print("accY ");
// Serial.println(accY,DEC);
// Serial.print("accZ ");
// Serial.println(accZ,DEC);
//
// Serial.print("angleX ");
// Serial.println(angleX,DEC);
// Serial.print("angleY ");
// Serial.println(angleY,DEC);
// Serial.print("angleZ ");
// Serial.println(angleZ,DEC);
//
// Serial.print("intAngleX ");
// Serial.println(intAngleX,DEC);
// Serial.print("radAngleX ");
// Serial.println(radAngleX,DEC);
// Serial.print("tan radAngleX ");
// Serial.println(tanRadAngleX,DEC);
// Serial.print("deltaY ");
// Serial.println(deltaY,DEC);
// Serial.print("endY ");
// Serial.println(endY,DEC);
delay(2000); // wait for next reading
/********************************************************************/
}//****endof infinite loop****
/********************************************************************
//function mapf to mimic map function but it uses floating point numbers
*******************************************************************/
float mapf(float x_, float in_min, float in_max, float out_min, float out_max)
{//****start mapf function****
return (x_ - in_min) * (out_max - out_min) / (in_max - in_min) + out_min;
}//****endof mapf function****
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment