Posts: 34
Threads: 12
Joined: Sep 2020
Hey everyone,
I am working on a program that gives me the values from different sensors.
On its own, the i2c screen seems to work fine, but when I use it with my program it seems to ‘slow down’. Like updating information seems to slow it down to the point where you can see the screen clear just to update one value.
Here is the module I’m using
Thanks!
Posts: 3,458
Threads: 101
Joined: Sep 2016
The lcd class calls time.sleep() several times in it's constructor, but that'd only be an issue if you're making tons of new instances.
So... share some code so we can give more helpful advice :)
Posts: 34
Threads: 12
Joined: Sep 2020
It’s in a while loop, so it might be the problem.
However, when I test it as a clock, that’s what i do, and it works fine.
The code is in my Pi. So I will have to get it tomorrow after work.
Posts: 34
Threads: 12
Joined: Sep 2020
Here is the code I use to control the lcd
from os import path
import ast
import time
import json
from lib.customLibs import lcdScreen
import lib. i2cLCD as lcddriver
from datetime import datetime
from auth import *
class displayScreen:
def __passedData():
values = {}
with open("systemHWDriverFiles/display_passValues.txt", 'rt') as inf:
r = str(inf.read()[1:-1]).split(', ')
for i in r:
for key, value in ast.literal_eval(i).items():
if key not in values:
values[key] = []
values[key].append(value)
return values
def __processData(data):
resp = {}
if 'apiCall' in data:
Session = loginInfo()
for i in data['apiCall']:
resp[i] = Session.makeCall(i).text
return resp
def run():
return displayScreen.__processData(displayScreen.__passedData())
test = displayScreen.run()
datetime.datetime.now()
now = datetime.datetime.now()
display = lcddriver.lcd()
display.lcd_display_string("Time: %s" %now.strftime("%H:%M:%S"), 1)
display.lcd_display_string(str(test['/api/phprobes/8/read']+'ppm '+test['/api/phprobes/9/read']+'F'), 2) My main script, loads in sensors based on api call, and ones that are manually entered and puts them into a while loop.
#Set up display /path from passed values
import json
from multiprocessing import Process
import ast
from os import path
import time
#Hardware Classes
from sensorClass import *
from lib.systemHW import *
#importing custom libs
from lib.customLibs import *
#import cred config files and system info
from auth import *
#API Sessions
Session = loginInfo()
#Create Sensors list
resp = Session.makeCall('/api/equipment')
hwObjects = {}
for k in json.loads(resp.text):
senIndex = len(hwObjects)
if chkFile(['Sensors/'+k['name']+'.py', 'driverFiles/'+k['name']+'_Sensor.txt', 'powerStatus/'+k['name']+'_Power.txt']):
hwObjects[senIndex] = Sensor(k['id'], k['name'], k['outlet'], k['on'], senIndex)
#adding SystemHW
senIndex = len(hwObjects)
hwObjects[senIndex] = (systemHW('display', senIndex))
hwObjects[senIndex].addArg({'apiCall': '/api/phprobes/8/read'})
hwObjects[senIndex].addArg({'apiCall': '/api/phprobes/9/read'})
hwObjects[senIndex].addArg({'path': 'driverFiles/TestEquipment_Sensor.txt'})
hwObjects[senIndex].addArg({'path': 'driverFiles/TestEquipment2_Sensor.txt'})
#Looping hwObjects
def processLoop():
func = []
for processes in hwObjects:
f = Process( target = hwObjects[processes].run, args=[])
f.start()
func.append(f)
for f in func:
f.join()
return True
while processLoop():
pass Here is the class that the lcd uses:
from os import path
import json
#define class
class systemHW:
def __init__(self, hwName, hwIndex):
self.hwName = hwName
self.hwFileLocation = "systemHWDriverFiles/"+hwName+"_passValues.txt"
self.hwIndex = hwIndex
self.arg = []
def addArg(self, *argv):
for i in argv:
self.arg.append(i)
def show(self, ):
return [str(self.hwName), str(self.hwFileLocation), str(self.hwIndex)]
def online(self):
return True
def run(self, *argv):
if self.online():
arg = self.arg
updateValue = open(self.hwFileLocation, "w")
updateValue.write(str(arg))
updateValue.close()
__import__('systemHW.'+self.hwName)
Posts: 5,151
Threads: 396
Joined: Sep 2016
Sep-10-2020, 10:39 AM
(This post was last modified: Sep-10-2020, 10:39 AM by metulburr.)
I just skimmed your code, did not follow control, etc. But these stand out to me.
Is there anything that is preventing this from occurring?
def processLoop():
func = []
for processes in hwObjects:
f = Process( target = hwObjects[processes].run, args=[])
f.start()
func.append(f)
for f in func:
f.join()
return True
while processLoop():
pass From my perspective it appears to constantly loop and create new processes which would drag a program to halt. Also concatenation is a sure way to bottleneck a program and IO (file write/read) is one of the slowest processes, so restricting them would be ideal.
Recommended Tutorials:
Posts: 34
Threads: 12
Joined: Sep 2020
(Sep-10-2020, 10:39 AM)metulburr Wrote: I just skimmed your code, did not follow control, etc. But these stand out to me.
Is there anything that is preventing this from occurring?
No, but that loop is kind of the point of the program.
It reads sensors and displays their values on the screen.
Is there a better way to do this?
I used join(), to make sure that the loop doesn’t start again until each process has finished.
Posts: 34
Threads: 12
Joined: Sep 2020
I removed all the IO in the scripts,
It is defiantly faster, but the screen screen is still kinda wonky
When I run the demo clock script, it looks like the just the seconds are changing. however when I put it in the program i wrote, the whole screen clears before anything updates.
I've read online that i could speed it up by using the screens cursor to just change what's needed. Is there a script that anyone knows that does that?
Posts: 3,458
Threads: 101
Joined: Sep 2016
What's the demo clock script? If it's doing most of what you want, and doing it well, it would be helpful to take a look at it.
My #1 concern with things like this is always that the code makes total sense, but I have no way of actually testing it, which makes it super hard to help figure out what's going on.
Posts: 34
Threads: 12
Joined: Sep 2020
I've changed the script a bit to remove the file io
Here is the Main script
#import cred config files and system info
from auth import *
#API Sessions
Session = loginInfo()
#Create Sensors list
resp = Session.makeCall('/api/equipment')
hwObjects = {}
for k in json.loads(resp.text):
senIndex = len(hwObjects)
if chkFile(['Sensors/'+k['name']+'.py', 'driverFiles/'+k['name']+'_Sensor.txt', 'powerStatus/'+k['name']+'_Power.txt']):
hwObjects[senIndex] = Sensor(k['id'], k['name'], k['outlet'], k['on'], senIndex, Session)
#adding SystemHW
senIndex = len(hwObjects)
hwObjects[senIndex] = (systemHW('display', senIndex))
hwObjects[senIndex].addArg({'apiCall': '/api/phprobes/8/read'})
hwObjects[senIndex].addArg({'apiCall': '/api/phprobes/9/read'})
#hwObjects[senIndex].addArg({'path': 'driverFiles/TestEquipment_Sensor.txt'})
#Looping hwObjects
def processLoop():
func = []
for processes in hwObjects:
f = Process( target = hwObjects[processes].run, args=[])
f.start()
func.append(f)
for f in func:
f.join()
return True
while processLoop():
pass Here is the Class that imports the lcd script
from os import path, getcwd
import json
from subprocess import Popen, PIPE
#define class
class systemHW:
def __init__(self, hwName, hwIndex):
self.hwName = hwName
self.hwFileLocation = "systemHWDriverFiles/"+hwName+"_passValues.txt"
self.hwIndex = hwIndex
self.arg = []
def addArg(self, *argv):
for i in argv:
self.arg.append(i)
def show(self, ):
return [str(self.hwName), str(self.hwFileLocation), str(self.hwIndex)]
def online(self):
return True
def run(self, *argv):
if self.online():
arg = self.arg
__import__('systemHW.'+self.hwName)
Posts: 34
Threads: 12
Joined: Sep 2020
I figured it out.
it was actually all due to this annoying little code
display = lcddriver.lcd() whenever an instance of the lcd() class is made, the __init__() function runs, and resets the screen. so anyone else having this problem, simply removing the line from the while loop will fix the problem
in mycoses, i couldn't do that, so i changed the __init__ method to a new one called start(), and wrote code that only runs it once.
|