PySerial — различия между версиями
Vooon (обсуждение | вклад) |
Vooon (обсуждение | вклад) |
||
Строка 2: | Строка 2: | ||
== Что потребуется? == | == Что потребуется? == | ||
− | * | + | *[http://ru.wikipedia.org/wiki/Python Python 2.3] |
− | * | + | *[http://ru.wikipedia.org/wiki/PyGTK PyGTK + GTK] |
− | *pyserial | + | *[http://pyserial.sourceforge.net/ PySerial] |
+ | |||
+ | PyGTK это обертка над GTK поэтому нужны обе библиотеки | ||
+ | они реализуют [http://ru.wikipedia.org/wiki/GUI GUI] | ||
+ | |||
+ | PySerial - библиотека работы с ком портом, работает как под Windows так и под [http://ru.wikipedia.org/wiki/POSIX POSIX] системами | ||
+ | |||
+ | == PySerial - examples == | ||
+ | Для примера используем '''miniterm.py''' из папки '''examples''' | ||
+ | |||
+ | ниже приведен его код: | ||
+ | |||
+ | #!/usr/bin/env python | ||
+ | # -*- coding: utf-8 -*- | ||
+ | # Very simple serial terminal | ||
+ | # (C)2002-2004 Chris Liechti <cliecht@gmx.net> | ||
+ | |||
+ | # Input characters are sent directly (only LF -> CR/LF/CRLF translation is | ||
+ | # done), received characters are displayed as is (or as trough pythons | ||
+ | # repr, useful for debug purposes) | ||
+ | # Baudrate and echo configuartion is done through globals | ||
+ | |||
+ | |||
+ | import sys, os, serial, threading, getopt | ||
+ | |||
+ | EXITCHARCTER = '\x04' #ctrl+D | ||
+ | |||
+ | #first choose a platform dependant way to read single characters from the console | ||
+ | if os.name == 'nt': | ||
+ | import msvcrt | ||
+ | def getkey(): | ||
+ | while 1: | ||
+ | if echo: | ||
+ | z = msvcrt.getche() | ||
+ | else: | ||
+ | z = msvcrt.getch() | ||
+ | if z == '\0' or z == '\xe0': #functions keys | ||
+ | msvcrt.getch() | ||
+ | else: | ||
+ | if z == '\r': | ||
+ | return '\n' | ||
+ | return z | ||
+ | # | ||
+ | elif os.name == 'posix': | ||
+ | import termios, sys, os | ||
+ | fd = sys.stdin.fileno() | ||
+ | old = termios.tcgetattr(fd) | ||
+ | new = termios.tcgetattr(fd) | ||
+ | new[3] = new[3] & ~termios.ICANON & ~termios.ECHO | ||
+ | new[6][termios.VMIN] = 1 | ||
+ | new[6][termios.VTIME] = 0 | ||
+ | termios.tcsetattr(fd, termios.TCSANOW, new) | ||
+ | s = '' # We'll save the characters typed and add them to the pool. | ||
+ | def getkey(): | ||
+ | c = os.read(fd, 1) | ||
+ | #~ c = sys.stdin.read(1) | ||
+ | if echo: sys.stdout.write(c); sys.stdout.flush() | ||
+ | return c | ||
+ | def clenaup_console(): | ||
+ | termios.tcsetattr(fd, termios.TCSAFLUSH, old) | ||
+ | sys.exitfunc = clenaup_console #terminal modes have to be restored on exit... | ||
+ | # | ||
+ | else: | ||
+ | raise "Sorry no implementation for your platform (%s) available." % sys.platform | ||
+ | # | ||
+ | CONVERT_CRLF = 2 | ||
+ | CONVERT_CR = 1 | ||
+ | CONVERT_LF = 0 | ||
+ | # | ||
+ | def reader(): | ||
+ | """loop forever and copy serial->console""" | ||
+ | while 1: | ||
+ | data = s.read() | ||
+ | if repr_mode: | ||
+ | sys.stdout.write(repr(data)[1:-1]) | ||
+ | else: | ||
+ | sys.stdout.write(data) | ||
+ | sys.stdout.flush() | ||
+ | # | ||
+ | def writer(): | ||
+ | """loop and copy console->serial until EOF character is found""" | ||
+ | while 1: | ||
+ | c = getkey() | ||
+ | if c == EXITCHARCTER: | ||
+ | break #exit app | ||
+ | elif c == '\n': | ||
+ | if convert_outgoing == CONVERT_CRLF: | ||
+ | s.write('\r\n') #make it a CR+LF | ||
+ | elif convert_outgoing == CONVERT_CR: | ||
+ | s.write('\r') #make it a CR | ||
+ | elif convert_outgoing == CONVERT_LF: | ||
+ | s.write('\n') #make it a LF | ||
+ | else: | ||
+ | s.write(c) #send character | ||
+ | # | ||
+ | # | ||
+ | #print a short help message | ||
+ | def usage(): | ||
+ | sys.stderr.write("""USAGE: %s [options] | ||
+ | Miniterm - A simple terminal program for the serial port. | ||
+ | - | ||
+ | options: | ||
+ | -p, --port=PORT: port, a number, default = 0 or a device name | ||
+ | -b, --baud=BAUD: baudrate, default 9600 | ||
+ | -r, --rtscts: enable RTS/CTS flow control (default off) | ||
+ | -x, --xonxoff: enable software flow control (default off) | ||
+ | -e, --echo: enable local echo (default off) | ||
+ | -c, --cr: do not send CR+LF, send CR only | ||
+ | -n, --newline: do not send CR+LF, send LF only | ||
+ | -D, --debug: debug received data (escape nonprintable chars) | ||
+ | - | ||
+ | """ % (sys.argv[0], )) | ||
+ | # | ||
+ | if __name__ == '__main__': | ||
+ | #initialize with defaults | ||
+ | port = 0 | ||
+ | baudrate = 9600 | ||
+ | echo = 0 | ||
+ | convert_outgoing = CONVERT_CRLF | ||
+ | rtscts = 0 | ||
+ | xonxoff = 0 | ||
+ | repr_mode = 0 | ||
+ | |||
+ | #parse command line options | ||
+ | try: | ||
+ | opts, args = getopt.getopt(sys.argv[1:], | ||
+ | "hp:b:rxecnD", | ||
+ | ["help", "port=", "baud=", "rtscts", "xonxoff", "echo", | ||
+ | "cr", "newline", "debug"] | ||
+ | ) | ||
+ | except getopt.GetoptError: | ||
+ | # print help information and exit: | ||
+ | usage() | ||
+ | sys.exit(2) | ||
+ | |||
+ | for o, a in opts: | ||
+ | if o in ("-h", "--help"): #help text | ||
+ | usage() | ||
+ | sys.exit() | ||
+ | elif o in ("-p", "--port"): #specified port | ||
+ | try: | ||
+ | port = int(a) | ||
+ | except ValueError: | ||
+ | port = a | ||
+ | elif o in ("-b", "--baud"): #specified baudrate | ||
+ | try: | ||
+ | baudrate = int(a) | ||
+ | except ValueError: | ||
+ | raise ValueError, "Baudrate must be a integer number, not %r" % a | ||
+ | elif o in ("-r", "--rtscts"): | ||
+ | rtscts = 1 | ||
+ | elif o in ("-x", "--xonxoff"): | ||
+ | xonxoff = 1 | ||
+ | elif o in ("-e", "--echo"): | ||
+ | echo = 1 | ||
+ | elif o in ("-c", "--cr"): | ||
+ | convert_outgoing = CONVERT_CR | ||
+ | elif o in ("-n", "--newline"): | ||
+ | convert_outgoing = CONVERT_LF | ||
+ | elif o in ("-D", "--debug"): | ||
+ | repr_mode = 1 | ||
+ | # | ||
+ | #open the port | ||
+ | try: | ||
+ | s = serial.Serial(port, baudrate, rtscts=rtscts, xonxoff=xonxoff) | ||
+ | except: | ||
+ | sys.stderr.write("Could not open port\n") | ||
+ | sys.exit(1) | ||
+ | sys.stderr.write("--- Miniterm --- type Ctrl-D to quit\n") | ||
+ | #start serial->console thread | ||
+ | r = threading.Thread(target=reader) | ||
+ | r.setDaemon(1) | ||
+ | r.start() | ||
+ | #and enter console->serial loop | ||
+ | writer() | ||
+ | # | ||
+ | sys.stderr.write("\n--- exit ---\n") |
Версия 01:27, 1 июля 2007
Опишу что потребуется для создания гипертерминала на питоне
Что потребуется?
PyGTK это обертка над GTK поэтому нужны обе библиотеки они реализуют GUI
PySerial - библиотека работы с ком портом, работает как под Windows так и под POSIX системами
PySerial - examples
Для примера используем miniterm.py из папки examples
ниже приведен его код:
#!/usr/bin/env python # -*- coding: utf-8 -*- # Very simple serial terminal # (C)2002-2004 Chris Liechti <cliecht@gmx.net> # Input characters are sent directly (only LF -> CR/LF/CRLF translation is # done), received characters are displayed as is (or as trough pythons # repr, useful for debug purposes) # Baudrate and echo configuartion is done through globals import sys, os, serial, threading, getopt EXITCHARCTER = '\x04' #ctrl+D #first choose a platform dependant way to read single characters from the console if os.name == 'nt': import msvcrt def getkey(): while 1: if echo: z = msvcrt.getche() else: z = msvcrt.getch() if z == '\0' or z == '\xe0': #functions keys msvcrt.getch() else: if z == '\r': return '\n' return z # elif os.name == 'posix': import termios, sys, os fd = sys.stdin.fileno() old = termios.tcgetattr(fd) new = termios.tcgetattr(fd) new[3] = new[3] & ~termios.ICANON & ~termios.ECHO new[6][termios.VMIN] = 1 new[6][termios.VTIME] = 0 termios.tcsetattr(fd, termios.TCSANOW, new) s = # We'll save the characters typed and add them to the pool. def getkey(): c = os.read(fd, 1) #~ c = sys.stdin.read(1) if echo: sys.stdout.write(c); sys.stdout.flush() return c def clenaup_console(): termios.tcsetattr(fd, termios.TCSAFLUSH, old) sys.exitfunc = clenaup_console #terminal modes have to be restored on exit... # else: raise "Sorry no implementation for your platform (%s) available." % sys.platform # CONVERT_CRLF = 2 CONVERT_CR = 1 CONVERT_LF = 0 # def reader(): """loop forever and copy serial->console""" while 1: data = s.read() if repr_mode: sys.stdout.write(repr(data)[1:-1]) else: sys.stdout.write(data) sys.stdout.flush() # def writer(): """loop and copy console->serial until EOF character is found""" while 1: c = getkey() if c == EXITCHARCTER: break #exit app elif c == '\n': if convert_outgoing == CONVERT_CRLF: s.write('\r\n') #make it a CR+LF elif convert_outgoing == CONVERT_CR: s.write('\r') #make it a CR elif convert_outgoing == CONVERT_LF: s.write('\n') #make it a LF else: s.write(c) #send character # # #print a short help message def usage(): sys.stderr.write("""USAGE: %s [options] Miniterm - A simple terminal program for the serial port. - options: -p, --port=PORT: port, a number, default = 0 or a device name -b, --baud=BAUD: baudrate, default 9600 -r, --rtscts: enable RTS/CTS flow control (default off) -x, --xonxoff: enable software flow control (default off) -e, --echo: enable local echo (default off) -c, --cr: do not send CR+LF, send CR only -n, --newline: do not send CR+LF, send LF only -D, --debug: debug received data (escape nonprintable chars) - """ % (sys.argv[0], )) # if __name__ == '__main__': #initialize with defaults port = 0 baudrate = 9600 echo = 0 convert_outgoing = CONVERT_CRLF rtscts = 0 xonxoff = 0 repr_mode = 0 #parse command line options try: opts, args = getopt.getopt(sys.argv[1:], "hp:b:rxecnD", ["help", "port=", "baud=", "rtscts", "xonxoff", "echo", "cr", "newline", "debug"] ) except getopt.GetoptError: # print help information and exit: usage() sys.exit(2) for o, a in opts: if o in ("-h", "--help"): #help text usage() sys.exit() elif o in ("-p", "--port"): #specified port try: port = int(a) except ValueError: port = a elif o in ("-b", "--baud"): #specified baudrate try: baudrate = int(a) except ValueError: raise ValueError, "Baudrate must be a integer number, not %r" % a elif o in ("-r", "--rtscts"): rtscts = 1 elif o in ("-x", "--xonxoff"): xonxoff = 1 elif o in ("-e", "--echo"): echo = 1 elif o in ("-c", "--cr"): convert_outgoing = CONVERT_CR elif o in ("-n", "--newline"): convert_outgoing = CONVERT_LF elif o in ("-D", "--debug"): repr_mode = 1 # #open the port try: s = serial.Serial(port, baudrate, rtscts=rtscts, xonxoff=xonxoff) except: sys.stderr.write("Could not open port\n") sys.exit(1) sys.stderr.write("--- Miniterm --- type Ctrl-D to quit\n") #start serial->console thread r = threading.Thread(target=reader) r.setDaemon(1) r.start() #and enter console->serial loop writer() # sys.stderr.write("\n--- exit ---\n")