GPS and MPU 6050 don't work together in one program - raspberry-pi

I'm working on a project that uses MPU 6050 and GPS together embedded in raspberry pi device. However, if I try to run the gps code alone or the code for MPU 6050 (accelerometer/gyroscope) alone, it works.
But the problem is when I try to run the code for GPS and MPU 6050 together in one program. It only runs the code for mpu 6050 and ignore many of the code and outputs of the gps.
I think the problem is related to the interfacing of both the gps and mpu 6050.
So, I hope I get any help ... thanks in advance ..
import gyro_acc
#import speed
import sys, time, requests, jsonify
import serial
import pynmea2
# defining the api-endpoint
# API_ENDPOINT = "https://gp-anamoly-api.herokuapp.com/create/anomaly"
# initialize MPU
gyro_acc.MPU_Init()
print(" ::: Start Reading ::: ")
# tracker for the number of potholes/cracks
i = 0
port="/dev/ttyS0"
ser = serial.Serial(port, baudrate=9600, timeout=0.2)
dataout = pynmea2.NMEAStreamReader()
while True:
# read data
Gx, Gy, Gz, Ax, Ay, Az = gyro_acc.mpu_read()
# print("Gx={:.2f} deg/s | Gy={:.2f} deg/s | Gz={:.2f} deg/s".format(Gx, Gy, Gz)) + "|| Ax={:.2f} m/s^2 | Ay={:.2f} m/s^2 | Az={:.2f} m/s^2".format(Ax, Ay, Az))
print("Gx={:.2f} deg/s | Gy={:.2f} deg/s | Gz={:.2f} deg/s".format(Gx, Gy, Gz))
print("Ax={:.2f} m/s^2 | Ay={:.2f} m/s^2 | Az={:.2f} m/s^2".format(Ax, Ay, Az))
# get the location and speed from gps data
newdata=ser.readline()
if newdata[0:6] == "$GPRMC":
newmsg=pynmea2.parse(newdata)
lat=newmsg.latitude
lng=newmsg.longitude
gps = "Latitude=" + str(lat) + " and Longitude=" + str(lng)
print(gps)
if newdata[0:6] == "$GPVTG":
newmsg=pynmea2.parse(newdata)
speed = newmsg.spd_over_grnd_kmph
speed_output = "Speed= {}KM/H".format(speed)
print(speed_output)
# separator
print("===========================")
# print data dynamically
# sys.stdout.write("\rGx={:.2f} deg/s | Gy={:.2f} deg/s | Gz={:.2f} deg/s".format(Gx, Gy, Gz) \
# + " || Ax={:.2f} m/s^2 | Ay={:.2f} m/s^2 | Az={:.2f} m/s^2".format(Ax, Ay, Az) + "\n"
# + "Speed: {:.1f} KM/H".format(vehicle_speed))
# sys.stdout.flush()
# print speed dynamically
# sys.stdout.write("\rSpeed: {:.1f} KM/H".format(vehicle_speed))
# sys.stdout.flush()
# check if it detect pothole/crack and save to database
if Az > 13.25:
# print pothole detected
# sys.stdout.write("\n")
print("---------------------------")
print("Pothole/Crack Detected (No.{})".format(i))
print("---------------------------")
i += 1
# sleep for one second
time.sleep(1)
the library gyro_acc is another I have in the project.

Related

Raspberry Pi 4 Aborts SSH Connection When TensorFlow Lite Has Initialized After Running Python 3 Script

