Уведомления

Группа в Telegram: @pythonsu

#1 Сен. 4, 2015 17:48:48

eleks
Зарегистрирован: 2014-08-14
Сообщения: 24
Репутация: +  0  -
Профиль   Отправить e-mail  

PCAN-USB подключение

Давно хочу приступить к изучению Python, а тут и проблема подходящая попалась - подключить PCAN-USB адаптер. На сайте производителя есть различные примеры под Windows, в том числе и на Python 2.6
Конечно это, скорей всего, не самый удачный материал для начинания, но ничего более простого и актуального на данный момент нет.
В архиве три файла:
PCANBasic.py
PCANBasicExample - (Read Event).pyw
PCANBasicExample.pyw
Судя по названиям, первый является некой основой, а два других, собственно, примеры.
Переименовываю PCANBasicExample.pyw в PCANBasicExample.py и запускаю его. В результате получаю список ошибок:
Traceback (most recent call last):
File “C:\Users\v_volodin\Documents\bp_unt\Soft\USB-CAN\Python 2.6\PCANBasicExample.py”, line 2205, in <module>
RunMain(root)
File “C:\Users\v_volodin\Documents\bp_unt\Soft\USB-CAN\Python 2.6\PCANBasicExample.py”, line 2188, in RunMain
basicExl = PCANBasicExample(root)

###*****************************************************************
### ROOT
###*****************************************************************
### Loop-Functionallity  
def RunMain(root):
    global basicExl
    # Creates a PCAN-Basic application
    #
    basicExl = PCANBasicExample(root) # line 2188 ################
    
    # Runs the Application / loop-start
    #
    basicExl.loop()
    
    # Application's destrution / loop-end
    #
    basicExl.destroy()
if __name__ == '__main__':
    # Creates the Tkinter-extension Root
    #
    root = Tix.Tk()
    # Uses the root to launch the PCAN-Basic Example application
    # 
    RunMain(root) # line 2205 ###################################
###*****************************************************************
File “C:\Users\v_volodin\Documents\bp_unt\Soft\USB-CAN\Python 2.6\PCANBasicExample.py”, line 275, in __init__
self.InitializeBasicComponents()
class PCANBasicExample(object):
    ## Constructor
    ##
    def __init__(self, parent):
        # Parent's configuration       
        self.m_Parent = parent
        self.m_Parent.wm_title("PCAN-Basic Example")
        self.m_Parent.resizable(False,False)
        self.m_Parent.protocol("WM_DELETE_WINDOW",self.Form_OnClosing)
               
        # Frame's configuration
        self.m_Frame =Frame(self.m_Parent)
        self.m_Frame.grid(row=0, column=0, padx=5, pady=2, sticky="nwes")
        # Example's configuration
        self.InitializeBasicComponents() # line 275 ###################################
        self.CenterTheWindow()
        self.InitializeWidgets()
        self.ConfigureLogFile()
        self.SetConnectionStatus(False)
File “C:\Users\v_volodin\Documents\bp_unt\Soft\USB-CAN\Python 2.6\PCANBasicExample.py”, line 338, in InitializeBasicComponents
self.m_objPCANBasic = PCANBasic()
File “C:\Users\v_volodin\Documents\bp_unt\Soft\USB-CAN\Python 2.6\PCANBasic.py”, line 327, in __init__
self.__m_dllBasic = windll.LoadLibrary(“PCANBasic”)
    ## Message loop
    ##
    def loop(self):
        # This is an explict replacement for _tkinter mainloop()
        # It lets catch keyboard interrupts easier, and avoids
        # the 20 msec. dead sleep() which burns a constant CPU.
        while self.exit < 0:
            # There are 2 whiles here. The outer one lets you continue
            # after a ^C interrupt.
            try:
                # This is the replacement for _tkinter mainloop()
                # It blocks waiting for the next Tcl event using select.
                while self.exit < 0:
                    # prevent UI concurrency errors with timers (read and
                    # display)
                    with self._lock:                    
                        self.m_Parent.tk.dooneevent(TCL_ALL_EVENTS)
            except SystemExit:
                # Tkinter uses SystemExit to exit
                self.exit = 1
                return
            except KeyboardInterrupt:
                if tkMessageBox.askquestion ('Interrupt', 'Really Quit?') == 'yes':
                    # self.tk.eval('exit')
                    self.exit = 1
                    return
                continue
            except:
                # Otherwise it's some other error
                t, v, tb = sys.exc_info()
                text = ""
                for line in traceback.format_exception(t,v,tb):
                    text += line + '\n'
                try: tkMessageBox.showerror ('Error', text)
                except: pass
                self.exit = 1
                raise SystemExit, 1            
# line 327 ###################################       
################################################################################################################################################
### Help functions
################################################################################################################################################
    ## Initializes app members
    ##
    def InitializeBasicComponents(self):
        self.m_Width =760
        self.m_Height = 650
        self.exit = -1        
        self.m_objPCANBasic = PCANBasic() # line 338 #############################       
        self.m_PcanHandle = PCAN_NONEBUS
        self.m_LastMsgsList = []
        self.m_IsFD = False
    
        self._lock = threading.RLock()

File “C:\Python27\lib\ctypes\__init__.py”, line 443, in LoadLibrary
return self._dlltype(name)
    def InitializeConnectionWidgets(self):
        # Control variables
        #
        self.m_BaudrateLA = StringVar(value="Baudrate:")
        self.m_HwTypeLA = StringVar(value="Hardware Type:")
        self.m_IOPortLA = StringVar(value="I/O Port:")
        self.m_InterruptLA = StringVar(value="Interrupt:")
        self.m_CanFDCHB = IntVar(value=0);
        self.m_BitrateTXT = StringVar(value="f_clock_mhz=20, nom_brp=5, nom_tseg1=2, nom_tseg2=1, nom_sjw=1, data_brp=2, data_tseg1=3, data_tseg2=1, data_sjw=1")
        
        Label(self.gbConnection, anchor=W, text="Hardware:").grid(row=0, sticky=W)
        self.cbbChannel = Tix.ComboBox(self.gbConnection, command=self.cbbChannel_SelectedIndexChanged)
        self.cbbChannel.subwidget('entry')['width'] = 18
        self.cbbChannel.subwidget('listbox')['width'] = 18 # line 338 ###############
        self.cbbChannel.grid(row=1,column=0,sticky=W) 
File “C:\Python27\lib\ctypes\__init__.py”, line 365, in __init__
self._handle = _dlopen(self._name, mode)
        self.m_BAUDRATES = {'1 MBit/sec':PCAN_BAUD_1M, '800 kBit/sec':PCAN_BAUD_800K, '500 kBit/sec':PCAN_BAUD_500K, '250 kBit/sec':PCAN_BAUD_250K,
                            '125 kBit/sec':PCAN_BAUD_125K, '100 kBit/sec':PCAN_BAUD_100K, '95,238 kBit/sec':PCAN_BAUD_95K, '83,333 kBit/sec':PCAN_BAUD_83K,
                            '50 kBit/sec':PCAN_BAUD_50K, '47,619 kBit/sec':PCAN_BAUD_47K, '33,333 kBit/sec':PCAN_BAUD_33K, '20 kBit/sec':PCAN_BAUD_20K,
                            '10 kBit/sec':PCAN_BAUD_10K, '5 kBit/sec':PCAN_BAUD_5K} # line 365 ##########
WindowsError: The specified module could not be found
К сожалению не могу разобраться с этими ошибками.

Офлайн

#2 Сен. 4, 2015 19:42:08

PooH
От:
Зарегистрирован: 2006-12-05
Сообщения: 1948
Репутация: +  72  -
Профиль   Отправить e-mail  

PCAN-USB подключение

Похоже что-то не установили из драйверов. Программа не может загрузить PCANBasic.dll.



Вот здесь один из первых отарков съел лаборанта. Это был такой умный отарк, что понимал даже теорию относительности. Он разговаривал с лаборантом, а потом бросился на него и загрыз…

Отредактировано PooH (Сен. 4, 2015 19:42:55)

Офлайн

#3 Сен. 4, 2015 22:47:55

eleks
Зарегистрирован: 2014-08-14
Сообщения: 24
Репутация: +  0  -
Профиль   Отправить e-mail  

PCAN-USB подключение

PooH
Похоже что-то не установили из драйверов. Программа не может загрузить PCANBasic.dll.
Спасибо за подсказку! Сейчас запустилось. Теперь легче, вижу что что-то работает. Буду разбираться.

Офлайн

#4 Сен. 9, 2015 10:41:35

eleks
Зарегистрирован: 2014-08-14
Сообщения: 24
Репутация: +  0  -
Профиль   Отправить e-mail  

PCAN-USB подключение

Слишком сильны стереотипы. Похоже уже сломал голову
Не удалось найти краткого описания Python, способного ответить на текущие вопросы, связанные с исследуемой программой. Сплошные фолианты под 1000 страниц и ни какой конкретики.
Все непонимания пока касаются общей структуре программы. Например, в Си всё ясно - основная программа, это функция main(). За пределами этой функции могут находится другие функции, а также объявления переменных и констант (как-то так).
Теперь, что касается рассматриваемой программы. Ссылки есть выше, но попытаюсь вставить её код в сообщение.

# -*- coding: cp1252 -*-
######################################################################
#  PCAN-Basic Example
#
#  ~~~~~~~~~~~~
#
#  ------------------------------------------------------------------
#  Author : Keneth Wagner
#  Language: Python 2.7
#  ------------------------------------------------------------------
#
#  Copyright (C) 1999-2015  PEAK-System Technik GmbH, Darmstadt
######################################################################
from PCANBasic import *        ## PCAN-Basic library import
## Imports for UI
##
from Tkinter import *          ## TK UI library
import Tix                     ## TK extensions library
import tkMessageBox            ## Simple-Messages library
import traceback               ## Error-Tracing library
import string                  ## String functions
import tkFont                  ## Font-Management library
import time                    ## Time-related library
import threading               ## Threading-based Timer library
TCL_DONT_WAIT           = 1<<1
TCL_WINDOW_EVENTS       = 1<<2
TCL_FILE_EVENTS         = 1<<3
TCL_TIMER_EVENTS        = 1<<4
TCL_IDLE_EVENTS         = 1<<5
TCL_ALL_EVENTS          = 0
COL_TYPE = 0
COL_ID = 1
COL_LENGTH = 2
COL_COUNT = 3
COL_TIME = 4
COL_DATA = 5
## Convert a CAN DLC value into the actual data length of the CAN/CAN-FD frame.
##
def GetLengthFromDLC(dlc, isSTD):
    if dlc <= 8:
        return dlc
    
    if isSTD :
        return 8
    
    if dlc == 9:
        return 12
    elif dlc == 10:
        return 16
    elif dlc == 11:
        return 20
    elif dlc == 12:
        return 24
    elif dlc == 13:
        return 32
    elif dlc == 14:
        return 48
    elif dlc == 15:
        return 64
    
    return dlc
    
###*****************************************************************
### Timer class
###*****************************************************************
class TimerRepeater(object):
    """
    A simple timer implementation that repeats itself
    """
    # Constructor
    #
    def __init__(self, name, interval, target, args=[], kwargs={}):
        """
        Creates a timer.
        Parameters:
            name        name of the thread
            interval    interval in second between execution of target
            target      function that is called every 'interval' seconds
            args        non keyword-argument list for target function
            kwargs      keyword-argument list for target function
        """
        # define thread and stopping thread event
        self._name = name
        self._thread = None
        self._event = None
        # initialize target and its arguments
        self._target = target
        self._args = args
        self._kwargs = kwargs
        # initialize timer
        self._interval = interval
        self._bStarted = False
    # Runs the thread that emulates the timer
    #
    def _run(self):
        """
        Runs the thread that emulates the timer.
        Returns:
            None
        """
        while not self._event.wait(self._interval):
            self._target(*self._args, **self._kwargs)
    # Starts the timer
    #
    def start(self):
        """
        Starts the timer
        Returns:
            None
        """
        # avoid multiple start calls
        if (self._thread == None):
            self._event = threading.Event()
            self._thread = threading.Thread(None, self._run, self._name)
            self._thread.start()
    # Stops the timer
    #
    def stop(self):
        """
        Stops the timer
        Returns:
            None
        """
        if (self._thread != None):
            self._event.set()
            self._thread = None
###*****************************************************************
### Message Status structure used to show CAN Messages
### in a ListView
###*****************************************************************
class MessageStatus(object):
    def __init__(self, canMsg = TPCANMsgFD(), canTimestamp = TPCANTimestampFD(), listIndex = -1):
        self.__m_Msg = canMsg
        self.__m_TimeStamp = canTimestamp
        self.__m_OldTimeStamp = canTimestamp
        self.__m_iIndex = listIndex
        self.__m_iCount = 1
        self.__m_bShowPeriod = True
        self.__m_bWasChanged = False
    def Update(self,canMsg,canTimestamp):
        self.__m_Msg = canMsg
        self.__m_OldTimeStamp = self.__m_TimeStamp
        self.__m_TimeStamp = canTimestamp
        self.__m_bWasChanged = True
        self.__m_iCount = self.__m_iCount + 1      
    @property
    def ShowingPeriod(self):
        return self.__m_bShowPeriod
    @ShowingPeriod.setter
    def ShowingPeriod(self, value):
        if self.__m_bShowPeriod ^ value:
            self.__m_bShowPeriod = value
            self.__m_bWasChanged = True
    @property
    def MarkedAsUpdated(self):
        return self.__m_bWasChanged
    @MarkedAsUpdated.setter
    def MarkedAsUpdated(self, value):
        self.__m_bWasChanged = value
    @property
    def TypeString(self):        
        if (self.__m_Msg.MSGTYPE & PCAN_MESSAGE_STATUS.value) == PCAN_MESSAGE_STATUS.value:
            return 'STATUS'
        
        if (self.__m_Msg.MSGTYPE & PCAN_MESSAGE_EXTENDED.value) == PCAN_MESSAGE_EXTENDED.value:
            strTemp = 'EXT'
        else:
            strTemp = 'STD'
        if (self.__m_Msg.MSGTYPE & PCAN_MESSAGE_RTR.value) == PCAN_MESSAGE_RTR.value:
            strTemp += '/RTR'
        else:
            if (self.__m_Msg.MSGTYPE > PCAN_MESSAGE_EXTENDED.value):
                strTemp += ' ['
                if (self.__m_Msg.MSGTYPE & PCAN_MESSAGE_FD.value) == PCAN_MESSAGE_FD.value:
                    strTemp += ' FD'
                if (self.__m_Msg.MSGTYPE & PCAN_MESSAGE_BRS.value) == PCAN_MESSAGE_BRS.value:                    
                    strTemp += ' BRS'
                if (self.__m_Msg.MSGTYPE & PCAN_MESSAGE_ESI.value) == PCAN_MESSAGE_ESI.value:
                    strTemp += ' ESI'
                strTemp += ' ]'
                
        return strTemp
    
    @property
    def TimeString(self):
        fTime = self.__m_TimeStamp.value / 1000.0
        if self.__m_bShowPeriod:
            fTime -= (self.__m_OldTimeStamp.value / 1000.0)
        return '%.1f' %fTime
    @property
    def IdString(self):
        if (self.__m_Msg.MSGTYPE & PCAN_MESSAGE_EXTENDED.value) == PCAN_MESSAGE_EXTENDED.value:
            return '%.8X' %self.__m_Msg.ID
        else:
            return '%.3X' %self.__m_Msg.ID
    @property
    def DataString(self):
        strTemp = ''
        if (self.__m_Msg.MSGTYPE & PCAN_MESSAGE_RTR.value) == PCAN_MESSAGE_RTR.value:
            return 'Remote Request'
        else:
            for i in range(GetLengthFromDLC(self.__m_Msg.DLC, not (self.__m_Msg.MSGTYPE & PCAN_MESSAGE_FD.value))):                
                strTemp += '%.2X ' % self.__m_Msg.DATA[i]
        return strTemp
    @property
    def CANMsg(self):
        return self.__m_Msg
    @property
    def Timestamp(self):
        return self.__m_TimeStamp
    @property
    def Position(self):
        return self.__m_iIndex
    @property
    def Count(self):
        return self.__m_iCount
