diff --git a/baudrate.py b/baudrate.py
new file mode 100755
index 0000000..e8f7667
--- /dev/null
+++ b/baudrate.py
@@ -0,0 +1,324 @@
+#!/usr/bin/env python
+
+import sys
+import time
+import serial
+from threading import Thread
+
+class RawInput:
+    """Gets a single character from standard input.  Does not echo to the screen."""
+    def __init__(self):
+        try:
+            self.impl = RawInputWindows()
+        except ImportError:
+            self.impl = RawInputUnix()
+
+    def __call__(self): return self.impl()
+
+
+class RawInputUnix:
+    def __init__(self):
+        import tty, sys
+
+    def __call__(self):
+        import sys, tty, termios
+        fd = sys.stdin.fileno()
+        old_settings = termios.tcgetattr(fd)
+        try:
+            tty.setraw(sys.stdin.fileno())
+            ch = sys.stdin.read(1)
+        finally:
+            termios.tcsetattr(fd, termios.TCSADRAIN, old_settings)
+        return ch
+
+
+class RawInputWindows:
+    def __init__(self):
+        import msvcrt
+
+    def __call__(self):
+        import msvcrt
+        return msvcrt.getch()
+
+class Baudrate:
+
+    VERSION = '1.0'
+    READ_TIMEOUT = 5
+    BAUDRATES = [
+#            "1200",
+#            "1800",
+#            "2400",
+#            "4800",
+            "9600",
+            "38400",
+            "19200",
+            "57600",
+            "115200",
+    ]
+
+    UPKEYS = ['u', 'U', 'A']
+    DOWNKEYS = ['d', 'D', 'B']
+
+    MIN_CHAR_COUNT = 25
+    WHITESPACE = [' ', '\t', '\r', '\n']
+    PUNCTUATION = ['.', ',', ':', ';', '?', '!']
+    VOWELS = ['a', 'A', 'e', 'E', 'i', 'I', 'o', 'O', 'u', 'U']
+
+    def __init__(self, port=None, threshold=MIN_CHAR_COUNT, timeout=READ_TIMEOUT, name=None, auto=True, verbose=False):
+        self.port = port
+        self.threshold = threshold
+        self.timeout = timeout
+        self.name = name
+        self.auto_detect = auto
+        self.verbose = verbose
+        self.index = len(self.BAUDRATES) - 1
+        self.valid_characters = []
+        self.ctlc = False
+        self.thread = None
+
+        self._gen_char_list()
+
+    def _gen_char_list(self):
+        c = ' '
+
+        while c <= '~':
+            self.valid_characters.append(c)
+            c = chr(ord(c) + 1)
+
+        for c in self.WHITESPACE:
+            if c not in self.valid_characters:
+                self.valid_characters.append(c)
+
+    def _print(self, data):
+        if self.verbose:
+            sys.stderr.write(data)
+
+    def Open(self):
+        self.serial = serial.Serial(self.port, timeout=self.timeout)
+        self.NextBaudrate(0)
+
+    def NextBaudrate(self, updn):
+
+        self.index += updn
+
+        if self.index >= len(self.BAUDRATES):
+            self.index = 0
+        elif self.index < 0:
+            self.index = len(self.BAUDRATES) - 1
+
+        sys.stderr.write('\n\n@@@@@@@@@@@@@@@@@@@@@ Baudrate: %s @@@@@@@@@@@@@@@@@@@@@\n\n' % self.BAUDRATES[self.index])
+
+        self.serial.flush()
+        self.serial.baudrate = self.BAUDRATES[self.index]
+        self.serial.flush()
+
+    def Detect(self):
+        count = 0
+        whitespace = 0
+        punctuation = 0
+        vowels = 0
+        start_time = 0
+        timed_out = False
+        clear_counters = False
+
+        if not self.auto_detect:
+            self.thread = Thread(None, self.HandleKeypress, None, (self, 1))
+            self.thread.start()
+
+        while True:
+            if start_time == 0:
+                start_time = time.time()
+
+            byte = self.serial.read(1)
+
+            if byte:
+                if self.auto_detect and byte in self.valid_characters:
+                    if byte in self.WHITESPACE:
+                        whitespace += 1
+                    elif byte in self.PUNCTUATION:
+                        punctuation += 1
+                    elif byte in self.VOWELS:
+                        vowels += 1
+
+                    count += 1
+                else:
+                    clear_counters = True
+
+                self._print(byte)
+
+                if count >= self.threshold and whitespace > 0 and punctuation > 0 and vowels > 0:
+                    break
+                elif (time.time() - start_time) >= self.timeout:
+                    timed_out = True
+            else:
+                timed_out = True
+
+            if timed_out and self.auto_detect:
+                start_time = 0
+                self.NextBaudrate(-1)
+                clear_counters = True
+                timed_out = False
+
+            if clear_counters:
+                whitespace = 0
+                punctuation = 0
+                vowels = 0
+                count = 0
+                clear_counters = False
+
+            if self.ctlc:
+                break
+
+        self._print("\n")
+        return self.BAUDRATES[self.index]
+
+    def HandleKeypress(self, *args):
+        userinput = RawInput()
+
+        while not self.ctlc:
+            c = userinput()
+            if c in self.UPKEYS:
+                self.NextBaudrate(1)
+            elif c in self.DOWNKEYS:
+                self.NextBaudrate(-1)
+            elif c == '\x03':
+                self.ctlc = True
+
+    def MinicomConfig(self, name=None):
+        success = True
+
+        if name is None:
+            name = self.name
+
+        config =  "########################################################################\n"
+        config += "# Minicom configuration file - use \"minicom -s\" to change parameters.\n"
+        config += "pu port             %s\n" % self.port
+        config += "pu baudrate         %s\n" % self.BAUDRATES[self.index]
+        config += "pu bits             8\n"
+        config += "pu parity           N\n"
+        config += "pu stopbits         1\n"
+        config += "pu rtscts           No\n"
+        config += "########################################################################\n"
+
+        if name is not None and name:
+            try:
+                open("/etc/minicom/minirc.%s" % name, "w").write(config)
+            except Exception, e:
+                print "Error saving minicom config file:", str(e)
+                success = False
+
+        return (success, config)
+
+    def Close(self):
+        self.ctlc = True
+        self.serial.close()
+
+
+
+if __name__ == '__main__':
+
+    import subprocess
+    from getopt import getopt as GetOpt, GetoptError
+
+    def usage():
+        baud = Baudrate()
+
+        print ""
+        print "Baudrate v%s" % baud.VERSION
+        print "Craig Heffner, http://www.devttys0.com"
+        print ""
+        print "Usage: %s [OPTIONS]" % sys.argv[0]
+        print ""
+        print "\t-p <serial port>       Specify the serial port to use [/dev/ttyUSB0]"
+        print "\t-t <seconds>           Set the timeout period used when switching baudrates in auto detect mode [%d]" % baud.READ_TIMEOUT
+        print "\t-c <num>               Set the minimum ASCII character threshold used during auto detect mode [%d]" % baud.MIN_CHAR_COUNT
+        print "\t-n <name>              Save the resulting serial configuration as <name> and automatically invoke minicom (implies -a)"
+        print "\t-a                     Enable auto detect mode"
+        print "\t-b                     Display supported baud rates and exit"
+        print "\t-q                     Do not display data read from the serial port"
+        print "\t-h                     Display help"
+        print ""
+        sys.exit(1)
+
+    def main():
+        display = False
+        verbose = True
+        auto = False
+        run = False
+        threshold = 25
+        timeout = 5
+        name = None
+        port = '/dev/ttyUSB0'
+
+        try:
+            (opts, args) = GetOpt(sys.argv[1:], 'p:t:c:n:abqh')
+        except GetoptError, e:
+            print e
+            usage()
+
+        for opt, arg in opts:
+            if opt == '-t':
+                timeout = int(arg)
+            elif opt == '-c':
+                threshold = int(arg)
+            elif opt == '-p':
+                port = arg
+            elif opt == '-n':
+                name = arg
+                auto = True
+                run = True
+            elif opt == '-a':
+                auto = True
+            elif opt == '-b':
+                display = True
+            elif opt == '-q':
+                verbose = False
+            else:
+                usage()
+
+        baud = Baudrate(port, threshold=threshold, timeout=timeout, name=name, verbose=verbose, auto=auto)
+
+        if display:
+            print ""
+            for rate in baud.BAUDRATES:
+                print "\t%s" % rate
+            print ""
+        else:
+            print ""
+            print "Starting baudrate detection on %s, turn on your serial device now." % port
+            print "Press Ctl+C to quit."
+            print ""
+
+            baud.Open()
+
+            try:
+                rate = baud.Detect()
+                print "\nDetected baudrate: %s" % rate
+
+                if name is None:
+                    print "\nSave minicom configuration as: ",
+                    name = sys.stdin.readline().strip()
+                    print ""
+
+                (ok, config) = baud.MinicomConfig(name)
+                if name and name is not None:
+                    if ok:
+                        if not run:
+                            print "Configuration saved. Run minicom now [n/Y]? ",
+                            yn = sys.stdin.readline().strip()
+                            print ""
+                            if yn == "" or yn.lower().startswith('y'):
+                                run = True
+
+                        if run:
+                            subprocess.call(["minicom", name])
+                    else:
+                        print config
+                else:
+                    print config
+            except KeyboardInterrupt:
+                pass
+
+            baud.Close()
+
+    main()