I want to use object detection using tensorflow lite in order to detect a clear face or a covered face where the statement "door opens" is printed when a clear face is detected. I could run this code smoothly previously but later after rebooting raspberry pi 4, although the tensorflow lite runtime is initialized, the raspberry pi 4 disconnects with the ssh completely. The following is the code:
######## Webcam Object Detection Using Tensorflow-trained Classifier #########
#
# Author: Evan Juras
# Date: 10/27/19
# Description:
# This program uses a TensorFlow Lite model to perform object detection on a live webcam
# feed. It draws boxes and scores around the objects of interest in each frame from the
# webcam. To improve FPS, the webcam object runs in a separate thread from the main program.
# This script will work with either a Picamera or regular USB webcam.
#
# This code is based off the TensorFlow Lite image classification example at:
# https://github.com/tensorflow/tensorflow/blob/master/tensorflow/lite/examples/python/label_image.py
#
# I added my own method of drawing boxes and labels using OpenCV.
# Import packages
import os
import argparse
import cv2
import numpy as np
import sys
import time
from threading import Thread
import importlib.util
import simpleaudio as sa
# Define VideoStream class to handle streaming of video from webcam in separate processing thread
# Source - Adrian Rosebrock, PyImageSearch: https://www.pyimagesearch.com/2015/12/28/increasing-raspberry-pi-fps-with-python-and-opencv/
class VideoStream:
"""Camera object that controls video streaming from the Picamera"""
def __init__(self,resolution=(640,480),framerate=30):
# Initialize the PiCamera and the camera image stream
self.stream = cv2.VideoCapture(0)
ret = self.stream.set(cv2.CAP_PROP_FOURCC, cv2.VideoWriter_fourcc(*'MJPG'))
ret = self.stream.set(3,resolution[0])
ret = self.stream.set(4,resolution[1])
# Read first frame from the stream
(self.grabbed, self.frame) = self.stream.read()
# Variable to control when the camera is stopped
self.stopped = False
def start(self):
# Start the thread that reads frames from the video stream
Thread(target=self.update,args=()).start()
return self
def update(self):
# Keep looping indefinitely until the thread is stopped
while True:
# If the camera is stopped, stop the thread
if self.stopped:
# Close camera resources
self.stream.release()
return
# Otherwise, grab the next frame from the stream
(self.grabbed, self.frame) = self.stream.read()
def read(self):
# Return the most recent frame
return self.frame
def stop(self):
# Indicate that the camera and thread should be stopped
self.stopped = True
# Define and parse input arguments
parser = argparse.ArgumentParser()
parser.add_argument('--modeldir', help='Folder the .tflite file is located in',
required=True)
parser.add_argument('--graph', help='Name of the .tflite file, if different than detect.tflite',
default='masktracker.tflite')
parser.add_argument('--labels', help='Name of the labelmap file, if different than labelmap.txt',
default='facelabelmap.txt')
parser.add_argument('--threshold', help='Minimum confidence threshold for displaying detected objects',
default=0.5)
parser.add_argument('--resolution', help='Desired webcam resolution in WxH. If the webcam does not support the resolution entered, errors may occur.',
default='640x480')
parser.add_argument('--edgetpu', help='Use Coral Edge TPU Accelerator to speed up detection',
action='store_true')
args = parser.parse_args()
MODEL_NAME = args.modeldir
GRAPH_NAME = args.graph
LABELMAP_NAME = args.labels
min_conf_threshold = float(args.threshold)
resW, resH = args.resolution.split('x')
imW, imH = int(resW), int(resH)
use_TPU = args.edgetpu
# Import TensorFlow libraries
# If tflite_runtime is installed, import interpreter from tflite_runtime, else import from regular tensorflow
# If using Coral Edge TPU, import the load_delegate library
pkg = importlib.util.find_spec('tflite_runtime')
if pkg:
from tflite_runtime.interpreter import Interpreter
if use_TPU:
from tflite_runtime.interpreter import load_delegate
else:
from tensorflow.lite.python.interpreter import Interpreter
if use_TPU:
from tensorflow.lite.python.interpreter import load_delegate
# If using Edge TPU, assign filename for Edge TPU model
if use_TPU:
# If user has specified the name of the .tflite file, use that name, otherwise use default 'edgetpu.tflite'
if (GRAPH_NAME == 'masktracker.tflite'):
GRAPH_NAME = 'edgetpu.tflite'
# Get path to current working directory
CWD_PATH = os.getcwd()
# Path to .tflite file, which contains the model that is used for object detection
PATH_TO_CKPT = os.path.join(CWD_PATH,MODEL_NAME,GRAPH_NAME)
# Path to label map file
PATH_TO_LABELS = os.path.join(CWD_PATH,MODEL_NAME,LABELMAP_NAME)
# Load the label map
with open(PATH_TO_LABELS, 'r') as f:
labels = [line.strip() for line in f.readlines()]
# Have to do a weird fix for label map if using the COCO "starter model" from
# https://www.tensorflow.org/lite/models/object_detection/overview
# First label is '???', which has to be removed.
if labels[0] == '???':
del(labels[0])
# Load the Tensorflow Lite model.
# If using Edge TPU, use special load_delegate argument
if use_TPU:
interpreter = Interpreter(model_path=PATH_TO_CKPT,
experimental_delegates=[load_delegate('libedgetpu.so.1.0')])
print(PATH_TO_CKPT)
else:
interpreter = Interpreter(model_path=PATH_TO_CKPT)
interpreter.allocate_tensors()
# Get model details
input_details = interpreter.get_input_details()
output_details = interpreter.get_output_details()
height = input_details[0]['shape'][1]
width = input_details[0]['shape'][2]
floating_model = (input_details[0]['dtype'] == np.float32)
input_mean = 127.5
input_std = 127.5
# Initialize frame rate calculation
frame_rate_calc = 1
freq = cv2.getTickFrequency()
global image_capture
image_capture = 0
# Initialize video stream
videostream = VideoStream(resolution=(imW,imH),framerate=30).start()
time.sleep(1)
#for frame1 in camera.capture_continuous(rawCapture, format="bgr",use_video_port=True):
while True:
# Start timer (for calculating frame rate)
t1 = cv2.getTickCount()
# Grab frame from video stream
frame1 = videostream.read()
# Acquire frame and resize to expected shape [1xHxWx3]
frame = frame1.copy()
frame_rgb = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
frame_resized = cv2.resize(frame_rgb, (width, height))
input_data = np.expand_dims(frame_resized, axis=0)
# Normalize pixel values if using a floating model (i.e. if model is non-quantized)
if floating_model:
input_data = (np.float32(input_data) - input_mean) / input_std
# Perform the actual detection by running the model with the image as input
interpreter.set_tensor(input_details[0]['index'],input_data)
interpreter.invoke()
# Retrieve detection results
boxes = interpreter.get_tensor(output_details[0]['index'])[0] # Bounding box coordinates of detected objects
classes = interpreter.get_tensor(output_details[1]['index'])[0] # Class index of detected objects
scores = interpreter.get_tensor(output_details[2]['index'])[0] # Confidence of detected objects
#num = interpreter.get_tensor(output_details[3]['index'])[0] # Total number of detected objects (inaccurate and not needed)
# Loop over all detections and draw detection box if confidence is above minimum threshold
for i in range(len(scores)):
if ((scores[i] > min_conf_threshold) and (scores[i] <= 1.0)):
# Get bounding box coordinates and draw box
# Interpreter can return coordinates that are outside of image dimensions, need to force them to be within image using max() and min()
ymin = int(max(1,(boxes[i][0] * imH)))
xmin = int(max(1,(boxes[i][1] * imW)))
ymax = int(min(imH,(boxes[i][2] * imH)))
xmax = int(min(imW,(boxes[i][3] * imW)))
# Draw label
object_name = labels[int(classes[i])] # Look up object name from "labels" array using class index
if (object_name=="face unclear" ):
color = (0, 255, 0)
cv2.rectangle(frame, (xmin,ymin), (xmax,ymax),color, 2)
print("Face Covered: Door Not Opened")
if(image_capture == 0):
path = r'/home/pi/Desktop/tflite_1/photographs'
date_string = time.strftime("%Y-%m-%d_%H%M%S")
#print(date_string)
cv2.imwrite(os.path.join(path, (date_string + ".jpg")),frame)
#cv2.imshow("Photograph",frame)
#mp3File = input(alert_audio.mp3)
print("Photo Taken")
#w_object = sa.WaveObject.from_wave_file('alert_audio.wav')
#p_object = w_object.play()
#p_object.wait_done()
image_capture = 1
else:
color = (0, 0, 255)
cv2.rectangle(frame, (xmin,ymin), (xmax,ymax),color, 2)
print("Face Clear: Door Opened")
image_capture = 0
#cv2.rectangle(frame, (xmin,ymin), (xmax,ymax),color, 2)
#image = np.asarray(ImageGrab.grab())
label = '%s: %d%%' % (object_name, int(scores[i]*100)) # Example: 'person: 72%'
labelSize, baseLine = cv2.getTextSize(label, cv2.FONT_HERSHEY_SIMPLEX, 0.7, 2) # Get font size
label_ymin = max(ymin, labelSize[1] + 10) # Make sure not to draw label too close to top of window
cv2.rectangle(frame, (xmin, label_ymin-labelSize[1]-10), (xmin+labelSize[0], label_ymin+baseLine-10), (255, 255, 255), cv2.FILLED) # Draw white box to put label text in
cv2.putText(frame, label, (xmin, label_ymin-7), cv2.FONT_HERSHEY_SIMPLEX, 0.7, (0, 0, 0), 2) # Draw label text
if ((scores[0] < min_conf_threshold)):
cv2.putText(frame,"No Face Detected",(260,260),
cv2.FONT_HERSHEY_SIMPLEX, 0.8, color=(255,0,0))
print("No Face Detected")
image_capture = 0
# Draw framerate in corner of frame
cv2.putText(frame,'FPS: {0:.2f}'.format(frame_rate_calc),(30,50),cv2.FONT_HERSHEY_SIMPLEX,1,(255,255,0),2,cv2.LINE_AA)
# All the results have been drawn on the frame, so it's time to display it.
cv2.imshow('Object detector', frame)
# Calculate framerate
t2 = cv2.getTickCount()
time1 = (t2-t1)/freq
frame_rate_calc= 1/time1
# Press 'q' to quit
if cv2.waitKey(1) == ord('q'):
break
# Clean up
cv2.destroyAllWindows()
videostream.stop()
Any help is appreciated.
Regards,
MD

