Таймер, который препятствует выполнению своих собственных функций, если не находится в пошаговом режиме

У меня проблема, за которую я застрял с прошлой недели, и это несмотря на советы старшего разработчика.

Я хочу отправить команду моторизации мотору через COM-порты через таймер.

  • Когда я делаю это шаг за шагом или когда добавляю точку остановки, это Хорошо! Однако, когда я позволяю таймеру и программе работать сами, команда моторизации никогда не бывает! Зачем? Команда должен работать так, как это делается пошаговым способом!

Я действительно вызываю метод envoi_commande_motorisation() без каких-либо аргументов. Он просто отправляет кадры в определенном формате на COM-порт, чтобы заставить двигатель двигаться. Тем не менее, похоже, это никогда не будет вызвано при выходе из отладки шаг за шагом. Эта команда содержится в Timer_moto_tick(sender, e) As Timer_moto.tick, который является только таймером, который я сделал, чтобы регулярно проверять, что двигатель находится в правильном азимуте, зная его положение с Demande_etat_motorisation().

Я менял частоту таймера от 1000 мс до 3000 мс на шаг 500 мс каждый раз, но ничего не менял...

  • Я добавил кнопку, которая вызывает envoi_commande_motorisation() вручную, и это работает! Тем не менее, это вручную, и я хочу автоматизировать он.

Вот картина места преступления:

Private Sub Timer_moto_Tick(sender As Object, e As EventArgs) Handles Timer_moto.Tick
 'asking for the motor position
 Demande_etat_motorisation()
 'checking if we are acually in the automatize management of the motor and not in the manual way
 If RadioButton_Manuel.Checked = False Then
 'checking if the motor isn't already at the right place
 If ((CDbl(Liste_azimut.Text) <> Val(Aff_position_azimut_source.Text)) Or (CDbl(Liste_elevation.Text) <> Val(Aff_position_site_source.Text))) Then
 'otherwise we change the motor position text and say him to go this way
 lecture_port_comm_moto()
 Liste_azimut.Text = CType(Val(Aff_position_azimut_source.Text), String)
 Liste_elevation.Text = CType(Val(Aff_position_site_source.Text), String)
 envoi_commande_motorisation()
 End If
 envoi_commande_motorisation()
 End If
End Sub

Как указано в комментариях, я также даю Demande_etat_motorisation и envoi_commande_motorisation

Public Sub Demande_etat_motorisation()
 Dim i As Integer
 Dim info As String
 If init_en_cours = True Then Exit Sub
 'asking for motor state
 'frame in hexa : 57 00 00 00 00 00 00 00 00 00 00 1F 20
 tableau_hexa(0) = &H57
 For i = 1 To 10
 tableau_hexa(i) = &H00
 Next i
 tableau_hexa(11) = &H1F
 tableau_hexa(12) = &H20
 'envoi de la données
 info = "sending frames on ports "
 'port 1 -------------------------------------------------------------------------------------------------------------------------
 If etat_port_4.Checked = True And CheckBox_Moto_1.Checked = True Then
 'chosing which port for motorisation
 Try
 Select Case Liste_port_4.Text
 Case Zone_param_comm1.Text
 Port_serie_1.Write(tableau_hexa, 0, 13)
 Port_serie_1.ReceivedBytesThreshold = seuil_port_reception_moto
 Case Zone_param_comm2.Text
 Port_serie_2.Write(tableau_hexa, 0, 13)
 Port_serie_2.ReceivedBytesThreshold = seuil_port_reception_moto
 Case Zone_param_comm3.Text
 Port_serie_3.Write(tableau_hexa, 0, 13)
 Port_serie_3.ReceivedBytesThreshold = seuil_port_reception_moto
 End Select
 Catch ex As Exception
 zone1.Text = "Error Motorisation 1 : " + ex.ToString
 End Try
 End If
 'End If
 'port 2 ----------------------------------------------------------------------------------------------------------------------
 If etat_port_5.Checked = True And CheckBox_Moto_2.Checked = True Then
 'sending the command
 'here we chose which port to write in for the motor
 Try
 'assignation du à ouvrir
 Select Case Liste_port_5.Text
 Case Zone_param_comm1.Text
 Port_serie_1.Write(tableau_hexa, 0, 13)
 Port_serie_1.ReceivedBytesThreshold = seuil_port_reception_moto
 Case Zone_param_comm2.Text
 Port_serie_2.Write(tableau_hexa, 0, 13)
 Port_serie_2.ReceivedBytesThreshold = seuil_port_reception_moto
 Case Zone_param_comm3.Text
 Port_serie_3.Write(tableau_hexa, 0, 13)
 Port_serie_3.ReceivedBytesThreshold = seuil_port_reception_moto
 End Select
 Catch ex As Exception
 zone1.Text = "Error Motorisation 2 : " + ex.ToString
 End Try
 End If
