Цикл while выполняется бесконечно. Невозможно завершить цикл while с помощью таймера

#python-2.7 #arduino-uno

#python-2.7 #arduino-uno

Вопрос:

Я пытаюсь включать и выключать электромагнитные клапаны с помощью Python. Этот режим переключения может быть определен до начала эксперимента с использованием информационного поля. Например, я могу определить, сколько раз может выполняться переключение (количество переключений) или как долго это будет происходить (время переключения в секундах). Я отправляю два байта в Arduino, один для выбора канала (от 1 до 8), а второй для состояния (0 или 1).

Количество переключений работает идеально. В цикле while я давал команду MyTime > 0 и при каждом переключении уменьшал его на единицу. Таким образом, цикл while будет выполняться до тех пор, пока MyTime или количество переключений не станут равными нулю.

Но когда я пытаюсь указать время из infobox, это становится бесконечным циклом. Я могу указать время из infobox и добавить его в time.time () и пытаюсь сравнить его в цикле while и хочу завершить цикл, как только time.time() станет больше желаемого времени.

Как я могу убедиться, что я могу завершить цикл while, используя оба условия?

 Python code: 

from __future__ import absolute_import, division, print_function
import serial
from time import sleep
import struct
from psychopy import core, data, event, gui, visual 
import time


try:
    arduino = serial.Serial('COM8',19200)
    sleep(2)
    print("Connection to "   'COM8'   " established succesfully!n")
except Exception as e:
    print(e)

global command

## create a DlgFromDict
info = {'Observer':'jwp', 'Channel':['1','2','3','4','5','6','7','8'],
    'BreathingCycle':4, 'Timer': 0, 'ExpVersion': 1.1, 'Debug Mode': True}
infoDlg = gui.DlgFromDict(dictionary=info, title='TestExperiment',
    order=['ExpVersion', 'Observer'],
    tip={'Observer': 'trained visual observer, initials'},
    fixed=['ExpVersion'])  

myChannel = info['Channel']
myTime = info ['BreathingCycle']
myTimer = info ['Timer']



win = visual.Window(fullscr=True, size=(1536, 864), monitor='laptop') 
#TODO: handle in a different way the screen resolution

instruction1 = visual.TextStim(win, text=u"""Valve on!""")

instruction2 = visual.TextStim(win, text=u"""Valve off!""")

instruction3 = visual.TextStim(win, text=u"""Thank you!""")


if infoDlg.OK:

Mytimer = time.time()   myTimer

while (myTime > 0 or time.time() < Mytimer):     

        if  myChannel == '1': 
            if u'i' in event.waitKeys():
                command = arduino.write(struct.pack(u'>H',513)) 
                myTime = myTime - 1
                instruction1.draw() 
                win.flip()
            if u'e' in event.waitKeys():
                command = arduino.write(struct.pack(u'>H',512))
                myTime = myTime - 1
                instruction2.draw()
                win.flip()
        elif  myChannel == '2': 
                if u'i' in event.waitKeys():
                    command = arduino.write(struct.pack(u'>H',257)) 
                    myTime = myTime - 1
                    instruction1.draw() 
                    win.flip()
                if u'e' in event.waitKeys():
                    command = arduino.write(struct.pack(u'>H',256))
                    myTime = myTime - 1
                    instruction2.draw()
                    win.flip()
        elif  myChannel == '3': 
                if u'i' in event.waitKeys():
                    command = arduino.write(struct.pack(u'>H',2049)) 
                    myTime = myTime - 1
                    instruction1.draw() 
                    win.flip()
                if u'e' in event.waitKeys():
                    command = arduino.write(struct.pack(u'>H',2048))
                    myTime = myTime - 1
                    instruction2.draw()
                    win.flip()
        elif  myChannel == '4': 
                if u'i' in event.waitKeys():
                    command = arduino.write(struct.pack(u'>H',1025)) 
                    myTime = myTime - 1
                    instruction1.draw() 
                    win.flip()
                if u'e' in event.waitKeys():
                    command = arduino.write(struct.pack(u'>H',1024))
                    myTime = myTime - 1
                    instruction2.draw()
                    win.flip()
        elif  myChannel == '5': 
                if u'i' in event.waitKeys():
                    command = arduino.write(struct.pack(u'>H',4097)) 
                    myTime = myTime - 1
                    instruction1.draw() 
                    win.flip()
                if u'e' in event.waitKeys():
                    command = arduino.write(struct.pack(u'>H',4096))
                    myTime = myTime - 1
                    instruction2.draw()
                    win.flip()
        elif  myChannel == '6': 
                if u'i' in event.waitKeys():
                    command = arduino.write(struct.pack(u'>H',8193)) 
                    myTime = myTime - 1
                    instruction1.draw() 
                    win.flip()
                if u'e' in event.waitKeys():
                    command = arduino.write(struct.pack(u'>H',8192))
                    myTime = myTime - 1
                    instruction2.draw()
                    win.flip()
        elif  myChannel == '7': 
                if u'i' in event.waitKeys():
                    command = arduino.write(struct.pack(u'>H',32769)) 
                    myTime = myTime - 1
                    instruction1.draw() 
                    win.flip()
                if u'e' in event.waitKeys():
                    command = arduino.write(struct.pack(u'>H',32768))
                    myTime = myTime - 1
                    instruction2.draw()
                    win.flip()
        elif  myChannel == '8': 
                if u'i' in event.waitKeys():
                    command = arduino.write(struct.pack(u'>H',16385)) 
                    myTime = myTime - 1
                    instruction1.draw() 
                    win.flip()
                if u'e' in event.waitKeys():
                    command = arduino.write(struct.pack(u'>H',16384))
                    myTime = myTime - 1
                    instruction2.draw()
                    win.flip()

win.close ()  
arduino.close()
  

Комментарии:

1. Опубликованный вами код имеет непоследовательный отступ — иногда выглядит как 4 пробела, иногда как 8. Убедитесь, что код, который вы пытаетесь запустить, последовательно использует одно соглашение. рекомендуется использовать 4 пробела, а не табуляцию.

2. Также единственной разницей между вашими восемью разными myChannel случаями, по-видимому, является числовое значение в struct.pack аргументах. Есть ли веская причина, по которой вы не можете просто найти эти значения, скажем, из dict с myChannel в качестве ключа, и передать их в единственную копию этого кода? Выполнение этого таким образом, вероятно, уменьшило бы ваши шансы на незамеченные ошибки.

3. @nekomatic Да, вы правы. Я должен измениться, но здесь это не проблема.

4. @nekomatic нанесен удар. pack упаковывает это число в два байта и отправляет его в Arduino, где я считываю первый байт как номер канала, например 1, 2, 4, 8 и так далее, а второй байт предназначен для 1 или 0 для переключения состояния. Тем не менее, здесь это также не проблема.

Ответ №1:

Я нашел решение, поскольку существуют функции event.waitKeys(), которые в основном ожидают ключ бесконечное количество времени, вот почему time.time() < Условие Mytimer не может быть проверено. Мне пришлось указать максимальное время ожидания в event.waitKeys().