I override variables with OMPython but the simulation starts with the default values

I'm trying to work on a system made in openmodelica and now i want to simulate it multiple time. On every iteration I have to change some value and i'm using OMPython to do it. This is the part of code where i override the interested parameters:
#Overwrite parameters
with open("newValues.txt", 'wt') as f:
f.write("const.N="+str(n)+"\n")
f.write("const.nIntr="+str(intr)+"\n")
f.write("const.nRocket="+str(miss)+"\n")
f.write("const.nStatObs="+str(statObs)+"\n")
for i in range(len(fault)):
for j in range(len(fault[i])):
f.write("fault.transMatrix["+str(i+1)+","+str(j+1)+"]="+str(fault[i][j])+"\n")
for i in range(3):
f.write("const.flyZone["+str(i+1)+"]="+str(flyZone)+"\n")
f.flush()
os.fsync(f)
os.system("./System -overrideFile=newValues.txt >> LogOverride.txt")
Now, if i try to take all the values overrided from the .mat file, for example, with this method:
print(str(omc.sendExpression("val(const.N," + str(stopTime) + ", \"System_res.mat\")")))
They are changed, but the simulation starts with the default value.
For example, if i set
const.N = 7
and in the .om file it is
const.N = 5
The simulation count N as 5 and not 7.
For more info, this is the github repository: https://github.com/BigMautone/Drones.git
The python script is in pythonScripts/testing.py and most of the parameter changed is in constant.mo
EDIT 1:
For more context, i'm explaining the purpose of the system and why i can't see the changes made it with the script. The system have to simulate a swarm of drones and implements different algorithms for pathfinding and for obstacle avoidance. Inside the record class K there are all the parameters used in the system, like the N parameter, defining the number of drones in the swarm. Because i want to simulate the system multiple times with different parameters, i have to change it. So, if the default value of K.N is 5 and i'm changing it with 7 inside the python script, i'm expecting to see 7 drones doing something. Instead, the system is simulated with the default values!
i'm adding here part of the code and where i can't see the changes made with the overrideFile option.
"""
Here i load all the file and model needed...
"""
omc.sendExpression("buildModel(System, stopTime=180)")
omc.sendExpression("getErrorString()")
#This is the function i made for run the simulation multiple times
def startSimulation(n, intr, miss, statObs, fault, flyZone):
#Overwrite parameters
with open("newValues.txt", 'wt') as f:
f.write("const.N="+str(n)+"\n")
f.write("const.nIntr="+str(intr)+"\n")
f.write("const.nRocket="+str(miss)+"\n")
f.write("const.nStatObs="+str(statObs)+"\n")
for i in range(len(fault)):
for j in range(len(fault[i])):
f.write("fault.transMatrix["+str(i+1)+","+str(j+1)+"]="+str(fault[i][j])+"\n")
for i in range(3):
f.write("const.flyZone["+str(i+1)+"]="+str(flyZone)+"\n")
f.flush()
os.fsync(f)
os.system("./System -overrideFile=newValues.txt >> LogOverride.txt")
os.system("rm -f newValues.txt") # .... to be on the safe side
#Down there i extract some values...
for j in range(1,n+1):
arrivalTime = omc.sendExpression("val(sucMo.arrivalTime[" + str(j) + "]," + str(stopTime) + ", \"System_res.mat\")")
droneArrived = omc.sendExpression("val(sucMo.arrived[" + str(j) + "]," + str(stopTime) + ", \"System_res.mat\")")
droneInfo[j] = (droneArrived, arrivalTime)
#Here i call the function and try to execute it
startSimulation(7,1,1,1,noFault,100)
If i print the droneInfo dictionary, it will have obviously 7 keys, but if the default value N is equal to 5, then i'll get this output:
{1: (1.0, 8.0), 2: (1.0, 5.0), 3: (1.0, 8.0), 4: (1.0, 9.0), 5: (1.0, 12.0), 6: ('NaN', 'NaN'), 7: ('NaN', 'NaN')} 0.0
EDIT 2: I have made some changes. I had not instantiated the K class, which i use a lot for array lenght and for loops. Now that i've done it in all other models, the problem persists. Also, now all the value of K class have the isValueChangeble flag to false
I tried to reproduce this. Made this small script to read the value at the end:
adrpo33#ida-0030 MINGW64 /c/home/adrpo33/dev/modelica/Drones
# cat val.mos
val(const.N, 9, "System_res.mat"); getErrorString();
Then ran the run.mos script:
adrpo33#ida-0030 MINGW64 /c/home/adrpo33/dev/modelica/Drones
# omc run.mos
record SimulationResult
resultFile = "C:/home/adrpo33/dev/modelica/Drones/System_res.mat",
simulationOptions = "startTime = 0.0, stopTime = 30.0, numberOfIntervals = 500, tolerance = 1e-06, method = 'dassl', fileNamePrefix = 'System', options = '', outputFormat = 'mat', variableFilter = '.*', cflags = '', simflags = ''",
messages = "LOG_SUCCESS | info | The initialization finished successfully without homotopy method.
[C:/home/adrpo33/dev/modelica/Drones/Monitors/MonitorSuccess.mo:52:28-52:116:writable]
stdout | info | Simulation call terminate() at time 9.000000
| | | | Message : Tutti i droni hanno raggiunto la destinazione oppure hanno avuto collisioni
LOG_SUCCESS | info | The simulation finished successfully.
",
timeFrontend = 0.3274193,
timeBackend = 1.4592339,
timeSimCode = 0.5092729,
timeTemplates = 0.1533226,
timeCompile = 24.1450323,
timeSimulation = 3.3621366,
timeTotal = 29.9572641
end SimulationResult;
"Warning: The initial conditions are not fully specified. For more information set -d=initialization. In OMEdit Tools->Options->Simulation->Show additional information from the initialization process, in OMNotebook call setCommandLineOptions(\"-d=initialization\").
"
Take the value out:
adrpo33#ida-0030 MINGW64 /c/home/adrpo33/dev/modelica/Drones
# omc val.mos
5.0
""
Override the value:
adrpo33#ida-0030 MINGW64 /c/home/adrpo33/dev/modelica/Drones
# ./System.exe -override const.N=7
LOG_SUCCESS | info | The initialization finished successfully without homotopy method.
[C:/home/adrpo33/dev/modelica/Drones/Monitors/MonitorSuccess.mo:52:28-52:116:writable]
stdout | info | Simulation call terminate() at time 9.000000
| | | | Message : Tutti i droni hanno raggiunto la destinazione oppure hanno avuto collisioni
LOG_SUCCESS | info | The simulation finished successfully.
Take the value out:
adrpo33#ida-0030 MINGW64 /c/home/adrpo33/dev/modelica/Drones
# omc val.mos
7.0
""
So I cannot really reproduce your behavior. When I change something the .mat file reflects the change.

