Henkjan 2 Ответов: 0

Резьба для CAN USB устройства от lawicel


Дорогие Все,
Может быть, кто-нибудь сможет мне помочь. У меня есть приложение с USB-соединением с конвертером lawicel CANUSB. Все работает нормально, но постепенно мое приложение работает медленно или даже замерзает.
Я знаю, что, возможно, использование второй нити поможет. Я вижу много примеров для последовательного порта, но, к сожалению, ничего для USB-устройства с прямой библиотекой.

Мое приложение запускает обновление данных CAN каждые 100 мс. около 40 различных CANid загружаются и будут обрабатываться в приложении. В данный момент обновление и загрузка обновленных CANids осуществляется через таймер.tick.

Есть ли лучшее решение, чтобы заставить его работать, не замедляя работу моего компьютера через час?

Что я уже пробовал:

Private Sub CANframes_Tick(sender As System.Object, e As System.EventArgs) Handles CANframes.Tick
        Dim retval As Short
        Dim msg As Lawicel.CANUSB.CANMsg
        Dim buffer As String = ""
        If (bOpen) Then
            retval = Lawicel.CANUSB.canusb_Read(h, msg)
            While (retval = Lawicel.CANUSB.ERROR_CANUSB_OK)
                If msg.id = 522 Then
                    byteres = BitConverter.GetBytes(msg.data)
                End If
                If msg.id = 420 Then

                    Readbyte1 = BitConverter.GetBytes(msg.data) 
                End If
                If msg.id = 421 Then
                    Readbyte2 = BitConverter.GetBytes(msg.data) 
                End If
                If msg.id = 422 Then
                    Readbyte3 = BitConverter.GetBytes(msg.data) 
                End If
                If msg.id = 423 Then
                    Readbyte4 = BitConverter.GetBytes(msg.data)
                End If
                If msg.id = 450 Then
                    Readbyte11 = BitConverter.GetBytes(msg.data)
                End If
                If msg.id = 460 Then
                    Readbyte12 = BitConverter.GetBytes(msg.data)
                End If
                If msg.id = 461 Then
                    Readbyte13 = BitConverter.GetBytes(msg.data)
                End If
                If msg.id = 462 Then
                    Readbyte14 = BitConverter.GetBytes(msg.data)
                End If
                If msg.id = 463 Then
                    Readbyte15 = BitConverter.GetBytes(msg.data)
                End If
                If msg.id = 150 Then
                    readvar7 = BitConverter.GetBytes(msg.data)
                End If
                If msg.id = 151 Then
                    readvar8 = BitConverter.GetBytes(msg.data)
                End If
                If msg.id = 152 Then
                    readvar9 = BitConverter.GetBytes(msg.data)
                End If
                If msg.id = 153 Then
                    readvar10 = BitConverter.GetBytes(msg.data)
                End If
                If msg.id = 154 Then
                    readvar11 = BitConverter.GetBytes(msg.data)
                End If
                If msg.id = 162 Then
                    readvar1 = BitConverter.GetBytes(msg.data)
                End If
                If msg.id = 164 Then
                    readvar2 = BitConverter.GetBytes(msg.data)
                End If
                If msg.id = 165 Then
                    readvar3 = BitConverter.GetBytes(msg.data)
                End If
                If msg.id = 166 Then
                    readvar4 = BitConverter.GetBytes(msg.data)
                End If
                If msg.id = 167 Then
                    readvar5 = BitConverter.GetBytes(msg.data)
                End If
                If msg.id = 168 Then
                    readvar6 = BitConverter.GetBytes(msg.data)
                End If
                If msg.id = 177 Then
                    readvar16 = BitConverter.GetBytes(msg.data)
                End If
                If msg.id = 202 Then
                    readvar12 = BitConverter.GetBytes(msg.data)
                End If
                If msg.id = 216 Then
                    readvar13 = BitConverter.GetBytes(msg.data)
                End If
                If msg.id = 217 Then
                    readvar14 = BitConverter.GetBytes(msg.data)
                End If
                If msg.id = 218 Then
                    readvar15 = BitConverter.GetBytes(msg.data)
                End If
                If msg.id = 223 Then
                    readvar17 = BitConverter.GetBytes(msg.data)
                End If
                If msg.id = 224 Then
                    readvar18 = BitConverter.GetBytes(msg.data)
                End If
                If msg.id = 773 Then
                    readwatchdog = BitConverter.GetBytes(msg.data)
                End If
                retval = Lawicel.CANUSB.canusb_Read(h, msg)
            End While
         
        End If
        If UpdateTimer.Enabled = False Then
            UpdateTimer.Enabled = True
        End If
   
    End Sub

Каждый CANID устанавливается в свой собственный байтовый массив из 8 байт. (например, readvar1)
UpdateTimer, который включен в нижней части, предназначен для обновления панели мониторинга формы.

MadMyche

Вы запускали это в отладке, наблюдая за памятью? Что произойдет, если снизить частоту обновления?

Jaroslav Mitrovic

Привет.

Я не видел ничего вредного...

Но, может быть, два вызова "ретваль = Лавицель.CANUSB.canusb_Read(h, msg)" внутри цикла слишком много. Я бы постарался избавиться от первого звонка (если время критическое, то и от последнего звонка). Ах, я скучал по нему... теперь понял. Вы используете первый вызов, чтобы сохранить "retval" для Условия While, но позже вы вспоминаете его внутри WhileLoop (в конце), пытаясь избавиться от последнего вызова "retval = Lawicel.CANUSB.canusb_Read(Н, МСГ)".

c.u. Zui из Гамбурга

Henkjan 2

Привет,

я попробую это сделать, но именно так поставщик построил свою собственную демонстрационную версию can read/write. Спасибо за предложение.
Greetz Henkjan

Jaroslav Mitrovic

Привет,

может быть, тогда у поставщика есть причина разместить его в своей демо-версии...
Вполне возможно, что значение внутри переменной (я предполагаю, что "msg") может быть изменено тем временем.
Но в любом случае сообщения типа "ОК" - это единственные, которые обрабатываются, так зачем же тогда читать их снова? Если вы получаете неправильные результаты или выходите из строя, возможно, вы также вынуждены читать значение внутри цикла.
Если это так, то вам нужна стратегия кэширования значений (?), если это необходимо, попробуйте FiFo LiFo или некоторые из этих причудливых именованных стеков или очередей ;) .
Но имейте в виду, что Фифи звучит мило, но она действительно большая (доберманы обычно бывают...).

О'Кей, забавная кость в придачу...

Я хотел бы использовать выбираем-случае, если-отчетность.

А также рефакторинг его внутри "аутсорсинговой" функции.

Может быть, вы можете "сгруппировать" выходы с помощью чего-то вроде
Кейс msg.id >= 420 AndAlso msg.id <= 463
'Вообще-то про ByteValues

и т.д.

Удачи и счастливого кодирования

0 Ответов