PySerial

Материал из roboforum.ru Wiki
Перейти к: навигация, поиск




Опишу что потребуется для создания гипертерминала на питоне

Что потребуется?

PyGTK это обертка над GTK поэтому нужны обе библиотеки они реализуют GUI

PySerial - библиотека работы с ком портом, работает как под Windows так и под POSIX системами

PySerial - examples

Во всех примерах линии RxD и TxD соединены.

miniterm.py

код: <source lang="python">

  1. !/usr/bin/env python
  2. -*- coding: utf-8 -*-
  3. Very simple serial terminal
  4. (C)2002-2004 Chris Liechti <cliecht@gmx.net>
  1. Input characters are sent directly (only LF -> CR/LF/CRLF translation is
  2. done), received characters are displayed as is (or as trough pythons
  3. repr, useful for debug purposes)
  4. Baudrate and echo configuartion is done through globals


import sys, os, serial, threading, getopt

EXITCHARCTER = '\x04' #ctrl+D

  1. 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, atexit
   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)
   atexit.register(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")

</source> Результат работы: <source lang="text"> vovan@ubuntu-vooon:~/scripts/python/com-wake/pyserial-2.2/examples$ python ./miniterm.py -Den -p 0 -b 115200 --- Miniterm --- type Ctrl-D to quit hheelllloo wwoorrlldd!! \n --- exit --- </source>

wxTerminal.py

Пример терминала с графическим интерфейсом требует библиотеки xWdigets и wxPython