End Sub
Public Sub envoi_commande_motorisation()
 'sending data on serial ports
 'sending 13 chars
 Dim i As Integer
 Dim cjunk, cjunk1 As String
 Dim nombre As Integer
 Dim info As String
 BorneMinAz = Nothing
 BorneMaxAz = Nothing
 BorneMinElev = Nothing
 BorneMaxElev = Nothing
 If init_en_cours = True Then Exit Sub
 If Me.Liste_azimut.Text <> "" And Me.Liste_elevation.Text <> "" Then
 Me.zone1.Text = ""
 'classical command is being sent
 tableau_hexa(0) = &H57
 tableau_hexa(1) = &H30
 'in degree degre
 tableau_hexa(5) = &H1
 tableau_hexa(6) = &H30
 tableau_hexa(10) = &H1
 'final bits for a command
 tableau_hexa(11) = &H2F
 tableau_hexa(12) = &H20
 'azimut calculation
 nombre = CInt(Liste_azimut.Text) + 360
 cjunk1 = CStr(nombre)
 'numbers upper to 100
 cjunk = Mid(cjunk1, 1, 1)
 tableau_hexa(2) = CByte(&H30 + Val(cjunk))
 'having back the decade
 cjunk = Mid(cjunk1, 2, 1)
 tableau_hexa(3) = CByte(&H30 + Val(cjunk))
 'unite
 cjunk = Mid(cjunk1, 3, 1)
 tableau_hexa(4) = CByte(&H30 + Val(cjunk))
 'tilt calculation
 nombre = CInt(Liste_elevation.Text) + 360
 cjunk1 = CStr(nombre)
 'number upper to 100
 cjunk = Mid(cjunk1, 1, 1)
 tableau_hexa(7) = CByte(&H30 + Val(cjunk))
 'decade recuperation
 cjunk = Mid(cjunk1, 2, 1)
 tableau_hexa(8) = CByte(&H30 + Val(cjunk))
 'unite
 cjunk = Mid(cjunk1, 3, 1)
 tableau_hexa(9) = CByte(&H30 + Val(cjunk))
 'affichage de la trame envoyée
 cjunk = ""
 For i = 0 To 12
 cjunk = cjunk + CStr(Hex(tableau_hexa(i))) + " "
 Next
 envoi_azimut_elevation.Text = "frame sent: " + cjunk
 info = "frames being sent on the port : "
 'port 1
 'motorisation 1 --------------------------------------------------------------------------------------------------------------------
 If etat_port_4.Checked = True And CheckBox_Moto_1.Checked = True Then
 'chosing port for motor 1
 Try
 Select Case Liste_port_4.Text
 Case Zone_param_comm1.Text
 Port_serie_1.Write(tableau_hexa, 0, 13)
 Port_serie_1.ReceivedBytesThreshold = seuil_port_reception_moto
 Case Zone_param_comm2.Text
 Port_serie_2.Write(tableau_hexa, 0, 13)
 Port_serie_2.ReceivedBytesThreshold = seuil_port_reception_moto
 Case Zone_param_comm3.Text
 Port_serie_3.Write(tableau_hexa, 0, 13)
 Port_serie_3.ReceivedBytesThreshold = seuil_port_reception_moto
 End Select
 Catch ex As Exception
 zone1.Text = "Erreur Motorisation 1 : " + ex.ToString
 End Try
 'affichage de l'info sur l'afficheur noir
 'azimut
 i = CInt(Val(Liste_azimut.Text))
 Select Case i
 Case 0 To 9
 Affiche_info_azimut.Text = "00" + Format(i, "##0")
 Case 10 To 99
 Affiche_info_azimut.Text = "0" + Format(i, "##0")
 Case Else
 Affiche_info_azimut.Text = Format(i, "##0")
 End Select
 Affiche_info_azimut.ForeColor = Color.Green
 'tilt
 i = CInt(Val(Liste_elevation.Text))
 Select Case i
 Case -9 To -1
 Affiche_info_elevation.Text = "-0" + Format(Abs(i), "##")
 Case 0 To 9
 Affiche_info_elevation.Text = "0" + Format(i, "##")
 Case Else
 Affiche_info_elevation.Text = Format(i, "##")
 End Select
 Affiche_info_elevation.ForeColor = Color.Green
 End If
 'port 2 -------------------------------------------------------------------------------------------------------------------------
 If etat_port_5.Checked = True And CheckBox_Moto_2.Checked = True Then
 'envoi de la commande
 'choix du port choisi pour la motorisation 1
 Try
 'assignation du à ouvrir
 Select Case Liste_port_5.Text
 Case Zone_param_comm1.Text
 Port_serie_1.Write(tableau_hexa, 0, 13)
 Port_serie_1.ReceivedBytesThreshold = seuil_port_reception_moto
 Case Zone_param_comm2.Text
 Port_serie_2.Write(tableau_hexa, 0, 13)
 Port_serie_2.ReceivedBytesThreshold = seuil_port_reception_moto
 Case Zone_param_comm3.Text
 Port_serie_3.Write(tableau_hexa, 0, 13)
 Port_serie_3.ReceivedBytesThreshold = seuil_port_reception_moto
 End Select
 Catch ex As Exception
 zone1.Text = "Erreur Motorisation 2 : " + ex.ToString
 End Try
 'affichage de l'info sur l'afficheur noir
 'azimut
 i = CInt(Val(Liste_azimut.Text))
 Select Case i
 Case 0 To 9
 Affiche_info_azimut.Text = "00" + Format(i, "##0")
 Case 10 To 99
 Affiche_info_azimut.Text = "0" + Format(i, "##0")
 Case Else
 Affiche_info_azimut.Text = Format(i, "##0")
 End Select
 Affiche_info_azimut.ForeColor = Color.LightGreen
 'elevation
 i = CInt(Val(Liste_elevation.Text))
 Select Case i
 Case -9 To -1
 Affiche_info_elevation.Text = "-0" + Format(Abs(i), "##")
 Case 0 To 9
 Affiche_info_elevation.Text = "0" + Format(i, "##")
 Case Else
 Affiche_info_elevation.Text = Format(i, "##")
 End Select
 Affiche_info_elevation.ForeColor = Color.Green
 'demande de position
 Demande_etat_motorisation()
 End If
 'End If
 '
 End If
