0

I have an ultrasonic sensor that writes the distance in a txt file, I want to get that data and plot it on a line graph in real time but I can't find a way to do it.

What I have done till now is that it would read the file but it never shows the data.

sensor.py

import RPi.GPIO as GPIO
import time


GPIO.setwarnings(False)
GPIO.cleanup()
GPIO.setmode(GPIO.BCM)

TRIG = 23
ECHO = 24

GPIO.setup(TRIG, GPIO.OUT)
GPIO.setup(ECHO, GPIO.IN)

GPIO.output(TRIG, True)
GPIO.output(TRIG,False)

def get_distance():
    GPIO.output(TRIG, True)
    time.sleep(0.0001)
    GPIO.output(TRIG, False)
        
    while GPIO.input(ECHO) == False:
        start = time.time()
        
    while GPIO.input(ECHO) == True:
        end = time.time()
        
    sig_time = end - start

    distance = sig_time/0.000058
    
    print('Distance: {} cm'.format(round(distance)))
    return distance
    
while True:
    distance = get_distance()
    data = round(distance)
    
    output = open("front sensor distance.txt", "w")
    output.write(str(data))
    time.sleep(2)
    output.close()

Whenever I run the code the distance gets deleted instantly and does not wait for time.sleep(2)

3
  • can you share a sample of your code? Commented Mar 31, 2022 at 20:04
  • Please create a minimal reproducible example. Commented Mar 31, 2022 at 20:06
  • I edited my answer to match your newly added code, please tell me if is there anything else I can help with. Commented Apr 1, 2022 at 21:42

1 Answer 1

2

First of all, make sure that the code that ultrasonic uses to write data to file is not buffering writes and writes to file instantly by forcing it to flush after every write output.flush(), I edited your code to do that and also changed it to append to file instead of removing all old data with each write also I made it to save time with each write to use it in the graph.

start_time = time.time()

while True:
    output = open("front sensor distance.txt", "a")
    output.write(str(round(time.time()-start_time))+","+str(round(get_distance()))+"\n")
    time.sleep(2)
    output.flush()

then you can use this code sample which reads data from the file every 1 second and updates the graph in real-time.

I tried to write it as close to your description as possible where the data file contains time,distance in each line separated by a comma.

import matplotlib.pyplot as plt
import matplotlib.animation as animation

fig = plt.figure()
ax = fig.add_subplot(1,1,1)

def animate(i):
    file_data = open("front sensor distance.txt","r").read()
    dataArray = file_data.split('\n')
    time = []
    distance = []
    for eachLine in dataArray:
        if len(eachLine)>1:
            x,y = eachLine.split(',')
            time.append(float(x))
            distance.append(float(y))
    ax.clear()
    ax.plot(time,distance)

def Main():
    ani = animation.FuncAnimation(fig, animate, interval=1000)
    plt.show()
    print("done")

Main()

I don't have the hardware you have to test with so I made distance function return random numbers on my machine to simulate your experience. and running both files will result in the following real-time graph

enter image description here

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.