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: 
			
		
	
								
								
									
	
		
			
		
	
								
							
							 
				 
 
		 
 
		 
 
		 
 
		 
 
		 
 
		