用户界面-无法使arduino串行通信在wxpython GUI中工作



这是用于更新GUI中标签的定义:

    def updateV(self, event):
    """"""
    global v
    ser = serial.Serial( port='COM3', baudrate=9600)
    x = ser.read()          # read one byte
    ser.close()
    print x
    if v>3:
        self.labelOne.SetBackgroundColour('red')
        self.labelOne.SetLabel('Battery Voltage : ' + x)
    else:
        self.labelOne.SetBackgroundColour('white')
        self.labelOne.SetLabel('Battery Voltage : ' + str(v))

    self.Refresh()

这是我一直在使用的简单arduino代码:

int a;
void setup() {
Serial.begin(9600);// put your setup code here, to run once:
}
void loop() {
a=5;
Serial.println(a);
delay(10);
}

我一直在使用这个定义来更新GUI的标签。我最近开始使用该代码在GUI上设置串行通信。从逻辑上讲,使用wx库的mainloop((,我想我可以更新"x"值并将其打印在GUI上。但是所有的GUI窗口都显示为0.0,即使python控制台定期打印5。请帮忙!我对此很陌生。

您的问题是ser.read()将阻塞。即使您调整了serial.Serial实例的超时,它仍然会使GUI繁忙。在这种情况下,我不知道有什么方法可以"强制"刷新/wx.Yield(),它根本不起作用。阻止调用的标准解决方案是启动线程或者定期轮询(例如使用wx.Timer(。然而,我只能让线程工作。该示例基于pyserial中的wxTerminal。

# -*- coding: utf-8 -*-
import wx
import serial
from threading import Thread
ARDUINO_NEWLINE = 'rn'
class serial_reader(object):
    def __init__(self, callback=None):
        """Creates serial reader.
        :param callback: callable, gets called when byte on serial arrives.
        """
        self.callback = callback
        self.thread = None
        # Signal if serial is alive and should be read
        self.alive = False
    def start_reader(self, serial_cfg):
        """Start the receiver thread.
        :param serial_cfg: dictionary, gets unpacked to parameters for :class:`serial.Serial`
        """
        self.ser_cfg = serial_cfg
        self.serial = serial.Serial(**serial_cfg)
        # set != None so it will not block for longer than timeout on shutdown
        self.serial.timeout = 0.1
        self.alive = True
        self.thread = Thread(target=self.serial_read)
        self.thread.daemon = True
        self.thread.start()
    def stop_reader(self):
        """Stop the receiver thread, wait util it is finished."""
        if self.thread is not None:
            # signal no more reads
            self.alive = False
            # wait until thread has finished
            self.thread.join()
            self.thread = None
        # cleanup
        self.serial.close()
    def serial_read(self):
        """Thread that handles the incoming traffic."""
        while self.alive:
            try:
                text = self.serial.read()
                if text and self.callback:
                    # return value to main loop in thread-safe manner
                    wx.CallAfter(self.callback, text)
            except serial.serialutil.SerialException:
                # will happen when Windows goes in sleep mode
                print 'serial.serialutil.SerialException'

class ser_frm(wx.Frame):
    def __init__(self, *args, **kwds):
        wx.Frame.__init__(self, *args, **kwds)        
        self.txt = wx.TextCtrl(self, -1, '', style=wx.TE_MULTILINE)
class serial_controller(object):
    def __init__(self, app):
        self.app = app
        # buffer for serial data
        self.ser_buf = ''
        self.frm = ser_frm(None, -1, 'testfrm')
        # setup serial configuration
        self.serial_cfg = {'port': 'COM4', 'baudrate': 9600}        
        # When parameter dsrdtr is set to True, the Arduino
        # will not reset on serial open, for details see
        # http://playground.arduino.cc/Main/DisablingAutoResetOnSerialConnection
        self.serial_cfg['dsrdtr'] = True
        self.ser_rd = serial_reader(callback=self.on_serial)
        tit = 'Arduino on port {port} at baudrate {baudrate}'.format(**self.serial_cfg)
        self.frm.SetTitle(tit)
        self.ser_rd.start_reader(self.serial_cfg)
        self.frm.Show()
        self.frm.Bind(wx.EVT_CLOSE, self.on_close)
    def on_close(self, evt):
        """Shutdown serial read thread before closing."""
        if self.ser_rd.alive:
            self.ser_rd.stop_reader()
        evt.Skip()
    def on_serial(self, text):
        """Handle input from the serial port."""
        self.ser_buf += text
        if self.ser_buf.endswith(ARDUINO_NEWLINE):
            if self.frm.txt.GetInsertionPoint() > 1000:
                self.frm.txt.SetValue('')
            self.frm.txt.AppendText(self.ser_buf)
            self.ser_buf = ''

if __name__ == "__main__":
    app = wx.App(redirect=False)
    serialctr = serial_controller(app)
    app.MainLoop()

编辑:没有必要在带有片上USB的Arduino上修改DSR/DTR(例如Arduino micro(,因此删除行

self.serial_cfg['dsrdtr'] = True

它仍然可以正常工作。

相关内容

  • 没有找到相关文章

最新更新