aelhadad
Posts: 34
Joined: Tue Jan 16, 2018 7:55 pm

plotting data from an IMU sensor

Tue Jan 16, 2018 8:05 pm

I am using raspberry pi 3 with an IMU sensor and i want to creat real time (live) data. I am using an MPU6050 sensor, the code is working fine and ican collect data. However, i could not plot the data as part of the code. I dont want to plot the data using STARTXWIN after the code is running, I want the plotting to be part of the code. Thanks

Code: Select all

import threading
import struct
import bluetooth


class MotionTracker(object):
    """Class to track movement from MPU6050 Bluetooth device.
    """

    def __init__(self, bd_addr, port=1):
        """Initialization for tracker object.
        Args:
            bd_addr (str) : Bluetooth address
            port (int, optional) : Port, defaults to 1
        Attributes:
            bd_addr (str): Bluetooth address
            port (int): Port
            sock (bluetooth.bluez.BluetoothSocket) : Bluetooth socket object
            acc_x (float) : acceleration in X
            acc_y (float) : acceleration in Y
            acc_z (float) : acceleration in Z
            angv_x (float) : angular velocity in X
            angv_y (float) : angular velocity in Y
            angv_z (float) : angular velocity in Z
            ang_x (float) : angle degrees in X
            ang_y (float) : angle degrees in Y
            ang_z (float) : angle degrees in Z
            temperature (float) : temperature in degrees celsius
            __thread_read_device_data (threading.Thread) : Read input thread
        """
        self.bd_addr = bd_addr
        self.port = port

        self.sock = bluetooth.BluetoothSocket(bluetooth.RFCOMM)
        self.sock.connect((self.bd_addr, self.port))

        self.acc_x = 0.0
        self.acc_y = 0.0
        self.acc_z = 0.0

        self.angv_x = 0.0
        self.angv_y = 0.0
        self.angv_z = 0.0

        self.ang_x = 0.0
        self.ang_y = 0.0
        self.ang_z = 0.0

        self.temperature = 0.0
        self.__thread_read_device_data = None

    def start_read_data(self):
        """Start reading from device. Wait for a second or two before
        reading class attributes to allow values to 'settle' in.
        Non blocking I/O performed via a private read thread.
        """

        self.__thread_read_device_data = threading.Thread(target=self.__read_device_data)
        self.__thread_read_device_data.is_running = True
        self.__thread_read_device_data.start()

    def stop_read_data(self):
        """Stop reading from device. Join back to main thread and
        close the socket.
        """

        self.__thread_read_device_data.is_running = False
        self.__thread_read_device_data.join()
        self.sock.close()

    def __read_device_data(self):
        """Private method to read device data in 9 byte blocks.
        """

        while self.__thread_read_device_data.is_running:
            data_block = self.sock.recv(1)
            if data_block == b'\x55':
                data_block_type = self.sock.recv(1)
                # Acceleration
                if data_block_type == b'\x51':
                    # Read 9 byte block
                    ax_l = self.sock.recv(1)
                    ax_h = self.sock.recv(1)
                    ay_l = self.sock.recv(1)
                    ay_h = self.sock.recv(1)
                    az_l = self.sock.recv(1)
                    az_h = self.sock.recv(1)
                    t_l = self.sock.recv(1)
                    t_h = self.sock.recv(1)
                    self.sock.recv(1) # Check sum, ignore

                    self.acc_x = struct.unpack("<h", ax_l + ax_h)[0] / 32768.0 * 16.0
                    self.acc_y = struct.unpack("<h", ay_l + ay_h)[0] / 32768.0 * 16.0
                    self.acc_z = struct.unpack("<h", az_l + az_h)[0] / 32768.0 * 16.0
                    self.temperature = struct.unpack("<h", t_l + t_h)[0] / 340.0 + 36.25
                # Angular velocity
                elif data_block_type == b'\x52':
                    # Read 9 byte block
                    wx_l = self.sock.recv(1)
                    wx_h = self.sock.recv(1)
                    wy_l = self.sock.recv(1)
                    wy_h = self.sock.recv(1)
                    wz_l = self.sock.recv(1)
                    wz_h = self.sock.recv(1)
                    t_l = self.sock.recv(1)
                    t_h = self.sock.recv(1)
                    self.sock.recv(1)  # Check sum, ignore

                    self.angv_x = struct.unpack("<h", wx_l + wx_h)[0] / 32768.0 * 2000.0
                    self.angv_y = struct.unpack("<h", wy_l + wy_h)[0] / 32768.0 * 2000.0
                    self.angv_z = struct.unpack("<h", wz_l + wz_h)[0] / 32768.0 * 2000.0
                    self.temperature = struct.unpack("<h", t_l + t_h)[0] / 340.0 + 36.25
                # Angle
                elif data_block_type == b'\x53':
                    # Read 9 byte block
                    roll_l = self.sock.recv(1)
                    roll_h = self.sock.recv(1)
                    pitch_l = self.sock.recv(1)
                    pitch_h = self.sock.recv(1)
                    yaw_l = self.sock.recv(1)
                    yaw_h = self.sock.recv(1)
                    t_l = self.sock.recv(1)
                    t_h = self.sock.recv(1)
                    self.sock.recv(1)  # Check sum, ignore

                    self.ang_x = struct.unpack("<h", roll_l + roll_h)[0] / 32768.0 * 180.0
                    self.ang_y = struct.unpack("<h", pitch_l + pitch_h)[0] / 32768.0 * 180.0
                    self.ang_z = struct.unpack("<h", yaw_l + yaw_h)[0] / 32768.0 * 180.0
                    self.temperature = struct.unpack("<h", t_l + t_h)[0] / 340.0 + 36.25


