# -*- coding: utf-8; -*- # # (c) 2014 protological.com/CLI Systems LLC http://clisystems.com # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . import sys import time import serial import threading STATE_IDLE = 0 STATE_LEN = 1 STATE_DATA = 2 STATE_CRC1 = 3 STATE_CRC2 = 4 TYPE_STRING = 1 TYPE_DATA = 2 # Classes ############################### class COMMPacket: type = 0 length = 0 data = [] incrc = 0 def __init__(self,intype): self.type = intype self.clear() def clear(self): self.length = 0 self.data = [] def dataadd(self,x): self.data.append(x) def getdatacount(self): return len(self.data) def getlength(self): return self.length def getdatastring(self): st = "" for x in self.data: try: st += chr(x) except: st += x return st class COMMSerial(threading.Thread): remainderstr = "" rawstr = "" def __init__(self,ser,rxcallback): super(COMMSerial, self).__init__() self.key = 0xAB self.packet = None self.state = STATE_IDLE self.ser = ser self.rxcallback = rxcallback; self.running = True def run(self): while(self.running): if self.ser.inWaiting: out = '' while self.ser.inWaiting() > 0: out += self.ser.read(1) if(len(out)>0): pkt = commserial.inputstr(out) if(pkt!=None and self.rxcallback!=None): self.rxcallback(pkt) def close(self): self.running = False def crc16(self,st): crc = 0xFFFF for c in st: x = ord(c) for y in range(8): if((crc ^ x) & 0x01): crc >>= 1; crc ^= 0x8408; else: crc >>= 1; x >>= 1; return ((~crc)&0xFFFF) def inputstr(self, st): #print " RX %d bytes" % len(st) for s in st: x = ord(s) # calc CRC if(self.state16): strlen=16 if(padto>strlen): out += chr(padto) for ch in st[:padto]: out += ch else: out += chr(strlen) for ch in st[:strlen]: out += ch if(padto>strlen): cnt = padto-strlen for ch in range(cnt): out += " " crc = self.crc16(out) # Append CRC out += chr(crc&0xFF) out += chr((crc>>8)&0xFF) pbuf("TX: ",out) self.ser.write(out); # Functions ############################### def pbuf(st,b): for x in b: try: st += "x%02X," % ord(x) except: st += "x%02X," % x print st def serialRX(pkt): #pbuf(out) if(pkt.type==0x80): key = pkt.data[0] #print "Key: x%02X" % key if(key==1): print "Up" elif(key==2): print "Down" elif(key==3): print "Left" elif(key==4): print "Right" elif(key==5): print "Enter" elif(key==6): print "Exit" else: return; else: print "Got packet!! type x%02X '%s'" % (pkt.type, pkt.getdatastring()) #pbuf("Data: ", pkt.data) print(">> "), sys.stdout.flush() # Main ############################### # Linux ser_port = "/dev/ttyUSB0" # Windows #ser_port = "COM1" ser_speed = 19200 # configure the serial connections (the parameters differs on the device you are connecting to) try: ser = serial.Serial( port=ser_port, baudrate=ser_speed, parity=serial.PARITY_NONE, stopbits=serial.STOPBITS_ONE, bytesize=serial.EIGHTBITS ) except: print "Can't setup port %s at %d" % (ser_port,ser_speed) #raise exit() try: if(ser.isOpen()==False): ser.open() if(ser.isOpen()==False): print "Error testing if port is open" exit(); except: print "Can't open port %s at %d" % (ser_port,ser_speed) raise exit() print 'Enter your commands below.\r\nInsert "exit" to leave the application.' commserial = COMMSerial(ser,serialRX) commserial.start() input="" while 1 : #print(">>"), #sys.stdout.flush() # get keyboard input indata = raw_input(">> ") # Python 3 users # input = input(">> ") if indata == 'exit': break; # Get HW and firmware version elif indata == "hw": commserial.tx(1,"") # Clear screen elif indata == "clear": commserial.tx(6,"") # Write row 1, Eg "ROW1 Testing123" elif indata[:4] == "ROW1": commserial.tx(7,indata[5:],16) # Write row 2 elif indata[:4] == "ROW2": commserial.tx(8,indata[5:],16) # Save these settings as the startup default elif indata == "store": commserial.tx(4,"") # Reboot the LCD elif indata == "reset": st = chr(8)+chr(18)+chr(99) commserial.tx(5,st) # Change the brightness of the LCD and LEDs. Eg "bright 50" elif indata[:6] == "bright": try: x = int(indata[7:]) print "'%d'" % x st = chr(x) commserial.tx(14,st) except: print "Invalid number?" else: # send the character to the device #commserial.tx(TYPE_STRING,indata) print "Ignoring command" commserial.close() commserial.join() ser.close() ser = None print "Done"