树莓派串口通信编码_树莓派实现串口通信

这是一个基于wxPython的Python程序,用于创建一个简单的串口终端,具备本地回显、不可见字符显示和换行模式设置等功能。用户可以通过菜单进行串口设置和终端配置,接收并显示来自串口的数据。
摘要由CSDN通过智能技术生成

#!/usr/bin/env python

# generated by wxGlade 0.3.1 on Fri Oct 03 23:23:45 2003

#from wxPython.wx import *

importwx

importwxSerialConfigDialog

importserial

importthreading

#----------------------------------------------------------------------

# Create an own event type, so that GUI updates can be delegated

# this is required as on some platforms only the main thread can

# access the GUI without crashing. wxMutexGuiEnter/wxMutexGuiLeave

# could be used too, but an event is more elegant.

SERIALRX = wx.NewEventType()

# bind to serial data receive events

EVT_SERIALRX = wx.PyEventBinder(SERIALRX, 0)

classSerialRxEvent(wx.PyCommandEvent):

eventType = SERIALRX

def__init__(self, windowID, data):

wx.PyCommandEvent.__init__(self,self.eventType, windowID)

self.data = data

defClone(self):

self.__class__(self.GetId(),self.data)

#----------------------------------------------------------------------

ID_CLEAR        = wx.NewId()

ID_SAVEAS       = wx.NewId()

ID_SETTINGS     = wx.NewId()

ID_TERM         = wx.NewId()

ID_EXIT         = wx.NewId()

NEWLINE_CR      = 0

NEWLINE_LF      = 1

NEWLINE_CRLF    = 2

classTerminalSetup:

"""Placeholder for various terminal settings. Used to pass the

options to the TerminalSettingsDialog."""

def__init__(self):

self.echo =False

self.unprintable =False

self.newline = NEWLINE_CRLF

classTerminalSettingsDialog(wx.Dialog):

"""Simple dialog with common terminal settings like echo, newline mode."""

def__init__(self, *args, **kwds):

self.settings = kwds['settings']

delkwds['settings']

# begin wxGlade: TerminalSettingsDialog.__init__

kwds["style"] = wx.DEFAULT_DIALOG_STYLE

wx.Dialog.__init__(self, *args, **kwds)

self.checkbox_echo = wx.CheckBox(self, -1,"Local Echo")

self.checkbox_unprintable = wx.CheckBox(self, -1,"Show unprintable characters")

self.radio_box_newline = wx.RadioBox(self, -1,"Newline Handling", choices=["CR only","LF only","CR+LF"], majorDimension=0, style=wx.RA_SPECIFY_ROWS)

self.button_ok = wx.Button(self, -1,"OK")

self.button_cancel = wx.Button(self, -1,"Cancel")

self.__set_properties()

self.__do_layout()

# end wxGlade

self.__attach_events()

self.checkbox_echo.SetValue(self.settings.echo)

self.checkbox_unprintable.SetValue(self.settings.unprintable)

self.radio_box_newline.SetSelection(self.settings.newline)

def__set_properties(self):

# begin wxGlade: TerminalSettingsDialog.__set_properties

self.SetTitle("Terminal Settings")

self.radio_box_newline.SetSelection(0)

self.button_ok.SetDefault()

# end wxGlade

def__do_layout(self):

# begin wxGlade: TerminalSettingsDialog.__do_layout

sizer_2 = wx.BoxSizer(wx.VERTICAL)

sizer_3 = wx.BoxSizer(wx.HORIZONTAL)

sizer_4 = wx.StaticBoxSizer(wx.StaticBox(self, -1,"Input/Output"), wx.VERTICAL)

sizer_4.Add(self.checkbox_echo,0, wx.ALL,4)

sizer_4.Add(self.checkbox_unprintable,0, wx.ALL,4)

sizer_4.Add(self.radio_box_newline,0,0,0)

sizer_2.Add(sizer_4, 0, wx.EXPAND,0)

sizer_3.Add(self.button_ok,0,0,0)

sizer_3.Add(self.button_cancel,0,0,0)

sizer_2.Add(sizer_3, 0, wx.ALL|wx.ALIGN_RIGHT,4)

self.SetAutoLayout(1)

self.SetSizer(sizer_2)

sizer_2.Fit(self)

sizer_2.SetSizeHints(self)

self.Layout()

# end wxGlade

def__attach_events(self):

self.Bind(wx.EVT_BUTTON,self.OnOK, id =self.button_ok.GetId())