def main():
    """Test driver stub.
    """

    try:
        session = MotionTracker(bd_addr="20:16:09:21:48:81")
        session.start_read_data()

        while True:
            print("ang_x:", session.ang_x, "ang_y:", session.ang_y, "ang_z:", session.ang_z)

    except KeyboardInterrupt:
        session.stop_read_data()


if __name__ == "__main__":
    main()
    

SurferTim
Posts: 1506
Joined: Sat Sep 14, 2013 9:27 am
Location: Miramar Beach, Florida

Re: plotting data from an IMU sensor

Tue Jan 16, 2018 10:18 pm

How do you want to display it? I'm using a BNO055 IMU by Bosch. I'm displaying it on an aircraft instrument panel using pygame, but it isn't easy. I started by running the numbers first. If you are good with trig, the rest you can work out.

Can I post a jpeg image here (<100k)?

aelhadad
Posts: 34
Joined: Tue Jan 16, 2018 7:55 pm

Re: plotting data from an IMU sensor

Wed Jan 17, 2018 2:06 am

please

B.Goode
Posts: 5622
Joined: Mon Sep 01, 2014 4:03 pm
Location: UK

Re: plotting data from an IMU sensor

Wed Jan 17, 2018 8:23 am

The Raspberry Pi Foundation have a Learning Resource that covers the use of matplotlib. This might meet your requirements.

https://www.raspberrypi.org/learning/vi ... worksheet/

If that is not suitable, using an internet search tool with the string Raspbian python plotting data will return a number of hits that might be helpful.

SurferTim
Posts: 1506
Joined: Sat Sep 14, 2013 9:27 am
Location: Miramar Beach, Florida

Re: plotting data from an IMU sensor

Wed Jan 17, 2018 12:10 pm

I don't know what you mean by plotting. I display the output of my IMU on a panel. See attached photo. The turn part of the turn and slip isn't complete yet. All other instruments are operational.

I cheat tho. I'm using a Mega2560 to do all the device reads and calculations (needed AD converter for airspeed), and the USB connection to a RPi Zero with a wifi connection to an AP on a RPi3. That is where this display is.
Attachments
instrumentpanel.jpg
instrumentpanel.jpg (92.8 KiB) Viewed 604 times

aelhadad
Posts: 34
Joined: Tue Jan 16, 2018 7:55 pm

Re: plotting data from an IMU sensor

Wed Jan 17, 2018 2:33 pm

what I want to plot is the displacement vs time for X,Y,Z. REAL TIME PLOT though.

SurferTim
Posts: 1506
Joined: Sat Sep 14, 2013 9:27 am
Location: Miramar Beach, Florida

Re: plotting data from an IMU sensor

Wed Jan 17, 2018 2:36 pm

aelhadad wrote: what I want to plot is the displacement vs time for X,Y,Z. REAL TIME PLOT though.
To where? Just to a file?

Edit: The instrument display I posted above is a 3D real time plot. The compass represent the X axis, and the attitude indicator is the Y and Z axis REAL TIME.

aelhadad
Posts: 34
Joined: Tue Jan 16, 2018 7:55 pm

Re: plotting data from an IMU sensor

Wed Jan 17, 2018 3:15 pm

http://mpmath.org/doc/0.19/_images/plot.png
I want the plot to update as long as the code running similar the heart rate plot in medical equipments.

SurferTim
Posts: 1506
Joined: Sat Sep 14, 2013 9:27 am
Location: Miramar Beach, Florida

Re: plotting data from an IMU sensor

Wed Jan 17, 2018 3:25 pm

That doesn't look that difficult to me. You should be able to do that with pygame. The first step is displaying the xyz output (in text) from the IMU. That is the top line of my display. The first three numbers ("127 127 127") is my joystick output, and second three ("8 0 2") are the xyz Euler values from the IMU.

Now plot them like a heart rate monitor.

Bear in mind this is the "Advanced" section of the forum.

nospam
Posts: 41
Joined: Sun Jun 14, 2015 10:38 pm

Re: plotting data from an IMU sensor

Sat Feb 10, 2018 6:49 pm

http://dygraphs.com

has worked very well for me so far but I don't run at high update frequencies

Return to “Advanced users”

Who is online

Users browsing this forum: drgeoff, welverin and 11 guests