###*****************************************************************
###*****************************************************************
### PCAN-basic Example app
###*****************************************************************
class PCANBasicExample(object):
    ## Constructor
    ##
    def __init__(self, parent):
        # Parent's configuration       
        self.m_Parent = parent
        self.m_Parent.wm_title("PCAN-Basic Example")
        self.m_Parent.resizable(False,False)
        self.m_Parent.protocol("WM_DELETE_WINDOW",self.Form_OnClosing)
               
        # Frame's configuration
        self.m_Frame =Frame(self.m_Parent)
        self.m_Frame.grid(row=0, column=0, padx=5, pady=2, sticky="nwes")
        # Example's configuration
        self.InitializeBasicComponents()
        self.CenterTheWindow()
        self.InitializeWidgets()
        self.ConfigureLogFile()
        self.SetConnectionStatus(False)
    ## Destructor
    ##
    def destroy (self):
        self.m_Parent.destroy()        
        
    ## Message loop
    ##
    def loop(self):
        # This is an explict replacement for _tkinter mainloop()
        # It lets catch keyboard interrupts easier, and avoids
        # the 20 msec. dead sleep() which burns a constant CPU.
        while self.exit < 0:
            # There are 2 whiles here. The outer one lets you continue
            # after a ^C interrupt.
            try:
                # This is the replacement for _tkinter mainloop()
                # It blocks waiting for the next Tcl event using select.
                while self.exit < 0:
                    # prevent UI concurrency errors with timers (read and
                    # display)
                    with self._lock:                    
                        self.m_Parent.tk.dooneevent(TCL_ALL_EVENTS)
            except SystemExit:
                # Tkinter uses SystemExit to exit
                self.exit = 1
                return
            except KeyboardInterrupt:
                if tkMessageBox.askquestion ('Interrupt', 'Really Quit?') == 'yes':
                    # self.tk.eval('exit')
                    self.exit = 1
                    return
                continue
            except:
                # Otherwise it's some other error
                t, v, tb = sys.exc_info()
                text = ""
                for line in traceback.format_exception(t,v,tb):
                    text += line + '\n'
                try: tkMessageBox.showerror ('Error', text)
                except: pass
                self.exit = 1
                raise SystemExit, 1            
        
