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!!)

Element14

Itechfy

BC-ROBOTICS

Kitflix