Skip to content

Instantly share code, notes, and snippets.

@pklaus
Last active July 14, 2017 17:15

Revisions

  1. pklaus revised this gist Jul 14, 2017. 2 changed files with 1 addition and 87 deletions.
    1 change: 1 addition & 0 deletions README.md
    Original file line number Diff line number Diff line change
    @@ -0,0 +1 @@
    Please check out the new repository: [pklaus / serialman](https://github.com/pklaus/serialman). It's great!
    87 changes: 0 additions & 87 deletions serialman.py
    Original file line number Diff line number Diff line change
    @@ -1,87 +0,0 @@
    #!/usr/bin/env python

    import serial
    import threading
    import time
    from multiprocessing import Process, Queue
    try:
    from queue import Empty
    except ImportError:
    from Queue import Empty

    class SerialManager(Process):
    """ This class has been written by
    Philipp Klaus and can be found on
    https://gist.github.com/4039175 . """

    def __init__(self, device, **kwargs):
    settings = dict()
    settings['baudrate'] = 9600
    settings['bytesize'] = serial.EIGHTBITS
    settings['parity'] = serial.PARITY_NONE
    settings['stopbits'] = serial.STOPBITS_ONE
    settings['timeout'] = 0.0005
    settings.update(kwargs)
    self._kwargs = settings
    self.ser = serial.Serial(device, **self._kwargs)
    self.in_queue = Queue()
    self.out_queue = Queue()
    self.closing = False # A flag to indicate thread shutdown
    self.read_num_bytes = 256
    self.sleeptime = None
    self._chunker = None
    Process.__init__(self, target=self.loop)

    def set_chunker(self, chunker):
    self._chunker = chunker
    self.in_queue = chunker.in_queue

    def loop(self):
    try:
    while not self.closing:
    if self.sleeptime: time.sleep(self.sleeptime)
    in_data = self.ser.read(self.read_num_bytes)
    if in_data:
    if self._chunker:
    self._chunker.new_data(in_data)
    else:
    self.in_queue.put(in_data)
    try:
    out_buffer = self.out_queue.get_nowait()
    self.ser.write(out_buffer)
    except Empty:
    pass
    except (KeyboardInterrupt, SystemExit):
    pass
    self.ser.close()

    def close(self):
    self.closing = True

    def main():
    import argparse
    parser = argparse.ArgumentParser(description='A class to manage reading and writing from and to a serial port.')
    parser.add_argument('--timeout', '-t', type=float, default=0.0005, help='Seconds until reading from serial port times out [default: 0.0005].')
    parser.add_argument('--sleeptime', '-s', type=float, default=None, help='Seconds to sleep before reading from serial port again [default: none].')
    parser.add_argument('--baudrate', '-b', type=int, default=9600, help='Baudrate of serial port [default: 9600].')
    parser.add_argument('device', help='The serial port to use (COM4, /dev/ttyUSB1 or similar).')
    args = parser.parse_args()

    s1 = SerialManager(args.device, baudrate=args.baudrate, timeout=args.timeout)
    s1.sleeptime = args.sleeptime
    s1.read_num_size = 512
    s1.start()

    try:
    while True:
    data = s1.in_queue.get()
    print(repr(data))
    except KeyboardInterrupt:
    s1.close()
    finally:
    s1.close()
    s1.join()

    if __name__ == "__main__":
    main()

  2. pklaus revised this gist Nov 26, 2014. 1 changed file with 1 addition and 1 deletion.
    2 changes: 1 addition & 1 deletion serialman.py
    Original file line number Diff line number Diff line change
    @@ -63,7 +63,7 @@ def main():
    parser = argparse.ArgumentParser(description='A class to manage reading and writing from and to a serial port.')
    parser.add_argument('--timeout', '-t', type=float, default=0.0005, help='Seconds until reading from serial port times out [default: 0.0005].')
    parser.add_argument('--sleeptime', '-s', type=float, default=None, help='Seconds to sleep before reading from serial port again [default: none].')
    parser.add_argument('--baudrate', '-b', type=int, default=9600, help='Baudrate of serial port.')
    parser.add_argument('--baudrate', '-b', type=int, default=9600, help='Baudrate of serial port [default: 9600].')
    parser.add_argument('device', help='The serial port to use (COM4, /dev/ttyUSB1 or similar).')
    args = parser.parse_args()

  3. pklaus revised this gist Nov 26, 2014. 1 changed file with 3 additions and 1 deletion.
    4 changes: 3 additions & 1 deletion serialman.py
    Original file line number Diff line number Diff line change
    @@ -27,6 +27,7 @@ def __init__(self, device, **kwargs):
    self.in_queue = Queue()
    self.out_queue = Queue()
    self.closing = False # A flag to indicate thread shutdown
    self.read_num_bytes = 256
    self.sleeptime = None
    self._chunker = None
    Process.__init__(self, target=self.loop)
    @@ -39,7 +40,7 @@ def loop(self):
    try:
    while not self.closing:
    if self.sleeptime: time.sleep(self.sleeptime)
    in_data = self.ser.read(256)
    in_data = self.ser.read(self.read_num_bytes)
    if in_data:
    if self._chunker:
    self._chunker.new_data(in_data)
    @@ -68,6 +69,7 @@ def main():

    s1 = SerialManager(args.device, baudrate=args.baudrate, timeout=args.timeout)
    s1.sleeptime = args.sleeptime
    s1.read_num_size = 512
    s1.start()

    try:
  4. pklaus revised this gist Nov 26, 2014. 1 changed file with 6 additions and 5 deletions.
    11 changes: 6 additions & 5 deletions serialman.py
    Original file line number Diff line number Diff line change
    @@ -20,14 +20,14 @@ def __init__(self, device, **kwargs):
    settings['bytesize'] = serial.EIGHTBITS
    settings['parity'] = serial.PARITY_NONE
    settings['stopbits'] = serial.STOPBITS_ONE
    settings['timeout'] = 0
    settings['timeout'] = 0.0005
    settings.update(kwargs)
    self._kwargs = settings
    self.ser = serial.Serial(device, **self._kwargs)
    self.in_queue = Queue()
    self.out_queue = Queue()
    self.closing = False # A flag to indicate thread shutdown
    self.sleeptime = 0.0005
    self.sleeptime = None
    self._chunker = None
    Process.__init__(self, target=self.loop)

    @@ -38,7 +38,7 @@ def set_chunker(self, chunker):
    def loop(self):
    try:
    while not self.closing:
    time.sleep(self.sleeptime)
    if self.sleeptime: time.sleep(self.sleeptime)
    in_data = self.ser.read(256)
    if in_data:
    if self._chunker:
    @@ -60,12 +60,13 @@ def close(self):
    def main():
    import argparse
    parser = argparse.ArgumentParser(description='A class to manage reading and writing from and to a serial port.')
    parser.add_argument('--sleeptime', '-s', type=float, default=0.001, help='Seconds to sleep between polling (0.001s).')
    parser.add_argument('--timeout', '-t', type=float, default=0.0005, help='Seconds until reading from serial port times out [default: 0.0005].')
    parser.add_argument('--sleeptime', '-s', type=float, default=None, help='Seconds to sleep before reading from serial port again [default: none].')
    parser.add_argument('--baudrate', '-b', type=int, default=9600, help='Baudrate of serial port.')
    parser.add_argument('device', help='The serial port to use (COM4, /dev/ttyUSB1 or similar).')
    args = parser.parse_args()

    s1 = SerialManager(args.device, baudrate=args.baudrate)
    s1 = SerialManager(args.device, baudrate=args.baudrate, timeout=args.timeout)
    s1.sleeptime = args.sleeptime
    s1.start()

  5. pklaus revised this gist Nov 21, 2014. 1 changed file with 4 additions and 4 deletions.
    8 changes: 4 additions & 4 deletions serialman.py
    Original file line number Diff line number Diff line change
    @@ -28,11 +28,11 @@ def __init__(self, device, **kwargs):
    self.out_queue = Queue()
    self.closing = False # A flag to indicate thread shutdown
    self.sleeptime = 0.0005
    self.chunker = None
    self._chunker = None
    Process.__init__(self, target=self.loop)

    def set_chunker(self, chunker):
    self.chunker = chunker
    self._chunker = chunker
    self.in_queue = chunker.in_queue

    def loop(self):
    @@ -41,8 +41,8 @@ def loop(self):
    time.sleep(self.sleeptime)
    in_data = self.ser.read(256)
    if in_data:
    if self.chunker:
    self.chunker.new_data(in_data)
    if self._chunker:
    self._chunker.new_data(in_data)
    else:
    self.in_queue.put(in_data)
    try:
  6. pklaus revised this gist Nov 21, 2014. 1 changed file with 1 addition and 1 deletion.
    2 changes: 1 addition & 1 deletion serialman.py
    Original file line number Diff line number Diff line change
    @@ -6,7 +6,7 @@
    from multiprocessing import Process, Queue
    try:
    from queue import Empty
    except:
    except ImportError:
    from Queue import Empty

    class SerialManager(Process):
  7. pklaus revised this gist Nov 20, 2014. 1 changed file with 11 additions and 1 deletion.
    12 changes: 11 additions & 1 deletion serialman.py
    Original file line number Diff line number Diff line change
    @@ -13,6 +13,7 @@ class SerialManager(Process):
    """ This class has been written by
    Philipp Klaus and can be found on
    https://gist.github.com/4039175 . """

    def __init__(self, device, **kwargs):
    settings = dict()
    settings['baudrate'] = 9600
    @@ -27,14 +28,23 @@ def __init__(self, device, **kwargs):
    self.out_queue = Queue()
    self.closing = False # A flag to indicate thread shutdown
    self.sleeptime = 0.0005
    self.chunker = None
    Process.__init__(self, target=self.loop)

    def set_chunker(self, chunker):
    self.chunker = chunker
    self.in_queue = chunker.in_queue

    def loop(self):
    try:
    while not self.closing:
    time.sleep(self.sleeptime)
    in_data = self.ser.read(256)
    if in_data: self.in_queue.put(in_data)
    if in_data:
    if self.chunker:
    self.chunker.new_data(in_data)
    else:
    self.in_queue.put(in_data)
    try:
    out_buffer = self.out_queue.get_nowait()
    self.ser.write(out_buffer)
  8. pklaus revised this gist Nov 20, 2014. 1 changed file with 5 additions and 2 deletions.
    7 changes: 5 additions & 2 deletions serialman.py
    Original file line number Diff line number Diff line change
    @@ -3,7 +3,6 @@
    import serial
    import threading
    import time
    import argparse
    from multiprocessing import Process, Queue
    try:
    from queue import Empty
    @@ -48,7 +47,8 @@ def loop(self):
    def close(self):
    self.closing = True

    if __name__ == "__main__":
    def main():
    import argparse
    parser = argparse.ArgumentParser(description='A class to manage reading and writing from and to a serial port.')
    parser.add_argument('--sleeptime', '-s', type=float, default=0.001, help='Seconds to sleep between polling (0.001s).')
    parser.add_argument('--baudrate', '-b', type=int, default=9600, help='Baudrate of serial port.')
    @@ -69,3 +69,6 @@ def close(self):
    s1.close()
    s1.join()

    if __name__ == "__main__":
    main()

  9. pklaus revised this gist Nov 20, 2014. 1 changed file with 2 additions and 0 deletions.
    2 changes: 2 additions & 0 deletions serialman.py
    Original file line number Diff line number Diff line change
    @@ -50,11 +50,13 @@ def close(self):

    if __name__ == "__main__":
    parser = argparse.ArgumentParser(description='A class to manage reading and writing from and to a serial port.')
    parser.add_argument('--sleeptime', '-s', type=float, default=0.001, help='Seconds to sleep between polling (0.001s).')
    parser.add_argument('--baudrate', '-b', type=int, default=9600, help='Baudrate of serial port.')
    parser.add_argument('device', help='The serial port to use (COM4, /dev/ttyUSB1 or similar).')
    args = parser.parse_args()

    s1 = SerialManager(args.device, baudrate=args.baudrate)
    s1.sleeptime = args.sleeptime
    s1.start()

    try:
  10. pklaus revised this gist Nov 20, 2014. 1 changed file with 2 additions and 2 deletions.
    4 changes: 2 additions & 2 deletions serialman.py
    Original file line number Diff line number Diff line change
    @@ -50,11 +50,11 @@ def close(self):

    if __name__ == "__main__":
    parser = argparse.ArgumentParser(description='A class to manage reading and writing from and to a serial port.')
    parser.add_argument('--baud', type=int, default=9600, help='Baudrate of serial port.')
    parser.add_argument('--baudrate', '-b', type=int, default=9600, help='Baudrate of serial port.')
    parser.add_argument('device', help='The serial port to use (COM4, /dev/ttyUSB1 or similar).')
    args = parser.parse_args()

    s1 = SerialManager(args.device, baudrate=args.baud)
    s1 = SerialManager(args.device, baudrate=args.baudrate)
    s1.start()

    try:
  11. pklaus revised this gist Nov 20, 2014. 1 changed file with 18 additions and 14 deletions.
    32 changes: 18 additions & 14 deletions serialman.py
    Original file line number Diff line number Diff line change
    @@ -4,12 +4,13 @@
    import threading
    import time
    import argparse
    from multiprocessing import Process, Queue
    try:
    from queue import Queue, Empty
    from queue import Empty
    except:
    from Queue import Queue, Empty
    from Queue import Empty

    class SerialManager(threading.Thread):
    class SerialManager(Process):
    """ This class has been written by
    Philipp Klaus and can be found on
    https://gist.github.com/4039175 . """
    @@ -27,18 +28,21 @@ def __init__(self, device, **kwargs):
    self.out_queue = Queue()
    self.closing = False # A flag to indicate thread shutdown
    self.sleeptime = 0.0005
    threading.Thread.__init__(self)
    Process.__init__(self, target=self.loop)

    def run(self):
    while not self.closing:
    time.sleep(self.sleeptime)
    in_data = self.ser.read(256)
    if in_data: self.in_queue.put(in_data)
    try:
    out_buffer = self.out_queue.get_nowait()
    self.ser.write(out_buffer)
    except Empty:
    pass
    def loop(self):
    try:
    while not self.closing:
    time.sleep(self.sleeptime)
    in_data = self.ser.read(256)
    if in_data: self.in_queue.put(in_data)
    try:
    out_buffer = self.out_queue.get_nowait()
    self.ser.write(out_buffer)
    except Empty:
    pass
    except (KeyboardInterrupt, SystemExit):
    pass
    self.ser.close()

    def close(self):
  12. pklaus revised this gist Nov 20, 2014. 1 changed file with 31 additions and 32 deletions.
    63 changes: 31 additions & 32 deletions serialman.py
    Original file line number Diff line number Diff line change
    @@ -3,61 +3,60 @@
    import serial
    import threading
    import time
    import argparse
    try:
    from queue import Queue, Empty
    except:
    from Queue import Queue, Empty

    class SerialManager(threading.Thread):
    """ This class has been written by
    Philipp Klaus and can be found on
    https://gist.github.com/4039175 . """
    def __init__(self, device, *args):
    self._target = self.read
    self._args = args
    self.__lock = threading.Lock()
    self.ser = serial.Serial(device)
    self.data_buffer = ""
    def __init__(self, device, **kwargs):
    settings = dict()
    settings['baudrate'] = 9600
    settings['bytesize'] = serial.EIGHTBITS
    settings['parity'] = serial.PARITY_NONE
    settings['stopbits'] = serial.STOPBITS_ONE
    settings['timeout'] = 0
    settings.update(kwargs)
    self._kwargs = settings
    self.ser = serial.Serial(device, **self._kwargs)
    self.in_queue = Queue()
    self.out_queue = Queue()
    self.closing = False # A flag to indicate thread shutdown
    self.sleeptime = 0.00005
    self.sleeptime = 0.0005
    threading.Thread.__init__(self)

    def run(self):
    self._target(*self._args)

    def read(self):
    while not self.closing:
    time.sleep(self.sleeptime)
    if not self.__lock.acquire(False):
    continue
    in_data = self.ser.read(256)
    if in_data: self.in_queue.put(in_data)
    try:
    self.data_buffer += self.ser.read(6)
    finally:
    self.__lock.release()
    out_buffer = self.out_queue.get_nowait()
    self.ser.write(out_buffer)
    except Empty:
    pass
    self.ser.close()

    def pop_buffer(self):
    # If a request is pending, we don't access the buffer
    if not self.__lock.acquire(False):
    return ""
    buf = self.data_buffer
    self.data_buffer = ""
    self.__lock.release()
    return buf

    def write(data):
    self.ser.write(data)

    def close(self):
    self.closing = True


    if __name__ == "__main__":
    device = '/dev/tty.usbserial'
    parser = argparse.ArgumentParser(description='A class to manage reading and writing from and to a serial port.')
    parser.add_argument('--baud', type=int, default=9600, help='Baudrate of serial port.')
    parser.add_argument('device', help='The serial port to use (COM4, /dev/ttyUSB1 or similar).')
    args = parser.parse_args()

    s1 = SerialManager(device)
    s1 = SerialManager(args.device, baudrate=args.baud)
    s1.start()

    try:
    while True:
    data = s1.pop_buffer()
    if data != "": print repr(data)
    data = s1.in_queue.get()
    print(repr(data))
    except KeyboardInterrupt:
    s1.close()
    finally:
  13. pklaus renamed this gist Nov 20, 2014. 1 changed file with 4 additions and 2 deletions.
    6 changes: 4 additions & 2 deletions serialrecv.py → serialman.py
    Original file line number Diff line number Diff line change
    @@ -3,7 +3,8 @@
    import serial
    import threading
    import time
    class SerialReceiver(threading.Thread):

    class SerialManager(threading.Thread):
    """ This class has been written by
    Philipp Klaus and can be found on
    https://gist.github.com/4039175 . """
    @@ -50,7 +51,7 @@ def close(self):
    if __name__ == "__main__":
    device = '/dev/tty.usbserial'

    s1 = SerialReceiver(device)
    s1 = SerialManager(device)
    s1.start()

    try:
    @@ -62,3 +63,4 @@ def close(self):
    finally:
    s1.close()
    s1.join()

  14. pklaus renamed this gist Nov 8, 2012. 1 changed file with 3 additions and 3 deletions.
    6 changes: 3 additions & 3 deletions threaded-binary-serial-dumper.py → serialrecv.py
    Original file line number Diff line number Diff line change
    @@ -1,13 +1,13 @@
    #!/usr/bin/env python

    import serial
    import threading
    import time
    class SerialReceiver(threading.Thread):
    """ This class has been written by
    Philipp Klaus and can be found on
    https://gist.github.com/4039175 . """
    def __init__(self, device, *args):
    import serial
    import threading
    import time
    self._target = self.read
    self._args = args
    self.__lock = threading.Lock()
  15. pklaus revised this gist Nov 8, 2012. 1 changed file with 9 additions and 10 deletions.
    19 changes: 9 additions & 10 deletions threaded-binary-serial-dumper.py
    Original file line number Diff line number Diff line change
    @@ -1,22 +1,20 @@
    #!/usr/bin/env python

    import serial
    import threading
    import time

    class SerialReceiver(threading.Thread):
    """ This class has been written by
    Philipp Klaus and can be found on
    https://gist.github.com/4039175 . """
    def __init__(self, device, *args):
    import serial
    import threading
    import time
    self._target = self.read
    self._args = args
    self.__lock = threading.Lock()

    self.ser = serial.Serial(device) # open first serial port
    print self.ser.portstr # check which port was really used
    self.ser = serial.Serial(device)
    self.data_buffer = ""

    self.closing = False
    self.closing = False # A flag to indicate thread shutdown
    self.sleeptime = 0.00005

    threading.Thread.__init__(self)

    def run(self):
    @@ -51,6 +49,7 @@ def close(self):

    if __name__ == "__main__":
    device = '/dev/tty.usbserial'

    s1 = SerialReceiver(device)
    s1.start()

  16. pklaus revised this gist Nov 8, 2012. 1 changed file with 15 additions and 2 deletions.
    17 changes: 15 additions & 2 deletions threaded-binary-serial-dumper.py
    100644 → 100755
    Original file line number Diff line number Diff line change
    @@ -2,17 +2,20 @@

    import serial
    import threading
    import time

    class SerialReceiver(threading.Thread):
    def __init__(self, device, *args):
    self._target = self.read
    self._args = args
    self.__lock = threading.Lock()

    self.ser = serial.Serial(device) # open first serial port
    print self.ser.portstr # check which port was really used
    self.data_buffer = ""

    self.closing = False
    self.sleeptime = 0.00005

    threading.Thread.__init__(self)

    @@ -21,12 +24,22 @@ def run(self):

    def read(self):
    while not self.closing:
    self.data_buffer += self.ser.read(6)
    time.sleep(self.sleeptime)
    if not self.__lock.acquire(False):
    continue
    try:
    self.data_buffer += self.ser.read(6)
    finally:
    self.__lock.release()
    self.ser.close()

    def pop_buffer(self):
    # If a request is pending, we don't access the buffer
    if not self.__lock.acquire(False):
    return ""
    buf = self.data_buffer
    self.data_buffer = ""
    self.__lock.release()
    return buf

    def write(data):
    @@ -49,4 +62,4 @@ def close(self):
    s1.close()
    finally:
    s1.close()
    s1.join()
    s1.join()
  17. pklaus created this gist Nov 8, 2012.
    52 changes: 52 additions & 0 deletions threaded-binary-serial-dumper.py
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,52 @@
    #!/usr/bin/env python

    import serial
    import threading

    class SerialReceiver(threading.Thread):
    def __init__(self, device, *args):
    self._target = self.read
    self._args = args

    self.ser = serial.Serial(device) # open first serial port
    print self.ser.portstr # check which port was really used
    self.data_buffer = ""

    self.closing = False

    threading.Thread.__init__(self)

    def run(self):
    self._target(*self._args)

    def read(self):
    while not self.closing:
    self.data_buffer += self.ser.read(6)
    self.ser.close()

    def pop_buffer(self):
    buf = self.data_buffer
    self.data_buffer = ""
    return buf

    def write(data):
    self.ser.write(data)

    def close(self):
    self.closing = True


    if __name__ == "__main__":
    device = '/dev/tty.usbserial'
    s1 = SerialReceiver(device)
    s1.start()

    try:
    while True:
    data = s1.pop_buffer()
    if data != "": print repr(data)
    except KeyboardInterrupt:
    s1.close()
    finally:
    s1.close()
    s1.join()