I'm pretty new to coding and stuff. I'm working on a digital weighing scale with a HX711 breakout board and outputting the values through a 4 digit 7 segment display.
The weighing()
loop read values at a slower rate than my display multiplexing time so the code wouldn't continue until a value has been read resulting in the display flashing like hell. So i tried running the weighing()
loop and the displaying()
loop simultaneously via concurrent.futures
. But the code would execute weighing()
only once and then get stuck in the display()
loop, so they are not running concurrently?
There must be something wrong with my code, please help me clarify and leave any suggestions for other methods.
import time
import RPi.GPIO as GPIO
import concurrent.futures
GPIO.setwarnings(False)
GPIO.setmode(GPIO.BCM)
segments = [2, 3, 4, 5, 6, 7, 8, 9]
digits = [12, 13, 18, 19]
GPIO.setup(segments, GPIO.OUT)
GPIO.output(segments, GPIO.HIGH)
GPIO.setup(digits, GPIO.OUT)
GPIO.output(digits, GPIO.LOW)
nums ={
0:(1,1,1,1,1,1,0),
1:(0,1,1,0,0,0,0),
2:(1,1,0,1,1,0,1),
3:(1,1,1,1,0,0,1),
4:(0,1,1,0,0,1,1),
5:(1,0,1,1,0,1,1),
6:(1,0,1,1,1,1,1),
7:(1,1,1,0,0,0,0),
8:(1,1,1,1,1,1,1),
9:(1,1,1,1,0,1,1)}
switchpolarity = {1: 0,
0:1}
def display(value):
while 1:
s = [int(d) for d in str(value)]
for digit in range(0,len(s)):
for segment in range(0,7):
GPIO.output(segments[segment], switchpolarity[nums[s[digit]][segment]])
GPIO.output(digits[digit], 1)
time.sleep(0.01)
GPIO.output(digits[digit], 0)
EMULATE_HX711=False
if not EMULATE_HX711:
from hx711 import HX711
else:
from emulated_hx711 import HX711
def weighing():
while 1:
val = round(abs(hx.get_weight(1)))
print(val)
hx.power_down()
hx.power_up()
return(val)
hx = HX711(9, 10)
hx.set_reading_format("MSB", "MSB")
hx.set_reference_unit(754)
hx.reset()
hx.tare()
print("Tare done! Add weight now...")
try:
with concurrent.futures.ProcessPoolExecutor() as executor:
weighing = executor.submit(weighing)
displaying = executor.submit(display, (t1.result()))
except(KeyboardInterrupt):
GPIO.cleanup()
I am very sorry for the typo in the code as I was posting i changed the processes names without testing. This is my new code which i can say is without stupid mistakes:
import time
import RPi.GPIO as GPIO
import concurrent.futures
GPIO.setwarnings(False)
GPIO.setmode(GPIO.BCM)
segments = [2, 3, 4, 5, 6, 7, 8, 9]
digits = [12, 13, 18, 19]
GPIO.setup(segments, GPIO.OUT)
GPIO.output(segments, GPIO.HIGH)
GPIO.setup(digits, GPIO.OUT)
GPIO.output(digits, GPIO.LOW)
nums ={
0:(1,1,1,1,1,1,0),
1:(0,1,1,0,0,0,0),
2:(1,1,0,1,1,0,1),
3:(1,1,1,1,0,0,1),
4:(0,1,1,0,0,1,1),
5:(1,0,1,1,0,1,1),
6:(1,0,1,1,1,1,1),
7:(1,1,1,0,0,0,0),
8:(1,1,1,1,1,1,1),
9:(1,1,1,1,0,1,1)}
switchpolarity = {1: 0,
0:1}
def display(value):
while 1:
s = [int(d) for d in str(value)]
for digit in range(0,len(s)):
for segment in range(0,7):
GPIO.output(segments[segment], switchpolarity[nums[s[digit]][segment]])
GPIO.output(digits[digit], 1)
time.sleep(0.01)
GPIO.output(digits[digit], 0)
EMULATE_HX711=False
if not EMULATE_HX711:
from hx711 import HX711
else:
from emulated_hx711 import HX711
def weighing():
while 1:
val = round(abs(hx.get_weight(1)))
print(val)
hx.power_down()
hx.power_up()
return(val)
hx = HX711(9, 10)
hx.set_reading_format("MSB", "MSB")
hx.set_reference_unit(754)
hx.reset()
hx.tare()
print("Tare done! Add weight now...")
try:
with concurrent.futures.ProcessPoolExecutor() as executor:
weighing1 = executor.submit(weighing)
displaying1 = executor.submit(display, (weighing1.result()))
except(KeyboardInterrupt):
GPIO.cleanup()
This is the main function for your "weighing" thread:
The
return(val)
statement will cause the function to return at the end of the first iteration of the loop. Once the function returns, the thread is finished. It won't ever run again.This is how you start your threads:
If I understand correctly,* The
executor.submit(weighing)
call returns a future, and thet1.result()
** awaits the completion of the future, and then returns whatever value was returned by theweighing
function.That means, that the
executor.submit(display, ...)
will not happen untilt1.result()
returns a value, which means that the second thread can not even start until the first thread is finished.IMO;
Your
weighing()
function should update a global variable and continue looping forever instead of returning a value, andYour
display()
function should get the value that it displays by copying from the global variable, andYou can just ignore the futures that are returned by the
ProcessPoolExecutor
. You aren't really using it as an executor service: You're just using it as a way to create two threads.* I'm not actually a Python guru.
** I'm assuming that
t1.result()
is a copy/paste error, and that you meant to sayweighing.result()
.