class USBController(): def __init__(self): try: self.bb = BitBangDevice() self.bb.port = 0xFF self.state = self.bb.read_pins() self.attenuation = 0 self.switch_1 = 1 self.switch_2 = 1 print self.state except: raise Exception("Failed to initialize USB controller") print "Failed to initialize USB controller. Please reconnect." def set_att(self, att): if att >=0 and att <=31: self.attenuation = att value = self.switch_1*32 + self.switch_2*64 + self.attenuation^0b11111 self.bb.port = value self.state = self.bb.read_pins() else: print "Attenuation value out of range" def set_switches(self, a, b): if a in [0,1] and b in [0,1]: self.switch_1 = a self.switch_2 = b value = self.switch_1*32 + self.switch_2*64 + self.attenuation^0b11111 self.bb.port = value self.state = self.bb.read_pins() else: print "Incorrent switch setting. Enter 0 or 1."
def bbang(self, bba): # Take the one-byte address to "bit bang" and bang the port self.bba = bba self.bbser = BitBangDevice() self.bbser.open() self.bbser.direction = 0x01 self.bbser.port = 1 time.sleep(.5) self.bbser.port = 0 outstr = "><" sys.stdout.write('\r' + outstr) sys.stdout.flush() time.sleep(.2) bbbitmask = 1 for i in range(8): if (self.bba[0] & bbbitmask) > 0: outbit = 1 else: outbit = 0 self.bbser.port = outbit outstr = ">" + str(outbit) + outstr[1:] sys.stdout.write('\r' + outstr) sys.stdout.flush() bbbitmask = bbbitmask * 2 time.sleep(.2) self.bbser.port = 1 sys.stdout.write("\n") self.bbser.close()
def main(): global bbd bbd = None # # Create an FTDI BigBangDevice instance, based on serial number passed in # bbd = BitBangDevice(device_index=0) # # Set direction regiser # bbd.direction = 0xFF # # Set initial port value to 0 # bbd.port = 0 # # That worked, setup XMLRPC server # server = SimpleXMLRPCServer.SimpleXMLRPCServer( ('localhost', int(sys.argv[1])), logRequests=False, allow_none=True) server.register_introspection_functions() server.register_function(set_bit, 'set_bit') server.serve_forever() return 0
def _ToggleRelayByName(self, req): boardExists = False foundRelay = False toggleSuccess = False if self.relayExists: # Do not do this if no relay exists. # Toggle Relay boardExists = True for i in range(1,9): # Walk the relays to find the one with the right name. relayEnabled = rospy.get_param("~relay" + str(i) + "enabled", False) if relayEnabled: # Do not touch (poll or anything) Relays that are not listed as enabled. relayLabel = rospy.get_param("~relay" + str(i) + "label", "No Label") if relayLabel == req.relay: foundRelay = True while self._Busy: # Prevent simultaneous polling of serial port by multiple processes within this app due to ROS threading. print "BitBangDevice Busy . . ." rospy.sleep(0.2) self._Busy = True if req.state: BitBangDevice(self.relaySerialNumber).port |= int(relay_data.address[str(i)], 16) #BitBangDevice(relaySerialNumber).port |= int(relay.address[leftMotorRelay], 16) elif not req.state: BitBangDevice(self.relaySerialNumber).port &= ~int(relay_data.address[str(i)], 16) checkState = get_relay_state( BitBangDevice(self.relaySerialNumber).port, str(i) ) self._Busy = False if checkState == 0: newState = False else: newState = True if newState == req.state: toggleSuccess = True return(boardExists, foundRelay, toggleSuccess)
class USBController(): def __init__(self): try: self.bb = BitBangDevice() self.bb.port = 0xFF self.state = self.bb.read_pins() self.attenuation = 0 self.switch_1 = 1 self.switch_2 = 1 print self.state except: raise Exception("Failed to initialize USB controller") print "Failed to initialize USB controller. Please reconnect." def set_att(self, att): if att >= 0 and att <= 31: self.attenuation = att value = self.switch_1 * 32 + self.switch_2 * 64 + self.attenuation ^ 0b11111 self.bb.port = value self.state = self.bb.read_pins() else: print "Attenuation value out of range" def set_switches(self, a, b): if a in [0, 1] and b in [0, 1]: self.switch_1 = a self.switch_2 = b value = self.switch_1 * 32 + self.switch_2 * 64 + self.attenuation ^ 0b11111 self.bb.port = value self.state = self.bb.read_pins() else: print "Incorrent switch setting. Enter 0 or 1."
def initialise(self, deviceID, baudRate, mask, bitMode): try: indexed = deviceID.split("#", 2) if len(indexed) == 2: deviceID = indexed[0] which = int(indexed[1]) else: which = 0 index = 0 found = False for dev in self.driver.list_devices(): if re.search(deviceID + '.+', dev[2].decode()): if which == index: found = True print('Found device %s#%d => %s' % (deviceID, index, dev[2].decode())) deviceID = dev[2].decode() break index += 1 if found: self.bb = BitBangDevice(deviceID) self.bb.direction = mask self.bb.open() except Exception as e: raise dae_RelayBoard_Common.Denkovi_Exception( 'Could not connect to relay board: %s: %s' % (e.__class__, e)) if not found: raise dae_RelayBoard_Common.Denkovi_Exception( 'Relay board: %s#%d not found' % (deviceID, index))
def _select_ftdi_channel(channel): """Select multiplexer channel. Currently uses a FTDI chip via pylibftdi""" if channel < 0 or channel > 8: raise ArgumentError( "FTDI-selected multiplexer only has channels 0-7 valid, make sure you specify channel with -c channel=number", channel=channel) from pylibftdi import BitBangDevice bb = BitBangDevice(auto_detach=False) bb.direction = 0b111 bb.port = channel
class FTD2XXLinux(object): def __init__(self): self.driver = Driver() self.bb = None self.comport = None def initialise(self, deviceID, baudRate, mask, bitMode): try: indexed = deviceID.split("#", 2) if len(indexed) == 2: deviceID = indexed[0] which = int(indexed[1]) else: which = 0 index = 0 found = False for dev in self.driver.list_devices(): if re.search(deviceID + '.+', dev[2].decode()): if which == index: found = True print('Found device %s#%d => %s' % (deviceID, index, dev[2].decode())) deviceID = dev[2].decode() break index += 1 if found: self.bb = BitBangDevice(deviceID) self.bb.direction = mask self.bb.open() except Exception as e: raise dae_RelayBoard_Common.Denkovi_Exception( 'Could not connect to relay board: %s: %s' % (e.__class__, e)) if not found: raise dae_RelayBoard_Common.Denkovi_Exception( 'Relay board: %s#%d not found' % (deviceID, index)) def close(self): if self.bb is not None: self.bb.close() self.bb = None def writeByte(self, byte): if self.bb is None: raise dae_RelayBoard_Common.Denkovi_Exception( 'Board non initialized') self.bb.port = byte def readByte(self): if self.bb is None: raise dae_RelayBoard_Common.Denkovi_Exception( 'Board non initialized') return self.bb.port
def Stop(self): rospy.loginfo("Shutting off all relays . . .") # At this point ROS is shutting down, so any attempts to check parameters or log may crash. self._Busy = True # We are shutting down, so make everyone else stall and plow ahead: for i in range(1, 9): # Walk the relays state = get_relay_state( BitBangDevice(self.relaySerialNumber).port, str(i)) while not state == 0: # Loop if it doesn't shut off. BitBangDevice(self.relaySerialNumber).port &= ~int( relay_data.address[str(i)], 16) state = get_relay_state( BitBangDevice(self.relaySerialNumber).port, str(i))
def __init__(self): try: self.bb = BitBangDevice() self.bb.port = 0xFF self.state = self.bb.read_pins() self.attenuation = 0 self.switch_1 = 1 self.switch_2 = 1 print self.state except: raise Exception("Failed to initialize USB controller") print "Failed to initialize USB controller. Please reconnect."
def Run(self): # Get and broadcast status of all USB Relays. while not rospy.is_shutdown(): relaystatus = usbRelayStatus() relaystatus.relayOn = [False] * 8 # Fill array for use. if self.relayExists: # Only poll if the relay exists. relaystatus.relayPresent = True # Gather USB Relay status for each relay and publish for i in range(1,9): relayEnabled = rospy.get_param("~relay" + str(i) + "enabled", False) if relayEnabled: # Do not touch (poll or anything) Relays that are not listed as enabled. relayLabel = rospy.get_param("~relay" + str(i) + "label", "No Label") while self._Busy: # Prevent simultaneous polling of serial port by multiple processes within this app due to ROS threading. print "BitBangDevice Busy . . ." rospy.sleep(0.1) self._Busy = True state = get_relay_state( BitBangDevice(self.relaySerialNumber).port, str(i) ) self._Busy = False if state == 0: #print "Relay " + str(i) + " state:\tOFF (" + str(state) + ")" #print str(i) + " - " + relayLabel + ": OFF" relaystatus.relayOn[i-1] = False else: #print "Relay " + str(i) + " state:\tON (" + str(state) + ")" #print str(i) + " - " + relayLabel + ": ON" relaystatus.relayOn[i-1] = True else: # If the relay does not exist just broadcast "False" to everything. relaystatus.relayPresent = False self._usbRelayStatusPublisher.publish(relaystatus) # Publish USB Relay status self.r.sleep() # Sleep long enough to maintain the rate set in __init__
def clkd(vt, command): # Clock the whole chain rback = [] datal = dusb(vt, command) print("bb") with BitBangDevice() as bb: bb.direction = (~DREAD) & 0xFF bb.port = 0xFF #chip_s("active") bb.port = (~CS) & 0xFF for k in xrange(len(datal)): if (datal[k] == 0): bb.port = 0xFF & (~CS) & (~CLK) & (~DWRITE) # send 0 bit bb.port = 0xFF & (~CS) & (~DWRITE) # send CLK else: bb.port = 0xFF & (~CS) & (~CLK) # send 1 bit bb.port = 0xFF & (~CS) # send CLK rr = bb.port if (rr & DREAD > 0): rback.append(0x01) else: rback.append(0x00) bb.port = 0xFF #chip_s("inactive") if (re_bitar(rback) == TESTWORD): return "LOOPBACK OK" else: return "USB OK"
def display(string, device_id=None): """ Display the given string on an attached LCD an optional `device_id` can be given. """ with BitBangDevice(device_id) as bb: # These LCDs are quite slow - and the actual baudrate # is 16x this in bitbang mode... bb.baudrate = 60 lcd = LCD(bb) lcd.init_four_bit() # 001xxxxx - function set lcd.write_cmd(0x20) # 00000001 - clear display lcd.write_cmd(0x01) # 000001xx - entry mode set # bit 1: inc(1)/dec(0) # bit 0: shift display lcd.write_cmd(0x06) # 00001xxx - display config # bit 2: display on # bit 1: display cursor # bit 0: blinking cursor lcd.write_cmd(0x0C) for i in string: lcd.write_data(ord(i))
def get_hardware_state(self): def get_relay_state(data, relay): def testBit(int_type, offset): mask = 1 << offset return (int_type & mask) if relay == "1": return testBit(data, 1) if relay == "2": return testBit(data, 3) if relay == "3": return testBit(data, 5) if relay == "4": return testBit(data, 7) if relay == "5": return testBit(data, 2) if relay == "6": return testBit(data, 4) if relay == "7": return testBit(data, 6) if relay == "8": return testBit(data, 8) data = None if 'BitBang' == self.__device_type: with BitBangDevice(self.__device) as device: device.baudrate = 9600 data = get_relay_state(device.port, str(self.get_address())) elif 'Serial' == self.__device_type: return None return terrariumPowerSwitch.OFF if data is None or data == 0 else terrariumPowerSwitch.ON
def __init__(self): try: self.ft245 = BitBangDevice() except: print 'It may be possible that your device it is not connected, check that and try again\n' sys.exit() self.__output_names = {"RELE1": 0, "RELE2": 1, "RELE3": 2, "RELE4": 3}
def relayOff(relayList): ''' Function to turn on specified relay(s) passed in a list ''' for item in relayList: if item in range(1, 9): relay = 2**(item - 1) with BitBangDevice() as bb: bb.port &= ~relay
def Stop(self): #rospy.sleep(5) # Give other nodes a chance to clean up before shutting down our services. rospy.loginfo("Shutting off all enabled relays . . .") for i in range(1,9): # Walk the relays to find the one with the right name. relayEnabled = rospy.get_param("~relay" + str(i) + "enabled", False) if relayEnabled: # Do not touch (poll or anything) Relays that are not listed as enabled. relayLabel = rospy.get_param("~relay" + str(i) + "label", "No Label") self._Busy = True # We are shutting down, so make everyone else stall and plow ahead: state = get_relay_state( BitBangDevice(self.relaySerialNumber).port, str(i) ) if state == 0: rospy.loginfo(str(i) + " - " + relayLabel + " already OFF") else: while not state == 0: # Loop if it doesn't shut off. #print state BitBangDevice(self.relaySerialNumber).port &= ~int(relay_data.address[str(i)], 16) state = get_relay_state( BitBangDevice(self.relaySerialNumber).port, str(i) ) rospy.loginfo(str(i) + " - " + relayLabel + " shut OFF by arlobot_usbrelay node.")
def flash_forever(rate): """toggle bit zero at rate Hz""" # put an LED with 1Kohm or similar series resistor # on D0 pin with BitBangDevice() as bb: while True: time.sleep(1.0 / (2 * rate)) bb.port ^= 1
def initialise(self, deviceID, baudRate, mask, bitMode): try: for dev in self.driver.list_devices(): if re.search(deviceID + '.+', dev[2]): deviceID = dev[2] print('Found device ' + deviceID) break if deviceID is None: raise dae_RelayBoard_Common.Denkovi_Exception( 'No board connected') self.bb = BitBangDevice(deviceID) self.bb.direction = mask self.bb.open() except Exception as e: raise dae_RelayBoard_Common.Denkovi_Exception( 'Could not connect to relay board: %s: %s' % (e.__class__, e))
def get_value(): """ get the value of the pins """ if not getattr(get_value, "dev", None): get_value.dev = BitBangDevice(direction=ALL_INPUTS) dev = getattr(get_value, "dev") return dev.port
def set_state(self, state, force = False): if self.get_state() is not state or force: if self.get_hardware_type() == 'ftdi': try: if 'BitBang' == self.device_type: with BitBangDevice(self.device) as device: device.baudrate = 9600 if state is terrariumSwitch.ON: device.port |= int(terrariumSwitch.BITBANG_ADDRESSES[str(self.get_address())], 16) else: device.port &= ~int(terrariumSwitch.BITBANG_ADDRESSES[str(self.get_address())], 16) device.close() elif 'Serial' == self.device_type: with SerialDevice(self.device) as device: device.baudrate = 9600 cmd = chr(0xff) + chr(0x0 + int(self.get_address())) + chr(0x0 + (1 if state is terrariumSwitch.ON else 0)) device.write(cmd) device.close() except Exception, err: # Ignore for now pass elif self.get_hardware_type() == 'eg-pm-usb': address = int(self.sensor_address) % 4 if address == 0: address = 4 logger.debug('Change remote Energenie USB power switch nr %s, on device nr %s, to state %s' % (address,self.device,state)) subprocess.call(['/usr/bin/sispmctl', '-d',str(self.device),('-o' if state is terrariumSwitch.ON else '-f'),str(address)],stdout=open(os.devnull, 'w'), stderr=subprocess.STDOUT) elif self.get_hardware_type() == 'eg-pm-lan': if self.device is None: logger.error('Energenie LAN device is not connected. Cannot trigger power switch') else: data = re.match(r"^http:\/\/((?P<passwd>[^@]+)@)?(?P<host>[^#\/]+)(\/)?#(?P<switch>[1-4])$",self.sensor_address) if data: address = int(data.group('switch')) % 4 if address == 0: address = 4 logger.debug('Change remote Energenie LAN power switch nr %s to state %s' % (address,state)) try: webstatus = self.device.getstatus() if webstatus['login'] == 1: logger.debug('Logged in at remote Energenie LAN power switch %s' % (self.sensor_address,)) if self.device.login(): webstatus = self.device.getstatus() if webstatus['login'] == 0: self.device.changesocket(address, ( 1 if state is terrariumSwitch.ON else 0 )) self.device.logout() else: logger.error('Could not login to the Energenie LAN device %s at location %s. Error status %s(%s)' % (self.get_name(),self.sensor_address,webstatus['logintxt'],webstatus['login'])) except Exception, ex: logger.exception('Could not login to the Energenie LAN device %s at location %s. Error status %s' % (self.get_name(),self.sensor_address,ex))
def slowInit11(self): # Take the one-byte address to "bit bang" and bang the port self.bbser = BitBangDevice() print("beginning slow init") self.bbser.open() self.bbser.direction = 0x01 self.bbser.port = 1 time.sleep(.5) self.bbser.port = 0 time.sleep(.2) self.bbser.port = 1 time.sleep(.2) self.bbser.port = 0 time.sleep(1.4) self.bbser.port = 1 time.sleep(.2) self.bbser.close() print("slow init sent")
def setFTDIDeviceDataForked(value): """ Write the bitbang value to the device. :param value: integer representing bitbang value :return: Returns nothing. """ with BitBangDevice() as ftdiDevice: ftdiDevice.baudrate=921600 ftdiDevice.write(int(value))
def flash_forever(rate): """toggle bit zero at rate Hz""" # put an LED with 1Kohm or similar series resistor # on D0 pin # Default is all outputs? with BitBangDevice() as bb: while True: #time.sleep(1.0 / (2 * rate)) time.sleep(3.0) bb.port ^= 0xff print "Toggling."
def set(self, relay_position, value): """Returns the current status of the passed in relay. Args: relay_position: Relay position. value: Turn_on or Turn_off the relay for the given relay_position. """ with BitBangDevice(self.device) as bb: if value == RelayState.NO: bb.port |= self.address[relay_position] else: bb.port &= ~(self.address[relay_position]) self.status_dict[relay_position] = value
def set_relays(): print "setting relay state..." k = 0 for i in xrange(RELAYS): k = k | (relay_state[i] << i) #k = struct.pack("B", k) try: with BitBangDevice(DEVICE) as bb: bb.port = k except Exception, err: print "Error: " + str(err) sys.exit(1)
def get_relay_status(self, relay_position): """Get relay status for the given relay position. Args: relay_position: Status for given Relay position. Returns: returns current status for given relay_position. """ with BitBangDevice(self.device) as bb: self.status_dict[relay_position] = self._get_relay_state( bb.port, relay_position) return self.status_dict[relay_position]
class FTD2XXLinux(object): def __init__(self): self.driver = Driver() self.bb = None self.comport = None def initialise(self, deviceID, baudRate, mask, bitMode): try: for dev in self.driver.list_devices(): if re.search(deviceID + '.+', dev[2]): deviceID = dev[2] print('Found device ' + deviceID) break if deviceID is None: raise dae_RelayBoard_Common.Denkovi_Exception( 'No board connected') self.bb = BitBangDevice(deviceID) self.bb.direction = mask self.bb.open() except Exception as e: raise dae_RelayBoard_Common.Denkovi_Exception( 'Could not connect to relay board: %s: %s' % (e.__class__, e)) def close(self): pass def writeByte(self, byte): if self.bb is None: raise dae_RelayBoard_Common.Denkovi_Exception( 'Board non initialized') self.bb.port = byte def readByte(self): if self.bb is None: raise dae_RelayBoard_Common.Denkovi_Exception( 'Board non initialized') return self.bb.port
class RelaySwitcher(object): def __init__(self): try: self.ft245 = BitBangDevice() except: print 'It may be possible that your device it is not connected, check that and try again\n' sys.exit() self.__output_names = {"RELE1": 0, "RELE2": 1, "RELE3": 2, "RELE4": 3} def __del__(self): self.ft245.close() pass def set_sw_by_name(self, sw_names): output_numbers = [self.__output_names[i] for i in sw_names] output_word = [output_mask[i] for i in output_numbers] output_word = sum(output_word) self.ft245.port |= output_word def clear_sw_by_name(self, sw_names): output_numbers = [self.__output_names[i] for i in sw_names] output_word = [output_mask[i] for i in output_numbers] output_word = sum(output_word)^255 self.ft245.port &= output_word def get_states(self): pins_status = self.ft245.read_pins() for k in sorted(self.__output_names.keys()): print "{}: {}\n".format(k,'ON'if output_mask[self.__output_names[k]]&pins_status else 'OFF') def set_names(self, rele1, rele2, rele3, rele4): self.__output_names = {rele1: 0, rele2: 1, rele3: 2, rele4: 3} return self.__output_names def get_names(self): return self.__output_names
def main(wpm=12): """ :param wpm: words per minute """ while True: try: s = input('Morse:> ' if isatty(0) else '').lower().strip() except EOFError: break with BitBangDevice() as device: output(s, device, wpm=wpm) if isatty(0): print("Bye!")
def set_hardware_state(self, state, force = False): if 'BitBang' == self.__device_type: with BitBangDevice(self.__device) as device: device.baudrate = 9600 if state is terrariumPowerSwitch.ON: device.port |= int(terrariumPowerSwitchFTDI.BITBANG_ADDRESSES[str(self.get_address())], 16) else: device.port &= ~int(terrariumPowerSwitchFTDI.BITBANG_ADDRESSES[str(self.get_address())], 16) device.close() elif 'Serial' == self.__device_type: with SerialDevice(self.__device) as device: device.baudrate = 9600 cmd = chr(0xff) + chr(0x0 + int(self.get_address())) + chr(0x0 + (1 if state is terrariumPowerSwitch.ON else 0)) device.write(cmd) device.close()
def set(self, relay_position, value): """Returns the current status of the passed in relay. Note that this board acts in reverse of normal relays. EG: NO = NC and NC = NO Args: relay_position: Relay position. value: Turn_on or Turn_off the relay for the given relay_position. """ with BitBangDevice(self.device) as bb: if value == RelayState.NO: bb.port &= ~(self.address[relay_position]) else: bb.port |= self.address[relay_position] self.status_dict[relay_position] = value
def _set_hardware_value(self, state): (device, device_type) = self.device if device_type == terrariumRelayFTDI.SERIAL: with SerialDevice(device) as device: device.baudrate = 9600 cmd = chr(0xff) + chr(0x0 + self._address[0]) + chr(0x0 + (1 if state == self.ON else 0)) device.write(cmd) elif device_type == terrariumRelayFTDI.BITBANG: with BitBangDevice(device) as device: device.baudrate = 9600 if state == self.ON: device.port |= int(terrariumRelayFTDI.BITBANG_ADDRESSES[str(self._address[0])], 16) else: device.port &= ~int(terrariumRelayFTDI.BITBANG_ADDRESSES[str(self._address[0])], 16) return True
#!/usr/bin/env python3 from pylibftdi import BitBangDevice from pylibftdi.driver import BITMODE_SYNCBB from time import sleep import argparse parser = argparse.ArgumentParser(description= 'Program ATMEGA162 through JTAG interface connected to an FT232R') parser.add_argument('--noverify', action='store_true', help='Do not verify after programming') parser.add_argument('elffile', help='.elf file to program in FLASH') args = parser.parse_args() dev = BitBangDevice(bitbang_mode=BITMODE_SYNCBB) TMS = 1 << 4 TDI = 1 << 2 TDO = 1 << 3 TCK = 1 << 5 dev.direction = TMS | TDI | TCK from math import ceil from enum import Enum def jtag_command(instruction, data): """Set the instruction register, shift in bits from data, return the output bits data[0] holds the least significant bits""" if not isinstance(instruction, AVR_JTAG): raise ValueError("instruction must be member of AVR_JTAG") irvalue = instruction.value[0] nbits = instruction.value[1] if isinstance(data, int):
class Ecu: def __init__(self): self.ser = Device(mode='b', lazy_open=True) def bbang(self, bba): # Take the one-byte address to "bit bang" and bang the port self.bba = bba self.bbser = BitBangDevice() self.bbser.open() self.bbser.direction = 0x01 self.bbser.port = 1 time.sleep(.5) self.bbser.port = 0 outstr = "><" sys.stdout.write('\r' + outstr) sys.stdout.flush() time.sleep(.2) bbbitmask = 1 for i in range(8): if (self.bba[0] & bbbitmask) > 0: outbit = 1 else: outbit = 0 self.bbser.port = outbit outstr = ">" + str(outbit) + outstr[1:] sys.stdout.write('\r' + outstr) sys.stdout.flush() bbbitmask = bbbitmask * 2 time.sleep(.2) self.bbser.port = 1 sys.stdout.write("\n") self.bbser.close() def initialize(self, connect): self.connect = connect if self.connect == "SLOW-0x11": self.ser.close() time.sleep(.5) self.ecuconnect = False while self.ecuconnect == False: print("Attempting ECU connect: " + self.connect ) # Bit bang the K-line bbseq = [ 0x11 ] self.bbang(bbseq) self.ser.open() self.ser.ftdi_fn.ftdi_set_line_property(8, 1, 0) self.ser.baudrate = 10400 self.ser.flush() # Wait for ECU response to bit bang waithex = [ 0x55, 0xef, 0x8f, 1 ] self.waitfor(waithex) # Wait a bit time.sleep(.026) # Send 0x70 self.send([ 0x70 ]) # 0xee means that we're talking to the ECU waithex = [ 0xee, 1 ] response = self.waitfor(waithex) if response[0] == True: self.ecuconnect = True else: print("ECU Connect Failed. Retrying.") def waitfor(self, wf): # This was used for debugging and really is only used for the init at this point. # wf should be a list with the timeout in the last element self.wf = wf isfound = False idx = 0 foundlist = [] capturebytes = [] to = self.wf[-1] timecheck = time.time() while (time.time() <= (timecheck+to)) & (isfound == False): try: recvbyte = self.recvraw(1) if recvbyte != "": recvdata = ord(recvbyte) capturebytes = capturebytes + [ recvdata ] if recvdata == self.wf[idx]: foundlist = foundlist + [ recvdata ] idx = idx + 1 else: foundlist = [] idx = 0 if idx == len(self.wf)-1: isfound = True except: print('error') break return [ isfound, foundlist, capturebytes ] def send(self, sendlist): self.sendlist = sendlist # Puts every byte in the sendlist out the serial port for i in self.sendlist: self.ser.write(chr(i)) def recvraw(self, bytes): self.bytes = bytes recvdata = self.ser.read(self.bytes) return recvdata def recv(self, bytes): self.bytes = bytes isread = False while isread == False: recvbyte = self.ser.read(self.bytes) if recvbyte != "": recvdata = recvbyte isread = True return recvdata def sendcommand(self, sendlist): # Wraps raw KWP command in a length byte and a checksum byte and hands it to send() self.sendlist = sendlist csum = 0 self.sendlist = [len(self.sendlist)] + self.sendlist csum = self.checksum(self.sendlist) self.sendlist = self.sendlist + [csum] self.send(self.sendlist) cmdval = self.commandvalidate(self.sendlist) return cmdval def commandvalidate(self, command): # Every KWP command is echoed back. This clears out these bytes. self.command = command cv = True for i in range(len(self.command)): recvdata = self.recv(1) if ord(recvdata) != self.command[i]: cv = cv & False return cv def checksum(self, checklist): # Calculates the simple checksum for the KWP command bytes. self.checklist = checklist csum = 0 for i in self.checklist: csum = csum + i csum = (csum & 0xFF) % 0xFF return csum def getresponse(self): # gets a properly formated KWP response from a command and returns the data. debugneeds = 4 numbytes = 0 while numbytes == 0: # This is a hack because sometimes responses have leading 0x00's. Why? This removes them. numbytes = ord(self.recv(1)) gr = [ numbytes ] if debug >= debugneeds: print("Get bytes: " + hex(numbytes)) for i in range(numbytes): recvdata = ord(self.recv(1)) if debug >= debugneeds: print("Get byte" + str(i) + ": " + hex(recvdata)) gr = gr + [ recvdata ] checkbyte = self.recv(1) if debug >= debugneeds: print(gr) if debug >= debugneeds: print("GR: " + hex(ord(checkbyte)) + "<-->" + hex(self.checksum(gr))) return (gr + [ ord(checkbyte) ]) def readecuid(self, paramdef): # KWP2000 command to pull the ECU ID self.paramdef = paramdef debugneeds = 4 reqserviceid = [ 0x1A ] sendlist = reqserviceid + self.paramdef if debug >= debugneeds: print( sendlist ) self.sendcommand(sendlist) response = self.getresponse() if debug >= debugneeds: print(response) return response def stopcomm(self): # KWP2000 command to tell the ECU that the communications is finished stopcommunication = [ 0x82 ] self.sendcommand(stopcommunication) response = self.getresponse() return response def startdiagsession(self, bps): # KWP2000 setup that sets the baud for the logging session self.bps = bps startdiagnosticsession = [ 0x10 ] setbaud = [ 0x86 ] #Is this the actual function of 0x86? # if self.bps == 10400: # bpsout = [ 0x?? ] # if self.bps == 14400: # bpsout = [ 0x?? ] if self.bps == 19200: bpsout = [ 0x30 ] if self.bps == 38400: bpsout = [ 0x50 ] if self.bps == 56000: bpsout = [ 0x63 ] if self.bps == 57600: bpsout = [ 0x64 ] # if self.bps == 125000: # bpsout = [ 0x?? ] sendlist = startdiagnosticsession + setbaud + bpsout self.sendcommand(sendlist) response = self.getresponse() self.ser.baudrate = self.bps time.sleep(1) return response def accesstimingparameter(self, params): # KWP2000 command to access timing parameters self.params = params accesstiming_setval = [ 0x083, 0x03 ] accesstiming = accesstiming_setval + self.params sendlist = accesstiming self.sendcommand(sendlist) response = self.getresponse() return response def readmembyaddr(self, readvals): # Function to read an area of ECU memory. debugneeds = 4 self.readvals = readvals rdmembyaddr = [ 0x23 ] sendlist = rdmembyaddr + self.readvals if debug >= debugneeds: print("readmembyaddr() sendlist: " + sendlist) self.sendcommand(sendlist) response = self.getresponse() if debug >= debugneeds: print("readmembyaddr() response: " + response) return response def writemembyaddr(self, writevals): # Function to write to an area of ECU memory. debugneeds = 4 self.writevals = writevals wrmembyaddr = [ 0x3D ] sendlist = wrmembyaddr + self.writevals if debug >= debugneeds: print("writemembyaddr() sendlist: " + sendlist) self.sendcommand(sendlist) response = self.getresponse() if debug >= debugneeds: print("writemembyaddr() response: " + response) return response def testerpresent(self): # KWP2000 TesterPresent command tp = [ 0x3E ] self.sendcommand(tp) response = self.getresponse() return response def setuplogrecord(self, logline): # KWP2000 command to access timing parameters self.logline = logline response = [] sendlist = [ 0xb7 ] # is 0xB7 the "locator?" sendlist = sendlist + [ 0x03 ] # Number of bytes per field ? sendlist = sendlist + self.logline self.sendcommand(sendlist) response = self.getresponse() return response def getlogrecord(self): # Command to request a logging record gr = [ 0xb7 ] self.sendcommand(gr) response = self.getresponse() return response def sendhexstring(self, dumpstring): # Takes a list of characters as a string, turns every two characters into a hex byte and sends it raw. # used as needed for dev/test/debug self.dumpstring = dumpstring for i in range(len(self.dumpstring)/2): self.send([ int('0x'+self.dumpstring[i*2:(i*2)+2],16) ])