How can I create an animated plot from incoming serial port data

I want to live plot incoming data from a serial port without writing and reading data from a file. I understand that it's necessary to run a thread where the serial data is coming in on the fly. While the thread is running the animation.FuncAnimation should grab the serial data and render the plot each time.
That's where I can't figure out how to code the handover to get the animation to work.
import serial
import threading
import matplotlib.pyplot as plt
import matplotlib.animation as animation
import itertools
def thread_data_gen():
i = 0
counter = itertools.count()
ser = serial.Serial('/dev/tty.SLAB_USBtoUART', 1000000, timeout=1) # Open port and read data.
ser.reset_input_buffer() # Flush input buffer, discarding all its contents.
while True:
ser_bytes = ser.readline() # Read serial data line by line
# Incoming lines in Format -> b'$ 32079 32079 32079 32079 32079 32079 32079 32079;\r\n'
# Each value represents a data channel which can measure torque, temperatur,...
# Right now all values are set to torque which is why they have the same values.
# 8 data channels available
decoded_bytes = ser_bytes.decode('utf-8')
decoded_bytes = decoded_bytes.lstrip('$').rstrip().split()
# Re-format to ['32274', '32274', '32274', '32274', '32274', '32274', '32274', '32274;']
if i == 0:
i += 1
continue
# Skip first read-out because the first transmitted line is empty. Don't know the reason.
t = next(counter) # Create values for x-axis
y = decoded_bytes[0] # Read channel 1 values for y-axis
yield t, y # Was thinking about a generator type of return but that's not working
def run(data): # Handing over yield data from thread_data_gen()
t, y = data # TypeError:"cannot unpack non-iterable int object" I don't know how to fix this.
# I have to convert the while loop in the running thread to something where I get iterable int data.
# That's where I don't see the solution
xdata.append(t) # Adding data to list for x-values
ydata.append(y) # Adding data to list for y-values
line.set_data(xdata, ydata) # Creating data for hand-over to plt
return line,
if __name__ == '__main__':
dgen = threading.Thread(target=thread_data_gen)
dgen.start()
fig, ax = plt.subplots()
line, = ax.plot([], [], lw=2)
ax.grid()
xdata, ydata = [], []
ani = animation.FuncAnimation(fig, run, interval=100)
plt.show()
Update
I just solved my own problem with:
# A sensor upgraded coupling in a power transmission system provides data per bluetooth.
# Data: Torque, force, temperature and acceleration (x-y-z-axis).
# A hardware gateway receives the data with an antenna.
# The purpose of this code is to read and plot out serial data from that hardware gateway
# which is linked via USB-C to the laptop. A USB-C to UART software bride,
# makes the data as serial port on MacOS or Windows available.
import time
import serial
import matplotlib.pyplot as plt
import matplotlib.animation as animation
import itertools
def data_gen():
i = 0
counter = itertools.count() # Create counter
ser = serial.Serial('/dev/tty.SLAB_USBtoUART', 1000000, timeout=1) # Open port and read data.
ser.reset_input_buffer() # Flush input buffer, discarding all its contents.
while True:
# Read serial data line by line.
# Incoming lines in Format -> b'$ 32079 32079 32079 32079 32079 32079 32079 32079;\r\n'
# Each value represents a data channel which can measure torque, temperatur, ...
# Right now all values are set to torque which is why they have the same values.
# 8 data channels are available
ser_bytes = ser.readline()
decoded_bytes = ser_bytes.decode('utf-8')
# Re-format to list ['32274', '32274', '32274', '32274', '32274', '32274', '32274', '32274;']
decoded_bytes = decoded_bytes.lstrip('$').rstrip().split()
# Skip first read-out because the first transmitted line is empty. Don't know the reason.
if i == 0:
i += 1
continue
t = next(counter) # Create values for x-axis
y = decoded_bytes[0] # Read channel 1 values for y-axis
yield t, float(y) # Yield back x and y values for plot
def run(data):
x, y = data
y_cal = round(y * 0.00166, 1) #
xdata.append(x) # Adding data to list for x-values
ydata.append(y_cal) # Adding data to list for y-values
line.set_data(xdata, ydata) # Creating a data set for hand-over to plot
return line,
if __name__ == '__main__':
fig, ax = plt.subplots() # Setup figure and axis
line, = ax.plot([], [], lw=2) # Setup line
ax.set_ylim(40, 80) # Set limitation in y
ax.set_xlim(0, 1000) # Set limitation in x
ax.grid() # Create grid
xdata, ydata = [], [] # Create empty lists
# Frames: Receives the generated data from the serial connection
# Run: Provides the line data
ani = animation.FuncAnimation(fig, run, frames=data_gen, blit=True, interval=10)
plt.show()