################################################################################################################################################
### Help functions
################################################################################################################################################
    ## Initializes app members
    ##
    def InitializeBasicComponents(self):
        self.m_Width =760
        self.m_Height = 650
        self.exit = -1        
        self.m_objPCANBasic = PCANBasic()
        self.m_PcanHandle = PCAN_NONEBUS
        self.m_LastMsgsList = []
        self.m_IsFD = False
    
        self._lock = threading.RLock()
        
        self.m_CHANNELS = {'PCAN_DNGBUS1':PCAN_DNGBUS1, 'PCAN_PCCBUS1':PCAN_PCCBUS1, 'PCAN_PCCBUS2':PCAN_PCCBUS2, 'PCAN_ISABUS1':PCAN_ISABUS1, 
                           'PCAN_ISABUS2':PCAN_ISABUS2, 'PCAN_ISABUS3':PCAN_ISABUS3, 'PCAN_ISABUS4':PCAN_ISABUS4, 'PCAN_ISABUS5':PCAN_ISABUS5,
                           'PCAN_ISABUS6':PCAN_ISABUS6, 'PCAN_ISABUS7':PCAN_ISABUS7, 'PCAN_ISABUS8':PCAN_ISABUS8, 'PCAN_PCIBUS1':PCAN_PCIBUS1,
                           'PCAN_PCIBUS2':PCAN_PCIBUS2, 'PCAN_PCIBUS3':PCAN_PCIBUS3, 'PCAN_PCIBUS4':PCAN_PCIBUS4, 'PCAN_PCIBUS5':PCAN_PCIBUS5,
                           'PCAN_PCIBUS6':PCAN_PCIBUS6, 'PCAN_PCIBUS7':PCAN_PCIBUS7, 'PCAN_PCIBUS8':PCAN_PCIBUS8, 'PCAN_PCIBUS9':PCAN_PCIBUS9,
                           'PCAN_PCIBUS10':PCAN_PCIBUS10, 'PCAN_PCIBUS11':PCAN_PCIBUS11, 'PCAN_PCIBUS12':PCAN_PCIBUS12, 'PCAN_PCIBUS13':PCAN_PCIBUS13,
                           'PCAN_PCIBUS14':PCAN_PCIBUS14, 'PCAN_PCIBUS15':PCAN_PCIBUS15, 'PCAN_PCIBUS16':PCAN_PCIBUS16, 'PCAN_USBBUS1':PCAN_USBBUS1,
                           'PCAN_USBBUS2':PCAN_USBBUS2, 'PCAN_USBBUS3':PCAN_USBBUS3, 'PCAN_USBBUS4':PCAN_USBBUS4, 'PCAN_USBBUS5':PCAN_USBBUS5,
                           'PCAN_USBBUS6':PCAN_USBBUS6, 'PCAN_USBBUS7':PCAN_USBBUS7, 'PCAN_USBBUS8':PCAN_USBBUS8, 'PCAN_USBBUS9':PCAN_USBBUS9,
                           'PCAN_USBBUS10':PCAN_USBBUS10, 'PCAN_USBBUS11':PCAN_USBBUS11, 'PCAN_USBBUS12':PCAN_USBBUS12, 'PCAN_USBBUS13':PCAN_USBBUS13,
                           'PCAN_USBBUS14':PCAN_USBBUS14, 'PCAN_USBBUS15':PCAN_USBBUS15, 'PCAN_USBBUS16':PCAN_USBBUS16, 'PCAN_LANBUS1':PCAN_LANBUS1,
                           'PCAN_LANBUS2':PCAN_LANBUS2, 'PCAN_LANBUS3':PCAN_LANBUS3, 'PCAN_LANBUS4':PCAN_LANBUS4, 'PCAN_LANBUS5':PCAN_LANBUS5,
                           'PCAN_LANBUS6':PCAN_LANBUS6, 'PCAN_LANBUS7':PCAN_LANBUS7, 'PCAN_LANBUS8':PCAN_LANBUS8, 'PCAN_LANBUS9':PCAN_LANBUS9,
                           'PCAN_LANBUS10':PCAN_LANBUS10, 'PCAN_LANBUS11':PCAN_LANBUS11, 'PCAN_LANBUS12':PCAN_LANBUS12, 'PCAN_LANBUS13':PCAN_LANBUS13,
                           'PCAN_LANBUS14':PCAN_LANBUS14, 'PCAN_LANBUS15':PCAN_LANBUS15, 'PCAN_LANBUS16':PCAN_LANBUS16}
        self.m_BAUDRATES = {'1 MBit/sec':PCAN_BAUD_1M, '800 kBit/sec':PCAN_BAUD_800K, '500 kBit/sec':PCAN_BAUD_500K, '250 kBit/sec':PCAN_BAUD_250K,
                            '125 kBit/sec':PCAN_BAUD_125K, '100 kBit/sec':PCAN_BAUD_100K, '95,238 kBit/sec':PCAN_BAUD_95K, '83,333 kBit/sec':PCAN_BAUD_83K,
                            '50 kBit/sec':PCAN_BAUD_50K, '47,619 kBit/sec':PCAN_BAUD_47K, '33,333 kBit/sec':PCAN_BAUD_33K, '20 kBit/sec':PCAN_BAUD_20K,
                            '10 kBit/sec':PCAN_BAUD_10K, '5 kBit/sec':PCAN_BAUD_5K}
        self.m_HWTYPES = {'ISA-82C200':PCAN_TYPE_ISA, 'ISA-SJA1000':PCAN_TYPE_ISA_SJA, 'ISA-PHYTEC':PCAN_TYPE_ISA_PHYTEC, 'DNG-82C200':PCAN_TYPE_DNG,
                         'DNG-82C200 EPP':PCAN_TYPE_DNG_EPP, 'DNG-SJA1000':PCAN_TYPE_DNG_SJA, 'DNG-SJA1000 EPP':PCAN_TYPE_DNG_SJA_EPP}
        self.m_IOPORTS = {'0100':0x100, '0120':0x120, '0140':0x140, '0200':0x200, '0220':0x220, '0240':0x240, '0260':0x260, '0278':0x278, 
                          '0280':0x280, '02A0':0x2A0, '02C0':0x2C0, '02E0':0x2E0, '02E8':0x2E8, '02F8':0x2F8, '0300':0x300, '0320':0x320,
                          '0340':0x340, '0360':0x360, '0378':0x378, '0380':0x380, '03BC':0x3BC, '03E0':0x3E0, '03E8':0x3E8, '03F8':0x3F8}
        self.m_INTERRUPTS = {'3':3, '4':4, '5':5, '7':7, '9':9, '10':10, '11':11, '12':12, '15':15}
        self.m_PARAMETERS = {'USBs Device Number':PCAN_DEVICE_NUMBER, 'USB/PC-Cards 5V Power':PCAN_5VOLTS_POWER,
                             'Auto-reset on BUS-OFF':PCAN_BUSOFF_AUTORESET, 'CAN Listen-Only':PCAN_LISTEN_ONLY,
                             'Debugs Log':PCAN_LOG_STATUS,'Receive Status':PCAN_RECEIVE_STATUS,
                             'CAN Controller Number':PCAN_CONTROLLER_NUMBER,'Trace File':PCAN_TRACE_STATUS,
                             'Channel Identification (USB)':PCAN_CHANNEL_IDENTIFYING,'FD Capability':PCAN_CHANNEL_FEATURES,
                             'Bit rate Adaptation':PCAN_BITRATE_ADAPTING,'Get Bit rate Information':PCAN_BITRATE_INFO,
                             'Get Bit rate FD Information':PCAN_BITRATE_INFO_FD, 'Get CAN Nominal Speed Bit/s':PCAN_BUSSPEED_NOMINAL,
                             'Get CAN Data Speed Bit/s':PCAN_BUSSPEED_DATA, 'Get IP Address':PCAN_IP_ADDRESS}
        
    ## Initializes the complete UI
    ##
    def InitializeWidgets(self):
        # Connection groupbox
        self.gbConnection = LabelFrame(self.m_Frame, height=70, width = 745, text=" Connection ")
        self.gbConnection.grid_propagate(0)
        self.gbConnection.grid(row=0, column = 0, padx=2, pady=2)
        self.InitializeConnectionWidgets()
        
        ## Message Filtering groupbox
        self.gbMsgFilter = LabelFrame(self.m_Frame, height=70, width = 745, text=" Message Filtering ")
        self.gbMsgFilter.grid_propagate(0)
        self.gbMsgFilter.grid(row=1, column = 0, padx=2, pady=2)
        self.InitializeFilteringWidgets()
        ## Configuration Parameters groupbox
        self.gbParameters = LabelFrame(self.m_Frame, height=70, width = 745, text=" Configuration Parameters ")
        self.gbParameters.grid_propagate(0)
        self.gbParameters.grid(row=2, column = 0, padx=2, pady=2)
        self.InitializeConfigurationWidgets()
        ## Messages Reading groupbox
        self.gbReading = LabelFrame(self.m_Frame, height=160, width = 745, text=" Messages Reading ")
        self.gbReading.grid_propagate(0)
        self.gbReading.grid(row=3, column = 0, padx=2, pady=2)
        self.InitializeReadingWidgets()
        ## Messages Writing groupbox
        self.gbWriting = LabelFrame(self.m_Frame, height=150, width = 745, text=" Write Messages ")
        self.gbWriting.grid_propagate(0)
        self.gbWriting.grid(row=4, column = 0, padx=2, pady=2)
        self.InitializeWritingWidgets()
        ## Information groupbox
        self.gbInfo = LabelFrame(self.m_Frame, height=100, width = 745, text=" Information ")
        self.gbInfo.grid_propagate(0)
        self.gbInfo.grid(row=5, column = 0, padx=2, pady=2)
        self.InitializeInformationWidgets()
        
        self.btnHwRefresh.invoke()
    ## Initializes controls and variables in the groupbox "Connection"
    ##
    def InitializeConnectionWidgets(self):
        # Control variables
        #
        self.m_BaudrateLA = StringVar(value="Baudrate:")
        self.m_HwTypeLA = StringVar(value="Hardware Type:")
        self.m_IOPortLA = StringVar(value="I/O Port:")
        self.m_InterruptLA = StringVar(value="Interrupt:")
        self.m_CanFDCHB = IntVar(value=0);
        self.m_BitrateTXT = StringVar(value="f_clock_mhz=20, nom_brp=5, nom_tseg1=2, nom_tseg2=1, nom_sjw=1, data_brp=2, data_tseg1=3, data_tseg2=1, data_sjw=1")
        
        Label(self.gbConnection, anchor=W, text="Hardware:").grid(row=0, sticky=W)
        self.cbbChannel = Tix.ComboBox(self.gbConnection, command=self.cbbChannel_SelectedIndexChanged)
        self.cbbChannel.subwidget('entry')['width'] = 18
        self.cbbChannel.subwidget('listbox')['width'] = 18
        self.cbbChannel.grid(row=1,column=0,sticky=W)        
        
        self.btnHwRefresh = Button(self.gbConnection, text="Refresh", command=self.btnHwRefresh_Click)
        self.btnHwRefresh.grid(row=1, column=1, sticky=W)
        self.txtBitrate = Entry(self.gbConnection, width = 63, textvariable=self.m_BitrateTXT)
                
        Label(self.gbConnection, anchor=W, textvariable=self.m_BaudrateLA).grid(row=0, column=2, sticky=W)
        self.cbbBaudrates = Tix.ComboBox(self.gbConnection)
        self.cbbBaudrates.subwidget('entry')['width'] = 14
        self.cbbBaudrates.subwidget('listbox')['width'] = 14
        self.cbbBaudrates.grid(row=1,column=2,sticky=W)
        for name, value in self.m_BAUDRATES.iteritems(): self.cbbBaudrates.insert(Tix.END,name)
        self.cbbBaudrates['selection']='500 kBit/sec'
                       
        Label(self.gbConnection, anchor=W, textvariable=self.m_HwTypeLA).grid(row=0, column=3, sticky=W)
        self.cbbHwType = Tix.ComboBox(self.gbConnection)
        self.cbbHwType.subwidget('entry')['width'] = 16
        self.cbbHwType.subwidget('listbox')['width'] = 16        
        self.cbbHwType.grid(row=1,column=3,sticky=W)
        for name, value in self.m_HWTYPES.iteritems(): self.cbbHwType.insert(Tix.END,name)
        self.cbbHwType['selection']='ISA-82C200'
        
        Label(self.gbConnection, anchor=W, textvariable=self.m_IOPortLA).grid(row=0, column=4, sticky=W)        
        self.cbbIO = Tix.ComboBox(self.gbConnection)
        self.cbbIO.subwidget('entry')['width'] = 5
        self.cbbIO.subwidget('listbox')['width'] = 5
        self.cbbIO.grid(row=1,column=4,sticky=W)
        for name, value in self.m_IOPORTS.iteritems(): self.cbbIO.insert(Tix.END,name)
        self.cbbIO['selection']=self.cbbIO.pick(0)        
        
        Label(self.gbConnection, anchor=W,width=13, textvariable=self.m_InterruptLA).grid(row=0, column=5, sticky=W)
        self.cbbInterrupt = Tix.ComboBox(self.gbConnection)
        self.cbbInterrupt.subwidget('entry')['width'] = 5
        self.cbbInterrupt.subwidget('listbox')['width'] = 5
        self.cbbInterrupt.grid(row=1,column=5, sticky=W)
        for name, value in self.m_INTERRUPTS.iteritems(): self.cbbInterrupt.insert(Tix.END,name)
        self.cbbInterrupt['selection']=self.cbbInterrupt.pick(0)
        Label(self.gbConnection, anchor=W,width=10, text="").grid(row=0, column=6, sticky=W)
        self.chbCanFD = Checkbutton(self.gbConnection, text="CAN-FD", variable=self.m_CanFDCHB, command=self.chbCanFD_CheckedChanged)
        self.chbCanFD.grid(row=1,column=6, padx=0, pady=0)
        self.btnInit = Button(self.gbConnection, width=8, text="Initialize", command= self.btnInit_Click)
        self.btnInit.grid(row=0, column=7, sticky=W)
        self.btnRelease = Button(self.gbConnection, width= 8, state=DISABLED, text="Release", command= self.btnRelease_Click)
        self.btnRelease.grid(row=1, column=7, sticky=W)        
  
    ## Initializes controls and variables in the groupbox "Message Filtering"
    ##
    def InitializeFilteringWidgets(self):
        # Control variables
        #
        self.m_FilteringRDB = IntVar(value=1)
        self.m_FilterExtCHB = IntVar(value=0)
        self.m_IdToNUD = StringVar(value="2047")
        self.m_IdFromNUD = StringVar(value="0");
        # Controls
        #
        Label(self.gbMsgFilter, anchor=W, text="From:").grid(row=0, column=4, sticky=W)
        Label(self.gbMsgFilter, anchor=W, width=16, text="To:").grid(row=0, column=5, sticky=W)
        
        self.chbFilterExt = Checkbutton(self.gbMsgFilter, text="Extended Frame", variable=self.m_FilterExtCHB, command=self.chbFilterExt_CheckedChanged)
        self.chbFilterExt.grid(row=1,column=0, padx=0, pady=2)
        self.rdbFilterOpen = Radiobutton(self.gbMsgFilter, text="Open", value = 1, variable=self.m_FilteringRDB)      
        self.rdbFilterOpen.grid(row=1,column=1, padx=0, pady=2)
        self.rdbFilterClose = Radiobutton(self.gbMsgFilter, text="Close", value = 0, variable=self.m_FilteringRDB)        
        self.rdbFilterClose.grid(row=1,column=2, padx=0, pady=2)
        self.rdbFilterCustom = Radiobutton(self.gbMsgFilter, anchor=W, width=20, text="Custom (expand)", value = 2, variable=self.m_FilteringRDB)
        self.rdbFilterCustom.grid(row=1,column=3, padx=0, pady=2, sticky=W)
        self.nudIdFrom = Spinbox(self.gbMsgFilter, width=10, from_=0, to=0x7FF, textvariable=self.m_IdFromNUD)
        self.nudIdFrom.grid(row=1, column=4,padx=0, pady=2)
        self.nudIdTo = Spinbox(self.gbMsgFilter, width=10, from_=0, to=0x7FF, textvariable=self.m_IdToNUD)
        self.nudIdTo.grid(row=1, column=5,padx=5, pady=2, sticky=W)
        self.btnFilterApply = Button(self.gbMsgFilter, width = 8, state=DISABLED, text = "Apply", command=self.btnFilterApply_Click)
        self.btnFilterApply.grid(row=1, padx = 5, column=6, sticky=W)
        self.btnFilterQuery = Button(self.gbMsgFilter, width = 8, state=DISABLED, text = "Query", command=self.btnFilterQuery_Click)
        self.btnFilterQuery.grid(row=1, column=7, sticky=W)
        self.rdbFilterOpen.select()
    ## Initializes controls and variables in the groupbox "Configuration Parameters"
    ##
    def InitializeConfigurationWidgets(self):
        # Control variables
        #        
        self.m_ConfigurationRDB = IntVar(value=1)
        self.m_DeviceIdNUD = StringVar(value="0");
        # Controls
        #        
        Label(self.gbParameters, anchor=W, text="Parameter:").grid(row=0, column=0, sticky=W)
        self.cbbParameter = Tix.ComboBox(self.gbParameters, command=self.cbbParameter_SelectedIndexChanged)
        self.cbbParameter.subwidget('entry')['width'] = 30
        self.cbbParameter.subwidget('listbox')['width'] = 30
        self.cbbParameter.subwidget('listbox')['height'] = 6
        self.cbbParameter.grid(row=1,column=0,sticky=W)
        for name, value in self.m_PARAMETERS.iteritems(): self.cbbParameter.insert(Tix.END,name)
        self.cbbParameter.bind("<<ComboboxSelected>>",self.cbbParameter_SelectedIndexChanged)
        self.cbbParameter['selection'] = 'Debugs Log'
        
        Label(self.gbParameters, anchor=W, text="Activation:").grid(row=0, column=1, sticky=W)
        self.rdbParamActive = Radiobutton(self.gbParameters, text="Active", value = 1, variable=self.m_ConfigurationRDB)
        self.rdbParamActive.grid(row=1,column=1, padx=0, pady=2, sticky=W)
        self.rdbParamInactive = Radiobutton(self.gbParameters, anchor=W,width = 20, text="Inactive", value = 0, variable=self.m_ConfigurationRDB)
        self.rdbParamInactive.grid(row=1,column=2, padx=0, pady=2, sticky=W)
        
        Label(self.gbParameters, anchor=W, width=20, text="Device ID:").grid(row=0, column=3, sticky=W)
        self.nudDeviceId = Spinbox(self.gbParameters, width=15, state=DISABLED, from_=0, to=0x7FF, textvariable=self.m_DeviceIdNUD)
        self.nudDeviceId.grid(row=1, column=3,padx=0, pady=2, sticky=W)
        self.btnParameterSet = Button(self.gbParameters, width = 8, state=ACTIVE, text = "Set", command=self.btnParameterSet_Click)
        self.btnParameterSet.grid(row=1, padx = 5, column=4, sticky=W)
        self.btnParameterGet = Button(self.gbParameters, width = 8, state=ACTIVE, text = "Get", command=self.btnParameterGet_Click)
        self.btnParameterGet.grid(row=1, column=5, sticky=W)
    ## Initializes controls and variables in the groupbox "Messages Reading"
    ##
    def InitializeReadingWidgets(self):
        # Control variables
        #
        self.m_ListColCaption = ["Type", "|ID", "|Length", "|Count", "|RcvTime","|Data"]
        self.m_ListColSpace = [18, 10, 7, 6, 8, 20]        
        
        self.m_ListCaptionPadxSpaces = []
        for colText, colWidth in zip(self.m_ListColCaption, self.m_ListColSpace):            
            self.m_ListCaptionPadxSpaces.append(colWidth - len(colText))
        self.m_ListCaptionPadxSpaces[0] = self.m_ListCaptionPadxSpaces[0]-1
        
        self.m_ListFont = tkFont.Font(family="Lucida Console", size ="10")
        
        self.m_ReadingRDB = IntVar(value=0)
        self.m_ShowPeriodCHB = IntVar(value=1)
        self.tmrRead = TimerRepeater("tmrRead", 0.050, self.tmrRead_Tick)
        self.tmrDisplay = TimerRepeater("tmrDisplay", 0.100, self.tmrDisplay_Tick)
       
        # Controls
        #
        self.rdbTimer = Radiobutton(self.gbReading, text="Read using a Timer", value = 1, variable=self.m_ReadingRDB, command=self.rdbTimer_CheckedChanged)
        self.rdbTimer.grid(row=0,column=0, padx=5, pady=2, sticky=W)
        self.rdbEvent = Radiobutton(self.gbReading, text="Reading using an Event", value = 2, variable=self.m_ReadingRDB, command=self.rdbTimer_CheckedChanged)        
        self.rdbEvent.grid(row=0,column=1, padx=5, pady=2, sticky=W)
        self.rdbManual = Radiobutton(self.gbReading, text="Manual Read", value = 0, variable=self.m_ReadingRDB, command=self.rdbTimer_CheckedChanged)
        self.rdbManual.grid(row=0,column=2, padx=5, pady=2, sticky=W)
        self.chbShowPeriod = Checkbutton(self.gbReading, width=16, text="Timestamp as period", variable=self.m_ShowPeriodCHB, command=self.chbShowPeriod_CheckedChanged)
        self.chbShowPeriod.grid(row=0,column=3, padx=5, pady=2)
        
        self.yReadScroll = Scrollbar(self.gbReading, orient=VERTICAL)
        self.yReadScroll.grid(row=1, column=4, rowspan=3, sticky=N+S)
        self.xReadScroll = Scrollbar(self.gbReading, orient=HORIZONTAL)
        self.xReadScroll.grid(row=3, padx=5, column=0, columnspan=4, sticky=W+E)        
        tempString = ""        
        for caption, spaces in zip(self.m_ListColCaption, self.m_ListCaptionPadxSpaces):
            tempString = tempString + "{0}{1}".format(caption," "*spaces)
        Label(self.gbReading, anchor=W, text=tempString, bg="#E2E2E3", fg="#000000", font=self.m_ListFont, relief=GROOVE).grid(row=1,column=0, columnspan=4, padx=5, sticky="nwes")
        
        self.lstMessages = Tix.TList(self.gbReading, relief=GROOVE, height = 5, orient="horizontal", itemtype ="text", font=self.m_ListFont, command=self.btnMsgClear_Click)
        self.lstMessages.grid(row=2, column=0, padx=5, columnspan=4, sticky="nwes")
        self.yReadScroll['command'] = self.lstMessages.yview
        self.xReadScroll['command'] = self.lstMessages.xview
        Label(self.gbReading, width=1, text=" ").grid(row=0,  column=5)
        
        self.btnRead = Button(self.gbReading, width = 8, state=DISABLED, text = "Read", command=self.btnRead_Click)        
        self.btnRead.grid(row=1, column=6, padx = 4, sticky=NW)
        self.btnMsgClear = Button(self.gbReading, width = 8, state=ACTIVE, text = "Clear", command=self.btnMsgClear_Click)
        self.btnMsgClear.grid(row=1, column=7, sticky=NW)
        
    ## Initializes controls and variables in the groupbox "Write Messages"
    ##
    def InitializeWritingWidgets(self):
        # Control variables
        #        
        self.m_IDTXT = StringVar(value="000")
        self.m_LengthLA = StringVar(value="8 B.")
        self.m_ExtendedCHB = IntVar(value=0)
        self.m_RemoteCHB = IntVar(value=0)
        self.m_FDCHB = IntVar(value=0)
        self.m_BRSCHB = IntVar(value=0)
        self.m_LengthNUD = StringVar(value="8")
        self.m_Data0TXT = StringVar(value="00")
        self.m_Data1TXT = StringVar(value="00")
        self.m_Data2TXT = StringVar(value="00")
        self.m_Data3TXT = StringVar(value="00")
        self.m_Data4TXT = StringVar(value="00")
        self.m_Data5TXT = StringVar(value="00")
        self.m_Data6TXT = StringVar(value="00")
        self.m_Data7TXT = StringVar(value="00")
        self.m_Data8TXT = StringVar(value="00")
        self.m_Data9TXT = StringVar(value="00")
        self.m_Data10TXT = StringVar(value="00")
        self.m_Data11TXT = StringVar(value="00")
        self.m_Data12TXT = StringVar(value="00")
        self.m_Data13TXT = StringVar(value="00")
        self.m_Data14TXT = StringVar(value="00")
        self.m_Data15TXT = StringVar(value="00")
        self.m_Data16TXT = StringVar(value="00")
        self.m_Data17TXT = StringVar(value="00")
        self.m_Data18TXT = StringVar(value="00")
        self.m_Data19TXT = StringVar(value="00")
        self.m_Data20TXT = StringVar(value="00")
        self.m_Data21TXT = StringVar(value="00")
        self.m_Data22TXT = StringVar(value="00")
        self.m_Data23TXT = StringVar(value="00")
        self.m_Data24TXT = StringVar(value="00")
        self.m_Data25TXT = StringVar(value="00")
        self.m_Data26TXT = StringVar(value="00")
        self.m_Data27TXT = StringVar(value="00")
        self.m_Data28TXT = StringVar(value="00")
        self.m_Data29TXT = StringVar(value="00")
        self.m_Data30TXT = StringVar(value="00")
        self.m_Data31TXT = StringVar(value="00")
        self.m_Data32TXT = StringVar(value="00")
        self.m_Data33TXT = StringVar(value="00")
        self.m_Data34TXT = StringVar(value="00")
        self.m_Data35TXT = StringVar(value="00")
        self.m_Data36TXT = StringVar(value="00")
        self.m_Data37TXT = StringVar(value="00")
        self.m_Data38TXT = StringVar(value="00")
        self.m_Data39TXT = StringVar(value="00")
        self.m_Data40TXT = StringVar(value="00")
        self.m_Data41TXT = StringVar(value="00")
        self.m_Data42TXT = StringVar(value="00")
        self.m_Data43TXT = StringVar(value="00")
        self.m_Data44TXT = StringVar(value="00")
        self.m_Data45TXT = StringVar(value="00")
        self.m_Data46TXT = StringVar(value="00")
        self.m_Data47TXT = StringVar(value="00")
        self.m_Data48TXT = StringVar(value="00")
        self.m_Data49TXT = StringVar(value="00")
        self.m_Data50TXT = StringVar(value="00")
        self.m_Data51TXT = StringVar(value="00")
        self.m_Data52TXT = StringVar(value="00")
        self.m_Data53TXT = StringVar(value="00")
        self.m_Data54TXT = StringVar(value="00")
        self.m_Data55TXT = StringVar(value="00")
        self.m_Data56TXT = StringVar(value="00")
        self.m_Data57TXT = StringVar(value="00")
        self.m_Data58TXT = StringVar(value="00")
        self.m_Data59TXT = StringVar(value="00")
        self.m_Data60TXT = StringVar(value="00")
        self.m_Data61TXT = StringVar(value="00")
        self.m_Data62TXT = StringVar(value="00")
        self.m_Data63TXT = StringVar(value="00")        
        # Controls
        #
        Label(self.gbWriting, anchor=W, text="Data (Hex):").grid(row=0, columnspan=2, padx = 0, column=0, sticky=W)
        Label(self.gbWriting, anchor=W, text=" ").grid(row=0, padx = 0, column=16, sticky=W)
       
        Label(self.gbWriting, anchor=W, text="ID (Hex):").grid(row=0, padx = 0, column=17, sticky=W)
        self.txtID = Entry(self.gbWriting, width = 11, textvariable=self.m_IDTXT)
        self.txtID.bind("<FocusOut>",self.txtID_Leave)
        self.txtID.grid(row=1,column=17, padx = 0, pady = 0, sticky=W)        
        Label(self.gbWriting, anchor=W, width=5, padx=5, text="DLC:").grid(row=0, column=18, sticky=W)
        self.nudLength = Spinbox(self.gbWriting, width=5, from_=0, to=8, textvariable=self.m_LengthNUD, command=self.nudLength_ValueChanged)
        self.nudLength.grid(row=1, column=18, padx=5, pady=2, sticky=W)
        Label(self.gbWriting, anchor=W, width=5, text="Length:").grid(row=0, column=19, sticky=W)
        Label(self.gbWriting, anchor=W, width=5, textvariable=self.m_LengthLA).grid(row=1, padx=5, column=19, sticky=W)
                
        self.chbExtended = Checkbutton(self.gbWriting, text="Extended", variable=self.m_ExtendedCHB, command=self.txtID_Leave)
        self.chbExtended.grid(row=2,column=17, padx=0, pady=0)
        self.chbRemote = Checkbutton(self.gbWriting, text="RTR", variable=self.m_RemoteCHB, command=self.chbRemote_CheckedChanged)
        self.chbRemote.grid(row=2,column=18, padx=0, pady=0, sticky=W)
        
        self.chbFD = Checkbutton(self.gbWriting, text="FD", variable=self.m_FDCHB, command=self.chbFD_CheckedChanged)
        #self.chbFD.grid(row=3,column=17, padx=0, pady=0, sticky=W)
        self.chbBRS = Checkbutton(self.gbWriting, text="BRS", variable=self.m_BRSCHB, state=DISABLED)
        #self.chbBRS.grid(row=3,column=18, padx=0, pady=0, sticky=W)
        self.btnWrite = Button(self.gbWriting, width = 6, state=DISABLED, text = "Write", command=self.btnWrite_Click)
        self.btnWrite.grid(row=3, column=19, columnspan=2, sticky=W)
        
        self.txtData0 = Entry(self.gbWriting, width = 4, textvariable=self.m_Data0TXT)        
        self.txtData0.grid(row=1,column=0, padx = 3, pady = 0, sticky=W)
        self.txtData0.bind("<FocusOut>",self.txtData0_Leave)
        self.txtData1 = Entry(self.gbWriting, width = 4, textvariable=self.m_Data1TXT)
        self.txtData1.grid(row=1,column=1, padx = 3, pady = 0, sticky=W)
        self.txtData1.bind("<FocusOut>",self.txtData0_Leave)
        self.txtData2 = Entry(self.gbWriting, width = 4, textvariable=self.m_Data2TXT)
        self.txtData2.grid(row=1,column=2, padx = 3, pady = 0, sticky=W)
        self.txtData2.bind("<FocusOut>",self.txtData0_Leave)
        self.txtData3 = Entry(self.gbWriting, width = 4, textvariable=self.m_Data3TXT)
        self.txtData3.grid(row=1,column=3, padx = 3, pady = 0, sticky=W)
        self.txtData3.bind("<FocusOut>",self.txtData0_Leave)
        self.txtData4 = Entry(self.gbWriting, width = 4, textvariable=self.m_Data4TXT)
        self.txtData4.grid(row=1,column=4, padx = 3, pady = 0, sticky=W)
        self.txtData4.bind("<FocusOut>",self.txtData0_Leave)
        self.txtData5 = Entry(self.gbWriting, width = 4, textvariable=self.m_Data5TXT)
        self.txtData5.grid(row=1,column=5, padx = 3, pady = 0, sticky=W)
        self.txtData5.bind("<FocusOut>",self.txtData0_Leave)
        self.txtData6 = Entry(self.gbWriting, width = 4, textvariable=self.m_Data6TXT)
        self.txtData6.grid(row=1,column=6, padx = 3, pady = 0, sticky=W)
        self.txtData6.bind("<FocusOut>",self.txtData0_Leave)
        self.txtData7 = Entry(self.gbWriting, width = 4, textvariable=self.m_Data7TXT)
        self.txtData7.grid(row=1,column=7, padx = 3, pady = 0, sticky=W)
        self.txtData7.bind("<FocusOut>",self.txtData0_Leave)
        self.txtData8 = Entry(self.gbWriting, width = 4, textvariable=self.m_Data8TXT, state=DISABLED)        
        self.txtData8.grid(row=1,column=8, padx = 3, pady = 0, sticky=W)
        self.txtData8.bind("<FocusOut>",self.txtData0_Leave)
        self.txtData9 = Entry(self.gbWriting, width = 4, textvariable=self.m_Data9TXT, state=DISABLED)
        self.txtData9.grid(row=1,column=9, padx = 3, pady = 0, sticky=W)
        self.txtData9.bind("<FocusOut>",self.txtData0_Leave)
        self.txtData10 = Entry(self.gbWriting, width = 4, textvariable=self.m_Data10TXT, state=DISABLED)
        self.txtData10.grid(row=1,column=10, padx = 3, pady = 0, sticky=W)
        self.txtData10.bind("<FocusOut>",self.txtData0_Leave)
        self.txtData11 = Entry(self.gbWriting, width = 4, textvariable=self.m_Data11TXT, state=DISABLED)
        self.txtData11.grid(row=1,column=11, padx = 3, pady = 0, sticky=W)
        self.txtData11.bind("<FocusOut>",self.txtData0_Leave)
        self.txtData12 = Entry(self.gbWriting, width = 4, textvariable=self.m_Data12TXT, state=DISABLED)
        self.txtData12.grid(row=1,column=12, padx = 3, pady = 0, sticky=W)
        self.txtData12.bind("<FocusOut>",self.txtData0_Leave)
        self.txtData13 = Entry(self.gbWriting, width = 4, textvariable=self.m_Data13TXT, state=DISABLED)
        self.txtData13.grid(row=1,column=13, padx = 3, pady = 0, sticky=W)
        self.txtData13.bind("<FocusOut>",self.txtData0_Leave)
        self.txtData14 = Entry(self.gbWriting, width = 4, textvariable=self.m_Data14TXT, state=DISABLED)
        self.txtData14.grid(row=1,column=14, padx = 3, pady = 0, sticky=W)
        self.txtData14.bind("<FocusOut>",self.txtData0_Leave)
        self.txtData15 = Entry(self.gbWriting, width = 4, textvariable=self.m_Data15TXT, state=DISABLED)
        self.txtData15.grid(row=1,column=15, padx = 3, pady = 0, sticky=W)
        self.txtData15.bind("<FocusOut>",self.txtData0_Leave)
        self.txtData16 = Entry(self.gbWriting, width = 4, textvariable=self.m_Data16TXT, state=DISABLED)        
        self.txtData16.grid(row=2,column=0, padx = 3, pady = 5, sticky=W)
        self.txtData16.bind("<FocusOut>",self.txtData0_Leave)
        self.txtData17 = Entry(self.gbWriting, width = 4, textvariable=self.m_Data17TXT, state=DISABLED)
        self.txtData17.grid(row=2,column=1, padx = 3, pady = 0, sticky=W)
        self.txtData17.bind("<FocusOut>",self.txtData0_Leave)
        self.txtData18 = Entry(self.gbWriting, width = 4, textvariable=self.m_Data18TXT, state=DISABLED)
        self.txtData18.grid(row=2,column=2, padx = 3, pady = 0, sticky=W)
        self.txtData18.bind("<FocusOut>",self.txtData0_Leave)
        self.txtData19 = Entry(self.gbWriting, width = 4, textvariable=self.m_Data19TXT, state=DISABLED)
        self.txtData19.grid(row=2,column=3, padx = 3, pady = 0, sticky=W)
        self.txtData19.bind("<FocusOut>",self.txtData0_Leave)
        self.txtData20 = Entry(self.gbWriting, width = 4, textvariable=self.m_Data20TXT, state=DISABLED)
        self.txtData20.grid(row=2,column=4, padx = 3, pady = 0, sticky=W)
        self.txtData20.bind("<FocusOut>",self.txtData0_Leave)
        self.txtData21 = Entry(self.gbWriting, width = 4, textvariable=self.m_Data21TXT, state=DISABLED)
        self.txtData21.grid(row=2,column=5, padx = 3, pady = 0, sticky=W)
        self.txtData21.bind("<FocusOut>",self.txtData0_Leave)
        self.txtData22 = Entry(self.gbWriting, width = 4, textvariable=self.m_Data22TXT, state=DISABLED)
        self.txtData22.grid(row=2,column=6, padx = 3, pady = 0, sticky=W)
        self.txtData22.bind("<FocusOut>",self.txtData0_Leave)
        self.txtData23 = Entry(self.gbWriting, width = 4, textvariable=self.m_Data23TXT, state=DISABLED)
        self.txtData23.grid(row=2,column=7, padx = 3, pady = 0, sticky=W)
        self.txtData23.bind("<FocusOut>",self.txtData0_Leave)
        self.txtData24 = Entry(self.gbWriting, width = 4, textvariable=self.m_Data24TXT, state=DISABLED)        
        self.txtData24.grid(row=2,column=8, padx = 3, pady = 0, sticky=W)
        self.txtData24.bind("<FocusOut>",self.txtData0_Leave)
        self.txtData25 = Entry(self.gbWriting, width = 4, textvariable=self.m_Data25TXT, state=DISABLED)
        self.txtData25.grid(row=2,column=9, padx = 3, pady = 0, sticky=W)
        self.txtData25.bind("<FocusOut>",self.txtData0_Leave)
        self.txtData26 = Entry(self.gbWriting, width = 4, textvariable=self.m_Data26TXT, state=DISABLED)
        self.txtData26.grid(row=2,column=10, padx = 3, pady = 0, sticky=W)
        self.txtData26.bind("<FocusOut>",self.txtData0_Leave)
        self.txtData27 = Entry(self.gbWriting, width = 4, textvariable=self.m_Data27TXT, state=DISABLED)
        self.txtData27.grid(row=2,column=11, padx = 3, pady = 0, sticky=W)
        self.txtData27.bind("<FocusOut>",self.txtData0_Leave)
        self.txtData28 = Entry(self.gbWriting, width = 4, textvariable=self.m_Data28TXT, state=DISABLED)
        self.txtData28.grid(row=2,column=12, padx = 3, pady = 0, sticky=W)
        self.txtData28.bind("<FocusOut>",self.txtData0_Leave)
        self.txtData29 = Entry(self.gbWriting, width = 4, textvariable=self.m_Data29TXT, state=DISABLED)
        self.txtData29.grid(row=2,column=13, padx = 3, pady = 0, sticky=W)
        self.txtData29.bind("<FocusOut>",self.txtData0_Leave)
        self.txtData30 = Entry(self.gbWriting, width = 4, textvariable=self.m_Data30TXT, state=DISABLED)
        self.txtData30.grid(row=2,column=14, padx = 3, pady = 0, sticky=W)
        self.txtData30.bind("<FocusOut>",self.txtData0_Leave)
        self.txtData31 = Entry(self.gbWriting, width = 4, textvariable=self.m_Data31TXT, state=DISABLED)
        self.txtData31.grid(row=2,column=15, padx = 3, pady = 0, sticky=W)
        self.txtData31.bind("<FocusOut>",self.txtData0_Leave)
        self.txtData32 = Entry(self.gbWriting, width = 4, textvariable=self.m_Data32TXT, state=DISABLED)        
        self.txtData32.grid(row=3,column=0, padx = 3, pady = 0, sticky=W)
        self.txtData32.bind("<FocusOut>",self.txtData0_Leave)
        self.txtData33 = Entry(self.gbWriting, width = 4, textvariable=self.m_Data33TXT, state=DISABLED)
        self.txtData33.grid(row=3,column=1, padx = 3, pady = 0, sticky=W)
        self.txtData33.bind("<FocusOut>",self.txtData0_Leave)
        self.txtData34 = Entry(self.gbWriting, width = 4, textvariable=self.m_Data34TXT, state=DISABLED)
        self.txtData34.grid(row=3,column=2, padx = 3, pady = 0, sticky=W)
        self.txtData34.bind("<FocusOut>",self.txtData0_Leave)
        self.txtData35 = Entry(self.gbWriting, width = 4, textvariable=self.m_Data35TXT, state=DISABLED)
        self.txtData35.grid(row=3,column=3, padx = 3, pady = 0, sticky=W)
        self.txtData35.bind("<FocusOut>",self.txtData0_Leave)
        self.txtData36 = Entry(self.gbWriting, width = 4, textvariable=self.m_Data36TXT, state=DISABLED)
        self.txtData36.grid(row=3,column=4, padx = 3, pady = 0, sticky=W)
        self.txtData36.bind("<FocusOut>",self.txtData0_Leave)
        self.txtData37 = Entry(self.gbWriting, width = 4, textvariable=self.m_Data37TXT, state=DISABLED)
        self.txtData37.grid(row=3,column=5, padx = 3, pady = 0, sticky=W)
        self.txtData37.bind("<FocusOut>",self.txtData0_Leave)
        self.txtData38 = Entry(self.gbWriting, width = 4, textvariable=self.m_Data38TXT, state=DISABLED)
        self.txtData38.grid(row=3,column=6, padx = 3, pady = 0, sticky=W)
        self.txtData38.bind("<FocusOut>",self.txtData0_Leave)
        self.txtData39 = Entry(self.gbWriting, width = 4, textvariable=self.m_Data39TXT, state=DISABLED)
        self.txtData39.grid(row=3,column=7, padx = 3, pady = 0, sticky=W)
        self.txtData39.bind("<FocusOut>",self.txtData0_Leave)
        self.txtData40 = Entry(self.gbWriting, width = 4, textvariable=self.m_Data40TXT, state=DISABLED)        
        self.txtData40.grid(row=3,column=8, padx = 3, pady = 0, sticky=W)
        self.txtData40.bind("<FocusOut>",self.txtData0_Leave)
        self.txtData41 = Entry(self.gbWriting, width = 4, textvariable=self.m_Data41TXT, state=DISABLED)
        self.txtData41.grid(row=3,column=9, padx = 3, pady = 0, sticky=W)
        self.txtData41.bind("<FocusOut>",self.txtData0_Leave)
        self.txtData42 = Entry(self.gbWriting, width = 4, textvariable=self.m_Data42TXT, state=DISABLED)
        self.txtData42.grid(row=3,column=10, padx = 3, pady = 0, sticky=W)
        self.txtData42.bind("<FocusOut>",self.txtData0_Leave)
        self.txtData43 = Entry(self.gbWriting, width = 4, textvariable=self.m_Data43TXT, state=DISABLED)
        self.txtData43.grid(row=3,column=11, padx = 3, pady = 0, sticky=W)
        self.txtData43.bind("<FocusOut>",self.txtData0_Leave)
        self.txtData44 = Entry(self.gbWriting, width = 4, textvariable=self.m_Data44TXT, state=DISABLED)
        self.txtData44.grid(row=3,column=12, padx = 3, pady = 0, sticky=W)
        self.txtData44.bind("<FocusOut>",self.txtData0_Leave)
        self.txtData45 = Entry(self.gbWriting, width = 4, textvariable=self.m_Data45TXT, state=DISABLED)
        self.txtData45.grid(row=3,column=13, padx = 3, pady = 0, sticky=W)
        self.txtData45.bind("<FocusOut>",self.txtData0_Leave)
        self.txtData46 = Entry(self.gbWriting, width = 4, textvariable=self.m_Data46TXT, state=DISABLED)
        self.txtData46.grid(row=3,column=14, padx = 3, pady = 0, sticky=W)
        self.txtData46.bind("<FocusOut>",self.txtData0_Leave)
        self.txtData47 = Entry(self.gbWriting, width = 4, textvariable=self.m_Data47TXT, state=DISABLED)
        self.txtData47.grid(row=3,column=15, padx = 3, pady = 0, sticky=W)
        self.txtData47.bind("<FocusOut>",self.txtData0_Leave)
        self.txtData48 = Entry(self.gbWriting, width = 4, textvariable=self.m_Data48TXT, state=DISABLED)        
        self.txtData48.grid(row=4,column=0, padx = 3, pady = 5, sticky=W)
        self.txtData48.bind("<FocusOut>",self.txtData0_Leave)
        self.txtData49 = Entry(self.gbWriting, width = 4, textvariable=self.m_Data49TXT, state=DISABLED)
        self.txtData49.grid(row=4,column=1, padx = 3, pady = 0, sticky=W)
        self.txtData49.bind("<FocusOut>",self.txtData0_Leave)
        self.txtData50 = Entry(self.gbWriting, width = 4, textvariable=self.m_Data50TXT, state=DISABLED)
        self.txtData50.grid(row=4,column=2, padx = 3, pady = 0, sticky=W)
        self.txtData50.bind("<FocusOut>",self.txtData0_Leave)
        self.txtData51 = Entry(self.gbWriting, width = 4, textvariable=self.m_Data51TXT, state=DISABLED)
        self.txtData51.grid(row=4,column=3, padx = 3, pady = 0, sticky=W)
        self.txtData51.bind("<FocusOut>",self.txtData0_Leave)
        self.txtData52 = Entry(self.gbWriting, width = 4, textvariable=self.m_Data52TXT, state=DISABLED)
        self.txtData52.grid(row=4,column=4, padx = 3, pady = 0, sticky=W)
        self.txtData52.bind("<FocusOut>",self.txtData0_Leave)
        self.txtData53 = Entry(self.gbWriting, width = 4, textvariable=self.m_Data53TXT, state=DISABLED)
        self.txtData53.grid(row=4,column=5, padx = 3, pady = 0, sticky=W)
        self.txtData53.bind("<FocusOut>",self.txtData0_Leave)
        self.txtData54 = Entry(self.gbWriting, width = 4, textvariable=self.m_Data54TXT, state=DISABLED)
        self.txtData54.grid(row=4,column=6, padx = 3, pady = 0, sticky=W)
        self.txtData54.bind("<FocusOut>",self.txtData0_Leave)
        self.txtData55 = Entry(self.gbWriting, width = 4, textvariable=self.m_Data55TXT, state=DISABLED)
        self.txtData55.grid(row=4,column=7, padx = 3, pady = 0, sticky=W)
        self.txtData55.bind("<FocusOut>",self.txtData0_Leave)
        self.txtData56 = Entry(self.gbWriting, width = 4, textvariable=self.m_Data56TXT, state=DISABLED)        
        self.txtData56.grid(row=4,column=8, padx = 3, pady = 0, sticky=W)
        self.txtData56.bind("<FocusOut>",self.txtData0_Leave)
        self.txtData57 = Entry(self.gbWriting, width = 4, textvariable=self.m_Data57TXT, state=DISABLED)
        self.txtData57.grid(row=4,column=9, padx = 3, pady = 0, sticky=W)
        self.txtData57.bind("<FocusOut>",self.txtData0_Leave)
        self.txtData58 = Entry(self.gbWriting, width = 4, textvariable=self.m_Data58TXT, state=DISABLED)
        self.txtData58.grid(row=4,column=10, padx = 3, pady = 0, sticky=W)
        self.txtData58.bind("<FocusOut>",self.txtData0_Leave)
        self.txtData59 = Entry(self.gbWriting, width = 4, textvariable=self.m_Data59TXT, state=DISABLED)
        self.txtData59.grid(row=4,column=11, padx = 3, pady = 0, sticky=W)
        self.txtData59.bind("<FocusOut>",self.txtData0_Leave)
        self.txtData60 = Entry(self.gbWriting, width = 4, textvariable=self.m_Data60TXT, state=DISABLED)
        self.txtData60.grid(row=4,column=12, padx = 3, pady = 0, sticky=W)
        self.txtData60.bind("<FocusOut>",self.txtData0_Leave)
        self.txtData61 = Entry(self.gbWriting, width = 4, textvariable=self.m_Data61TXT, state=DISABLED)
        self.txtData61.grid(row=4,column=13, padx = 3, pady = 0, sticky=W)
        self.txtData61.bind("<FocusOut>",self.txtData0_Leave)
        self.txtData62 = Entry(self.gbWriting, width = 4, textvariable=self.m_Data62TXT, state=DISABLED)
        self.txtData62.grid(row=4,column=14, padx = 3, pady = 0, sticky=W)
        self.txtData62.bind("<FocusOut>",self.txtData0_Leave)
        self.txtData63 = Entry(self.gbWriting, width = 4, textvariable=self.m_Data63TXT, state=DISABLED)
        self.txtData63.grid(row=4,column=15, padx = 3, pady = 0, sticky=W)
        self.txtData63.bind("<FocusOut>",self.txtData0_Leave)
        self.m_CtrlEdits = [self.txtData0, self.txtData1, self.txtData2, self.txtData3, self.txtData4, self.txtData5, self.txtData6, self.txtData7, \
                            self.txtData8, self.txtData9, self.txtData10, self.txtData11, self.txtData12, self.txtData13, self.txtData14, self.txtData15, \
                            self.txtData16, self.txtData17, self.txtData18, self.txtData19, self.txtData20, self.txtData21, self.txtData22, self.txtData23, \
                            self.txtData24, self.txtData25, self.txtData26, self.txtData27, self.txtData28, self.txtData29, self.txtData30, self.txtData31, \
                            self.txtData32, self.txtData33, self.txtData34, self.txtData35, self.txtData36, self.txtData37, self.txtData38, self.txtData39, \
                            self.txtData40, self.txtData41, self.txtData42, self.txtData43, self.txtData44, self.txtData45, self.txtData46, self.txtData47, \
                            self.txtData48, self.txtData49, self.txtData50, self.txtData51, self.txtData52, self.txtData53, self.txtData54, self.txtData55, \
                            self.txtData56, self.txtData57, self.txtData58, self.txtData59, self.txtData60, self.txtData61, self.txtData62, self.txtData63]
        self.m_DataEdits = [self.m_Data0TXT, self.m_Data1TXT, self.m_Data2TXT, self.m_Data3TXT, self.m_Data4TXT, self.m_Data5TXT, self.m_Data6TXT, self.m_Data7TXT, \
                            self.m_Data8TXT, self.m_Data9TXT, self.m_Data10TXT, self.m_Data11TXT, self.m_Data12TXT, self.m_Data13TXT, self.m_Data14TXT, self.m_Data15TXT, \
                            self.m_Data16TXT, self.m_Data17TXT, self.m_Data18TXT, self.m_Data19TXT, self.m_Data20TXT, self.m_Data21TXT, self.m_Data22TXT, self.m_Data23TXT, \
                            self.m_Data24TXT, self.m_Data25TXT, self.m_Data26TXT, self.m_Data27TXT, self.m_Data28TXT, self.m_Data29TXT, self.m_Data30TXT, self.m_Data31TXT, \
                            self.m_Data32TXT, self.m_Data33TXT, self.m_Data34TXT, self.m_Data35TXT, self.m_Data36TXT, self.m_Data37TXT, self.m_Data38TXT, self.m_Data39TXT, \
                            self.m_Data40TXT, self.m_Data41TXT, self.m_Data42TXT, self.m_Data43TXT, self.m_Data44TXT, self.m_Data45TXT, self.m_Data46TXT, self.m_Data47TXT, \
                            self.m_Data48TXT, self.m_Data49TXT, self.m_Data50TXT, self.m_Data51TXT, self.m_Data52TXT, self.m_Data53TXT, self.m_Data54TXT, self.m_Data55TXT, \
                            self.m_Data56TXT, self.m_Data57TXT, self.m_Data58TXT, self.m_Data59TXT, self.m_Data60TXT, self.m_Data61TXT, self.m_Data62TXT, self.m_Data63TXT]
        
        
    ## Initializes controls and variables in the groupbox "Information"
    ##
    def InitializeInformationWidgets(self):
        # Controls
        #         
        self.yInfoScroll = Scrollbar(self.gbInfo, orient=VERTICAL)
        self.yInfoScroll.grid(row=0, column=1, sticky=N+S)
       
        self.lbxInfo = Listbox(self.gbInfo, width=90, height=3, activestyle="none", yscrollcommand=self.yInfoScroll.set) 
        self.lbxInfo.grid(row=0, column = 0, padx=5, sticky="nwes")
        self.lbxInfo.bind("<Double-1>", self.btnInfoClear_Click)
        self.yInfoScroll['command'] = self.lbxInfo.yview        
        self.lbxInfo.insert(END,"Select a Hardware and a configuration for it. Then click ""Initialize"" button")
        self.lbxInfo.insert(END,"When activated, the Debug-Log file will be found in the same directory as this application")
        self.lbxInfo.insert(END,"When activated, the PCAN-Trace file will be found in the same directory as this application")        
        Label(self.gbInfo, width=2, text=" ").grid(row=0, column=2)
        
        self.btnGetVersions = Button(self.gbInfo, width = 8, state=DISABLED, text = "Versions", command=self.btnGetVersions_Click)
        self.btnGetVersions.grid(row=0, column=3, padx = 4, sticky=NW)
        self.btnInfoClear = Button(self.gbInfo, width = 8, state=ACTIVE, text = "Clear", command=self.btnInfoClear_Click)
        self.btnInfoClear.grid(row=0, column=4, sticky=NW)
        self.btnStatus = Button(self.gbInfo, width = 8, state=DISABLED, text = "Status", command=self.btnStatus_Click)
        self.btnStatus.grid(row=0, column=3, padx = 4, pady=25, sticky=W)
        self.btnReset = Button(self.gbInfo, width = 8, state=DISABLED, text = "Reset", command=self.btnReset_Click)
        self.btnReset.grid(row=0, column=4, pady=25, sticky=W)
              
        
    ## Centers the app from in the middle of the screen
    ##
    def CenterTheWindow(self):
        Desktop = self.m_Parent.winfo_toplevel()
        desktopWidth = Desktop.winfo_screenwidth()
        desktopHeight = Desktop.winfo_screenheight()
        
        self.m_Parent.geometry("{0}x{1}+{2}+{3}".format(self.m_Width,
                                                        self.m_Height,
                                                        (desktopWidth-self.m_Width)/2,
                                                        (desktopHeight-self.m_Height)/2))           
    ## Configures the Debug-Log file of PCAN-Basic
    ##
    def ConfigureLogFile(self):
        # Sets the mask to catch all events
        #
        iBuffer = LOG_FUNCTION_ALL
        # Configures the log file. 
        # NOTE: The Log capability is to be used with the NONEBUS Handle. Other handle than this will 
        # cause the function fail.
        #
        self.m_objPCANBasic.SetValue(PCAN_NONEBUS, PCAN_LOG_CONFIGURE, iBuffer)
    ## Configures the PCAN-Trace file for a PCAN-Basic Channel
    ##
    def ConfigureTraceFile(self):
        # Configure the maximum size of a trace file to 5 megabytes
        #
        iBuffer = 5
        stsResult = self.m_objPCANBasic.SetValue(self.m_PcanHandle, PCAN_TRACE_SIZE, iBuffer)
        if stsResult != PCAN_ERROR_OK:
            self.IncludeTextMessage(self.GetFormatedError(stsResult))
        # Configure the way how trace files are created: 
        # * Standard name is used
        # * Existing file is ovewritten, 
        # * Only one file is created.
        # * Recording stopts when the file size reaches 5 megabytes.
        #
        iBuffer = TRACE_FILE_SINGLE | TRACE_FILE_OVERWRITE
        stsResult = self.m_objPCANBasic.SetValue(self.m_PcanHandle, PCAN_TRACE_CONFIGURE, iBuffer)        
        if stsResult != PCAN_ERROR_OK:
            self.IncludeTextMessage(self.GetFormatedError(stsResult))
            
    ## Help Function used to get an error as text
    ##
    def GetFormatedError(self, error):
        # Gets the text using the GetErrorText API function
        # If the function success, the translated error is returned. If it fails,
        # a text describing the current error is returned.
        #
        stsReturn = self.m_objPCANBasic.GetErrorText(error, 0)
        if stsReturn[0] != PCAN_ERROR_OK:
            return "An error occurred. Error-code's text ({0:X}h) couldn't be retrieved".format(error)
        else:
            return stsReturn[1]
    ## Includes a new line of text into the information Listview
    ##
    def IncludeTextMessage(self, strMsg):
        self.lbxInfo.insert(END, strMsg);
        self.lbxInfo.see(END)
    ## Gets the current status of the PCAN-Basic message filter
    ##
    def GetFilterStatus(self):
        # Tries to get the sttaus of the filter for the current connected hardware
        #
        stsResult = self.m_objPCANBasic.GetValue(self.m_PcanHandle, PCAN_MESSAGE_FILTER)
        # If it fails, a error message is shown
        #
        if stsResult[0] != PCAN_ERROR_OK:
            tkMessageBox.showinfo("Error!", self.GetFormatedError(stsResult[0]))
            return False,
        else:
            return True, stsResult[1]
    ## Activates/deaactivates the different controls of the form according
    ## with the current connection status
    ##
    def SetConnectionStatus(self, bConnected=True):
        # Gets the status values for each case
        #
        self.m_Connected = bConnected
        if bConnected:
            self.m_Connected = True
            stsConnected = ACTIVE
            stsNotConnected = DISABLED
        else:
            stsConnected = DISABLED
            stsNotConnected = ACTIVE
            
        # Buttons
        #
        self.btnInit['state'] = stsNotConnected
        if (self.m_ReadingRDB.get() == 0) and bConnected:
            self.btnRead['state'] = ACTIVE
        else:
            self.btnRead['state'] = DISABLED
        self.btnWrite['state'] = stsConnected;
        self.btnRelease['state'] = stsConnected
        self.btnFilterApply['state'] = stsConnected
        self.btnFilterQuery['state'] = stsConnected
        self.btnGetVersions['state'] = stsConnected
        self.btnHwRefresh['state'] = stsNotConnected
        self.btnStatus['state'] = stsConnected
        self.btnReset['state'] = stsConnected
        # ComboBoxs
        #
        self.cbbBaudrates['state'] = stsNotConnected;
        self.cbbChannel['state'] = stsNotConnected;
        self.cbbHwType['state'] = stsNotConnected;
        self.cbbIO['state'] = stsNotConnected;
        self.cbbInterrupt['state'] = stsNotConnected;
        # Check-Buttons
        #
        self.chbCanFD['state'] = stsNotConnected;
        
        # Hardware configuration and read mode
        #
        if not bConnected:
            self.cbbChannel_SelectedIndexChanged(self.cbbChannel['value'])
            self.tmrDisplay.stop()
        else:
            self.rdbTimer_CheckedChanged()
            self.tmrDisplay.start()
    def FormatChannelName(self, handle, isFD = False):
        if handle < 0x100:
            devDevice = handle.value >> 4
            byChannel = handle.value & 0xF
        else:
            devDevice = handle.value >> 8
            byChannel = handle.value & 0xFF
        toRet = StringVar()
        if isFD:
            toRet.set('%s: FD %s (%.2X)' % (devDevice, byChannel, handle.value))
        else:
            toRet.set('%s: %s (%.2X)' % (devDevice, byChannel, handle.value))
        
        return toRet
        
    