End Sub

До сих пор старший разработчик по-прежнему считает, что проблема с частотой таймера.

Возможно, мне следует работать с прерываниями для последовательных портов, но как я могу это сделать? Он сказал мне установить порог для каждого порта, чтобы начать чтение прерыванием, чтобы я прочитал буфер, когда он заполнен.

Edit:

Diagnostics.Debug.Writeline

Как мне посоветовал, я написал Diagnostics.Debug.Writeline("some specific text here") всю свою программу, возможно, разбился. Собственно, после того, как вы подняли строки, написанные на терминале, я заметил, что это проблема Serialports.Writeline(,,).

Действительно, следующие строки кода и отладки:

Private Sub Timer_moto_Tick(sender As Object, e As EventArgs) Handles Timer_moto.Tick
 'asking for the motor position
 Demande_etat_motorisation()
 'checking if we are acually in the automatize management of the motor and not in the manual way
 If RadioButton_Manuel.Checked = False Then
 Diagnostics.Debug.WriteLine("test if we are at the right place")
 If ((CDbl(Liste_azimut.Text) <> Val(Aff_position_azimut_source.Text)) Or (CDbl(Liste_elevation.Text) <> Val(Aff_position_site_source.Text))) Then
 lecture_port_comm_moto()
 Liste_azimut.Text = CType(Val(Aff_position_azimut_source.Text), String)
 Liste_elevation.Text = CType(Val(Aff_position_site_source.Text), String)
 envoi_commande_motorisation()
 Diagnostics.Debug.WriteLine("we have just send the orders to the camera")
 End If
 End If