Grove I2C display not working on Raspberry Pi 3B

I only have my RPi 3B and a I²C display, I don't own any GrovePi hat and I want to show some text to the said display. Is there a way to make it work?
My display.
i2cdetect -y 1 shows this result, meaning the RPi is detecting the I²C display and it should work. But nothing seemed to be showing on the display, except for the full block on the first row.
I've tried literally everything on the internet, some library worked (as in throwing no errors) but the display still stays the same, full block on the first row.
I've installed python3, smbus, smbus2 and i2c-tools. I've changed the address to 3e.
My most recent *.py file. It does write 'LCD printing' yet nothing else works.
I don't find a way to change the contrast of the LCD (no potentiometer or whatsoever)
#!/usr/bin/python3
import smbus2 as smbus
import time
# Define some device parameters
I2C_ADDR = 0x3e # I2C device address, if any error, change this address to 0x3f
LCD_WIDTH = 16 # Maximum characters per line
# Define some device constants
LCD_CHR = 1 # Mode - Sending data
LCD_CMD = 0 # Mode - Sending command
LCD_LINE_1 = 0x80 # LCD RAM address for the 1st line
LCD_LINE_2 = 0xC0 # LCD RAM address for the 2nd line
LCD_LINE_3 = 0x94 # LCD RAM address for the 3rd line
LCD_LINE_4 = 0xD4 # LCD RAM address for the 4th line
LCD_BACKLIGHT = 0x08 # On
ENABLE = 0b00000100 # Enable bit
# Timing constants
E_PULSE = 0.0005
E_DELAY = 0.0005
# Open I2C interface
# bus = smbus.SMBus(0) # Rev 1 Pi uses 0
bus = smbus.SMBus(1) # Rev 2 Pi uses 1
def lcd_init():
# Initialise display
lcd_byte(0x33, LCD_CMD) # 110011 Initialise
lcd_byte(0x32, LCD_CMD) # 110010 Initialise
lcd_byte(0x06, LCD_CMD) # 000110 Cursor move direction
lcd_byte(0x0C, LCD_CMD) # 001100 Display On,Cursor Off, Blink Off
lcd_byte(0x28, LCD_CMD) # 101000 Data length, number of lines, font size
lcd_byte(0x01, LCD_CMD) # 000001 Clear display
time.sleep(E_DELAY)
def lcd_byte(bits, mode):
# Send byte to data pins
# bits = the data
# mode = 1 for data
# 0 for command
bits_high = mode | (bits & 0xF0) | LCD_BACKLIGHT
bits_low = mode | ((bits << 4) & 0xF0) | LCD_BACKLIGHT
# High bits
bus.write_byte(I2C_ADDR, bits_high)
lcd_toggle_enable(bits_high)
# Low bits
bus.write_byte(I2C_ADDR, bits_low)
lcd_toggle_enable(bits_low)
def lcd_toggle_enable(bits):
# Toggle enable
time.sleep(E_DELAY)
bus.write_byte(I2C_ADDR, (bits | ENABLE))
time.sleep(E_PULSE)
bus.write_byte(I2C_ADDR, (bits & ~ENABLE))
time.sleep(E_DELAY)
def lcd_string(message, line):
# Send string to display
message = message.ljust(LCD_WIDTH, " ")
lcd_byte(line, LCD_CMD)
for i in range(LCD_WIDTH):
lcd_byte(ord(message[i]), LCD_CHR)
if __name__ == '__main__':
lcd_init()
while True:
# Send some test
lcd_string("Hello ", LCD_LINE_1)
lcd_string(" World", LCD_LINE_2)
print('LCD printing!')
time.sleep(3)