################################################################################################################################################
### Message-proccessing functions
################################################################################################################################################
    def GetMsgString(self, msgStatus):
        # The Type of the message
        strTemp = msgStatus.TypeString
        toRet = (strTemp + " "*(self.m_ListColSpace[COL_TYPE] - len(strTemp)))
        # The msg ID
        strTemp = msgStatus.IdString
        toRet = toRet + (strTemp + " "*(self.m_ListColSpace[COL_ID] - len(strTemp)))
        # The length of the msg
        strTemp = str(GetLengthFromDLC(msgStatus.CANMsg.DLC, not (msgStatus.CANMsg.MSGTYPE & PCAN_MESSAGE_FD.value)))
        toRet = toRet + (strTemp + " "*(self.m_ListColSpace[COL_LENGTH] - len(strTemp)))
        # The count of msgs
        strTemp = str(msgStatus.Count)
        toRet = toRet + (strTemp + " "*(self.m_ListColSpace[COL_COUNT] - len(strTemp)))
        # The timestamp
        strTemp = msgStatus.TimeString
        toRet = toRet + (strTemp + " "*(self.m_ListColSpace[COL_TIME] - len(strTemp)))            
        # The Data
        strTemp = msgStatus.DataString
        toRet = toRet + (strTemp + " "*(self.m_ListColSpace[COL_DATA] - len(strTemp)))                    
        return toRet
            
    ## Display CAN messages in the Message-ListView
    ##
    def DisplayMessages(self):
        with self._lock:
            for msgStatus in self.m_LastMsgsList:
                if msgStatus.MarkedAsUpdated:                    
                    self.lstMessages.delete(msgStatus.Position)
                    self.lstMessages.insert(msgStatus.Position,text=self.GetMsgString(msgStatus))
                    msgStatus.MarkedAsUpdated = False
                    
    ## Inserts a new entry for a new message in the Message-ListView
    ##
    def InsertMsgEntry(self, newMsg, timeStamp):
        # Format the new time information
        #
        with self._lock:
            # The status values associated with the new message are created
            #
            msgStsCurrentMsg = MessageStatus(newMsg,timeStamp,len(self.m_LastMsgsList))
            msgStsCurrentMsg.ShowingPeriod = self.m_ShowPeriodCHB.get()
            self.m_LastMsgsList.append(msgStsCurrentMsg)
            
            # We add this status in the last message list
            #
            self.lstMessages.insert(END,text=self.GetMsgString(msgStsCurrentMsg))
    def ProcessMessageFD(self, *args):
        with self._lock:
            # Split the arguments. [0] TPCANMsgFD, [1] TPCANTimestampFD
            #
            theMsg = args[0][0]
            itsTimeStamp = args[0][1]
            
            for msg in self.m_LastMsgsList:
                if (msg.CANMsg.ID == theMsg.ID) and (msg.CANMsg.MSGTYPE == theMsg.MSGTYPE):
                    msg.Update(theMsg, itsTimeStamp)                    
                    return
            self.InsertMsgEntry(theMsg, itsTimeStamp)
        
    ## Processes a received message, in order to show it in the Message-ListView
    ##
    def ProcessMessage(self, *args):        
        with self._lock:       
            # Split the arguments. [0] TPCANMsg, [1] TPCANTimestamp
            #
            theMsg = args[0][0]
            itsTimeStamp = args[0][1]    
            newMsg = TPCANMsgFD()
            newMsg.ID = theMsg.ID
            newMsg.DLC = theMsg.LEN
            for i in range(8 if (theMsg.LEN > 8) else theMsg.LEN):
                newMsg.DATA[i] = theMsg.DATA[i]
            newMsg.MSGTYPE = theMsg.MSGTYPE
            newTimestamp = TPCANTimestampFD()
            newTimestamp.value = (itsTimeStamp.micros + 1000 * itsTimeStamp.millis + 0x100000000 * 1000 * itsTimeStamp.millis_overflow)
            self.ProcessMessageFD([newMsg, newTimestamp])
