Снова про Com порт

Язык Visual Basic на платформе .NET.

Модераторы: Ramzes, Sebas

Qwertiy
Доктор VB наук
Доктор VB наук
 
Сообщения: 2753
Зарегистрирован: 26.06.2011 (Вс) 21:26

Сообщение Qwertiy » 22.08.2013 (Чт) 18:39

А какой основной вид деятельности?
В чём ты измеряешь скорость?
Так что происходит при вызове Write на целый массив при нормальном таймауте? Под нормальным я понимаю в 2 раза больший, чем то время, за которое отрабатывает твоя программа при правильной скорости.

insite2012
Продвинутый пользователь
Продвинутый пользователь
 
Сообщения: 109
Зарегистрирован: 22.03.2013 (Пт) 8:06
Откуда: Россия, Саратов

Re: Снова про Com порт

Сообщение insite2012 » 22.08.2013 (Чт) 18:46

Основной вид деятельности - я электронщик, исследую контроллеры, изучаю возможности их записи (и чтения, естественно :D ). Ну и еще занимаюсь ремонтом электроники в современной бытовой технике (в основном специализируюсь на СМА).
Сейчас попробую сразу послать весь массив на запись в порт.
Dulce et decorum est pro patria mori

Qwertiy
Доктор VB наук
Доктор VB наук
 
Сообщения: 2753
Зарегистрирован: 26.06.2011 (Вс) 21:26

Сообщение Qwertiy » 22.08.2013 (Чт) 18:48

insite2012 писал(а):Основной вид деятельности - я электронщик, исследую контроллеры, изучаю возможности их записи (и чтения, естественно :D ).

Я всегда считал, что чтением и записью контроллеров занимаются программисты...

insite2012
Продвинутый пользователь
Продвинутый пользователь
 
Сообщения: 109
Зарегистрирован: 22.03.2013 (Пт) 8:06
Откуда: Россия, Саратов

Re: Снова про Com порт

Сообщение insite2012 » 22.08.2013 (Чт) 18:49

Хм... Метод Write вызывается только для отправки строки... А у меня байты...
Dulce et decorum est pro patria mori

insite2012
Продвинутый пользователь
Продвинутый пользователь
 
Сообщения: 109
Зарегистрирован: 22.03.2013 (Пт) 8:06
Откуда: Россия, Саратов

Re: Снова про Com порт

Сообщение insite2012 » 22.08.2013 (Чт) 18:51

Qwertiy писал(а):
insite2012 писал(а):Основной вид деятельности - я электронщик, исследую контроллеры, изучаю возможности их записи (и чтения, естественно :D ).

Я всегда считал, что чтением и записью контроллеров занимаются программисты...

А мне это по работе необходимо. :D Сами понимаете, современная техника вся на них собрана. Потому я и решил хоть немного, но стать программистом.
Ну и нравится мне это, не скрою. Думаю, Вы уже поняли основное назначение этой программы. :D
Dulce et decorum est pro patria mori

Qwertiy
Доктор VB наук
Доктор VB наук
 
Сообщения: 2753
Зарегистрирован: 26.06.2011 (Вс) 21:26

Сообщение Qwertiy » 22.08.2013 (Чт) 18:55

insite2012 писал(а):Хм... Метод Write вызывается только для отправки строки... А у меня байты...

Ну написано же что для кучка массива байтов. Более того, ты именно его и используешь, но передаёшь j как начальную границу и 1 как длину...
Кстати, там есть странное предупреждение про кодировку...

insite2012 писал(а):Ну и нравится мне это, не скрою.

Ну так хорошо :)

insite2012 писал(а):Думаю, Вы уже поняли основное назначение этой программы. :D

Тестирование работы контроллера?

insite2012
Продвинутый пользователь
Продвинутый пользователь
 
Сообщения: 109
Зарегистрирован: 22.03.2013 (Пт) 8:06
Откуда: Россия, Саратов

Re: Снова про Com порт

Сообщение insite2012 » 22.08.2013 (Чт) 19:00

Не только тестирование... Там же дальше передача будет (если ответ от контроллера корректный). И анализ того, что принято. Если анализ отрицательный - посылка другого значения... И так далее, до совпадения. Более подробно рассказывать в открытую не стоит, надеюсь Вы меня поняли.
Сейчас закоментирую в тестовом проекте свой код и попробую через Write...
Dulce et decorum est pro patria mori

Qwertiy
Доктор VB наук
Доктор VB наук
 
Сообщения: 2753
Зарегистрирован: 26.06.2011 (Вс) 21:26