End Sub

Каждые строки отладки считываются на терминале, я добавил некоторые из них в envoi_commande_motorisation()

Public Sub envoi_commande_motorisation()
'sending data on serial ports
'sending 13 chars
 Dim i As Integer
 Dim cjunk, cjunk1 As String
 Dim nombre As Integer
 Dim info As String
 BorneMinAz = Nothing
 BorneMaxAz = Nothing
 BorneMinElev = Nothing
 BorneMaxElev = Nothing
 Diagnostics.Debug.WriteLine("We just get into envoi_commande_motorisation()")
 If init_en_cours = True Then Exit Sub
 If Me.Liste_azimut.Text <> "" And Me.Liste_elevation.Text <> "" Then
 Me.zone1.Text = ""
 'classical command is being sent
 tableau_hexa(0) = &H57
 tableau_hexa(1) = &H30
 'transforming it in degree
 tableau_hexa(5) = &H1
 tableau_hexa(6) = &H30
 'again
 tableau_hexa(10) = &H1
 'final bits for a command
 tableau_hexa(11) = &H2F
 tableau_hexa(12) = &H20
 'azimut calculation
 nombre = CInt(Liste_azimut.Text) + 360
 cjunk1 = CStr(nombre)
 'number bigger than 100
 cjunk = Mid(cjunk1, 1, 1)
 tableau_hexa(2) = CByte(&H30 + Val(cjunk))
 'taking the decade
 cjunk = Mid(cjunk1, 2, 1)
 tableau_hexa(3) = CByte(&H30 + Val(cjunk))
 'unity
 cjunk = Mid(cjunk1, 3, 1)
 tableau_hexa(4) = CByte(&H30 + Val(cjunk))
 'elevation calculation
 nombre = CInt(Liste_elevation.Text) + 360
 cjunk1 = CStr(nombre)
 'number bigger than 100
 cjunk = Mid(cjunk1, 1, 1)
 tableau_hexa(7) = CByte(&H30 + Val(cjunk))
 'taking the decade
 cjunk = Mid(cjunk1, 2, 1)
 tableau_hexa(8) = CByte(&H30 + Val(cjunk))
 'units
 cjunk = Mid(cjunk1, 3, 1)
 tableau_hexa(9) = CByte(&H30 + Val(cjunk))
 displaying the frame sent 
 cjunk = ""
 For i = 0 To 12
 cjunk = cjunk + CStr(Hex(tableau_hexa(i))) + " "
 Next
 envoi_azimut_elevation.Text = "Trame envoi : " + cjunk
 Diagnostics.Debug.WriteLine("We are going to get into the writes")
 info = "sending data on ports "
 'port 1
 'motorisation 1 --------------------------------------------------------------------------------------------------------------------
 If etat_port_4.Checked = True And CheckBox_Moto_1.Checked = True Then
 'chosing ports
 Try
 Select Case Liste_port_4.Text
 Case Zone_param_comm1.Text
 Port_serie_1.Write(tableau_hexa, 0, 13)
 'Port_serie_1.ReceivedBytesThreshold = seuil_port_reception_moto
 Case Zone_param_comm2.Text
 Port_serie_2.Write(tableau_hexa, 0, 13)
 'Port_serie_2.ReceivedBytesThreshold = seuil_port_reception_moto
 Case Zone_param_comm3.Text
 Port_serie_3.Write(tableau_hexa, 0, 13)
 'Port_serie_3.ReceivedBytesThreshold = seuil_port_reception_moto
 Case Zone_param_comm4.Text
 Diagnostics.Debug.WriteLine("we are going to write in COM port 4")
 Port_serie_4.Write(tableau_hexa, 0, 13)
 Diagnostics.Debug.WriteLine("We just wrote in COM Port 4")
 Timer_moto.Start()
 'Port_serie_4.ReceivedBytesThreshold = seuil_port_reception_moto
 Case Zone_param_comm5.Text
 Port_serie_5.Write(tableau_hexa, 0, 13)
 'Port_serie_5.ReceivedBytesThreshold = seuil_port_reception_moto
 Case Zone_param_comm6.Text
 Port_serie_6.Write(tableau_hexa, 0, 13)
 'Port_serie_6.ReceivedBytesThreshold = seuil_port_reception_moto
 End Select
 Catch ex As Exception
 zone1.Text = "Erreur Motorisation 1 : " + ex.ToString
 End Try
 'displaying azimut infomations on screen
 'azimut
 i = CInt(Val(Liste_azimut.Text))
 Select Case i
 Case 0 To 9
 Affiche_info_azimut.Text = "00" + Format(i, "##0")
 Case 10 To 99
 Affiche_info_azimut.Text = "0" + Format(i, "##0")
 Case Else
 Affiche_info_azimut.Text = Format(i, "##0")
 End Select
 Affiche_info_azimut.ForeColor = Color.Green
 'elevation
 i = CInt(Val(Liste_elevation.Text))
 Select Case i
 Case -9 To -1
 Affiche_info_elevation.Text = "-0" + Format(Abs(i), "##")
 Case 0 To 9
 Affiche_info_elevation.Text = "0" + Format(i, "##")
 Case Else
 Affiche_info_elevation.Text = Format(i, "##")
 End Select
 Affiche_info_elevation.ForeColor = Color.Green
 End If
 'port 2 -------------------------------------------------------------------------------------------------------------------------
 If etat_port_5.Checked = True And CheckBox_Moto_2.Checked = True Then
 'sending command
 'chosing port
 Try
 Select Case Liste_port_5.Text
 Case Zone_param_comm1.Text
 Port_serie_1.Write(tableau_hexa, 0, 13)
 'Port_serie_1.ReceivedBytesThreshold = seuil_port_reception_moto
 Case Zone_param_comm2.Text
 Port_serie_2.Write(tableau_hexa, 0, 13)
 'Port_serie_2.ReceivedBytesThreshold = seuil_port_reception_moto
 Case Zone_param_comm3.Text
 Port_serie_3.Write(tableau_hexa, 0, 13)
 'Port_serie_3.ReceivedBytesThreshold = seuil_port_reception_moto
 Case Zone_param_comm4.Text
 Port_serie_4.Write(tableau_hexa, 0, 13)
 'Port_serie_4.ReceivedBytesThreshold = seuil_port_reception_moto
 Case Zone_param_comm5.Text
 Port_serie_5.Write(tableau_hexa, 0, 13)
 'Port_serie_5.ReceivedBytesThreshold = seuil_port_reception_moto
 Case Zone_param_comm6.Text
 Port_serie_6.Write(tableau_hexa, 0, 13)
 'Port_serie_6.ReceivedBytesThreshold = seuil_port_reception_moto
 End Select
 Catch ex As Exception
 zone1.Text = "Erreur Motorisation 2 : " + ex.ToString
 End Try
 'affichage de l'info sur l'afficheur noir
 'azimut
 i = CInt(Val(Liste_azimut.Text))
 Select Case i
 Case 0 To 9
 Affiche_info_azimut.Text = "00" + Format(i, "##0")
 Case 10 To 99
 Affiche_info_azimut.Text = "0" + Format(i, "##0")
 Case Else
 Affiche_info_azimut.Text = Format(i, "##0")
 End Select
 Affiche_info_azimut.ForeColor = Color.LightGreen
 'elevation
 i = CInt(Val(Liste_elevation.Text))
 Select Case i
 Case -9 To -1
 Affiche_info_elevation.Text = "-0" + Format(Abs(i), "##")
 Case 0 To 9
 Affiche_info_elevation.Text = "0" + Format(i, "##")
 Case Else
 Affiche_info_elevation.Text = Format(i, "##")
 End Select
 Affiche_info_elevation.ForeColor = Color.Green
 'demande de position
 'Demande_etat_motorisation()
 End If
 'End If
 '
 End If
