Interface ADXL345 Accelerometer with Arduino & Processing Animation:
In this tutorial, we will learn how to Interface ADXL345 Accelerometer with Arduino & Processing Animation with 3D Animation view. We will also learn how does the Accelerometer ADXL345 works and also about some practical applications using this sensor.
You can also visit our few tutorials that are related to accelerometer:
1. Acceleration Measurement with Accelerometer ADXL335 & Arduino
2. Arduino Earthquake Detector Alarm with Seismic Graph using Accelerometer
3. Arduino Tilt Angle & Distance Meter with ADXL335 & HC-SR04
What is MEMS Accelerometer?
Most accelerometers are Micro-Electro-Mechanical Sensors (MEMS).
An accelerometer is an electromechanical device that measures both static (gravity) and dynamic (motion or vibration) accelerations. An accelerometer measures proper acceleration, which is the acceleration it experiences relative to freefall and is the acceleration felt by people and objects. For example, an accelerometer at rest on the surface of the Earth will measure an acceleration due to Earth’s gravity, straight upwards (by definition) of g ≈ 9.81 m/s2. By contrast, accelerometers in free fall (falling toward the center of the Earth at a rate of about 9.81 m/s2) will measure zero.
Structure of Accelerometer:
Conceptually, an accelerometer behaves as a damped mass on a spring. When the accelerometer experiences an acceleration, the mass is displaced to the point that the spring is able to accelerate the mass at the same rate as the casing. The displacement is then measured to give the acceleration.
In commercial devices, piezoelectric, piezoresistive and capacitive components are commonly used to convert the mechanical motion into an electrical signal. Modern accelerometers are often small micro-electro-mechanical systems (MEMS) and are indeed the simplest MEMS devices possible, consisting of little more than a cantilever beam with a proof mass (also known as seismic mass).
Working of Accelerometer:
There are many different ways to make an accelerometer! Some accelerometers use the piezoelectric effect – they contain microscopic crystal structures that get stressed by accelerative forces, which causes a voltage to be generated.
Another way to do it is by sensing changes in capacitance. If you have two microstructures next to each other, they have a certain capacitance between them. If an accelerative force moves one of the structures, then the capacitance will change. Add some circuitry to convert from capacitance to voltage, and you will get an accelerometer. There are even more methods, including the use of the piezoresistive effect, hot air bubbles, and light.
ADXL345 3 Axis Accelerometer:
ADXL345 3 Axis Accelerometer:
ADXL345 is a 3-axis accelerometer with a high-resolution (13-bit) measurement at up to ±16 g. Digital output data is formatted as a 16-bit twos complement and is accessible through either an SPI (3- or 4-wire) or I2C digital interface.
The ADXL345 is well suited to measures the static acceleration of gravity in tilt-sensing applications, as well as dynamic acceleration resulting from motion or shock. Its high resolution (4 mg/LSB) enables measurement of inclination changes less than 1.0 degrees.
Pins Description & Function:
ADXL345 Working with I2C Communication:
The I2C bus is a shared bus that consists of only two signals, a clock line (SCL) and a data line (SDA). A single I2C bus can connect two or more devices and any device can be a master or a slave (the same device can even assume both roles at different times). Only masters can initiate communication. Slave devices are assigned unique 7-bit or 10-bit device addresses through hardware configuration and monitor the bus for their address to be called, responding to any master device that begins a transaction. That means that you have to ensure that each slave device on your I2C bus has a unique address.
An I2C bus requires pull-ups on the SDA and SCL lines to keep the bus at a high voltage level when neither the master nor slave device is driving the bus. The pull-ups are created by attaching each of the interface wires to the supply voltage through an appropriately-sized resistor. The size of the resistor is chosen by the length of trace that will be used, which impacts the capacitance of the trace, and the speed of the I2C bus. Long traces create higher capacitance and require a lower value resistor to return the wire to a high voltage level after an I2C device has stopped driving the wire to a low voltage level.
How to Interface ADXL345 Accelerometer with Arduino & Processing?
To Interface ADXL345 Accelerometer with Arduino & Processing IDE you need Breadboard, Connecting Wires, Arduino UNO Board, ADXL345 accelerometer, and 16*2 LCD (optional). Assemble the circuit as shown in the figure below.
Source Code/Program:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 |
#include <Wire.h> #include<LiquidCrystal.h> LiquidCrystal lcd(12,11,5,4,3,2); #define DEVICE (0x53) //ADXL345 device address #define TO_READ (6) //num of bytes we are going to read each time (two bytes for each axis) #define offsetX -10.5 // place your OFFSET values here #define offsetY -2.5 #define offsetZ -4.5 #define gainX 257.5 // place your GAIN factors #define gainY 254.5 #define gainZ 248.5 byte buff[TO_READ] ; //6 bytes buffer for saving data read from the device char str[512]; //string buffer to transform data before sending it to the serial port void setup() { Wire.begin(); // join i2c bus (address optional for master) Serial.begin(9600); // start serial for output lcd.begin(16,2); //Turning on the ADXL345 writeTo(DEVICE, 0x2D, 0); writeTo(DEVICE, 0x2D, 16); writeTo(DEVICE, 0x2D, 8); } void loop() { int regAddress = 0x32; //first axis-acceleration-data register on the ADXL345 int x, y, z; readFrom(DEVICE, regAddress, TO_READ, buff); //read the acceleration data from the ADXL345 //each axis reading comes in 10 bit resolution, ie 2 bytes. Least Significat Byte first!! //thus we are converting both bytes in to one int x = (((int)buff[1]) << 8) | buff[0]; y = (((int)buff[3])<< 8) | buff[2]; z = (((int)buff[5]) << 8) | buff[4]; //we send the x y z values as a string to the serial port sprintf(str, "%d %d %d", x, y, z); Serial.print(str); Serial.print(10, byte()); lcd.setCursor(1,0); lcd.print("X:"); lcd.setCursor(3,0); lcd.print(x); lcd.setCursor(9,0); lcd.print("Y:"); lcd.setCursor(11,0); lcd.print(y); lcd.setCursor(5,1); lcd.print("Z:"); lcd.setCursor(7,1); lcd.print(z); //It appears that delay is needed in order not to clog the port delay(100); } //---------------- Functions //Writes val to address register on device void writeTo(int device, byte address, byte val) { Wire.beginTransmission(device); //start transmission to device Wire.write(address); // send register address Wire.write(val); // send value to write Wire.endTransmission(); //end transmission } //reads num bytes starting from address register on device in to buff array void readFrom(int device, byte address, int num, byte buff[]) { Wire.beginTransmission(device); //start transmission to device Wire.write(address); //sends address to read from Wire.endTransmission(); //end transmission Wire.beginTransmission(device); //start transmission to device Wire.requestFrom(device, num); // request 6 bytes from device int i = 0; while(Wire.available()) //device may send less than requested (abnormal) { buff[i] = Wire.read(); // receive a byte i++; } Wire.endTransmission(); //end transmission } |
Processing IDE 3D Animation Code
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 |
import processing.opengl.*; import processing.serial.*; //Sets variables for serial port, bytes, and floats Serial sp; byte[] buff; float[] r; float OFFSET_X = 2.5, OFFSET_Y = -2.5; //These offsets are chip specific, and vary. Play with them to get the best ones for you //This sets up the Processing 3 Java window dimension and visuals void setup() { size(400, 300, P3D); sp = new Serial(this, "/dev/cu.wchusbserial1410", 9600); //You have to rename your port in the "" and change the baud rate. buff = new byte[128]; r = new float[3]; } float protz, protx; void draw() { //perspective( 45, 4.0/3.0, 1, 5000 ); translate(400/2, 300/2, -400); //Sets left/right, up/down, and toward/away translation background(0); //Sets background color to black buildShape(protz, protx); //Used to define a new shape int bytes = sp.readBytesUntil((byte)10, buff); //It will only read until 10 bytes of data String mystr = (new String(buff, 0, bytes)).trim(); //trim removes whitespace at start of string if(mystr.split(" ").length != 3) { //uses string to break characters by using a delimiter "" println(mystr); return; } setVals(r, mystr); float z = r[0], x = r[1]; if(abs(protz - r[0]) < 0.05) z = protz; if(abs(protx - r[1]) < 0.05) x = protx; background(0); buildShape(z, x); protz = z; protx = x; println(r[0] + ", " + r[1] + ", " + r[2]); //prints x, y, z values in the console } //This sets up the 3D object inside the window void buildShape(float rotz, float rotx) { pushMatrix(); scale(6,6,14); rotateZ(rotz); rotateX(rotx); fill(255); stroke(0); box(60, 10, 10); fill(0, 255, 0); box(10, 9, 40); translate(0, -10, 20); fill(255, 0, 0); box(5, 12, 10); popMatrix(); } //Sets the values in an array void setVals(float[] r, String s) { int i = 0; r[0] = -(float)(Integer.parseInt(s.substring(0, i = s.indexOf(" "))) +OFFSET_X)*HALF_PI/256; r[1] = -(float)(Integer.parseInt(s.substring(i+1, i = s.indexOf(" ", i+1))) + OFFSET_Y)*HALF_PI/256; r[2] = (float) Integer.parseInt(s.substring(i+1)); } |
Video Tutorial & Explanation:
Apart from all this you can see our project with the application of ADXL345: Earthquake Detector Using Accelerometer and Arduino with Seismic Graph