Сообщение Qwertiy » 22.08.2013 (Чт) 19:05

insite2012 писал(а):И анализ того, что принято. Если анализ отрицательный - посылка другого значения...

Я примерно это и имел в виду под тестированием, но всё-таки видимо немного не это.
Я подумал про проверку работоспособности, путём проверки ответов на корректность.
Тут видимо что-то немного другое... Может идентификация чего-либо?

insite2012 писал(а):Более подробно рассказывать в открытую не стоит

Ладно, я всё равно в микроэлектронике не разбираюсь...

insite2012
Продвинутый пользователь
Продвинутый пользователь
 
Сообщения: 109
Зарегистрирован: 22.03.2013 (Пт) 8:06
Откуда: Россия, Саратов

Re: Снова про Com порт

Сообщение insite2012 » 22.08.2013 (Чт) 19:11

В общем, что-то я не понял, какой ТаймАут ставить... Ставлю WriteTimeOut, любой - все равно весь массив сразу в порт летит, и толком ничего не принимается...
Да, примерно похоже на идентификацию... Если мои 8 байт совпали с тем,что есть внутри мк,то я смогу его считать.Если нет-только стереть и записать по новой.
Dulce et decorum est pro patria mori

insite2012
Продвинутый пользователь
Продвинутый пользователь
 
Сообщения: 109
Зарегистрирован: 22.03.2013 (Пт) 8:06
Откуда: Россия, Саратов

Re: Снова про Com порт

Сообщение insite2012 » 23.08.2013 (Пт) 3:50

Ув. Qwertiy, еще раз спасибо Вам за науку. :D Сделал вчера опытный проект, и выяснилось, что с моей хитрой процедурой с веселым названием zad() работает программа не стабильно... То порт закроется в не то время, то еще что... Почитал в справочнике, применил Thread.Sleep, поставил везде одинаковую задержку - и все пошло работать намного стабильнее.
Dulce et decorum est pro patria mori

insite2012
Продвинутый пользователь
Продвинутый пользователь
 
Сообщения: 109
Зарегистрирован: 22.03.2013 (Пт) 8:06
Откуда: Россия, Саратов

Re: Снова про Com порт

Сообщение insite2012 » 23.08.2013 (Пт) 21:31

Возвращаюсь к своей теме... Вроде бы все написал, но никак не могу добиться стабильности. Моя задача - отправив один байт, принять два (или три, в зависимости от ситуации). И вот я никак не могу добиться полной синхронизации между тем что отправляю и что принимаю. Идет рассинхронизация, и естественно, в буфере приема не те значения, что нужны, и все сравнение не проходит... Подскажите, может есть методы для синхронизации отправляемого потока байтов и принимаемого... Сейчас добавлю код моего творения...
Уже что только не думал, вплоть до того, чтобы все это к таймеру привязать...Со вчерашнего дня бьюсь с этой задачей. :D