End Sub

Каждое сообщение Diagnostics.Debug.WriteLine считывается и отображается на терминале, но камера не перемещается. Поэтому, когда он связан с COM-портом 4, я думаю, что это Port_serie_4.Write(tableau_hexa, 0, 13) имеет серьезную проблему,  даже если остальная часть кода задерживается, как показано ниже. Странно то, что он всегда пишет мне test if we are at the right place. Даже если я дам ему приказ двигаться, как если бы он думал, что мы были в нужном месте, не нажимая на кнопку, которая требует envoi_commande_motorisation(). .

Задержка

Я тоже добавил задержку:

Case Zone_param_comm4.Text
 Diagnostics.Debug.WriteLine("we are going to write in COM port 4")
 Port_serie_4.Write(tableau_hexa, 0, 13)
 System.Threading.Thread.Sleep(500)
 Diagnostics.Debug.WriteLine("We just wrote in COM Port 4")

Тем не менее, на данный момент ничего не меняется.

Может быть, я должен удалить некоторые части кода этого вопроса или сверху. Не стесняйтесь предлагать это и спасибо за всю помощь, которую вы все приносите для решения этой проблемы.

2 ответа

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

Прежде всего, создайте новый проект с формой и кнопкой. Когда вы нажимаете кнопку, он открывает COM-порт.