################################################################################################################################################
### Event Handlers
################################################################################################################################################        
    ## Form-Closing Function / Finish function
    ##
    def Form_OnClosing(self, event=None):
        # Releases the used PCAN-Basic channel
        #
        self.m_objPCANBasic.Uninitialize(self.m_PcanHandle)
        """Quit our mainloop."""
        self.exit = 0
    ## Button btnHwRefresh handler
    ##
    def btnHwRefresh_Click(self):
        # Clears the Channel comboBox and fill it again with 
        # the PCAN-Basic handles for no-Plug&Play hardware and
        # the detected Plug&Play hardware
        #        
        items = []
        myText = self.cbbChannel.subwidget('listbox').delete(0,Tix.END)
        for name, value in self.m_CHANNELS.iteritems():
            # Includes all no-Plug&Play Handles
            #
            if (value <= PCAN_DNGBUS1):
                items.append(name)
            else:
                # Checks for a Plug&Play Handle and, according with the return value, includes it
                # into the list of available hardware channels.
                #                
                result =  self.m_objPCANBasic.GetValue(value, PCAN_CHANNEL_CONDITION)
                if  (result[0] == PCAN_ERROR_OK) and (result[1] & PCAN_CHANNEL_AVAILABLE):
                    result =  self.m_objPCANBasic.GetValue(value, PCAN_CHANNEL_FEATURES)
                    isFD = (result[0] == PCAN_ERROR_OK) and (result[1] & FEATURE_FD_CAPABLE)
                    items.append(name)
                    
        items.sort()
        self.cbbChannel
        for name in items:
            self.cbbChannel.insert(Tix.END, name)
        self.cbbChannel['selection'] = self.cbbChannel.pick(Tix.END)
    ## Button btnInit handler
    ##
    def btnInit_Click(self):
        # gets the connection values
        #
        baudrate = self.m_BAUDRATES[self.cbbBaudrates['selection']]
        hwtype = self.m_HWTYPES[self.cbbHwType['selection']]
        ioport = int(self.cbbIO['selection'],16)
        interrupt = int(self.cbbInterrupt['selection'])
        # Connects a selected PCAN-Basic channel
        #
        if self.m_IsFD:
            result =  self.m_objPCANBasic.InitializeFD(self.m_PcanHandle, self.m_BitrateTXT.get())
        else:
            result =  self.m_objPCANBasic.Initialize(self.m_PcanHandle,baudrate,hwtype,ioport,interrupt)
        if result != PCAN_ERROR_OK:
            if result != PCAN_ERROR_CAUTION:
                tkMessageBox.showinfo("Error!", self.GetFormatedError(result))
            else:
                self.IncludeTextMessage('******************************************************')
                self.IncludeTextMessage('The bitrate being used is different than the given one')
                self.IncludeTextMessage('******************************************************')
                result = PCAN_ERROR_OK
        else:
            # Prepares the PCAN-Basic's PCAN-Trace file
            #
            self.ConfigureTraceFile()
        # Sets the connection status of the form
        #
        self.SetConnectionStatus(result == PCAN_ERROR_OK)
    ## Button btnRelease handler
    ##
    def btnRelease_Click(self):
        # We stop to read from the CAN queue
        #
        self.tmrRead.stop()
        # Releases a current connected PCAN-Basic channel
        #
        self.m_objPCANBasic.Uninitialize(self.m_PcanHandle)
                                                 
        # Sets the connection status of the main-form
        #
        self.SetConnectionStatus(False)
    ## Button btnFilterApply handler
    ##
    def btnFilterApply_Click(self):
        if self.m_FilterExtCHB.get():
            filterMode = PCAN_MODE_EXTENDED
        else:
            filterMode = PCAN_MODE_STANDARD
        # Gets the current status of the message filter
        #
        filterRet = self.GetFilterStatus()
        if not filterRet[0]:
            return 
        # Configures the message filter for a custom range of messages
        #
        if self.m_FilteringRDB.get() == 2:
            # Sets the custom filter
            #
            result = self.m_objPCANBasic.FilterMessages(self.m_PcanHandle,
                                                        int(self.m_IdFromNUD.get()),
                                                        int(self.m_IdToNUD.get()),
                                                        filterMode)
            # If success, an information message is written, if it is not, an error message is shown
            #
            if result == PCAN_ERROR_OK:
                self.IncludeTextMessage("The filter was customized. IDs from {0:X} to {1:X} will be received".format(int(self.m_IdFromNUD.get()),int(self.m_IdToNUD.get())))
            else:
                tkMessageBox.showinfo("Error!", self.GetFormatedError(result))
            return
        # The filter will be full opened or complete closed
        #
        if self.m_FilteringRDB.get() == 0:
            filterMode = PCAN_FILTER_CLOSE
            textEnd = "closed"
        else:
            filterMode = PCAN_FILTER_OPEN
            textEnd = "opened"
        # The filter is configured
        #
        result = self.m_objPCANBasic.SetValue(self.m_PcanHandle,
                                              PCAN_MESSAGE_FILTER,
                                              filterMode)
        
        # If success, an information message is written, if it is not, an error message is shown
        #
        if result == PCAN_ERROR_OK:
            self.IncludeTextMessage("The filter was successfully "+ textEnd)
        else:
            tkMessageBox.showinfo("Error!", self.GetFormatedError(result))
    ## Button btnFilterQuery handler
    ##
    def btnFilterQuery_Click(self):
        # Queries the current status of the message filter
        #
        filterRet = self.GetFilterStatus()
        if filterRet[0]:
            if filterRet[1] == PCAN_FILTER_CLOSE:
                self.IncludeTextMessage("The Status of the filter is: closed.")
            elif filterRet[1] == PCAN_FILTER_OPEN:
                self.IncludeTextMessage("The Status of the filter is: full opened.")
            elif filterRet[1] == PCAN_FILTER_CUSTOM:
                self.IncludeTextMessage("The Status of the filter is: customized.")
            else:
                self.IncludeTextMessage("The Status ofself.tmrRead the filter is: Invalid.")
                
    ## Button btnParameterSet handler
    ##
    def btnParameterSet_Click(self):
        currentVal = self.cbbParameter['selection']
        iVal = self.m_PARAMETERS[currentVal]
        if self.m_ConfigurationRDB.get() == 1:
            iBuffer = PCAN_PARAMETER_ON
            lastStr = "activated"
            lastStr2 = "ON"
        else:
            iBuffer = PCAN_PARAMETER_OFF
            lastStr = "deactivated"
            lastStr2 = "OFF"
        # The Device-Number of an USB channel will be set
        #
        if iVal == PCAN_DEVICE_NUMBER:
            iBuffer = int(self.m_DeviceIdNUD.get())
            result = self.m_objPCANBasic.SetValue(self.m_PcanHandle,PCAN_DEVICE_NUMBER,iBuffer)
            if result == PCAN_ERROR_OK:
                self.IncludeTextMessage("The desired Device-Number was successfully configured")
        # The 5 Volt Power feature of a PC-card or USB will be set
        #        
        elif iVal == PCAN_5VOLTS_POWER:
            result = self.m_objPCANBasic.SetValue(self.m_PcanHandle,PCAN_5VOLTS_POWER,iBuffer)
            if result == PCAN_ERROR_OK:
                self.IncludeTextMessage("The USB/PC-Card 5 power was successfully " + lastStr)
            
        # The feature for automatic reset on BUS-OFF will be set
        #        
        elif iVal == PCAN_BUSOFF_AUTORESET:
            result = self.m_objPCANBasic.SetValue(self.m_PcanHandle,PCAN_BUSOFF_AUTORESET,iBuffer)
            if result == PCAN_ERROR_OK:
                self.IncludeTextMessage("The automatic-reset on BUS-OFF was successfully " + lastStr)
            
        # The CAN option "Listen Only" will be set
        #        
        elif iVal == PCAN_LISTEN_ONLY:
            result = self.m_objPCANBasic.SetValue(self.m_PcanHandle,PCAN_LISTEN_ONLY,iBuffer)
            if result == PCAN_ERROR_OK:
                self.IncludeTextMessage("The CAN option ""Listen Only"" was successfully " + lastStr)
        # The feature for logging debug-information will be set
        #
        elif iVal == PCAN_LOG_STATUS:
            result = self.m_objPCANBasic.SetValue(PCAN_NONEBUS,PCAN_LOG_STATUS,iBuffer)
            if result == PCAN_ERROR_OK:
                self.IncludeTextMessage("The feature for logging debug information was successfully " + lastStr)
        # The channel option "Receive Status" will be set
        #        
        elif iVal == PCAN_RECEIVE_STATUS:
            result = self.m_objPCANBasic.SetValue(self.m_PcanHandle,PCAN_RECEIVE_STATUS,iBuffer)
            if result == PCAN_ERROR_OK:
                self.IncludeTextMessage("The channel option ""Receive Status"" was set to  " + lastStr2)
        # The feature for tracing will be set
        #        
        elif iVal == PCAN_TRACE_STATUS:
            result = self.m_objPCANBasic.SetValue(self.m_PcanHandle,PCAN_TRACE_STATUS,iBuffer)
            if result == PCAN_ERROR_OK:
                self.IncludeTextMessage("The feature for tracing data was successfully " + lastStr)
        # The feature for tracing will be set
        #        
        elif iVal == PCAN_CHANNEL_IDENTIFYING:
            result = self.m_objPCANBasic.SetValue(self.m_PcanHandle,PCAN_CHANNEL_IDENTIFYING,iBuffer)
            if result == PCAN_ERROR_OK:
                self.IncludeTextMessage("The procedure for channel identification was successfully " + lastStr)
        # The feature for using an already configured bit rate will be set
        #        
        elif iVal == PCAN_BITRATE_ADAPTING:
            result = self.m_objPCANBasic.SetValue(self.m_PcanHandle,PCAN_BITRATE_ADAPTING,iBuffer)
            if result == PCAN_ERROR_OK:
                self.IncludeTextMessage("The feature for bit rate adaptation was successfully " + lastStr)                
                
        # The current parameter is invalid
        #
        else:
            stsResult = PCAN_ERROR_UNKNOWN
            tkMessageBox.showinfo("Error!", "Wrong parameter code.")
        # If the function fail, an error message is shown
        #
        if result != PCAN_ERROR_OK:
            tkMessageBox.showinfo("Error!", self.GetFormatedError(result))
    ## Button btnParameterGet handler
    ##
    def btnParameterGet_Click(self):
        currentVal = self.cbbParameter['selection']
        iVal = self.m_PARAMETERS[currentVal]
        # The Device-Number of an USB channel will be retrieved
        #
        if iVal == PCAN_DEVICE_NUMBER:
            iBuffer = int(self.m_DeviceIdNUD.get())
            result = self.m_objPCANBasic.GetValue(self.m_PcanHandle,PCAN_DEVICE_NUMBER)
            if result[0] == PCAN_ERROR_OK:
                self.IncludeTextMessage("The configured Device-txtData0_LeaveNumber is {0:X}h".format(result[1]))
        # The activation status of the 5 Volt Power feature of a PC-card or USB will be retrieved
        #
        elif iVal == PCAN_5VOLTS_POWER:
            result = self.m_objPCANBasic.GetValue(self.m_PcanHandle,PCAN_5VOLTS_POWER)
            if result[0] == PCAN_ERROR_OK:
                if result[1] == PCAN_PARAMETER_ON:
                    lastStr = "ON"
                else:
                    lastStr = "OFF"
                self.IncludeTextMessage("The 5-Volt Power of the USB/PC-Card is " + lastStr)
                
        # The activation status of the feature for automatic reset on BUS-OFF will be retrieved
        #
        elif iVal == PCAN_BUSOFF_AUTORESET:
            result = self.m_objPCANBasic.GetValue(self.m_PcanHandle,PCAN_BUSOFF_AUTORESET)
            if result[0] == PCAN_ERROR_OK:
                if result[1] == PCAN_PARAMETER_ON:
                    lastStr = "ON"
                else:
                    lastStr = "OFF"
                self.IncludeTextMessage("The automatic-reset on BUS-OFF is " + lastStr)
        # The activation status of the CAN option "Listen Only" will be retrieved
        #
        elif iVal == PCAN_LISTEN_ONLY:
            result = self.m_objPCANBasic.GetValue(self.m_PcanHandle,PCAN_LISTEN_ONLY)
            if result[0] == PCAN_ERROR_OK:
                if result[1] == PCAN_PARAMETER_ON:
                    lastStr = "ON"
                else:
                    lastStr = "OFF"
                self.IncludeTextMessage("The CAN option ""Listen Only"" is " + lastStr)
        # The activation status for the feature for logging debug-information will be retrieved
        #
        elif iVal == PCAN_LOG_STATUS:
            result = self.m_objPCANBasic.GetValue(PCAN_NONEBUS,PCAN_LOG_STATUS)
            if result[0] == PCAN_ERROR_OK:
                if result[1] == PCAN_PARAMETER_ON:
                    lastStr = "ON"
                else:
                    lastStr = "OFF"
                self.IncludeTextMessage("The feature for logging debug information is " + lastStr)
        # The activation status of the channel option "Receive Status"  will be retrieved
        #
        elif iVal == PCAN_RECEIVE_STATUS:
            result = self.m_objPCANBasic.GetValue(self.m_PcanHandle,PCAN_RECEIVE_STATUS)
            if result[0] == PCAN_ERROR_OK:
                if result[1] == PCAN_PARAMETER_ON:
                    lastStr = "ON"
                else:
                    lastStr = "OFF"
                self.IncludeTextMessage("The channel option ""Receive Status"" is " + lastStr)
        # The Number of the CAN-Controller used by a PCAN-Channel
        #
        elif iVal == PCAN_CONTROLLER_NUMBER:
            result = self.m_objPCANBasic.GetValue(self.m_PcanHandle,PCAN_CONTROLLER_NUMBER)
            if result[0] == PCAN_ERROR_OK:
                self.IncludeTextMessage("The CAN Controller number is {0}".format(result[1]))
        # The activation status for the feature for tracing data will be retrieved
        #
        elif iVal == PCAN_TRACE_STATUS:
            result = self.m_objPCANBasic.GetValue(self.m_PcanHandle,PCAN_TRACE_STATUS)
            if result[0] == PCAN_ERROR_OK:
                if result[1] == PCAN_PARAMETER_ON:
                    lastStr = "ON"
                else:
                    lastStr = "OFF"
                self.IncludeTextMessage("The feature for tracing data is " + lastStr)
        # The activation status of the Channel Identifying procedure will be retrieved
        #
        elif iVal == PCAN_CHANNEL_IDENTIFYING:
            result = self.m_objPCANBasic.GetValue(self.m_PcanHandle,PCAN_CHANNEL_IDENTIFYING)
            if result[0] == PCAN_ERROR_OK:
                if result[1] == PCAN_PARAMETER_ON:
                    lastStr = "ON"
                else:
                    lastStr = "OFF"
                self.IncludeTextMessage("The identification procedure of the selected channel is " + lastStr)
        # The extra capabilities of a hardware will asked
        #
        elif iVal == PCAN_CHANNEL_FEATURES:
            result = self.m_objPCANBasic.GetValue(self.m_PcanHandle,PCAN_CHANNEL_FEATURES)
            if result[0] == PCAN_ERROR_OK:
                if (result[1] & FEATURE_FD_CAPABLE) == FEATURE_FD_CAPABLE:
                    lastStr = "does support"
                else:
                    lastStr = "DOESN'T SUPPORT"
                self.IncludeTextMessage("The channel %s Flexible Data-Rate (CAN-FD) " % lastStr)
        # The status of the bit rate adapting feature will be retrieved
        #
        elif iVal == PCAN_BITRATE_ADAPTING:
            result = self.m_objPCANBasic.GetValue(self.m_PcanHandle,PCAN_BITRATE_ADAPTING)
            if result[0] == PCAN_ERROR_OK:
                if result[1] == PCAN_PARAMETER_ON:
                    lastStr = "ON"
                else:
                    lastStr = "OFF"
                self.IncludeTextMessage("The feature for bit rate adaptation is %s" % lastStr)
        # The bit rate of the connected channel will be retrieved (BTR0-BTR1 value)
        #
        elif iVal == PCAN_BITRATE_INFO:
            result = self.m_objPCANBasic.GetValue(self.m_PcanHandle,PCAN_BITRATE_INFO)
            if result[0] == PCAN_ERROR_OK:
                self.IncludeTextMessage("The bit rate of the channel is %.4Xh" % result[1])
                                
        # The bit rate of the connected FD channel will be retrieved (String value)
        #
        elif iVal == PCAN_BITRATE_INFO_FD:
            result = self.m_objPCANBasic.GetValue(self.m_PcanHandle,PCAN_BITRATE_INFO_FD)
            if result[0] == PCAN_ERROR_OK:
                self.IncludeTextMessage("The bit rate of the channel is %s" % result[1])
        # The nominal speed configured on the CAN bus will be retrived (bits/second)
        #
        elif iVal == PCAN_BUSSPEED_NOMINAL:
            result = self.m_objPCANBasic.GetValue(self.m_PcanHandle,PCAN_BUSSPEED_NOMINAL)
            if result[0] == PCAN_ERROR_OK:
                self.IncludeTextMessage("The nominal speed of the channel is %d bit/s" % result[1])
        # The data speed configured on the CAN bus will be retrived (bits/second)
        #
        elif iVal == PCAN_BUSSPEED_DATA:
            result = self.m_objPCANBasic.GetValue(self.m_PcanHandle,PCAN_BUSSPEED_DATA)
            if result[0] == PCAN_ERROR_OK:
                self.IncludeTextMessage("The data speed of the channel is %d bit/s" % result[1])
        # The IP address of a LAN channel as string, in IPv4 format
        #
        elif iVal == PCAN_IP_ADDRESS:
            result = self.m_objPCANBasic.GetValue(self.m_PcanHandle,PCAN_IP_ADDRESS)
            if result[0] == PCAN_ERROR_OK:
                self.IncludeTextMessage("The IP address of the channel is %s" % result[1])                
                
        # The current parameter is invalid
        #
        else:
            stsResult = PCAN_ERROR_UNKNOWN,
            tkMessageBox.showinfo("Error!", "Wrong parameter code.")
         #If the function fail, an error message is shown
        #
        if result[0] != PCAN_ERROR_OK:
            tkMessageBox.showinfo("Error!", self.GetFormatedError(result[0]))
    ## Function for reading CAN messages on normal CAN devices
    ##
    def ReadMessage(self):
        # We execute the "Read" function of the PCANBasic
        #
        result = self.m_objPCANBasic.Read(self.m_PcanHandle)
        if result[0] == PCAN_ERROR_OK:
            # We show the received message
            #
            self.ProcessMessage(result[1:])
            
        return result[0]
    def ReadMessageFD(self):
        # We execute the "ReadFD" function of the PCANBasic
        #
        result = self.m_objPCANBasic.ReadFD(self.m_PcanHandle)
        if result[0] == PCAN_ERROR_OK:
            # We show the received message
            #
            self.ProcessMessageFD(result[1:])
            
        return result[0]
    def ReadMessages(self):
        stsResult = PCAN_ERROR_OK
        # We read at least one time the queue looking for messages.
        # If a message is found, we look again trying to find more.
        # If the queue is empty or an error occurr, we get out from
        # the dowhile statement.
        #
        while (self.m_Connected and not (stsResult & PCAN_ERROR_QRCVEMPTY)):
                stsResult = self.ReadMessageFD() if self.m_IsFD else self.ReadMessage()
                if stsResult == PCAN_ERROR_ILLOPERATION:
                    break
    
    ## Button btnRead handler
    ##
    def btnRead_Click(self):
        # We execute the "Read" function of the PCANBasic
        #
        result = self.ReadMessageFD() if self.m_IsFD else self.ReadMessage()
        if result != PCAN_ERROR_OK:
            # If an error occurred, an information message is included
            #
            self.IncludeTextMessage(self.GetFormatedError(result))
    ## Button btnGetVersions handler
    ##
    def btnGetVersions_Click(self):
        # We get the vesion of the PCAN-Basic API
        #
        result = self.m_objPCANBasic.GetValue(PCAN_NONEBUS, PCAN_API_VERSION)
        if result[0] ==PCAN_ERROR_OK:
            self.IncludeTextMessage("API Version: " + result[1])
            # We get the driver version of the channel being used
            #
            result = self.m_objPCANBasic.GetValue(self.m_PcanHandle, PCAN_CHANNEL_VERSION)
            if result[0] == PCAN_ERROR_OK:
                # Because this information contains line control characters (several lines)
                # we split this also in several entries in the Information List-Box
                #
                lines = string.split(result[1],'\n')
                self.IncludeTextMessage("Channel/Driver Version: ")
                for line in lines:
                    self.IncludeTextMessage("     * " + line)
        # If an error ccurred, a message is shown
        #
        if result[0] != PCAN_ERROR_OK:
            tkMessageBox.showinfo("Error!", self.GetFormatedError(result[0]))
    ## Button btnMsgClear handler
    ##
    def btnMsgClear_Click(self, *args):
        # The information contained in the messages List-View
        # is cleared
        #
        with self._lock:
            self.lstMessages.delete(0,END)
            self.m_LastMsgsList = []
    ## Button btnInfoClear handler
    ##
    def btnInfoClear_Click(self, event=None):
        # The information contained in the Information List-Box 
        # is cleared
        #
        self.lbxInfo.delete(0,END)
    def WriteFrame(self):   
        # We create a TPCANMsg message structure
        #
        CANMsg = TPCANMsg()
        # We configurate the Message.  The ID,
        # Length of the Data, Message Type and the data
        #
        CANMsg.ID = int(self.m_IDTXT.get(),16)
        CANMsg.LEN = int(self.m_LengthNUD.get())
        CANMsg.MSGTYPE = PCAN_MESSAGE_EXTENDED if self.m_ExtendedCHB.get() else PCAN_MESSAGE_STANDARD
        # If a remote frame will be sent, the data bytes are not important.
        #
        if self.m_RemoteCHB.get():
            CANMsg.MSGTYPE |= PCAN_MESSAGE_RTR.value
        else:
            # We get so much data as the Len of the message
            #
            for i in range(CANMsg.LEN):
                CANMsg.DATA[i] = int(self.m_DataEdits[i].get(),16)
        # The message is sent to the configured hardware
        #
        return self.m_objPCANBasic.Write(self.m_PcanHandle, CANMsg)
    def WriteFrameFD(self):
        # We create a TPCANMsgFD message structure
        #
        CANMsg = TPCANMsgFD()
        # We configurate the Message.  The ID,
        # Length of the Data, Message Type and the data
        #
        CANMsg.ID = int(self.m_IDTXT.get(),16)
        CANMsg.DLC = int(self.m_LengthNUD.get())
        CANMsg.MSGTYPE = PCAN_MESSAGE_EXTENDED if self.m_ExtendedCHB.get() else PCAN_MESSAGE_STANDARD
        CANMsg.MSGTYPE |= PCAN_MESSAGE_FD.value if self.m_FDCHB.get() else PCAN_MESSAGE_STANDARD.value
        CANMsg.MSGTYPE |= PCAN_MESSAGE_BRS.value if self.m_BRSCHB.get() else PCAN_MESSAGE_STANDARD.value
        # If a remote frame will be sent, the data bytes are not important.
        #
        if self.m_RemoteCHB.get():
            CANMsg.MSGTYPE |= PCAN_MESSAGE_RTR.value
        else:
            #iLength = self.GetLengthFromDLC(CANMsg.DLC, not(CANMsg.MSGTYPE & PCAN_MESSAGE_FD.value))
            iLength = GetLengthFromDLC(CANMsg.DLC, not(CANMsg.MSGTYPE & PCAN_MESSAGE_FD.value))
            # We get so much data as the Len of the message
            #
            for i in range(iLength):
                CANMsg.DATA[i] = int(self.m_DataEdits[i].get(),16)
        # The message is sent to the configured hardware
        #
        return self.m_objPCANBasic.WriteFD(self.m_PcanHandle, CANMsg)                
    ## Button btnWrite handler
    ##
    def btnWrite_Click(self):
        # Send the message
        #
        stsResult = self.WriteFrameFD() if self.m_IsFD else self.WriteFrame()
        # The message was successfully sent
        #
        if stsResult == PCAN_ERROR_OK:
            self.IncludeTextMessage("Message was successfully SENT")
        else:
            # An error occurred.  We show the error.
            #
            tkMessageBox.showinfo(self.GetFormatedError(stsResult))
    ## Button btnReset handler
    ##
    def btnReset_Click(self):
        # Resets the receive and transmit queues of a PCAN Channel.
        #
        result = self.m_objPCANBasic.Reset(self.m_PcanHandle)
        # If it fails, a error message is shown
        #
        if result != PCAN_ERROR_OK:
            tkMessageBox.showinfo("Error!", self.GetFormatedTex(result))
        else:
            self.IncludeTextMessage("Receive and transmit queues successfully reset")
    ## Button btnStatus handler
    ##            
    def btnStatus_Click(self):
        # Gets the current BUS status of a PCAN Channel.
        #
        result = self.m_objPCANBasic.GetStatus(self.m_PcanHandle)
        # Switch On Error Name
        #
        if result == PCAN_ERROR_INITIALIZE:
            errorName = "PCAN_ERROR_INITIALIZE"
        elif result == PCAN_ERROR_BUSLIGHT:
            errorName = "PCAN_ERROR_BUSLIGHT"
        elif result == PCAN_ERROR_BUSHEAVY: # PCAN_ERROR_BUSWARNING
            errorName = "PCAN_ERROR_BUSHEAVY" if not self.m_IsFD else "PCAN_ERROR_WARNING"
        elif result == PCAN_ERROR_BUSPASSIVE:
            errorName = "PCAN_ERROR_BUSPASSIVE"
        elif result == PCAN_ERROR_BUSOFF:
            errorName = "PCAN_ERROR_BUSOFF"
        elif result == PCAN_ERROR_OK:
            errorName = "PCAN_ERROR_OK"
        else:
            errorName = "See Documentation"
        # Display Message
        #
        self.IncludeTextMessage("Status: {0} ({1:X}h)".format(errorName, result))
    ## Combobox cbbChannel handler
    ##          
    def cbbChannel_SelectedIndexChanged(self, currentValue):
        # Get the handle from the text being shown
        #
        self.m_PcanHandle = self.m_CHANNELS[currentValue]
        # Determines if the handle belong to a No Plug&Play hardware
        #
        if self.m_PcanHandle < PCAN_DNGBUS1:
            putItActive = NORMAL
        else:
            putItActive = DISABLED
        # Activates/deactivates configuration controls according with the 
        # kind of hardware
        #
        self.cbbHwType['state'] = putItActive
        self.cbbIO['state'] = putItActive
        self.cbbInterrupt['state'] = putItActive
    ## Combobox cbbParameter handler
    ##     
    def cbbParameter_SelectedIndexChanged(self, currentValue=None):
        # Activates/deactivates controls according with the selected 
        # PCAN-Basic parameter
        #
        bIsRB = currentValue != 'USBs Device Number'
        if bIsRB:
            self.rdbParamActive['state'] = ACTIVE
            self.rdbParamInactive['state'] = ACTIVE
            self.nudDeviceId['state'] = DISABLED
        else:
            self.rdbParamActive['state'] = DISABLED
            self.rdbParamInactive['state'] = DISABLED
            self.nudDeviceId['state'] = NORMAL
            
    ## Checkbox chbRemote handler
    ## 
    def chbRemote_CheckedChanged(self):     
        # Determines the status for the textboxes
        # according wiht the cehck-status
        #
        if self.m_RemoteCHB.get():            
            newStatus = DISABLED
            iCount = 8
        else:
            newStatus = NORMAL
            iCount = int(self.m_LengthNUD.get())        
        self.chbFD['state'] = newStatus
        
        # If the message is a RTR, no data is sent. The textboxes for data 
        # will be disabled
        #
        for i in range(iCount):
            self.m_CtrlEdits[i]['state'] = newStatus
    def chbFD_CheckedChanged(self):        
        self.chbRemote['state'] = NORMAL if (not self.m_FDCHB.get()) else DISABLED
        self.chbBRS['state'] = NORMAL if self.m_FDCHB.get() else DISABLED
        if self.chbBRS['state'] == DISABLED:
            self.chbBRS.deselect()
        self.nudLength['to'] = 15 if self.m_FDCHB.get() else 8
        self.nudLength_ValueChanged()
    ## Checkbox chbFilterExt handler
    ##             
    def chbFilterExt_CheckedChanged(self):
        # Determines the maximum value for a ID
        # according with the Filter-Type
        #
        if self.m_FilterExtCHB.get():
            self.nudIdTo['to'] = 0x1FFFFFFF
            self.nudIdFrom['to'] = 0x1FFFFFFF
        else:
            self.nudIdTo['to'] = 0x7FF
            self.nudIdFrom['to'] = 0x7FF
        # We check that the maximum value for a selected filter 
        # mode is used
        #
        if int(self.m_IdToNUD.get()) > self.nudIdTo['to']:
            self.m_IdToNUD.set(iMaxValue)
        if int(self.m_IdFromNUD.get()) > self.nudIdFrom['to']:
            self.m_IdFromNUD.set(iMaxValue)
    ## Checkbox chbFilterExt handler
    ##             
    def chbCanFD_CheckedChanged(self):
        self.m_IsFD = self.m_CanFDCHB.get()
        
        # Determines the maximum value for a ID
        # according with the Filter-Type
        #
        if self.m_CanFDCHB.get():
            self.m_BaudrateLA.set("Bit rate:")
            self.m_HwTypeLA.set(" ")
            self.m_IOPortLA.set(" ")
            self.m_InterruptLA.set(" ")
            self.cbbBaudrates.grid_forget()
            self.cbbHwType.grid_forget()
            self.cbbIO.grid_forget()
            self.cbbInterrupt.grid_forget()
            self.txtBitrate.grid(row=1,column=2, columnspan=4, padx=10, pady= 0)
            self.chbFD.grid(row=3,column=17, padx=0, pady=0, sticky=W)
            self.chbBRS.grid(row=3,column=18, padx=0, pady=0, sticky=W)
        else:
            self.m_BaudrateLA.set("Baudrate:")
            self.m_HwTypeLA.set("Hardware Type:")
            self.m_IOPortLA.set("I/O Port:")
            self.m_InterruptLA.set("Interrupt:")
            self.cbbBaudrates.grid(row=1,column=2,sticky=W)
            self.cbbHwType.grid(row=1,column=3,sticky=W)
            self.cbbIO.grid(row=1,column=4,sticky=W)
            self.cbbInterrupt.grid(row=1,column=5, sticky=W)
            self.txtBitrate.grid_forget()
            self.chbFD.grid_forget()
            self.chbBRS.grid_forget()
        if (self.nudLength['to'] > 8) and (not self.m_IsFD):
            self.chbFD.deselect()
            self.chbFD_CheckedChanged()
    ## checkbutton chbShowPeriod handler
    ##              
    def chbShowPeriod_CheckedChanged(self):
        with self._lock:
            for msgStatus in self.m_LastMsgsList:
                msgStatus.ShowingPeriod = self.m_ShowPeriodCHB.get()
        
    ## Radiobutton rdbTimer handler
    ##              
    def rdbTimer_CheckedChanged(self):
        if self.btnRelease['state'] == DISABLED:
            return
        # Stop the timer, if running
        #
        self.tmrRead.stop()
        
        # According with the kind of reading, a timer, a thread or a button will be enabled
        #
        if self.m_ReadingRDB.get() == 1:
            #tkMessageBox.showinfo(message="TODO (rdbTimer_CheckedChanged): Reading with a TIMER")
            self.tmrRead.start()
        if self.m_ReadingRDB.get() == 2:
            tkMessageBox.showinfo(message="Reading using an EVENT requires Win32Event module. It is done in a separated example!!!")
            
        if (self.btnRelease['state'] != DISABLED) and (self.m_ReadingRDB.get() == 0):
            self.btnRead['state'] = ACTIVE
        else:
            self.btnRead['state'] = DISABLED        
       
    ## Entry txtID OnLeave handler
    ##                   
    def txtID_Leave(self,*args):
        # Calculates the text length and Maximum ID value according
        # with the Message Typ
        #
        if self.m_ExtendedCHB.get():
            iTextLength = 8
            uiMaxValue = 0x1FFFFFFF
        else:
            iTextLength = 3
            uiMaxValue = 0x7FF
        
        try:
            iValue = int(self.m_IDTXT.get(),16)       
        except ValueError:
            iValue = 0
        finally:
            # The Textbox for the ID is represented with 3 characters for 
            # Standard and 8 characters for extended messages.
            # We check that the ID is not bigger than current maximum value
            #
            if iValue > uiMaxValue:
                iValue = uiMaxValue            
            self.m_IDTXT.set("{0:0{1}X}".format(iValue,iTextLength))
            return True
        
    ## Entry txtData0 OnLeave handler
    ##   
    def txtData0_Leave(self,*args):        
        for i in range(8):
            # The format of all Textboxes Data fields are checked.
            #
            self.txtData0_LeaveHelper(self.m_DataEdits[i])
    ## Helper function for the above funciton
    #
    def txtData0_LeaveHelper(self, editVar):
        try:
            iValue = int(editVar.get(),16)       
        except ValueError:
            iValue = 0
        finally:
            # All the Textbox Data fields are represented with 2 characters.
            # The maximum value allowed is 255 (0xFF)
            #
            if iValue > 255:
                iValue = 255
            editVar.set("{0:0{1}X}".format(iValue,2))
        
    # Spinbutton nudLength handler
    def nudLength_ValueChanged(self):       
        #iCount = self.GetLengthFromDLC(int(self.m_LengthNUD.get()), not self.m_FDCHB.get())
        iCount = GetLengthFromDLC(int(self.m_LengthNUD.get()), not self.m_FDCHB.get())
        self.m_LengthLA.set('%s B.' % iCount)
        # The Textbox Data fields are enabled or disabled according
        # with the desaired amount of data
        #
        for i in range(64):
            if i < iCount:
                self.m_CtrlEdits[i]['state'] = NORMAL
            else:
                self.m_CtrlEdits[i]['state'] = DISABLED
                
                             
    def tmrRead_Tick(self):
        # Checks if in the receive-queue are currently messages for read
        # 
        self.ReadMessages()
    def tmrDisplay_Tick(self):
        self.DisplayMessages()
    