Код: Выделить всё
Imports System.IO
Imports System.IO.Ports
Imports System.Threading
Public Class Form1
    Dim Mass_Size As Integer
    Dim MyPorts As Array
    Dim Zapros_MassArray() As Byte = New Byte() {&HFF, &HFF, &HFF, &HFF, &HFF, &HFF, &HFF, &HFF}
    Dim Otvet_massArray() As Byte = New Byte(24) {}
    Dim Zapros_from_file() As Byte = New Byte(7) {}
    Dim Zapros_stage_1() As Byte = New Byte() {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, &H4A, &HFF, &HF6}
    Dim Zapros_stage_2() As Byte = New Byte() {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, &H4A, &HFF, &HF7}
    Dim file_with_code As String
   

    Private Sub Form1_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
        Me.Text = "Finder"
        Me.ShowInTaskbar = True
        Button1.Text = "Проверить соединение с м/к"
        Button2.Text = "Загрузить файл"
        Button3.Text = "Поиск"
        Label1.Text = "Выбор порта"
        Label2.Text = "Выбор скорости"
        Label3.Text = ""
        Button2.Enabled = False
        Button3.Enabled = False
        'Button4.Enabled = False
        OpenFileDialog1.FileName = Nothing
        OpenFileDialog1.Filter = ".ini files (*.ini)|*.ini"

        MyPorts = IO.Ports.SerialPort.GetPortNames()
        For i = 0 To UBound(MyPorts)
            ComboBox1.Items.Add(MyPorts(i))
        Next
        With ComboBox2.Items
            .Add(4800)
            .Add(7200)
            .Add(8861)
            .Add(9600)
            .Add(19200)
            .Add(28800)
            .Add(38400)
            .Add(57600)
        End With
        Try
            ComboBox1.Text = ComboBox1.Items.Item(0)
            ComboBox2.Text = ComboBox2.Items.Item(0)

        Catch Exc As Exception
            MessageBox.Show("В системе отсутствуют доступные COM порты", "Ошибка",
                            MessageBoxButtons.OK, MessageBoxIcon.Exclamation)
            Me.Close()
        End Try

        With SerialPort1
            .Parity = IO.Ports.Parity.None
            .StopBits = IO.Ports.StopBits.One
            .DataBits = 8
        End With
    End Sub


    Function string_to_byte(ByVal A As String) As Byte
        Dim str As String = A
        str = "&H" & str
        Dim intByte As Byte
        Dim int As Integer
        int = CDbl(str)
        intByte = Convert.ToByte(int)
        Return intByte
    End Function


    Private Sub ComboBox2_KeyPress(ByVal sender As Object, ByVal e As System.Windows.Forms.KeyPressEventArgs) Handles ComboBox2.KeyPress
        e.Handled = True
    End Sub


    Private Sub ComboBox1_KeyPress(ByVal sender As Object, ByVal e As System.Windows.Forms.KeyPressEventArgs) Handles ComboBox1.KeyPress
        e.Handled = True
    End Sub


    Private Sub Button1_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles Button1.Click
        SerialPort1.PortName = ComboBox1.Text
        SerialPort1.BaudRate = ComboBox2.Text
        Dim i As Integer = 0
        Dim j As Integer = 0
        SerialPort1.DtrEnable = True
        SerialPort1.Open()
        Label3.Text = ""
        For i = 0 To 7
            SerialPort1.Write(Zapros_MassArray, j, 1)
            j += 1
            Thread.Sleep(60)
        Next

        If Otvet_massArray(16) <> &H0 Or Otvet_massArray(15) <> Zapros_MassArray(7) Then
            MessageBox.Show("Проверьте скорость и соединение с м/к!", "Finder",
                            MessageBoxButtons.OK, MessageBoxIcon.Exclamation)
            SerialPort1.DtrEnable = False
            SerialPort1.Close()
            Array.Clear(Otvet_massArray, 0, 16 + Mass_Size)
            Mass_Size = 0
            Button2.Enabled = False
            Button3.Enabled = False
        Else
            MessageBox.Show("Соединение с м/к корректное",
                            "Finder", MessageBoxButtons.OK, MessageBoxIcon.Asterisk)
            SerialPort1.DtrEnable = False
            SerialPort1.Close()
            Array.Clear(Otvet_massArray, 0, 18 + Mass_Size)
            Mass_Size = 7
            Button1.Enabled = False
            Button2.Enabled = True
            ComboBox1.Enabled = False
            ComboBox2.Enabled = False
        End If
    End Sub


    Private Sub Button2_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles Button2.Click
        If OpenFileDialog1.ShowDialog = DialogResult.OK Then
            file_with_code = OpenFileDialog1.FileName
            Button2.Enabled = False
            Button3.Enabled = True
        End If
    End Sub


    Private Sub Button3_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles Button3.Click
        'Me.Hide()       
        With SerialPort1
            .Parity = IO.Ports.Parity.None
            .StopBits = IO.Ports.StopBits.One
            .DataBits = 8
        End With
        Button3.Enabled = False
        Dim reader As New StreamReader(file_with_code)
        Dim str_with_code As String
        SerialPort1.DtrEnable = True
        SerialPort1.Open()
        SerialPort1.DiscardInBuffer()
        Do While reader.Peek() - 1
            str_with_code = reader.ReadLine
            Dim n As Integer = 0
            For S As Integer = 0 To 6
                str_with_code = str_with_code.Remove(3 + n, 1)
                n += 3
            Next
            str_with_code = str_with_code.Remove(0, 1)
            Dim str_mass() As String = str_with_code.Split("$")
            For Q As Integer = 0 To 7
                Zapros_from_file(Q) = string_to_byte(str_mass(Q))
            Next
            Array.Clear(str_mass, 0, 8)
            SerialPort1.DtrEnable = True
            Array.Clear(Otvet_massArray, 0, 25)
            Dim R As Integer = 0
            For Q As Integer = 0 To 7
                SerialPort1.Write(Zapros_from_file, R, 1)
                R += 1
                Module1.Pause(500)
            Next
            If Otvet_massArray(16) = &H0 Then
                Dim G As Integer = 17
                For S As Integer = 0 To 2
                    SerialPort1.Write(Zapros_stage_1, G, 1)
                    G += 1
                    Module1.Pause(500)
                    If Otvet_massArray(23) = Zapros_from_file(0) Then
                        Array.Clear(Otvet_massArray, 0, 25)
                        Dim H As Integer = 0
                        For K As Integer = 0 To 7
                            SerialPort1.Write(Zapros_from_file, H, 1)
                            H += 1
                            Module1.Pause(500)
                            If Otvet_massArray(16) = &H0 Then
                                Dim L As Integer = 17
                                For M As Integer = 0 To 2
                                    SerialPort1.Write(Zapros_stage_2, L, 1)
                                    L += 1
                                    Module1.Pause(500)
                                    If Otvet_massArray(21) = Zapros_from_file(1) Then
                                        MessageBox.Show("Yes!", "Finder", MessageBoxButtons.OK,
                                                        MessageBoxIcon.Asterisk)
                                        Label3.Text = str_with_code
                                        Array.Clear(Otvet_massArray, 0, 24)
                                        Exit Do
                                    End If
                                Next
                            End If     
                        Next
                    End If
                Next               
            End If
        Loop
        SerialPort1.Close()
        SerialPort1.DtrEnable = False
        Button1.Enabled = True
        ComboBox1.Enabled = True
        ComboBox2.Enabled = True
    End Sub


    Private Sub SerialPort1_DataReceived(ByVal sender As Object, ByVal e As System.IO.Ports.SerialDataReceivedEventArgs) Handles SerialPort1.DataReceived
        Try
            Dim i As Integer
            For i = 0 To 24
                Otvet_massArray(i) = SerialPort1.ReadByte
            Next
        Catch ex As System.IO.IOException
        Catch ex As System.TimeoutException
        End Try
    End Sub
