diff options
author | Anthony LaTorre <telatorre@gmail.com> | 2011-06-09 20:46:59 -0400 |
---|---|---|
committer | Anthony LaTorre <telatorre@gmail.com> | 2011-06-09 20:46:59 -0400 |
commit | daee9b48ac6bbc42e1bd406dc4a1c138cb19d257 (patch) | |
tree | 876bf89c626b4ca512b88ca7dadb6957885f94e6 /sock.py | |
parent | 76982ea70f1eefa481af3cd9f7bafdf92733aad0 (diff) | |
download | lecrunch-daee9b48ac6bbc42e1bd406dc4a1c138cb19d257.tar.gz lecrunch-daee9b48ac6bbc42e1bd406dc4a1c138cb19d257.tar.bz2 lecrunch-daee9b48ac6bbc42e1bd406dc4a1c138cb19d257.zip |
you can now take data using sequence mode! also, updated the README file to include more examples. sock.py now replaces scope.py. sock.py is almost identical, but i renamed the class to Socket and fixed it so that data headers are properly received; previously, it was assumed that the 8 byte header was sent in a single recv() call, which is not always the case. draw.py is a new script to draw waveforms using matplotlib instead of root.
Diffstat (limited to 'sock.py')
-rwxr-xr-x | sock.py | 103 |
1 files changed, 103 insertions, 0 deletions
@@ -0,0 +1,103 @@ +#!/usr/bin/env python + +import struct +import socket +import os + +headerformat = '>BBBBL' + +errors = { 1 : 'unrecognized command/query header', + 2 : 'illegal header path', + 3 : 'illegal number', + 4 : 'illegal number suffix', + 5 : 'unrecognized keyword', + 6 : 'string error', + 7 : 'GET embedded in another message', + 10 : 'arbitrary data block expected', + 11 : 'non-digit character in byte count field of arbitrary data ' + 'block', + 12 : 'EOI detected during definite length data block transfer', + 13 : 'extra bytes detected during definite length data block ' + 'transfer' } + +class Socket(object): + def __init__(self, host, port=1861, timeout=5.0): + self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) + self.sock.connect((host, port)) + self.sock.settimeout(timeout) + + def clear(self, timeout=0.5): + """ + Clear any bytes in the oscilloscope's output queue by receiving + packets until the connection blocks for more than `timeout` seconds. + """ + t = self.sock.gettimeout() + self.sock.settimeout(timeout) + try: + while True: + self.sock.recv(4096) + except socket.timeout: + pass + self.sock.settimeout(t) + + def send(self, msg): + """Format and send the string `msg`.""" + if not msg.endswith('\n'): + msg += '\n' + header = struct.pack(headerformat, 129, 1, 1, 0, len(msg)) + self.sock.sendall(header + msg) + + def check_last_command(self): + """ + Check that the last command sent was received okay; if not, raise + an exception with details about the error. + """ + self.send('cmr?') + err = int(self.recv().split(' ')[-1].rstrip('\n')) + + if err in errors: + self.sock.close() + raise Exception(errors[err]) + + def recv(self): + """Return a message from the scope.""" + + reply = '' + while True: + header = '' + + while len(header) < 8: + header += self.sock.recv(8 - len(header)) + + operation, headerver, seqnum, spare, totalbytes = \ + struct.unpack(headerformat, header) + + buffer = '' + + while len(buffer) < totalbytes: + buffer += self.sock.recv(totalbytes - len(buffer)) + + reply += buffer + + if operation % 2: + break + + return reply + + def __del__(self): + self.sock.close() + +if __name__ == '__main__': + import sys + import setup + + sock = Socket(setup.scope_ip) + sock.clear() + + for msg in sys.argv[1:]: + sock.send(msg) + + if '?' in msg: + print repr(sock.recv()) + + sock.check_last_command() |