###*****************************************************************
        
###*****************************************************************
### ROOT
###*****************************************************************
### Loop-Functionallity  
def RunMain(root):
    global basicExl
    # Creates a PCAN-Basic application
    #
    basicExl = PCANBasicExample(root)
    
    # Runs the Application / loop-start
    #
    basicExl.loop()
    
    # Application's destrution / loop-end
    #
    basicExl.destroy()
if __name__ == '__main__':
    # Creates the Tkinter-extension Root
    #
    root = Tix.Tk()
    # Uses the root to launch the PCAN-Basic Example application
    #
    RunMain(root)
###*****************************************************************

Офлайн

#5 Сен. 9, 2015 10:55:27

eleks
Зарегистрирован: 2014-08-14
Сообщения: 24
Репутация: +  0  -
Профиль   Отправить e-mail  

PCAN-USB подключение

Честно сказать, опасался, что код не влезет.
И так:
Вначале идёт импорт внешних библиотек. С этим вроде бы ясно.
Далее определение каких-то констант.
А ещё дальше функция, потом три класса и ещё функция.
Как понял, вложенность полностью определяется величиной отступа?
Ну, первая функция GetLengthFromDLC(dlc, isSTD), как-бы не тянет на основную программу. Классы тоже сами по себе не являются программой. Тогда получается основная программа это функция RunMain(root)? RunMain это какое-то волшебное слово или название основной функции выбирается из каких-то других принципов? Что означает входной параметр (root)?
Теперь классы. С ними наиболее сложно. Похоже в них навалено всё что угодно скопом, какие-то функции, присвоение значений… Где-то есть на них более менее вменяемое описание?
Потом строка

basicExl = PCANBasicExample(root)
тоже выглядит странно. Как можно приравнять некую переменную классу? И чем эта переменная будет являтся после такого приравнивания? Что означает входной параметр (root) для класса?

Отредактировано eleks (Сен. 9, 2015 10:56:52)

Офлайн

#6 Сен. 9, 2015 11:13:40

i.slepov
Зарегистрирован: 2015-05-28
Сообщения: 53
Репутация: +  5  -
Профиль   Отправить e-mail  

PCAN-USB подключение

eleks
Например, в Си всё ясно - основная программа, это функция main(). За пределами этой функции могут находится другие функции, а также объявления переменных и констант (как-то так).

Всё то же самое.

eleks
Тогда получается основная программа это функция RunMain(root)?

У вас же в коде всё написано.

if __name__ == '__main__':  # Если рантайм требует функцию main
    # Creates the Tkinter-extension Root
    #
    root = Tix.Tk()
    # Uses the root to launch the PCAN-Basic Example application
    #
    RunMain(root)

eleks
Как можно приравнять некую переменную классу?

Не приравнять, а создать экземпляр.

Офлайн

#7 Сен. 9, 2015 11:42:47

eleks
Зарегистрирован: 2014-08-14
Сообщения: 24
Репутация: +  0  -
Профиль   Отправить e-mail  

