Hi all,
I still control a 3D printer print from Android, in the Timer event _Tick I read gcode lines one by one and send to a printer,
the printer should respond with 'ok' acknowledge message.
Inside a Timer event I have more that one Wait For that call subs in the same module and even on other classes, eg. I have a SerialConnector class and a SocketManager class that is used to send feedback over wifi.
Before I send a command to a 3D printer I put ACK_OK variable to False and when I receive 'ok' I put it to True, inside a Timer I check if ACK_OK is True, if it is True I continue to read and send gcode lines until receive 'ok' and so...
The problem here is that if I put the timer interval to 50-100 milliseconds all works, when I try to decrease it I have a lots of miss packets from 3D printer and all works in a strange way.
I know that Wait For and Resumable subs looks like a return to the parent but the problem is that these probably cannot be used in a timer ?
it is best to use a Do While loop instead of Timers while use Resumable subs?
Here is how my Timer event looks.
Many thanks for clarifications
I still control a 3D printer print from Android, in the Timer event _Tick I read gcode lines one by one and send to a printer,
the printer should respond with 'ok' acknowledge message.
Inside a Timer event I have more that one Wait For that call subs in the same module and even on other classes, eg. I have a SerialConnector class and a SocketManager class that is used to send feedback over wifi.
Before I send a command to a 3D printer I put ACK_OK variable to False and when I receive 'ok' I put it to True, inside a Timer I check if ACK_OK is True, if it is True I continue to read and send gcode lines until receive 'ok' and so...
The problem here is that if I put the timer interval to 50-100 milliseconds all works, when I try to decrease it I have a lots of miss packets from 3D printer and all works in a strange way.
I know that Wait For and Resumable subs looks like a return to the parent but the problem is that these probably cannot be used in a timer ?
it is best to use a Do While loop instead of Timers while use Resumable subs?
Here is how my Timer event looks.
Many thanks for clarifications
B4X:
Private Sub TimerLine_Tick
' LogMessage("TimerLine_Tick: ACK_OK: " & ACK_OK, True, False)
If SerialConn.Connected = False Then Return
' If Loader.LineNumber > Loader.NumberOfLines Then Return ' VEDERE SE CI VUOLE
If Loader.LineNumber <= Loader.NumberOfLines Then
' Sleep(0) ' <<<<<<<<<<<<< DA CONTROLLARE
If ACK_OK And Not(PAUSED) Then
' If ACK_OK Then
Line = Loader.ReadNextLine
' Wait For (LogMessage ("TIMERLINE READ LINE [" & Loader.LineNumber & "]: " & Loader.LastLine, True, False)) Complete (o As Object)
Wait For (LogMessage ("TIMERLINE READ LINE: [" & Loader.LineNumber & "/" & mNumberOfLines & "] [" & Line & "]", True, False)) Complete (o As Object)
' If Line.Length = 0 Then Return 'Continue
If Line.Contains("M105") Then Line = Line.Replace("M105", "") ' Preso dallo sketch di ESP
If Line = "END" Or STOP_MOVE Then 'Or Paused Then
If WAIT_ACK Then
If SHOW_GENERAL_LOG Then
Wait For (LogMessage("TimerLine (WAIT_ACK): Read <END> or STOP_MOVE", True, False)) Complete (o As Object)
End If
Else
If SHOW_GENERAL_LOG Then
Wait For (LogMessage("TimerLine (NO WAIT_ACK): Read <END> or STOP_MOVE", True, False)) Complete (o As Object)
End If
End If
Wait For (LogMessage("DISATTIVO TIMERLINE", True, False)) Complete (o As Object)
TimerLine.Enabled = False ' <<<<<<<<<<<<<< FILE TERMINATO DISABILITA IL TIMER LETTURA LINEE
Wait For (ShowComplete(DateTime.Now)) Complete (b As Boolean)
Return
End If
Wait For (SocketManager.Send("CMD: LINE: " & Loader.LineNumber)) Complete (rtn As Boolean)
' Log("INVIATO VIA SOCKET CMD: LINE: " & Loader.LineNumber)
Wait For (SocketManager.Send("CMD: READ: " & Loader.ReadBytes)) Complete (rtn As Boolean)
' Log("INVIATO VIA SOCKET CMD: READ: " & Loader.ReadBytes)
Dim LineNumber As Long = Loader.LineNumber
If (LineNumber > 0) Then
' If(Loader.LineNumber Mod ProgressFactor = 0) And SHOW_PROGRESS_LOG Then SetProgress
If (LineNumber Mod (LineNumber / 100) = 0) Then
Wait For (SetProgress) Complete (o As Object)
End If
' If SHOW_PROGRESS_LOG Then SetProgress
End If
Parser.ParseLine(Line)
If (Parser.Command.Length > 0) And (Parser.IsCommentLine = False) Then
If SHOW_VERBOSE_LOG Then
Wait For (LogMessage ("CURRENT COMMAND: [" & LineNumber & "/" & mNumberOfLines & "] [" & Parser.Command & "]", True, False)) Complete (o As Object)
End If
If mCNCType = TYPE_CNC_PRINTER And Parser.Command <> "M105" Then
Wait For (SocketManager.Send("CMD: " & Parser.Command)) Complete (r As Boolean)
Else
Wait For (SocketManager.Send("CMD: " & Parser.Command)) Complete (r As Boolean)
End If
''''' ProcessLine
Wait For (ProcessLine) Complete (succ As Boolean)
If succ = False Then
Wait For (LogMessage ("TimerLine: ProcessLine: Cannot process line: " & Parser.Command, True, True)) Complete (o As Object)
End If
If mCNCType = TYPE_CNC_PRINTER Then
If (Line.startsWith ("M104") Or Line.startsWith ("M140") Or Line.startsWith ("M109") Or Line.startsWith ("M190")) Then
Wait For (Beep (2200, 10)) Complete (rt As Boolean)
Dim temp As Int = Parser.Value ("S")
If (Line.startsWith ("M104")) Then
Wait For (LogMessage ("SET EXTRUDER TEMPERATURE TO " & temp & " C", True, True)) Complete (o As Object)
Else If (Line.startsWith ("M140")) Then
Wait For (LogMessage ("SET BED TEMPERATURE TO " & temp & " C", True, True)) Complete (o As Object)
Else If (Line.startsWith ("M109")) Then
Wait For (LogMessage ("WAITING EXTRUDER TEMPERATURE " & temp & " C ...", True, True)) Complete (o As Object)
Else If (Line.startsWith ("M190")) Then
Wait For (LogMessage ("WAITING BED TEMPERATURE " & temp & " C ...", True, True)) Complete (o As Object)
Else If (Line.startsWith ("M105")) Then
Wait For (LogMessage ("TEMPERATURE REQUEST" & temp & " C ...", True, True)) Complete (o As Object)
End If
End If
End If
If WAIT_ACK Then ACK_OK = False 'IMPORTANTE AZZERA ACK PRIMA DELL'INVIO. MESSO NELLA SUB Send PER INVIO SERIALE
If (Parser.Command <> "M105") Then
Wait For (SendSerial (Parser.Command)) Complete (succ As Boolean)
If succ = True Then
Wait For (LogMessage ("TimerLine: Successfull sent to Serial: " & Parser.Command, True, True)) Complete (o As Object)
End If
End If
If (WAIT_ACK = False) Then
'----- DELAY -----
If (Feedrate < 50) Then Feedrate = 50
Dim dly As Long = (LastTravel * 64000.0) / Feedrate
dly = dly * 180 / 1000
If (Line.length > 0) And (Parser.IsCommentLine = False) Then ' Real control withouth Acknowledge. We add a delay based On last travel
If SHOW_VERBOSE_LOG Then
Wait For (LogMessage ("Wait " & dly & " ms (NO_ACK) Feedrate: " & Feedrate, True, True)) Complete (o As Object)
End If
Sleep (dly)
End If
End If
If WAIT_ACK Then Return ' FORSE NON SERVE
Else
' If SHOW_VERBOSE_LOG And Line.Length > 0 Then LogMessage("TimerLine (WAIT_ACK): COMMENT on line [" & Loader.LineNumber & " of " & Loader.NumberOfLines & "] -> " & Line, True, False)
If Line.Length > 0 Then
Wait For (LogMessage("TimerLine (WAIT_ACK): COMMENT on line [" & LineNumber & " of " & mNumberOfLines & "] -> " & Line, True, False)) Complete (o As Object)
End If
Sleep (1)
' Sleep(200)
End If
End If ' END OF ACK_OK = TRUE
End If ' END OF Loader.LineNumber <= Loader.NumberOfLines
End Sub
Last edited: