Мне нужно запустить цикл до тех пор, пока кнопка не будет нажата снова без остановки - PullRequest
0 голосов
/ 07 февраля 2019

Я использую Raspberry Pi 3b для сбора данных по SPI из цифрового преобразователя времени (TDC-GPX2).По сути, TDC отмечает, когда in видит событие (скажем, передний фронт электрического импульса), и отправляет информацию о синхронизации моему Pi.Моей целью для этого было бы собрать данные без паузы (так как пропущенные импульсы увеличивают вероятность ошибок в моих данных), как можно быстрее, пока не будет выключено переключение.

Примечание. Мы разрабатываем драйверы связи LVDS на нашей FPGA для более быстрого сбора данных от TDC, но это поможет в быстрых тестах и ​​других проектах.Мы также используем spidev для SPI: я понимаю, что запрашивать информацию обо всех 4 остановках неэффективно, но я могу изменить это позже

Я использую Kivy в качестве графического решения для этого программного обеспечения.показать важные фрагменты кода ниже.Я использую основной код с графическим интерфейсом и библиотеку для TDC с циклом внутри него.Я никогда не публиковал здесь раньше, поэтому я не уверен, что включить в код, если потребуется больше, я опубликую это!Я попробовал библиотеку «thread», но она, похоже, действительно не отвечала и резко замедлила работу графического интерфейса.

def press_callback(obj):
    global tdcinit, f
    print("Button pressed,",obj.text)

    if obj.text == 'Read TDC':
        if obj.state=="down":
            f.write("New Trial \r\n")
            TDC.ReadTDC(f,obj.state)
        else:
            TDC.ReadTDC(f,obj.state)
            TDC.Reset()
            print('Done Recording, plz save before close')

определение кнопки ниже:

Class MyApp(App):
    def build(self):
        layout=GridLayout(cols=5)
        Window.clearcolor(0.2,0.2,0.2,1)
        TDCRead = ToggleButton(text='Read TDC')
        TDCRead.bind(on_press=press_callback)
        layout.add_widget(TDCRead)

        return layout

Функция вМоя вызываемая библиотека TDC:

def ReadTDC(self,f,state):
    while state=='down':
        GPIO.output(29,0) #this is just for SPI
        i=8
        j=1
        self.__transfer(0x68)
        while i<32:
            byteback = self.__transfer(0x00)
            if j<4:
                f.write("Ref: %02X\r\n" % (byteback))
                j=j+1
            elif j>=4 and j<6:
                f.write("Res: %02X\r\n" % (byteback))
            else:
                f.write("Res: %02X\r\n" % (byteback))
                j=1
            i=i+1
        GPIO.output(29,1)
    return f

Функция __transfer на самом деле просто использует xfer2 и печатает результаты для отладки.

Я надеялся, что это сработает как "Press ToggleButton с именем Read"ВМТ и цикл запускается до тех пор, пока я снова не нажму на тумблер, «но он просто фокусировал цикл, пока я не нажал Ctrl + C»

Ответы [ 2 ]

0 голосов
/ 11 февраля 2019

В итоге я понял это, и вот как я его получил (опять же, возможно, это не самый оптимальный код, но он был протестирован).Опять же, это использует Kivy и Python 3 на моем Raspberry pi.Я добавил это к моей инициализации:

import multiprocessing
from multiprocessing import Process, Queue

q = Queue()

Мне пришлось добавить это определение, чтобы использовать многопроцессорную библиотеку (я пишу в файл, вы можете игнорировать это, если вам не нужно):

def readprocess(qstate):
    f = open("TDCData.txt","a+")
    f.write("New Trial \r\n")
    print('reading process began')
    run = True
    while run:
        while not qstate.empty():
            if qstate.get() == "stop":
                run = False
        TDC.ReadTDC(f)
    f.close()

Затем я определяю переменную ap, чтобы я мог использовать ее глобально (не уверен, если это необходимо, я просто сделал это для безопасности), далее следует часть реализации Kivy:

p=0
def press_callback(obj)
    global tdcinit, q, p
    print("Button pressed,", obj.text)
    if obj.text == 'ReadTDC':
        if obj.state =="down":
            p = Process(target = readprocess, args=(q,))
            p.start()
        else:
            q.put("stop")
            p.join()
            TDC.Reset()
            print("Done Recording")

Моя функция TDC.Reset () просто вызывает свою команду сброса при включении питания, указанную в документации (останавливает измерения и повторно инициализирует).Обновленная функция в библиотеке TDC для ReadTDC:

def ReadTDC(self,f):
    GPIO.output(29,0)
    i=8
    j=1
    self.__transfer(0x68)
    while i<32:
        byteback=self.__transfer(0x00)
        if j<4:
            f.write("Ref: %02X\r\n" % (byteback))
            j=j+1
        elif j>=4 and j<6:
            f.write("Res: %02X\r\n" % (byteback))
            j=j+1
        else:
            f.write("Res: %02X\r\n" % (byteback))
            j=1
        i=i+1
    f.write("\r\n")
    GPIO.output(29,1)
    return f

Надеюсь, что это поможет любому, кто ищет это, я планирую сделать наши TDC-GPX2, AD5592R (DAC / ADC Combo) и LMH6401 (ПрограммируемыйGain Amplifier) ​​библиотеки публично каким-то образом (может быть, Git?) После того, как мы доработали их и начали работать.

0 голосов
/ 07 февраля 2019

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

https://docs.python.org/release/3.1.3/library/multiprocessing.html

...