Friday 11 December 2015

X-Y Axis Level Indicator Using Arduino

Continuing my previous idea about 3 Axis Accelerometer (ADXL345) using Arduino, I would like to do a little improvement about this idea. When you have a smartphone and install some tools in it, you will have one of the tools is level indicator.

In this opportunity, I would like to make a simple level indicator using collaboration between Arduino and servos. This simple level indicator have two main axis, X Axis and Y Axis, that will be shown in the movement of servos as an indicator.


Step 1: Components Gathering


1x Arduino
1x Accelerometer ADXL345
2x Servos
2x Hand Made Arrows
1x ProtoBoard
~x Cable Jumper

I replaced ProtoBoard and Cable Jumper with handmade Arduino shield. I made the shield based on the wiring procedure that will be described later.

Step 2: Wiring

We already knew that ADXL345 using I2C to communicate with the microcontroller.

And if you already done with the wiring, the final product will be like this.

I used my handmade Arduino shield for easy attachment, the shield follows the wiring procedure above. There is a box I use for placing the servos.

Step 3: Coding

 #include <Wire.h>  
 #include <Servo.h>  
 Servo xservo;  
 Servo yservo;  
 int xval, yval;  
 #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)  
 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  
  xservo.attach(5);  
  yservo.attach(6);  
  //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.write(10);  
  xval = x;  
  xval = map(xval, -250, 250, 0, 180);  
  xservo.write(xval);  
  delay(10);   
  yval = y;  
  yval = map(yval, -250, 250, 0, 180);  
  yservo.write(yval);  
  delay(10);   
  //It appears that delay is needed in order not to clog the port  
  delay(10);  
 }  
 //---------------- 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  
 }  

Step 4: Testing

After all wiring and coding are done, here we come with the testing.

Thank you for your time to visit my blog and I am very sorry for the dirty pillow behind :p. hahaha

No comments:

Post a Comment