Overview of ADXL335 Accelerometer
Accelerometer is an electromechanical device that measures the force of acceleration due to gravity in a g unit.
It can be used in applications requiring tilt sensing.
The ADXL335 measures acceleration along the X, Y, and Z axes and gives analog voltage output proportional to the acceleration along these 3 axes.
Microcontrollers can process these voltages by converting them to digital signals using ADC.
For more information about the ADXL335 accelerometer and how to use it, refer the topic ADXL335 Accelerometer Module in the sensors and modules section.
ADXL335 Accelerometer Hardware Connection with the ESP32
Read Acceleration using ADXL335 Sensor
Let’s take a simple example to find the roll and pitch of the device using analog voltages of the accelerometer module and displaying them on the serial monitor of Arduino.
Code for Read ADXL335 Accelerometer Serially using ESP32
/*
ESP32 ADXL335 Accelerometer Serial Monitor
http:://www.electronicwings.com
*/
#include <math.h>
double roll, pitch, yaw;
const int x_out = A0; /* connect x_out of module to A1 of UNO board */
const int y_out = A3; /* connect y_out of module to A2 of UNO board */
const int z_out = A6; /* connect z_out of module to A3 of UNO board */
void setup(void){
Serial.begin(115200); /*Set the baudrate to 115200*/
}
void loop() {
int x_adc_value, y_adc_value, z_adc_value;
double x_g_value, y_g_value, z_g_value;
x_adc_value = analogRead(x_out); /* Digital value of voltage on x_out pin */
y_adc_value = analogRead(y_out); /* Digital value of voltage on y_out pin */
z_adc_value = analogRead(z_out); /* Digital value of voltage on z_out pin */
Serial.print("x = ");
Serial.print(x_adc_value);
Serial.print("\t\t");
Serial.print("y = ");
Serial.print(y_adc_value);
Serial.print("\t\t");
Serial.print("z = ");
Serial.print(z_adc_value);
Serial.println("");
x_g_value = ( ( ( (double)(x_adc_value * 3.3)/4096) - 1.65 ) / 0.330 ); /* Acceleration in x-direction in g units */
y_g_value = ( ( ( (double)(y_adc_value * 3.3)/4096) - 1.65 ) / 0.330 ); /* Acceleration in y-direction in g units */
z_g_value = ( ( ( (double)(z_adc_value * 3.3)/4096) - 1.80 ) / 0.330 ); /* Acceleration in z-direction in g units */
roll = ( ( (atan2(y_g_value,z_g_value) * 180) / 3.14 ) + 180 ); /* Formula for roll */
pitch = ( ( (atan2(z_g_value,x_g_value) * 180) / 3.14 ) + 180 ); /* Formula for pitch */
yaw = ( ( (atan2(x_g_value,y_g_value) * 180) / 3.14 ) + 180 ); /* Formula for yaw */
/* Not possible to measure yaw using accelerometer. Gyroscope must be used if yaw is also required */
/* Display the results (acceleration is measured in m/s^2) */
Serial.print("Roll = ");
Serial.print(roll);
Serial.print("\t");
Serial.print("Pitch = ");
Serial.print(pitch);
Serial.print("\t");
Serial.print("Yaw = ");
Serial.print(yaw);
Serial.print("\n\n");
/*wait a second*/
delay(1000);
}
- Now upload the above code to see the output on the serial monitor of Arduino IDE. (While uploading the code make sure your ESP32 board is in the boot mode.)
- After uploading the code open the serial monitor and set the baud rate to 115200 to see the output.
ADXL335 Output on the serial monitor
Let’s understand the code
The code starts by initializing the required library.
#include <math.h>
Define the variables to store the result.
double roll, pitch, yaw;
Declare the ESP32’s analog input pins to which the sensor’s X, Y, and Z output pins are connected.
const int x_out = A0; /* connect x_out of module to A1 of UNO board */
const int y_out = A3; /* connect y_out of module to A2 of UNO board */
const int z_out = A6; /* connect z_out of module to A3 of UNO board */
In setup function
We have initiated the serial communication with a 9600 Baud rate.
Serial.begin(9600);
In loop function
In the loop function, we will read the ADC values and convert them into Roll, Yaw, and Pitch then display them on the serial monitor.
First, read the three analog inputs from the ADXL335 sensor and store in the variables.
x_adc_value = analogRead(x_out); /* Digital value of voltage on x_out pin */
y_adc_value = analogRead(y_out); /* Digital value of voltage on y_out pin */
z_adc_value = analogRead(z_out); /* Digital value of voltage on z_out pin */
Print these values on the serial monitor
Serial.print("x = ");
Serial.print(x_adc_value);
Serial.print("\t\t");
Serial.print("y = ");
Serial.print(y_adc_value);
Serial.print("\t\t");
Serial.print("z = ");
Serial.print(z_adc_value);
Serial.println("");
Convert the acceleration into g unit using the below formula for all axis
x_g_value = ( ( ( (double)(x_adc_value * 3.3)/4096) - 1.65 ) / 0.330 ); /* Acceleration in x-direction in g units */
y_g_value = ( ( ( (double)(y_adc_value * 3.3)/4096) - 1.65 ) / 0.330 ); /* Acceleration in y-direction in g units */
z_g_value = ( ( ( (double)(z_adc_value * 3.3)/4096) - 1.80 ) / 0.330 ); /* Acceleration in z-direction in g units */
Now from the g unit, we will calculate the roll, pitch, and yaw using the atan2()
function. The atan2()
function is used to return a value in the range -π to π radians.
roll = ( ( (atan2(y_g_value,z_g_value) * 180) / 3.14 ) + 180 ); /* Formula for roll */
pitch = ( ( (atan2(z_g_value,x_g_value) * 180) / 3.14 ) + 180 ); /* Formula for pitch */
yaw = ( ( (atan2(x_g_value,y_g_value) * 180) / 3.14 ) + 180 ); /* Formula for yaw */
Then display roll, yaw, and pitch values on the serial monitor.
/* Display the results (acceleration is measured in m/s^2) */
Serial.print("Roll = ");
Serial.print(roll);
Serial.print("\t");
Serial.print("Pitch = ");
Serial.print(pitch);
Serial.print("\t");
Serial.print("Yaw = ");
Serial.print(yaw);
Serial.print("\n\n");
Accelerometer ADXL335 Web Server using ESP32
Now let’s take another example to display the same readings on the web server using the Arduino IDE.
Before uploading the code make sure you have added your SSID and Password as follow.
const char* ssid = "*Your SSID*"; /*Enter Your SSID*/
const char* password = "*Your Password*"; /*Enter Your Password*/
Code for ADXL335 Accelerometer Web Server using ESP32
/*
ESP32 ADXL335 WebServer Monitoring
http:://www.electronicwings.com
*/
#include <WiFi.h>
#include <WebServer.h>
#include "html.h"
#include <math.h>
WebServer server(80);
const char* ssid = "*Your SSID*"; /*Enter Your SSID*/
const char* password = "*Your Password*"; /*Enter Your Password*/
double roll, pitch, yaw;
const int x_out = A0; /* connect x_out of module to A1 of UNO board */
const int y_out = A3; /* connect y_out of module to A2 of UNO board */
const int z_out = A6; /* connect z_out of module to A3 of UNO board */
void MainPage() {
String _html_page = html_page; /*Read The HTML Page*/
server.send(200, "text/html", _html_page); /*Send the code to the web server*/
}
void ADXL335html() {
String data = "[\""+String(roll)+"\",\""+String(pitch)+"\",\""+String(yaw)+"\"]";
server.send(200, "text/plane", data);
}
void setup(void){
Serial.begin(115200); /*Set the baudrate to 115200*/
WiFi.mode(WIFI_STA); /*Set the WiFi in STA Mode*/
WiFi.begin(ssid, password);
Serial.print("Connecting to ");
Serial.println(ssid);
delay(1000); /*Wait for 1000mS*/
while(WiFi.waitForConnectResult() != WL_CONNECTED){Serial.print(".");} /*Wait while connecting to WiFi*/
Serial.print("Connected to ");
Serial.println(ssid);
Serial.print("Your Local IP address is: ");
Serial.println(WiFi.localIP()); /*Print the Local IP*/
server.on("/", MainPage); /*Display the Web/HTML Page*/
server.on("/readADXL335", ADXL335html); /*Display the updated Distance value(CM and INCH)*/
server.begin(); /*Start Server*/
delay(1000); /*Wait for 1000mS*/
}
void loop() {
int x_adc_value, y_adc_value, z_adc_value;
double x_g_value, y_g_value, z_g_value;
x_adc_value = analogRead(x_out); /* Digital value of voltage on x_out pin */
y_adc_value = analogRead(y_out); /* Digital value of voltage on y_out pin */
z_adc_value = analogRead(z_out); /* Digital value of voltage on z_out pin */
Serial.print("x = ");
Serial.print(x_adc_value);
Serial.print("\t\t");
Serial.print("y = ");
Serial.print(y_adc_value);
Serial.print("\t\t");
Serial.print("z = ");
Serial.print(z_adc_value);
Serial.println("");
x_g_value = ( ( ( (double)(x_adc_value * 3.3)/4096) - 1.65 ) / 0.330 ); /* Acceleration in x-direction in g units */
y_g_value = ( ( ( (double)(y_adc_value * 3.3)/4096) - 1.65 ) / 0.330 ); /* Acceleration in y-direction in g units */
z_g_value = ( ( ( (double)(z_adc_value * 3.3)/4096) - 1.80 ) / 0.330 ); /* Acceleration in z-direction in g units */
roll = ( ( (atan2(y_g_value,z_g_value) * 180) / 3.14 ) + 180 ); /* Formula for roll */
pitch = ( ( (atan2(z_g_value,x_g_value) * 180) / 3.14 ) + 180 ); /* Formula for pitch */
yaw = ( ( (atan2(x_g_value,y_g_value) * 180) / 3.14 ) + 180 ); /* Formula for yaw */
/* Not possible to measure yaw using accelerometer. Gyroscope must be used if yaw is also required */
/* Display the results (acceleration is measured in m/s^2) */
Serial.print("Roll = ");
Serial.print(roll);
Serial.print("\t");
Serial.print("Pitch = ");
Serial.print(pitch);
Serial.print("\t");
Serial.print("Yaw = ");
Serial.print(yaw);
Serial.print("\n\n");
server.handleClient();
/*wait a second*/
delay(1000);
}
- Now upload the code. (While uploading the code make sure your ESP32 board is in the boot mode.)
- After uploading the code open the serial monitor and set the baud rate to 115200 then reset the ESP32 board and check the IP address as shown in the below image
- Now open any mobile browser and type the IP address which is shown in the serial monitor and hit the enter button.
- If all are ok, then the web page will start the showing current acceleration on the web server like in the below image.
Note: make sure your ESP32 and mobile are connected to the same router/server, if they are connected to the same router or server then only you will be able to visible the web page.
Output on the webserver
Let’s Understand the code.
To understand this code, please refer to the basics guide of “How to create the ESP32 Server”.
Once you get the basics of ESP32 server creation, it will be very simple to understand the code.
This code starts with important header files and libraries, In WiFi.h
file contains all ESP32 WiFi related definitions, here we have used them for network connection purposes.
The WebServer.h
file supports handling the HTTP GET and POST requests as well as setting up a server. In the html.h
file contains all the web page code, Wire.h
allows you to communicate with I2C device i.e ADXL345 and then add the Adafruit_Sensor and Adafruit_ADXL345_U library file.
#include <WiFi.h>
#include <WebServer.h>
#include "html.h"
#include <math.h>
Let’s define HTTP port i.e., Port 80 as follows
WebServer server(80);
Define the variables for three axis of the ADXL335 sensor
double roll, pitch, yaw;
Assign the pin numbers for three axis to the ADXL335 sensor
const int x_out = A0; /* connect x_out of module to A1 of UNO board */
const int y_out = A3; /* connect y_out of module to A2 of UNO board */
const int z_out = A6; /* connect z_out of module to A3 of UNO board */
Setup Function
In the setup function, first we set the WiFi as an STA mode and connect to the given SSID and password
WiFi.mode(WIFI_STA); /*Set the WiFi in STA Mode*/
WiFi.begin(ssid, password);
Serial.print("Connecting to ");
Serial.println(ssid);
delay(1000); /*Wait for 1000mS*/
while(WiFi.waitForConnectResult() != WL_CONNECTED){Serial.print(".");}
After successfully connecting to the server print the local IP address on the serial window.
Serial.print("Your Local IP address is: ");
Serial.println(WiFi.localIP()); /*Print the Local IP*/
Handling Client Requests and Serving the Page:
To handle the client request, we use server.on()
function.
It takes two parameters, The first is the requested URL path, and the second is the function name, which we want to execute.
As per the below code, when a client requests the root (/)
path, the “MainPage()
” function executes.
Also, when a client requests the “/readADXL335
” path, The ADXL335html()
function will be called.
server.on("/", MainPage); /*Client request handling: calls the function to serve HTML page */
server.on("/readADXL335", ADXL335html); /*Display the updated Distance value(CM and INCH)*/
Now start the server using server.begin()
function.
server.begin(); /*Start Server*/
Functions for Serving HTML
We have defined the complete HTML page in a file named “html.h
” and added it to the header file. With the following function, we are sending the complete page to the client via server.send()
function.
While sending, we are passing the first parameter “200” which is the status response code as OK (Standard response for successful HTTP requests).
Second parameter is the content type as “text/html
“, and the third parameter is html page code.
void MainPage() {
String _html_page = html_page; /*Read The HTML Page*/
server.send(200, "text/html", _html_page); /*Send HTM page to Client*/
}
Now in the below function only we are sending the updated acceleration values to the web page.
void ADXL335html() {
String data = "[\""+String(roll)+"\",\""+String(pitch)+"\",\""+String(yaw)+"\"]";
server.send(200, "text/plane", data);
}
Loop Function
Now to handle the incoming client requests and serve the relevant HTML page, we can use handleClient()
function. It executing relevant server.on()
as a callback function although it is defined in void setup()
So, it continuously serves the client requests.
server.handleClient();
HTML Page Code
/*
ESP32 HTML WebServer Page Code
http:://www.electronicwings.com
*/
const char html_page[] PROGMEM = R"RawString(
<!DOCTYPE html>
<html>
<style>
body {font-family: sans-serif;}
h1 {text-align: center; font-size: 30px;}
p {text-align: center; color: #4CAF50; font-size: 40px;}
</style>
<body>
<h1>ADXL335 Interface with ESP32 </h1><br>
<p>Roll : <span id="_X">0</span> m/s²</p>
<p>Pitch : <span id="_Y">0</span> m/s²</p>
<p>Yaw : <span id="_Z">0</span> m/s²</p>
<script>
setInterval(function() {
var xhttp = new XMLHttpRequest();
xhttp.onreadystatechange = function() {
if (this.readyState == 4 && this.status == 200) {
const text = this.responseText;
const myArr = JSON.parse(text);
document.getElementById("_X").innerHTML = myArr[0];
document.getElementById("_Y").innerHTML = myArr[1];
document.getElementById("_Z").innerHTML = myArr[2];
}
};
xhttp.open("GET", "readADXL335", true);
xhttp.send();
},100);
</script>
</body>
</html>
)RawString";
Let’s understand the code step by step
All html pages start with the <!DOCTYPE html>
declaration, it is just information to the browser about what type of document is expected.
<!DOCTYPE html>
The html tag is the container of the complete html page which represents on the top of the html code.
<html>
Now here we are defining the style information for a web page using the <style>
tag. Inside the style tag we have defined the font name, size, color, and test alignment.
<style>
body {font-family: sans-serif;}
h1 {text-align: center; font-size: 30px;}
p {text-align: center; color: #4CAF50; font-size: 40px;}
</style>
Inside the body, we are defining the document body, in below we have used headings, and paragraphs if you want you can add images, hyperlinks, tables, lists, etc. also.
On the web page, we are displaying the heading of the page, and inside a paragraph three accelerations i.e., Roll, Pitch, and Yaw readings.
Now accelerations values updates under the span id which is manipulated with JavaScript using the id attribute.
<body>
<h1>ADXL335 Interface with ESP32 </h1><br>
<p>Roll : <span id="_X">0</span> m/s²</p>
<p>Pitch : <span id="_Y">0</span> m/s²</p>
<p>Yaw : <span id="_Z">0</span> m/s²</p>
Now, this is the javascript that comes under the <script> tag, this is also called a client-side script.
<script>
In setInterval()
method we are calling the function at every 50mS intervals.
setInterval(function() {},50);
here we are creating the html XMLHttpRequest
object
var xhttp = new XMLHttpRequest();
The xhttp.onreadystatechange
event is triggered every time the readyState changes and the readyState holds the status of the XMLHttpRequest.
Now in the below code, the ready state is 4 means the request finished and response is ready and the status is 200 which means OK.
xhttp.onreadystatechange = function() {
if (this.readyState == 4 && this.status == 200) {
const myArr = JSON.parse(this.responseText);
now here is the main thing, we are updating the acceleration values in html page using _X, _Y, and _Z id.
document.getElementById("_X").innerHTML = myArr[0];
document.getElementById("_Y").innerHTML = myArr[1];
document.getElementById("_Z").innerHTML = myArr[2];
here we used the AJAX method to send the updated values to the server without refreshing the page.
In the below function we have used the GET method and sent the readADXL335
function which we defined in the main code asynchronously.
xhttp.open("GET", "readADXL335", true);
Send the request to the server using xhttp.send();
function.
xhttp.send();
Close the script
</script>
Close the body
</body>
Close the html.
</html>
Components Used |
||
---|---|---|
ADXL335 Accelerometer Module Accelerometer ADXL335 sensor measures acceleration of gravity. It is used to measure the angle of tilt or inclination in application systems such as in mobile devices, gaming applications, laptops, digital cameras, aeroplanes etc. |
X 1 | |
ESP32 WROOM WiFi Development Tools - 802.11 ESP32 General Development Kit, embeds ESP32-WROOM-32E, 4MB flash. |
X 1 |