Using The GY-511 LSM303DLHC Accelerometer To Detect Waving Motion
2018-04-25 - By Venkata Pavan Kumar Peri, Jerin Rebecca Rejin, Sri Lakshman Raman, Robert Elder
Introduction
The purpose of this article is to review the findings of a student-led project whose aim was to use the GY-511 circuit, with onboard LSM303DLHC accelerometer/magnetometer chip, to detect an individual waving motion similar to what would be found during exercise. This would allow the device to count the number of 'reps' of a particular exercise that were performed:
For this project, the GY-511 circuit was an inexpensive model purchased from eBay for $2.43 USD. The product title for the eBay listing was 'LSM303DLHC e-Compass 3 axis Accelerometer and 3 axis Magnetometer Module'.
As is often the case with inexpensive parts purchased on eBay, it can be difficult to find accurate documentation. The students found information in the following Schematic for the GY-511 to be useful.
Code
Provided below is the resulting C program that the students used to read acceleration values and send any detected motions to the thinkspeak API. This program was run in the Arduino environment:
#include <ThingSpeak.h>
#include <Wire.h>
#include <LiquidCrystal.h>
#include <SoftwareSerial.h>
#include <stdlib.h>
// Acclerometer registr addresses
#define X_Axis_Register_DATAX0 0x28
#define X_Axis_Register_DATAX1 0x29
#define Y_Axis_Register_DATAY0 0x2A
#define Y_Axis_Register_DATAY1 0x2B
#define Z_Axis_Register_DATAZ0 0x2C
#define Z_Axis_Register_DATAZ1 0x2D
#define samples 100
#define ACCELEROMETER_ADDR 0x19
#define MAG_ADDR 0x1e
unsigned int acc_data[6];
float Xa,Ya,Za;
int rep;
const int rs = 12, en = 11, d4 = 5, d5 = 4, d6 = 3, d7 = 2;
LiquidCrystal lcd(rs, en, d4, d5, d6, d7);
int peizoPin =13;
String apiKey ="..."; // Copy your write API key here from thingspeak
SoftwareSerial ser(7,8); // RX, TX
void Write1(int address, int controlreg, int value) {
int rc;
Wire.beginTransmission(address);
Wire.write (controlreg);
Wire.write(value);
rc = Wire.endTransmission(true);
}
int Read1(int address,int controlreg) {
Wire.beginTransmission(address);
Wire.write(controlreg);
Wire.endTransmission(false);
Wire.requestFrom(address,1,true);
if(Wire.available()==1) {
return Wire.read ();
} else
return -1;
}
void setup() {
Wire.begin();
Serial.begin(9600);
delay (100);
Write1(ACCELEROMETER_ADDR,0x20, 0x47); // Set Control register 1a
Write1(ACCELEROMETER_ADDR,0x23, 0x48); // Set Control register 4a
/*Write(MAG_ADDR,0x00, 0x14);
Write(MAG_ADDR,0x02, 0x00);*/
lcd.begin(16, 2);
lcd.setCursor(0, 0);
lcd.print(" LoadTronics");
delay (100);
lcd.setCursor(0, 1);
lcd.print("Reps are ");
Serial.begin(9600);
ser.begin(9600);
ser.println("AT+RST");
}
void loop() {
int acc_data[6];
int16_t Xout,Yout,Zout,i;
unsigned char temp,MR_Data[6];
float MAG;
int arr[10];
int upscounted=0;
int downcounted=0;
static int transactionState = 1;
int sum,AVG,up,down,idle;
for(i=0;i<10;i++) {
acc_data[0]=Read1(ACCELEROMETER_ADDR,0x28);
acc_data[1]=Read1(ACCELEROMETER_ADDR,0x29);
acc_data[2]=Read1(ACCELEROMETER_ADDR,0x2A);
acc_data[3]=Read1(ACCELEROMETER_ADDR,0x2B);
acc_data[4]=Read1(ACCELEROMETER_ADDR,0x2C);
acc_data[5]=Read1(ACCELEROMETER_ADDR,0x2D);
Xout=(acc_data[0]<<8) + acc_data[1];
Xa=Xout/256;
Yout=int (acc_data[2]<<8) + acc_data[3];
Ya=Yout/256;
Zout=int (acc_data[4]<<8) + acc_data[5];
Za=Zout/256;
MAG = sqrt ((Xa*Xa)+(Ya*Ya)+(Za*Za));
arr[i]=MAG;
}
sum=0;
for (int j=0;j<10;j++) {
sum = sum+arr[j];
}
AVG=sum/10;
up=0;down=0;idle=0;
if (AVG>80) {
up=1;
}
if (AVG>60 && AVG<=80) {
idle=1;
}
if (AVG<=60) {
down=1;
}
switch (transactionState) {
case 0:
if(up) {
transactionState++;
}
break;
case 1:
if(down) {
transactionState++;
}
break;
case 2:
if(idle) {
transactionState++;
}
break;
case 3:
if(down) {
transactionState++;
}
break;
case 4:
if(up) {
transactionState++;
}
break;
case 5:
if(idle) {
transactionState=0;
rep++;
Serial.print("Reps are= ");Serial.println(rep);
lcd.setCursor(14, 1);lcd.print(rep);
if (rep>5) {
tone(peizoPin,3000,2000);
delay(1000);
}
// Connecting WIFI network
String cmd = "AT+CIPSTART=\"TCP\",\"";
cmd += "184.106.153.149"; // api.thingspeak.com
cmd += "\",80";
ser.println(cmd);
Serial.println(cmd);
if(ser.find("Error")) {
Serial.println("AT+CIPSTART error");
return;
}
// Prepare GET string
String getStr = "GET /update?api_key=";
getStr += apiKey;
getStr +="&field1=";
getStr += String(rep);
getStr += "\r\n\r\n";
// Upoading values to the thinkspeak
cmd= "AT+CIPSEND=";
cmd +=String(getStr.length());
ser.println(cmd);
delay(1000);
// Send data length
if(ser.find(">")) {
ser.print(getStr);
Serial.print(getStr);
} else{
ser.println("AT+CIPCLOSE");
Serial.println("AT+CIPCLOSE");
}
}
break;
}
}
Resources
The students found the following links useful in their analysis:
- LSM303DLHC e-Compass: 3D accelerometer, 3D digital magnetic sensor, ultra compact, high performance, I2C, SPI interfaces
- LSM303DLHC ST Manual
How To Make A CPU - A Simple Picture Based Explanation
Published 2021-11-09 |
$1.00 CAD |
Example Uses Of Semiconductors - More Than Just CPUs
Published 2022-03-03 |
What Causes Bit Flips In Computer Memory?
Published 2023-02-08 |
Jeri Ellsworth & the Robot Uprising of 2038
Published 2018-10-11 |
CPUs Are Smaller Than You Think
Published 2021-11-09 |
Can You Create A Wireless Bridge With ESP8266 Modules?
Published 2018-09-02 |
Routing Packets Directly Between ESP8266 Modules
Published 2018-12-30 |
Join My Mailing List Privacy Policy |
Why Bother Subscribing?
|