End Class

Dulce et decorum est pro patria mori

Qwertiy
Доктор VB наук
Доктор VB наук
 
Сообщения: 2753
Зарегистрирован: 26.06.2011 (Вс) 21:26

Сообщение Qwertiy » 23.08.2013 (Пт) 21:56

Что-то у тебя странный код... И почему всё ещё 24?
Посылай следующую последовательность когда текущая обработана, из обработчика соответствующего события. Но используй для этого таймер, чтобы происходило завершение процедуры.

insite2012
Продвинутый пользователь
Продвинутый пользователь
 
Сообщения: 109
Зарегистрирован: 22.03.2013 (Пт) 8:06
Откуда: Россия, Саратов

Re: Снова про Com порт

Сообщение insite2012 » 23.08.2013 (Пт) 22:02

Qwertiy писал(а):Что-то у тебя странный код... И почему всё ещё 24?
Посылай следующую последовательность когда текущая обработана, из обработчика соответствующего события. Но используй для этого таймер, чтобы происходило завершение процедуры.

Если не трудно, подскажите, как бы это получше сделать... Я пока сам не могу понять, уже сутки воюю с ней. :D
Dulce et decorum est pro patria mori

Qwertiy
Доктор VB наук
Доктор VB наук
 
Сообщения: 2753
Зарегистрирован: 26.06.2011 (Вс) 21:26

Сообщение Qwertiy » 23.08.2013 (Пт) 22:09

А проект этот можешь выложить?

insite2012
Продвинутый пользователь
Продвинутый пользователь
 
Сообщения: 109
Зарегистрирован: 22.03.2013 (Пт) 8:06
Откуда: Россия, Саратов

Re: Снова про Com порт

Сообщение insite2012 » 23.08.2013 (Пт) 22:11

Qwertiy писал(а):А проект этот можешь выложить?

Отправил. Я с ним уже реально сутки занимаюсь, прошлую ночь не спал...
Могу подробно расписать алгоритм зависимости приема и отправки, если это поможет...
Dulce et decorum est pro patria mori

Qwertiy
Доктор VB наук
Доктор VB наук
 
Сообщения: 2753
Зарегистрирован: 26.06.2011 (Вс) 21:26

Сообщение Qwertiy » 23.08.2013 (Пт) 23:25

insite2012 писал(а):Отправил.