Если это работает, вы просто отправляете одну команду после открытия вашего порта. команда, которая будет устанавливать вашу камеру в заданной позиции.

Если это работает, вы добавляете TextBox, где вы можете ввести желаемую позицию. Поэтому, когда вы нажимаете кнопку, она перемещает камеру в эту позицию.

Если это работает,...

И вы продолжаете строить, как это, пока не найдете, что не так.


Предполагая, что вы не отключили некоторые прерывания во время отладки, есть что-то, что асинхронно может выполнить во время задержки, когда вы нажимаете "следующий", когда вы выполняете один шаг через программы, которые не завершаются, когда вы позволяете ему запускаться автоматически. Я просмотрел ваш код, и ничего не видно.

Сначала попробуйте добавить задержку между шагами, которые вы делаете с помощью отладчика. Что-то вроде одной секунды за шаг, так что это будет похоже на то, что вы нажимаете "следующий... следующий... следующий", но вместо этого это будет просто "задержка... задержка... задержка". Если это работает, попробуйте устранить задерживает по одному, пока не перестанет работать. Затем вы узнаете, какая часть вашего кода ищет результаты, которые еще не готовы.

Я подозреваю, что вам нужно что-то в вашем коде, чтобы проверить, что предыдущее сообщение завершено. Тогда, если предыдущее сообщение не будет завершено, вы ничего не сделаете до следующего цикла. Вам, вероятно, будет лучше всего превратить ваш код в конечный автомат, где вы будете проходить через операции по одному и не переходить в следующее состояние, пока не сможете проверить, что система выполнена с предыдущим состоянием.

licensed under cc by-sa 3.0 with attribution.