#!/usr/bin/python3 #### # This is a sample program, which introduces the functions and applications of the Baby-LIN-DLL. To run this program you need the current LINWorks software and # a Baby-LIN device from Lipowsky Industrie-Elektronik GmbH. Make sure that there is a USB connection between your PC and the Baby-LIN-Device and # that a voltage of 8-26 VDC is applied to the LIN-Bus. # # Table of Contents: # 1. Display Version of Baby-LIN-DLL und Wrapper # 2. Connection with the Baby-LIN-Device # 3. Connection to the LIN-Channel # 4. Write SerialNumber to signal # 5. Excecute macro and processing MacroResultString # 6. Use of getsig/setsig for signal handling # 7. Frame registration and display of the framecallbacks # 8. Error handling #### from __future__ import unicode_literals from asyncio.windows_events import NULL from ctypes import * from hashlib import new import os, sys, argparse, six try: # import the BabyLIN Python wrapper import BabyLIN_library except ImportError as e: six.print_(e) def parse_arguments(): """ """ # get sdf file from the path where the executable is parser = argparse.ArgumentParser(description="run `main.py` on sdf file") parser.add_argument("-s", "--sdf", help="sdf file to load", default="Example.sdf") parser.add_argument("-v", "--verbose", action="count", default=0) args = parser.parse_args() return args.sdf, args.verbose def main(sdf_name, verbose): """ Standard example. """ def framecallback(handle, frame): """ frame callback to be used later.""" six.print_(frame) return 0 if verbose == 1: six.print_("Using dynamic library " + BabyLIN.BABYLIN_DLL_PATH_NAME) # create the BabyLIN class contained in BabyLIN_DLL.py BabyLIN = BabyLIN_library.create_BabyLIN() # inject BabyLIN names into local namespace, so you can, e.g. write # BLC_getVersion instead of BabyLIN.BLC_getVersion for k, v in BabyLIN.__dict__['_libNames'].items(): globals()[k] = getattr(BabyLIN, k) if verbose == 1: six.print_("Using sdf file " + sdf_name) try: six.print_("Test programm started") six.print_("#####################################") six.print_("") # ------------------------------------------------------------------------------------------------------------------------------------------------------------------------ # 1. Display Version of Baby-LIN-DLL und Wrapper # ------------------------------------------------------------------------------------------------------------------------------------------------------------------------ # Display the version of the BabyLIN DLL and the .net Wrapper six.print_("DLL and wrapper version are read out") six.print_("") dllVersion = BLC_getVersionString() wrapperVersion = BLC_getWrapperVersion() six.print_("BabyLIN version: ", dllVersion) six.print_("BabyLIN python Wrapper version: ", wrapperVersion) six.print_("") # ------------------------------------------------------------------------------------------------------------------------------------------------------------------------ # 2. Connection with the Baby-LIN-Device # ------------------------------------------------------------------------------------------------------------------------------------------------------------------------ # Search for Baby-LIN devices # The BLC_getBabyLinPortsTimeout() function is also searching for network devices # If you are using only Baby-LIN devices with USB port, you can use BLC_getBabyLinPorts() portCount = 100 # Find up to 100 devices six.print_("Search for Baby-LIN-Devices for connection...") portList = BLC_getBabyLinPorts(portCount) if portList == 0: six.print_("Could not find any Baby-LIN devices.") sys.exit(-1) six.print_(str(len(portList)) + " devices were found for the connection") six.print_("") portList = BLC_getBabyLinPortsTimout(portCount, 3000) if portList == 0: six.print_("Could not find any Baby-LIN devices.") sys.exit(-1) # In this example, we will be using the first found Baby-LIN device if len(portList) < 1: six.print_("Could not find any Baby-LIN devices.") sys.exit(-1) port = portList[0] # Open a connection to the first found BabyLIN six.print_("The connection to the first Baby-LIN-Device of the portlist is established.") handle = BLC_openPort(port) if handle == NULL: six.print_("The connection to the BabyLIN could not be opened. Please check, that the COM Port is correct.") sys.exit(-1) # Download the SDF file into the BabyLIN device six.print_("SDF download...") six.print_("") rc = BLC_loadSDF(handle, sdf_name, 1) if rc != 0: six.print_("The SDF file could not be loaded into the BabyLIN. Please check, that the filename is correct.") sys.exit(-1) # ------------------------------------------------------------------------------------------------------------------------------------------------------------------------ # 3. Connection to the LIN-Channel # ------------------------------------------------------------------------------------------------------------------------------------------------------------------------ # Get the number of available channels six.print_("Output of the channel info") channelCount = BLC_getChannelCount(handle) six.print_("available channels: " + str(channelCount)) # the example will open the first device with an included # LIN channel, download the sdf to it, start the LIN bus, # register a frame-callback and watch the incoming LIN-frames # in the callback. # open the device(s) conHandle = (handle for port in portList) # get the device's number of channels channelCount = ((BLC_getChannelCount(h), h) for h in conHandle) # among these, look for the first LIN channel: channelRange = ((range(chNr), h) for chNr, h in channelCount) # first, get the corresponding channel handles channelHandle = ((BLC_getChannelHandle(h, channelIndex), h) for r, h in channelRange for channelIndex in r) # for each channel (handle), get the channel info chInfo = ((BLC_getChannelInfo(ch), h, ch) for ch, h in channelHandle) # using the channel info, filter the LIN channels # using 'info.type == 0' conH_chH = ((h, ch) for info, h, ch in chInfo if info.type == 0) for conHandle, channelHandle in conH_chH: # for debugging, print ChannelInfo channelInfos = BLC_getChannelInfo(channelHandle) six.print_("Channel info: Name=" + str(channelInfos.name) + " , Type=" + str(channelInfos.type) + " , MaxBaudrate=" + str(channelInfos.maxbaudrate)) # start the LIN bus six.print_("Connect to channel number 1 and start the schedule number 0") six.print_("") scheduleNr = 0 rc = BLC_sendCommand(channelHandle, "start schedule " + str(scheduleNr) + ";") if rc != 0: six.print_("Could not start the LIN bus.") sys.exit(-1) # ------------------------------------------------------------------------------------------------------------------------------------------------------------------------ # 4. Write SerialNumber to signal # ------------------------------------------------------------------------------------------------------------------------------------------------------------------------ # Write Signal Serial_Number # The SDF provides the following signals: SN_Byte_0, SN_Byte_1, SN_Byte_2 ,SN_Byte_3, SN_Byte_4, SN_Byte_5, SN_Byte_6, SN_Byte_7 # With the BLCvarWrite() command the signals can all be written with one operation. The varible data_len determines the number of signals to be set. # Exactly one byte is assigned to each signal six.print_("Precessing the serial number") signal_nr = 0 data_len = 8 data = bytes([83, 78, 48, 49, 50, 51, 52, 53]) # ASCII-Code: "SN012345" rc = BLC_varWrite(channelHandle, signal_nr, data, data_len) if rc != 0: six.print_("Could not write into signal Serial_Number.") sys.exit(-1) # Read signal Serial_number for control # The BLC_varRead() command reads a certain number of signals and stores them in a byte buffer, which is passed to the function when it is called. # The number of signals to be read is determined by the variable lenght. lenght = 8 SignalValue = BLC_varRead(channelHandle, signal_nr, lenght) if SignalValue == 0: six.print_("Could not read the signal Serial_Number.") sys.exit(-1) six.print_("Serial number set via BLC_varWrite command") six.print_("") # ------------------------------------------------------------------------------------------------------------------------------------------------------------------------ # 5. Excecute macro and processing MacroResultString # ------------------------------------------------------------------------------------------------------------------------------------------------------------------------ # Execute 01_process_SerialNumber # In this macro the data from the SN_Byte signals are read out and combined to a result string. # The Baby_LIN_DLL provides a set of Baby_LIN commands which can be executed with the BLC_sendCommand(). # # The macro_exec command executes the macro with the passed macro number. The BLC command does not wait until the macro is fully executed. # This must be implemented by the user with the function BLC_macro_result. As long as the macro is still executed, the BLC function returns the value 150. six.print_("Create MacroResultString out of serial number bytes") macro_nr = 0 return_value = 0 timeout_ms = 250 rc = BLC_sendCommand(channelHandle, "macro_exec " + str(macro_nr) + ";") if rc != 0: six.print_("BLC command could not be executed.") sys.exit(-1) rc = BLC_macro_result(channelHandle, macro_nr, timeout_ms) if rc != 0: six.print_("BLC command could not be executed.") sys.exit(-1) # Get MacroResultString # When executing a macro it returns a result string after successful completion.This can be set additionally by MAcro command print. # With parameter passing the values from the signals can be put together to a result string easily. The encoding of the output can also be set, # which is shown by the two outputs in ASCII code and HEXByte code. MacroResultStringASCII = BLC_getMacroResultString(channelHandle, macro_nr) six.print_("Serial number: " + MacroResultStringASCII + "(ASCII Code)") six.print_("") # ------------------------------------------------------------------------------------------------------------------------------------------------------------------------ # 6. Use of getsig/setsig for signal handling # ------------------------------------------------------------------------------------------------------------------------------------------------------------------------ # Use of getsig and setsig with BLC_sendCommand() # The BabyLIN commands getsig and setsig are responsible for reading and setting individual signals. # The signal used is determined by the signal number. This can be found in the bus description of the SDF. # The signal_flag can be used to determine at which time or event the signal is to be read out: # signal_flag = 0x00, returns the last value written to the bus signal. # signal_flag = 0x01, reset fresh flag and wait for fresh signal value appearing on bus. # signal_flag = 0x02, return signal value as result, if fresh value is availble, otherwise returns RETCODE_OPERATION_PENDING six.print_("Set the bus signals of brightness by setsig and getsig command") signal_nr = 8 signal_flag = 0 index = 0 luminanceValue = 100 BLC_sendCommand(channelHandle, "getsig " + str(signal_nr) + " " + str(signal_flag) + ";") if rc != 0: six.print_("BLC command could not be executed.") sys.exit(-1) rc = BLC_lastAnswerHasData(channelHandle) if rc == 0: ByteValue = BLC_getAnswerByIndex(channelHandle, index) six.print_("Current luminance configuration: " + str(ord(ByteValue))) # Signal value luminance is set to 100 with BLC_sendCommand "setsig" rc = BLC_sendCommand(channelHandle, "setsig " + str(signal_nr) + " " + str(luminanceValue) + ";") if rc != 0: six.print_("BLC command could not be executed.") sys.exit(-1) # Control setsig Command with readout the Signal value again via getsig rc = BLC_sendCommand(channelHandle, "getsig " + str(signal_nr) + " " + str(signal_flag) + ";") if rc != 0: six.print_("BLC command could not be executed.") sys.exit(-1) rc = BLC_lastAnswerHasData(channelHandle) if rc == 0: ByteValue = BLC_getAnswerByIndex(channelHandle, index) six.print_("Luminance increased to 100") six.print_("Current luminance configuration: " + str(ord(ByteValue))) six.print_("") # ------------------------------------------------------------------------------------------------------------------------------------------------------------------------ # 7. Frame registration and display of the framecallbacks # ------------------------------------------------------------------------------------------------------------------------------------------------------------------------ # Here we will subscribe to get frames and write their data # The disframe command can be used to subscribe to specific frames. These are determined by the frame ID. # If you pass 0xff as parameter, a special case is executed and all frames defined in the SDf are subscribed. # The frames are defined as a structure in the DLL and thus offer the possibility to display all information, such as the FrameID or the timestamp. six.print_("Subscribe to Frames") # Subscribe to frames FrameIDForAllFrames = 0xff rc = BLC_sendCommand(channelHandle, "disframe " + str(FrameIDForAllFrames) + " 1;") if rc != 0: six.print_("BLC command could not be executed.") sys.exit(-1) # the output of the callback will fill up the screen quickly # press to see the incoming frames, and again # to stop the output try: p = "Starting frame callback now...\n" p += "Press to start and stop" input(p) except Exception as e: pass # register the frame-callback BLC_registerFrameCallback(channelHandle, framecallback) try: input("") # waiting for the next except Exception as e: pass # de-register the frame-callback BLC_registerFrameCallback(channelHandle, None) # stop the LIN-bus BLC_sendCommand(channelHandle, "stop;") # close all devices. end of example. BLC_closeAll() break # ------------------------------------------------------------------------------------------------------------------------------------------------------------------------ # 8. Error handling # ------------------------------------------------------------------------------------------------------------------------------------------------------------------------ except BabyLIN.BabyLINException as e: six.print_(e) if __name__ == '__main__': sdf, verbose = parse_arguments() try: main(sdf, verbose) except KeyboardInterrupt: pass