self.Bind(wx.EVT_BUTTON,self.OnCancel, id =self.button_cancel.GetId())

defOnOK(self, events):

"""Update data wil new values and close dialog."""

self.settings.echo =self.checkbox_echo.GetValue()

self.settings.unprintable =self.checkbox_unprintable.GetValue()

self.settings.newline =self.radio_box_newline.GetSelection()

self.EndModal(wx.ID_OK)

defOnCancel(self, events):

"""Do not update data but close dialog."""

self.EndModal(wx.ID_CANCEL)

# end of class TerminalSettingsDialog

classTerminalFrame(wx.Frame):

"""Simple terminal program for wxPython"""

def__init__(self, *args, **kwds):

self.serial = serial.Serial()

self.serial.timeout =0.5#make sure that the alive event can be checked from time to time

self.settings = TerminalSetup()#placeholder for the settings

self.thread =None

self.alive = threading.Event()

# begin wxGlade: TerminalFrame.__init__

kwds["style"] = wx.DEFAULT_FRAME_STYLE

wx.Frame.__init__(self, *args, **kwds)

self.text_ctrl_output = wx.TextCtrl(self, -1, "", style=wx.TE_MULTILINE|wx.TE_READONLY)

# Menu Bar

self.frame_terminal_menubar = wx.MenuBar()

self.SetMenuBar(self.frame_terminal_menubar)

wxglade_tmp_menu = wx.Menu()

wxglade_tmp_menu.Append(ID_CLEAR, "&Clear", "", wx.ITEM_NORMAL)

wxglade_tmp_menu.Append(ID_SAVEAS, "&Save Text As...", "", wx.ITEM_NORMAL)

wxglade_tmp_menu.AppendSeparator()

wxglade_tmp_menu.Append(ID_SETTINGS, "&Port Settings...", "", wx.ITEM_NORMAL)

wxglade_tmp_menu.Append(ID_TERM, "&Terminal Settings...", "", wx.ITEM_NORMAL)

wxglade_tmp_menu.AppendSeparator()

wxglade_tmp_menu.Append(ID_EXIT, "&Exit", "", wx.ITEM_NORMAL)

self.frame_terminal_menubar.Append(wxglade_tmp_menu,"&File")

# Menu Bar end

self.__set_properties()

self.__do_layout()

# end wxGlade

self.__attach_events()#register events

self.OnPortSettings(None)#call setup dialog on startup, opens port

ifnotself.alive.isSet():

self.Close()

defStartThread(self):

"""Start the receiver thread"""

self.thread = threading.Thread(target=self.ComPortThread)

self.thread.setDaemon(1)

self.alive.set()

self.thread.start()

defStopThread(self):

"""Stop the receiver thread, wait util it's finished."""

ifself.threadisnotNone:

self.alive.clear()#clear alive event for thread

self.thread.join()#wait until thread has finished

self.thread =None

def__set_properties(self):

# begin wxGlade: TerminalFrame.__set_properties

self.SetTitle("Serial Terminal")

self.SetSize((546,383))

# end wxGlade

def__do_layout(self):

# begin wxGlade: TerminalFrame.__do_layout

sizer_1 = wx.BoxSizer(wx.VERTICAL)

sizer_1.Add(self.text_ctrl_output,1, wx.EXPAND,0)

self.SetAutoLayout(1)

self.SetSizer(sizer_1)

self.Layout()

# end wxGlade

def__attach_events(self):

#register events at the controls

self.Bind(wx.EVT_MENU,self.OnClear, id = ID_CLEAR)

self.Bind(wx.EVT_MENU,self.OnSaveAs, id = ID_SAVEAS)

self.Bind(wx.EVT_MENU,self.OnExit, id = ID_EXIT)

self.Bind(wx.EVT_MENU,self.OnPortSettings, id = ID_SETTINGS)

self.Bind(wx.EVT_MENU,self.OnTermSettings, id = ID_TERM)

self.text_ctrl_output.Bind(wx.EVT_CHAR,self.OnKey)

self.Bind(EVT_SERIALRX,self.OnSerialRead)

self.Bind(wx.EVT_CLOSE,self.OnClose)

defOnExit(self, event):

"""Menu point Exit"""

self.Close()

defOnClose(self, event):

"""Called on application shutdown."""

self.StopThread()#stop reader thread

self.serial.close()#cleanup

self.Destroy()#close windows, exit app

defOnSaveAs(self, event):

"""Save contents of output window."""

filename = None

dlg = wx.FileDialog(None,"Save Text As...",".", "", "Text File|*.txt|All Files|*",  wx.SAVE)

