daily pastebin goal
58%
SHARE
TWEET

BaudRate.py

osteth Apr 16th, 2017 59 Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. #!/usr/bin/env python
  2.  
  3. import sys
  4. import time
  5. import serial
  6. from threading import Thread
  7.  
  8. class RawInput:
  9.     """Gets a single character from standard input.  Does not echo to the screen."""
  10.     def __init__(self):
  11.         try:
  12.             self.impl = RawInputWindows()
  13.         except ImportError:
  14.             self.impl = RawInputUnix()
  15.  
  16.     def __call__(self): return self.impl()
  17.  
  18.  
  19. class RawInputUnix:
  20.     def __init__(self):
  21.         import tty, sys
  22.  
  23.     def __call__(self):
  24.         import sys, tty, termios
  25.         fd = sys.stdin.fileno()
  26.         old_settings = termios.tcgetattr(fd)
  27.         try:
  28.             tty.setraw(sys.stdin.fileno())
  29.             ch = sys.stdin.read(1)
  30.         finally:
  31.             termios.tcsetattr(fd, termios.TCSADRAIN, old_settings)
  32.         return ch
  33.  
  34.  
  35. class RawInputWindows:
  36.     def __init__(self):
  37.         import msvcrt
  38.  
  39.     def __call__(self):
  40.         import msvcrt
  41.         return msvcrt.getch()
  42.  
  43. class Baudrate:
  44.  
  45.     VERSION = '1.0'
  46.     READ_TIMEOUT = 5
  47.     BAUDRATES = [
  48. #            "1200",
  49. #            "1800",
  50. #            "2400",
  51. #            "4800",
  52.             "9600",
  53.             "38400",
  54.             "19200",
  55.             "57600",
  56.             "115200",
  57.     ]
  58.  
  59.     UPKEYS = ['u', 'U', 'A']
  60.     DOWNKEYS = ['d', 'D', 'B']
  61.  
  62.     MIN_CHAR_COUNT = 25
  63.     WHITESPACE = [' ', '\t', '\r', '\n']
  64.     PUNCTUATION = ['.', ',', ':', ';', '?', '!']
  65.     VOWELS = ['a', 'A', 'e', 'E', 'i', 'I', 'o', 'O', 'u', 'U']
  66.  
  67.     def __init__(self, port=None, threshold=MIN_CHAR_COUNT, timeout=READ_TIMEOUT, name=None, auto=True, verbose=False):
  68.         self.port = port
  69.         self.threshold = threshold
  70.         self.timeout = timeout
  71.         self.name = name
  72.         self.auto_detect = auto
  73.         self.verbose = verbose
  74.         self.index = len(self.BAUDRATES) - 1
  75.         self.valid_characters = []
  76.         self.ctlc = False
  77.         self.thread = None
  78.  
  79.         self._gen_char_list()
  80.  
  81.     def _gen_char_list(self):
  82.         c = ' '
  83.  
  84.         while c <= '~':
  85.             self.valid_characters.append(c)
  86.             c = chr(ord(c) + 1)
  87.  
  88.         for c in self.WHITESPACE:
  89.             if c not in self.valid_characters:
  90.                 self.valid_characters.append(c)
  91.  
  92.     def _print(self, data):
  93.         if self.verbose:
  94.             sys.stderr.write(data)
  95.  
  96.     def Open(self):
  97.         self.serial = serial.Serial(self.port, timeout=self.timeout)
  98.         self.NextBaudrate(0)
  99.  
  100.     def NextBaudrate(self, updn):
  101.  
  102.         self.index += updn
  103.  
  104.         if self.index >= len(self.BAUDRATES):
  105.             self.index = 0
  106.         elif self.index < 0:
  107.             self.index = len(self.BAUDRATES) - 1
  108.  
  109.         sys.stderr.write('\n\n@@@@@@@@@@@@@@@@@@@@@ Baudrate: %s @@@@@@@@@@@@@@@@@@@@@\n\n' % self.BAUDRATES[self.index])
  110.  
  111.         self.serial.flush()
  112.         self.serial.baudrate = self.BAUDRATES[self.index]
  113.         self.serial.flush()
  114.  
  115.     def Detect(self):
  116.         count = 0
  117.         whitespace = 0
  118.         punctuation = 0
  119.         vowels = 0
  120.         start_time = 0
  121.         timed_out = False
  122.         clear_counters = False
  123.  
  124.         if not self.auto_detect:
  125.             self.thread = Thread(None, self.HandleKeypress, None, (self, 1))
  126.             self.thread.start()
  127.  
  128.         while True:
  129.             if start_time == 0:
  130.                 start_time = time.time()
  131.  
  132.             byte = self.serial.read(1)
  133.  
  134.             if byte:
  135.                 if self.auto_detect and byte in self.valid_characters:
  136.                     if byte in self.WHITESPACE:
  137.                         whitespace += 1
  138.                     elif byte in self.PUNCTUATION:
  139.                         punctuation += 1
  140.                     elif byte in self.VOWELS:
  141.                         vowels += 1
  142.  
  143.                     count += 1
  144.                 else:
  145.                     clear_counters = True
  146.  
  147.                 self._print(byte)
  148.  
  149.                 if count >= self.threshold and whitespace > 0 and punctuation > 0 and vowels > 0:
  150.                     break
  151.                 elif (time.time() - start_time) >= self.timeout:
  152.                     timed_out = True
  153.             else:
  154.                 timed_out = True
  155.  
  156.             if timed_out and self.auto_detect:
  157.                 start_time = 0
  158.                 self.NextBaudrate(-1)
  159.                 clear_counters = True
  160.                 timed_out = False
  161.  
  162.             if clear_counters:
  163.                 whitespace = 0
  164.                 punctuation = 0
  165.                 vowels = 0
  166.                 count = 0
  167.                 clear_counters = False
  168.  
  169.             if self.ctlc:
  170.                 break
  171.  
  172.         self._print("\n")
  173.         return self.BAUDRATES[self.index]
  174.  
  175.     def HandleKeypress(self, *args):
  176.         userinput = RawInput()
  177.  
  178.         while not self.ctlc:
  179.             c = userinput()
  180.             if c in self.UPKEYS:
  181.                 self.NextBaudrate(1)
  182.             elif c in self.DOWNKEYS:
  183.                 self.NextBaudrate(-1)
  184.             elif c == '\x03':
  185.                 self.ctlc = True
  186.  
  187.     def MinicomConfig(self, name=None):
  188.         success = True
  189.  
  190.         if name is None:
  191.             name = self.name
  192.  
  193.         config =  "########################################################################\n"
  194.         config += "# Minicom configuration file - use \"minicom -s\" to change parameters.\n"
  195.         config += "pu port             %s\n" % self.port
  196.         config += "pu baudrate         %s\n" % self.BAUDRATES[self.index]
  197.         config += "pu bits             8\n"
  198.         config += "pu parity           N\n"
  199.         config += "pu stopbits         1\n"
  200.         config += "pu rtscts           No\n"
  201.         config += "########################################################################\n"
  202.  
  203.         if name is not None and name:
  204.             try:
  205.                 open("/etc/minicom/minirc.%s" % name, "w").write(config)
  206.             except Exception, e:
  207.                 print "Error saving minicom config file:", str(e)
  208.                 success = False
  209.  
  210.         return (success, config)
  211.  
  212.     def Close(self):
  213.         self.ctlc = True
  214.         self.serial.close()
  215.  
  216.  
  217.  
  218. if __name__ == '__main__':
  219.  
  220.     import subprocess
  221.     from getopt import getopt as GetOpt, GetoptError
  222.  
  223.     def usage():
  224.         baud = Baudrate()
  225.  
  226.         print ""
  227.         print "Baudrate v%s" % baud.VERSION
  228.         print "Craig Heffner, http://www.devttys0.com"
  229.         print ""
  230.         print "Usage: %s [OPTIONS]" % sys.argv[0]
  231.         print ""
  232.         print "\t-p <serial port>       Specify the serial port to use [/dev/ttyUSB0]"
  233.         print "\t-t <seconds>           Set the timeout period used when switching baudrates in auto detect mode [%d]" % baud.READ_TIMEOUT
  234.         print "\t-c <num>               Set the minimum ASCII character threshold used during auto detect mode [%d]" % baud.MIN_CHAR_COUNT
  235.         print "\t-n <name>              Save the resulting serial configuration as <name> and automatically invoke minicom (implies -a)"
  236.         print "\t-a                     Enable auto detect mode"
  237.         print "\t-b                     Display supported baud rates and exit"
  238.         print "\t-q                     Do not display data read from the serial port"
  239.         print "\t-h                     Display help"
  240.         print ""
  241.         sys.exit(1)
  242.  
  243.     def main():
  244.         display = False
  245.         verbose = True
  246.         auto = False
  247.         run = False
  248.         threshold = 25
  249.         timeout = 5
  250.         name = None
  251.         port = '/dev/ttyUSB0'
  252.  
  253.         try:
  254.             (opts, args) = GetOpt(sys.argv[1:], 'p:t:c:n:abqh')
  255.         except GetoptError, e:
  256.             print e
  257.             usage()
  258.  
  259.         for opt, arg in opts:
  260.             if opt == '-t':
  261.                 timeout = int(arg)
  262.             elif opt == '-c':
  263.                 threshold = int(arg)
  264.             elif opt == '-p':
  265.                 port = arg
  266.             elif opt == '-n':
  267.                 name = arg
  268.                 auto = True
  269.                 run = True
  270.             elif opt == '-a':
  271.                 auto = True
  272.             elif opt == '-b':
  273.                 display = True
  274.             elif opt == '-q':
  275.                 verbose = False
  276.             else:
  277.                 usage()
  278.  
  279.         baud = Baudrate(port, threshold=threshold, timeout=timeout, name=name, verbose=verbose, auto=auto)
  280.  
  281.         if display:
  282.             print ""
  283.             for rate in baud.BAUDRATES:
  284.                 print "\t%s" % rate
  285.             print ""
  286.         else:
  287.             print ""
  288.             print "Starting baudrate detection on %s, turn on your serial device now." % port
  289.             print "Press Ctl+C to quit."
  290.             print ""
  291.  
  292.             baud.Open()
  293.  
  294.             try:
  295.                 rate = baud.Detect()
  296.                 print "\nDetected baudrate: %s" % rate
  297.  
  298.                 if name is None:
  299.                     print "\nSave minicom configuration as: ",
  300.                     name = sys.stdin.readline().strip()
  301.                     print ""
  302.  
  303.                 (ok, config) = baud.MinicomConfig(name)
  304.                 if name and name is not None:
  305.                     if ok:
  306.                         if not run:
  307.                             print "Configuration saved. Run minicom now [n/Y]? ",
  308.                             yn = sys.stdin.readline().strip()
  309.                             print ""
  310.                             if yn == "" or yn.lower().startswith('y'):
  311.                                 run = True
  312.  
  313.                         if run:
  314.                             subprocess.call(["minicom", name])
  315.                     else:
  316.                         print config
  317.                 else:
  318.                     print config
  319.             except KeyboardInterrupt:
  320.                 pass
  321.  
  322.             baud.Close()
  323.  
  324.     main()
RAW Paste Data
We use cookies for various purposes including analytics. By continuing to use Pastebin, you agree to our use of cookies as described in the Cookies Policy. OK, I Understand
 
Top