Брррр.. Не понимаю, как оно вообще может работать... У тебя же только один процесс, значит событие DataReceived не произойдёт, пока выполняется другая функция, по крайней мере, если не вызывать DoEvents... Да и вообще, бред какой-то... И даже дебажить не на чем :(

insite2012
Продвинутый пользователь
Продвинутый пользователь
 
Сообщения: 109
Зарегистрирован: 22.03.2013 (Пт) 8:06
Откуда: Россия, Саратов

Re: Снова про Com порт

Сообщение insite2012 » 23.08.2013 (Пт) 23:31

Ну я понимаю... Вот принцип работы: Посылка из 8 байт. Посылаем байт - в ответ получаем два, повторяющих посланный (если контроллер в режиме). Так восемь раз. Потом приходят 2 нуля (как мне сказали, это сигнал Break от порта, но я так и не понял, как его опознать...). Потом посылка байта, два ответа, еще посылка, два ответа, и еще посылка и два ответа. И вот после последнего ответа мы получаем байт, который и говорит о том, совпала ли наша первая восьмибайтная посылка или нет. Если нет - меняем нашу посылку и так по кругу...
А по сигналу Break опознается состояние, вошел контроллер в режим или нет...
Dulce et decorum est pro patria mori

Qwertiy
Доктор VB наук
Доктор VB наук
 
Сообщения: 2753
Зарегистрирован: 26.06.2011 (Вс) 21:26

Сообщение Qwertiy » 23.08.2013 (Пт) 23:38

У тебя данные никогда не считываются, кажется... Или я что-то не то смотрю...

insite2012
Продвинутый пользователь
Продвинутый пользователь
 
Сообщения: 109
Зарегистрирован: 22.03.2013 (Пт) 8:06
Откуда: Россия, Саратов

Re: Снова про Com порт

Сообщение insite2012 » 23.08.2013 (Пт) 23:43

Ну я по монитору порта смотрю, что-то считывается... Только нет стабильности. Мне бы понять, как организовать отдельный поток приема байт, по событию... Про Do Event я уже тоже думал...
Dulce et decorum est pro patria mori

Qwertiy
Доктор VB наук
Доктор VB наук
 
Сообщения: 2753
Зарегистрирован: 26.06.2011 (Вс) 21:26

Re: Снова про Com порт

Сообщение Qwertiy » 24.08.2013 (Сб) 0:53

Изучай MSDN'овский пример.

insite2012
Продвинутый пользователь
Продвинутый пользователь
 
Сообщения: 109
Зарегистрирован: 22.03.2013 (Пт) 8:06
Откуда: Россия, Саратов

Re: Снова про Com порт

Сообщение insite2012 » 24.08.2013 (Сб) 8:53

Qwertiy писал(а):Изучай MSDN'овский пример.

Да, я уже пытался... Только если бы там что понятно было... Я же говорю, никак не могу понять, как мне засинхронизировать отправляемый и принимаемый потоки. И как организовать вызов события приема из порт при отправке своего массива в порт.
Я вот только единственного не понимаю. Я отправляю массив байтов в порт. И если у меня есть ответ, то если я поставлю обработку события порта по приему данных, то должен быть прием, правильно? Я вот только никак не пойму, как мне добиться, чтобы был точный прием. К примеру, я отправляю один байт, в ответ должно прийти два. А у меня или один придет, или все три... Действительно может попробовать по таймеру обработать событие отправки и приема...
Dulce et decorum est pro patria mori

insite2012
Продвинутый пользователь
Продвинутый пользователь
 
Сообщения: 109
Зарегистрирован: 22.03.2013 (Пт) 8:06
Откуда: Россия, Саратов

Re: Снова про Com порт

Сообщение insite2012 » 25.08.2013 (Вс) 23:12

Ну вот, двое суток труда и что-то получилось... Создал поток в обработчике, считывает. Хотел еще один обработчик подключить, а этот удалить в процессе работы программы, но что-то не вышло. А два обработчика мешают друг другу...
Код: Выделить всё
Private Sub SerialPort1_DataReceived(ByVal sender As Object, ByVal e As System.IO.Ports.SerialDataReceivedEventArgs)
       
        Try
            Dim stream As Stream = SerialPort1.BaseStream
            Dim Reader As New BinaryReader(stream)
            Dim B1 As Byte = Reader.ReadByte
            Dim B2 As Byte = Reader.ReadByte
            Otvet_massArray(0) = B1
            Otvet_massArray(1) = B2
            If flag_for_read = True Then
                Dim B3 As Byte = Reader.ReadByte
                Otvet_massArray(2) = B3
            End If
            flag_for_read = False
        Catch ex As Exception

        End Try

    End Sub
Dulce et decorum est pro patria mori

Пред.

Вернуться в Visual Basic .NET

Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 14

    TopList  
cron