ifdlg.ShowModal() ==  wx.ID_OK:

filename = dlg.GetPath()

dlg.Destroy()

iffilenameisnotNone:

f = file(filename, 'w')

text = self.text_ctrl_output.GetValue()

iftype(text) == unicode:

text = text.encode("latin1")#hm, is that a good asumption?

f.write(text)

f.close()

defOnClear(self, event):

"""Clear contents of output window."""

self.text_ctrl_output.Clear()

defOnPortSettings(self, event=None):

"""Show the portsettings dialog. The reader thread is stopped for the

settings change."""

ifeventisnotNone:#will be none when called on startup

self.StopThread()

self.serial.close()

ok = False

whilenotok:

dialog_serial_cfg = wxSerialConfigDialog.SerialConfigDialog(None, -1, "",

show=wxSerialConfigDialog.SHOW_BAUDRATE|wxSerialConfigDialog.SHOW_FORMAT|wxSerialConfigDialog.SHOW_FLOW,

serial=self.serial

)

result = dialog_serial_cfg.ShowModal()

dialog_serial_cfg.Destroy()

#open port if not called on startup, open it on startup and OK too

ifresult == wx.ID_OKoreventisnotNone:

try:

self.serial.open()

exceptserial.SerialException, e:

dlg = wx.MessageDialog(None, str(e),"Serial Port Error", wx.OK | wx.ICON_ERROR)

dlg.ShowModal()

dlg.Destroy()

else:

self.StartThread()

self.SetTitle("Serial Terminal on %s [%s, %s%s%s%s%s]"% (

self.serial.portstr,

self.serial.baudrate,

self.serial.bytesize,

self.serial.parity,

self.serial.stopbits,

self.serial.rtsctsand' RTS/CTS'or'',

self.serial.xonxoffand' Xon/Xoff'or'',

)

)

ok = True

else:

#on startup, dialog aborted

self.alive.clear()

ok = True

defOnTermSettings(self, event):

"""Menu point Terminal Settings. Show the settings dialog

with the current terminal settings"""

dialog = TerminalSettingsDialog(None, -1, "", settings=self.settings)

result = dialog.ShowModal()

dialog.Destroy()

defOnKey(self, event):

"""Key event handler. if the key is in the ASCII range, write it to the serial port.

Newline handling and local echo is also done here."""

code = event.GetKeyCode()

ifcode <256:#is it printable?

ifcode ==13:#is it a newline? (check for CR which is the RETURN key)

ifself.settings.echo:#do echo if needed

self.text_ctrl_output.AppendText('\n')

ifself.settings.newline == NEWLINE_CR:

self.serial.write('\r')#send CR

elifself.settings.newline == NEWLINE_LF:

self.serial.write('\n')#send LF

elifself.settings.newline == NEWLINE_CRLF:

self.serial.write('\r\n')#send CR+LF

else:

char = chr(code)

ifself.settings.echo:#do echo if needed

self.text_ctrl_output.WriteText(char)

self.serial.write(char)#send the charcater

else:

print"Extra Key:", code

defOnSerialRead(self, event):

"""Handle input from the serial port."""

text = event.data

ifself.settings.unprintable:

text = ''.join([(c >=' ')andcor''% ord(c)forcintext])

self.text_ctrl_output.AppendText(text)

defComPortThread(self):

"""Thread that handles the incomming traffic. Does the basic input

transformation (newlines) and generates an SerialRxEvent"""

whileself.alive.isSet():#loop while alive event is true

text = self.serial.read(1)#read one, with timout

iftext:#check if not timeout

n = self.serial.inWaiting()#look if there is more to read

ifn:

text = text + self.serial.read(n)#get it

#newline transformation

ifself.settings.newline == NEWLINE_CR:

text = text.replace('\r','\n')

elifself.settings.newline == NEWLINE_LF:

pass

elifself.settings.newline == NEWLINE_CRLF:

text = text.replace('\r\n','\n')

event = SerialRxEvent(self.GetId(), text)

self.GetEventHandler().AddPendingEvent(event)

#~ self.OnSerialRead(text)         #output text in window

# end of class TerminalFrame

classMyApp(wx.App):

defOnInit(self):

wx.InitAllImageHandlers()

frame_terminal = TerminalFrame(None, -1, "")

self.SetTopWindow(frame_terminal)

frame_terminal.Show(1)

return1

# end of class MyApp

if__name__ =="__main__":

app = MyApp(0)

app.MainLoop()

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值