Storage values using os.stat(filename)

I'm trying to create an EDUCATIONAL PURPOSES ONLY virus. I do not plan on spreading it. It's purpose is to grow a file to the point your storage is full and slow your computer down. It prints the size of the file every 0.001 seconds. With that, I also want to know how fast it is growing the file. The following code doesn't seem to let it run:
class Vstatus():
def _init_(Status):
Status.countspeed == True
Status.active == True
Status.growingspeed == 0
import time
import os
#Your storage is at risk of over-expansion. Please do not let this file run forever, as your storage will fill continuously.
#This is for educational purposes only.
while Vstatus.Status.countspeed == True:
f = open('file.txt', 'a')
f.write('W')
fsize = os.stat('file.txt')
Key1 = fsize
time.sleep(1)
Key2 = fsize
Vstatus.Status.growingspeed = (Key2 - Key1)
Vstatus.Status.countspeed = False
while Vstatus.Status.active == True:
time.sleep(0.001)
f = open('file.txt', 'a')
f.write('W')
fsize = os.stat('file.txt')
print('size:' + fsize.st_size.__str__() + ' at a speed of ' + Vstatus.Status.growingspeed + 'bytes per second.')
This is for Educational Purposes ONLY
The main error I keep getting when running the file is here:
TypeError: unsupported operand type(s) for -: 'os.stat_result' and 'os.stat_result'
What does this mean? I thought os.stat returned an integer Can I get a fix on this?
Vstatus.Status.growingspeed = (Key2 - Key1)
You can't subtract os.stat objects. Your code also has some other problems. Your loops will run sequentially, meaning that your first loop will try to estimate how quickly the file is being written to without writing anything to the file.
import time # Imports at the top
import os
class VStatus:
def __init__(self): # double underscores around __init__
self.countspeed = True # Assignment, not equality test
self.active = True
self.growingspeed = 0
status = VStatus() # Make a VStatus instance
# You need to do the speed estimation and file appending in the same loop
with open('file.txt', 'a+') as f: # Only open the file once
start = time.time() # Get the current time
starting_size = os.fstat(f.fileno()).st_size
while status.active: # Access the attribute of the VStatus instance
size = os.fstat(f.fileno()).st_size # Send file desciptor to stat
f.write('W') # Writing more than one character at a time will be your biggest speed up
f.flush() # make sure the byte is written
if status.countspeed:
diff = time.time() - start
if diff >= 1: # More than a second has gone by
status.countspeed = False
status.growingspeed = (os.fstat(f.fileno()).st_size - starting_size)/diff # get rate of growth
else:
print(f"size: {size} at a speed of {status.growingspeed}")