How to send real-time sensor data to PC from Raspberry Pi Zero?
Asked Answered
P

2

6

I've written a Python3 script which runs on Raspberry Pi Zero W that collects data from an IMU sensor (MPU9250) and creates 3 different angle values; roll, pitch, yaw. Which looks like this:

def main():
    while True:
        dataAcc = mpu.readAccelerometerMaster()
        dataGyro = mpu.readGyroscopeMaster()
        dataMag = mpu.readMagnetometerMaster()

        [ax, ay, az] = [round(dataAcc[0], 5), round(dataAcc[1], 5), round(dataAcc[2], 5)]
        [gx, gy, gz] = [round(dataGyro[0], 5), round(dataGyro[1], 5), round(dataGyro[2], 5)]
        [mx, my, mz] = [round(dataMag[0], 5), round(dataMag[1], 5), round(dataMag[2], 5)]

        update(gx, gy, gz, ax, ay, az, mx, my, mz)
        roll = getRoll()
        pitch = getPitch()
        yaw = getYaw()

        print(f"Roll: {round(roll, 2)}\tPitch: {round(pitch, 2)}\tYaw: {round(yaw, 2)}")

The thing I want to do is send these 3 values to my PC and read them. Is there any way to send this data. (If possible except serial).

Pride answered 2/11, 2020 at 8:30 Comment(0)
T
11

There are many ways of doing this, to name a few:

  • send UDP messages from the Raspi to the PC
  • send a TCP stream from the Raspi to the PC
  • throw the readings into Redis and allow anyone on your network to collect them - example here
  • publish the readings from your Raspi with an MQTT client and subscribe to that topic on your PC as server
  • run a Python Multiprocessing Manager on one machine and connect from the other - see "Using a Remote Manager" here
  • send the readings via Bluetooth

Here's a possible implementation of the first suggestion above with UDP. First, the Raspi end generates 3 readings X, Y and Z and sends them to the PC every second via UDP:

#!/usr/bin/env python3

import socket
import sys
from time import sleep
import random
from struct import pack

# Create a UDP socket
sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)

host, port = '192.168.0.8', 65000
server_address = (host, port)

# Generate some random start values
x, y, z = random.random(), random.random(), random.random()

# Send a few messages
for i in range(10):

    # Pack three 32-bit floats into message and send
    message = pack('3f', x, y, z)
    sock.sendto(message, server_address)

    sleep(1)
    x += 1
    y += 1
    z += 1

Here's the matching code for the PC end of it:

#!/usr/bin/env python3

import socket
import sys
from struct import unpack

# Create a UDP socket
sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)

# Bind the socket to the port
host, port = '0.0.0.0', 65000
server_address = (host, port)

print(f'Starting UDP server on {host} port {port}')
sock.bind(server_address)

while True:
    # Wait for message
    message, address = sock.recvfrom(4096)

    print(f'Received {len(message)} bytes:')
    x, y, z = unpack('3f', message)
    print(f'X: {x}, Y: {y}, Z: {z}')

Here's a possible implementation of the MQTT suggestion. First, the Publisher which is publishing the three values. Note that I have the mosquitto broker running on my desktop:

#!/usr/bin/env python3

from time import sleep
import random
import paho.mqtt.client as mqtt

broker = '192.168.0.8'
client = mqtt.Client()
client.connect(broker,1883,60)

# Generate some random start values
x, y, z = random.random(), random.random(), random.random()

# Send a few messages
for i in range(10):

    # Publish out three values
    client.publish("topic/XYZ", f'{x},{y},{z}');

    sleep(1)
    x += 1
    y += 1
    z += 1

And here is the subscriber, which listens for the messages and prints them:

#!/usr/bin/env python3

import socket
import sys
import paho.mqtt.client as mqtt

def on_connect(client, userdata, flags, rc):
  print("Connected with result code "+str(rc))
  client.subscribe("topic/XYZ")

def on_message(client, userdata, msg):
  message = msg.payload.decode()
  print(f'Message received: {message}')
    
broker = '192.168.0.8'
client = mqtt.Client()
client.connect(broker,1883,60)

client.on_connect = on_connect
client.on_message = on_message

client.loop_forever()

There's an example of Bluetooth communication here.


There is a similar answer with more examples here.

Treasury answered 2/11, 2020 at 14:3 Comment(2)
how to get the host and port value?Officinal
@AchmadSetiawan You get the host IP address on a Raspberry Pi with hostname -I. On Windows you will probably use ipconfig and on macOS you will use ifconfig -a or look in Apple menu->System Preferences->Newtork. You can choose any port you like as long as it is less than 65536 and in general it is easier to use unprivileged ports which are those above 1024. So, try 65,000 or something like that.Treasury
U
2

you could setup a simple web server on the pi and access that server from any device that's on the same network without going through any fancy setups.

If your pi zero is has wifi or if you can get the adapter, you can easily fire up your server with flask or Django.

Uniflorous answered 2/11, 2020 at 8:47 Comment(1)
Any examples or resources you can point to for this?Blackbeard

© 2022 - 2024 — McMap. All rights reserved.