PCAN-USB подключение

i.slepov
У вас же в коде всё написано.
if __name__ == '__main__':  # Если рантайм требует функцию main
    # Creates the Tkinter-extension Root
    #
    root = Tix.Tk()
    # Uses the root to launch the PCAN-Basic Example application
    #
    RunMain(root)
Получается, что собственно программа начинается условием
if __name__ == '__main__':
и если условие верно, то root получает значение
root = Tix.Tk()
и затем запускается функция RunMain(root) ?
Если так, то продолжим.
Что это за параметр __name__ ? Это какая-то встроенная переменная Python? В каком случае этот параметр будет иметь значение в виде строки ‘__main__’ , а в каком не будет? И какие вообще значения может иметь этот параметр?
Я тут читаю один талмуд по Python, но разъяснения этих вопросов пока не обнаружил.

Отредактировано eleks (Сен. 9, 2015 11:44:14)

Офлайн

#8 Сен. 9, 2015 12:15:42

eleks
Зарегистрирован: 2014-08-14
Сообщения: 24
Репутация: +  0  -
Профиль   Отправить e-mail  

PCAN-USB подключение

eleks
Что это за параметр __name__ ?
Кое-что об этом нашел в теме if __name__ == “__main__” :

Офлайн

#9 Сен. 9, 2015 12:24:14

J.R.
Зарегистрирован: 2015-07-18
Сообщения: 147
Репутация: +  16  -
Профиль  

PCAN-USB подключение

.

Отредактировано J.R. (Янв. 27, 2016 08:56:36)

Офлайн

#10 Сен. 9, 2015 12:36:21

i.slepov
Зарегистрирован: 2015-05-28
Сообщения: 53
Репутация: +  5  -
Профиль   Отправить e-mail  

PCAN-USB подключение

eleks
Получается, что собственно программа начинается условием

В языке Си интерфейсы описываются в заголовочных файлах (.h). и оттуда импортируются.
В python такого разделения нет. Любой файл с исходником может быть как основной программой, так и библиотекой. Любой файл с программным кодом может быть импортирован. По умолчанию всё что вы пишете непосредственно в теле программы выполняется.

То есть если вы выполните:
#!/usr/bin/env python
# hello.py
print('Hello World!')

То увидите сообщение `Hello World! `.

Если вы предполагаете использовать этот файл только как библиотеку, то тогда пишите

# libhello.py
def hello():
   print("Hello World!)

Если вы выполните эту программу то никакого вывода не увидите, т. к. функция hello не выполнится.
Но теперь вы можете импортировать эту функцию из другой программы:

#sampleimport.py
import libhello
libhello.hello()

И всё сработает. Но как быть если вы предполагаете что файл может быть использован как библиотека так и выполнен самостоятельно? Приходит например такая мысль:

# libhello.py
def hello():
   print("Hello World!)
hello()

и:

#sampleimport.py
import libhello
libhello.hello()

Если вы выполните libhello.py то увидите строку `Hello World! `. А если выполните sampleimport.py то неожиданно увидите эту строчку дважды. Первый раз выполнится при импорте, второй раз когда вы выполните функцию.
Чтобы это “разрулить” применяют такую конструкцию:
# libhello.py
def hello():
   print("Hello World!)
if __name__ == '__main__':
    hello()
Которая буквально говорит о том, что код под ней будет выполнен только при самостоятельном запуске и при импорте не произойдет ничего непредвиденного.


Офлайн

Board footer

Модераторировать

Powered by DjangoBB

Lo-Fi Version