Introduction: RPI ADXL345 Data Graph to Phone Via Gmail
Hello and welcome to my Instructable. For this project, I programmed a Raspberry Pi 3B+ to log data from an ADXL345 using an SPI connection, input the data into a graph using Matplot, and send the graph to the user via Gmail. The program runs once the RPI receives a signal from the BlueDot app on an Android device via bluetooth. This is very useful for testing the running frequencies of electronics, or the speed an object rotates at. For example, you can check the revolutions made by an HDD in a PC. Below, I go in depth on how to create this project for yourself. Here is a demo video of the project...
The sources/resources I used to create this project are listed at the end of this Instructable.
Supplies
Raspberry Pi 3, 4, or Zero W (running RPI OS) (if you don't have a RPI 3, 4 or Zero W, you can use a USB Bluetooth Dongle)
ADXL345 Accelerometer
6 Jumper Wires
Android Device (running Android 4.0 and up)
Step 1: Wiring
The wiring from ADXL345 to RPI goes as follows...
GND - GND
VCC - 3V3
CS - 24
SDO - 21
SDA - 19
SCL - 23
There is also a diagram above that shows the RPI 3B+ to ADXL345 wiring.
Step 2: Installing Libraries and Software
For this program, we will need to install the following libraries...
- Bluedot
- SMTPLib
- MatplotLib
The rest of the libraries we need should already be included in RPI OS.
To install these libraries simply use the following commands in the RPI terminal.
sudo pip3 install bluedot
sudo pip3 install smtplib
sudo pip3 install matplotlib
Next we will need to install the ADXL345 SPI software created by Nagimov on GitHub.
sudo apt-get update
git clone https://github.com/nagimov/adxl345spi
cd adxl345spi
sudo make
sudo make install
Step 3: Allow Less Secure Apps on Gmail
1. While logged into your gmail at gmail.com, go to https://myaccount.google.com/security
2. Scroll down to the part that says "Allow less secure apps"
3. Turn ON "allow less secure apps."
If you don't want to make your main gmail less secure, or if you don't already have gmail, then sign up for a new gmail solely for this purpose.
Step 4: Writing the Script
Once you open your preferred IDE, follow along and type in the following code;
First, lets include all of our libraries.
from bluedot import BlueDot import os import numpy as np from matplotlib import mlab import matplotlib.pylot as plt from datetime import datetime import time import smtplib from email.mime.multipart import MIMEMultipart from email.mime.text import MIMEText from email.mime.base import MIMEBase from email import encoders
Right under that we include our accelerometer prefrences and our BlueDot initiation.
sample_rate_Hz = 1000 length_s = 10 bd = BlueDot()
Next we need to define our accel(): function. The code in this section is credited to Nagimov on GitHub.
def accel(): os.system(f'sudo adxl345spi -t {length_s} -f {sample_rate_Hz} -s out.csv') acc_data = np.genfromtxt('out.csv', delimiter=',', names=True) acc_x, freq_x, _ = mlab.specgram(acc_data['x'], Fs=sample_rate_Hz, NFFT=sample_rate_Hz * length_s) acc_y, freq_y, _ = mlab.specgram(acc_data['y'], Fs=sample_rate_Hz, NFFT=sample_rate_Hz * length_s) acc_z, freq_z, _ = mlab.specgram(acc_data['z'], Fs=sample_rate_Hz, NFFT=sample_rate_Hz * length_s) plt.plot(freq_x[10:], acc_x[10:], label='x', linewidth=0.5) plt.plot(freq_y[10:], acc_y[10:], label='y', linewidth=0.5) plt.plot(freq_z[10:], acc_z[10:], label='z', linewidth=0.5) plt.yscale('log') plt.xlim((0,100)) plt.legend(loc='lower left') plt.savefig(picturename)
Now we need to define our email(): function. The code in this section is credited to Kitflix and BC-ROBOTICS. Make sure to fill in the fromaddr, toaddr, and password variables. You should fill in the password for the account only. MAKE SURE TO KEEP THE QUOTATION MARKS.
def email(): fromaddr = "ADD FROM ADDRESS HERE" toaddr = "ADD TO ADDRESS HERE" password = "ADD FROM PASSWORD HERE" msg = MIMEMultipart() msg['From'] = fromaddr msg['To'] = toaddr msg['Subject'] = "ADXL345 Graph" body = "Here is the graph... filename: " + picturename msg.attach(MIMEText(body, 'plain')) filename = picturename attachment = open('/home/pi/Desktop/' + picturename, "rb") part = MIMEBase('application', 'octet-stream') part.set_payload((attachment).read()) encoders.encode_base64(part) part.add_header('Content-Disposition', "attachment; filename= %s" % filename) msg.attach(part) server = smtplib.SMTP('smtp.gmail.com', 587) server.starttls() server.login(fromaddr, password) text = msg.as_string() server.sendmail(fromaddr, toaddr, text) server.quit()
**NOTE - The graph always saves in the same path of your script. By default, this script is setup to look in the Desktop path. Therefore, you must save your script in the Desktop path. If you wish to change the path of the script you must change the following line in the email function to your preferred path.
attachment = open('INSERT YOUR PATH HERE ENDING WITH /' + picturename, "rb")
Make sure to end your path with a / . For example...
attachment = open('/home/pi/Desktop/' + picturename, "rb")
Lastly, we need to add the loop that runs each function at a time, changes the color of the button on the BlueDot app, and changes the filename of our graph to include the time and date of the measuring time.
while True: plt.cla() picturename = f"Spectrum-{datetime.now():%Y-%m-%d-%H-%M-%S}.png" bd.wait_for_press() bd.color = "green" accel() bd.color = "yellow" email() bd.color = "blue"
Here is the final code...
from bluedot import BlueDot import os import numpy as np from matplotlib import mlab import matplotlib.pyplot as plt from datetime import datetime import time import smtplib from email.mime.multipart import MIMEMultipart from email.mime.text import MIMEText from email.mime.base import MIMEBase from email import encoders sample_rate_Hz = 1000 length_s = 10 bd = BlueDot() def accel(): os.system(f'sudo adxl345spi -t {length_s} -f {sample_rate_Hz} -s out.csv') acc_data = np.genfromtxt('out.csv', delimiter=',', names=True) acc_x, freq_x, _ = mlab.specgram(acc_data['x'], Fs=sample_rate_Hz, NFFT=sample_rate_Hz * length_s) acc_y, freq_y, _ = mlab.specgram(acc_data['y'], Fs=sample_rate_Hz, NFFT=sample_rate_Hz * length_s) acc_z, freq_z, _ = mlab.specgram(acc_data['z'], Fs=sample_rate_Hz, NFFT=sample_rate_Hz * length_s) plt.plot(freq_x[10:], acc_x[10:], label='x', linewidth=0.5) plt.plot(freq_y[10:], acc_y[10:], label='y', linewidth=0.5) plt.plot(freq_z[10:], acc_z[10:], label='z', linewidth=0.5) plt.yscale('log') plt.xlim((0,100)) plt.legend(loc='lower left') plt.savefig(picturename) def email(): fromaddr = "ADD FROM ADDRESS HERE" toaddr = "ADD TO ADDRESS HERE" password = "ADD FROM PASSWORD HERE" msg = MIMEMultipart() msg['From'] = fromaddr msg['To'] = toaddr msg['Subject'] = "ADXL345 Graph" body = "Here is the graph... filename: " + picturename msg.attach(MIMEText(body, 'plain')) filename = picturename attachment = open('/home/pi/Desktop/' + picturename, "rb") part = MIMEBase('application', 'octet-stream') part.set_payload((attachment).read()) encoders.encode_base64(part) part.add_header('Content-Disposition', "attachment; filename= %s" % filename) msg.attach(part) server = smtplib.SMTP('smtp.gmail.com', 587) server.starttls() server.login(fromaddr, password) text = msg.as_string() server.sendmail(fromaddr, toaddr, text) server.quit() while True: plt.cla() picturename = f"Spectrum-{datetime.now():%Y-%m-%d-%H-%M-%S}.png" bd.wait_for_press() bd.color = "green" accel() bd.color = "yellow" email() bd.color = "blue"
Step 5: Finalizing
- Download the BlueDot app on your android device.
- If you would like, you can add a line to rc.local on the RPI to make the script start on bootup. There are also other methods you can use, but we recommend rc.local. By default, running the script from rc.local does not save your graphs on the Desktop. The graphs will save in root meaning that they won't be able to be deleted. To combat this, you can create a folder on your desktop with your script inside it. If you choose to run the script on bootup with rc.local, you must change the attatchment path line in the email command to the path you are using. For example...
attachment = open('/home/pi/Desktop/ADXL345Readings/' + picturename, "rb")
Now, here is how to edit the rc.local file;
Open your RPI terminal and type in this command:
sudo nano /etc/rc.local
That should bring you to the nano editor. The file should look something like this...
#!/bin/sh -e # # rc.local # # This script is executed at the end of each multiuser runlevel. # Make sure that the script will "exit 0" on success or any other # value on error. # # In order to enable or disable this script just change the execution # bits. # # By default this script does nothing. # Print the IP address _IP=$(hostname -I) || true if [ "$_IP" ]; then printf "My IP address is %s\n" "$_IP" fi exit 0
Delete all of the text after the last comment. You can delete the comments as well if you would like. Make sure to keep the "exit 0" line. It should look something like this.
#!/bin/sh -e # # rc.local # # This script is executed at the end of each multiuser runlevel. # Make sure that the script will "exit 0" on success or any other # value on error. # # In order to enable or disable this script just change the execution # bits. # # By default this script does nothing. # Print the IP address exit 0
Make sure to keep two lines between the comment and the "exit 0" line.
Now, we need to add the following lines between the "exit 0" and comments.
cd /home/pi/Desktop/YOUR FOLDER NAME HERE python3 /home/pi/Desktop/YOUR FOLDER NAME HERE/YOUR SCRIPT NAME HERE ENDING IN .py &
Make sure to add your folder and script's name at the end of both lines where they are designated to be placed.
**WARNING**
MAKE SURE TO KEEP THE AMPERSAND ONE SPACE AFTER YOUR PATH OTHERWISE YOUR RPI WILL NOT BOOT UP
The finished script should look something like this...
#!/bin/sh -e # # rc.local # # This script is executed at the end of each multiuser runlevel. # Make sure that the script will "exit 0" on success or any other # value on error. # # In order to enable or disable this script just change the execution # bits. # # By default this script does nothing. # Print the IP address cd /home/pi/Desktop/YOUR FOLDER NAME HERE python3 /home/pi/Desktop/YOUR FOLDER NAME HERE/YOUR SCRIPT NAME HERE ENDING IN .py & exit 0
To exit and save from the nano editor, click ctrl+x then Y to confirm the save. You might have to click enter as well to confirm the filename.
Step 6: Running the Project / Conclusion
FIRST STARTUP STEPS
Before using the BlueDot app, your phone must already be paired with your RPI.
To do this, make your RPI discoverable by clicking the bluetooth icon in the top right hand corner, and click the option that says "make discoverable."
You should then be able to see the RPI on your phone when you scan for bluetooth devices. Click on it to pair and press accept on the RPI's pair pop-up. You might have to do the same on your phone as well. Once you are done that, you can move on to the next steps.
CONNECTING VIA BLUEDOT/MEASURING
I have created a youtube video that demonstrates this portion of the tutorial. I have also written down the steps of the measuring below the embeded video as well.
1. Run your script on the RPI using your preferred IDE, or just boot up your RPI if you are using the rc.local script.
2. Open the BlueDot app on your mobile device and make sure your bluetooth is turned on.
3. You should see a list of your paired devices, if your RPI script is running you will be able to connect to it by clicking on "raspberrypi."
4. You are now connected! Click on the blue dot and your script will run! Once the dot turns blue again, you should receive an email within 5-7 secs. You can also run the script again if you are still connected in the app.
Thank you for reading my Instructables! Hopefully you found this project interesting! If you have any questions or are having making this project, leave a comment below or message me through Instructables and I would be happy to help.
Huge Thanks to all the Sources below! This project wouldn't be a thing without them!
Nagimov on GitHub (Helped a ton!!)