Почему два моих цикла while не работают одновременно? - PullRequest
0 голосов
/ 25 марта 2020

Я довольно новичок в кодировании и прочем. Я работаю над цифровыми весами с секционной платой HX711 и выводю значения через сегментный дисплей 4 di git 7.

weighing() l oop считывает значения с меньшей скоростью, чем мое время мультиплексирования дисплея, поэтому код не будет продолжаться до тех пор, пока не будет прочитано значение, в результате чего дисплей будет мигать, как ад. Поэтому я попытался запустить weighing() l oop и displaying() l oop одновременно через concurrent.futures. Но код будет weighing() выполняться только один раз, а затем застревать в display() l oop, поэтому они не будут работать одновременно?

Возможно, что-то не так с моим кодом, пожалуйста помогите мне уточнить и оставить любые предложения для других методов.

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()

Я очень сожалею об опечатке в коде, поскольку я публиковал, я изменил имена процессов без тестирования. Это мой новый код, который я могу сказать без глупых ошибок:

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()

1 Ответ

0 голосов
/ 25 марта 2020

Это основная функция для вашего «взвешивающего» потока:

def weighing():
    while 1:
        val = round(abs(hx.get_weight(1)))
        ...
        return(val)

Оператор return(val) приведет к возврату функции в конце первой итерации l oop. Как только функция возвращается, поток завершается. Он больше никогда не запустится.

Вот как вы начинаете свои потоки:

weighing = executor.submit(weighing)
displaying = executor.submit(display, (t1.result()))

Если я правильно понимаю, * executor.submit(weighing) вызов возвращает future и t1.result()** ожидает завершения будущего, а затем возвращает любое значение, возвращенное функцией weighing.

Это означает, что executor.submit(display, ...) не произойдет, пока t1.result() не вернет значение, что означает, что второй поток не может даже запуститься, пока не завершится первый поток.


IMO;

  • Ваша функция weighing() должна обновить глобальную переменную и продолжить цикл навсегда вместо того, чтобы возвращать значение, и

  • Ваша display() функция должен получить значение, которое он отображает, копируя из глобальной переменной, и

  • Вы можете просто игнорировать фьючерсы, которые возвращаются ProcessPoolExecutor. Вы на самом деле не используете его как службу исполнителя: вы просто используете его как способ создания двух потоков.


* На самом деле я не Python гуру.

** Я предполагаю, что t1.result() - это ошибка копирования / вставки, и вы хотели сказать weighing.result().

...