'Declare Public Variables 'PreserveVariables SequentialMode 'ComPortIsActive (COMRS232) '=========================================== GENERAL VARIABLES 'Dim bool As Boolean Public systemTimeZone As Long = 7 ' Public systemStatusTableUpdateInterval As Long = 60 ' second '=========================================== FTP VARIABLES Public FTPEnabled As Boolean = 1 Const FTP_HOST = "someftpserver.com" Const FTP_USER="ftpuser" Const FTP_PASS="ftppass" '========================================== ' ALARM TRIGGER '========================================== Public Battery_Is_Low As Boolean Public AlarmTriggerEnabled As Boolean = 0 Public BatteryAlarmTrigger As Boolean Public Test_BatteryAlarmTrigger As Boolean '========================================== ' NTP VARIABLES '========================================== Public timeIsSynced As Boolean Public timeDiff As Long Dim NTPSyncInterval As Long Dim fastNTPSyncInterval As Long = 60 Dim slowNTPSyncInterval As Long = 21600 Dim lastNTPSync As String Public triggerSyncNTP As Boolean = false '=========================== Timing Vars Public Masterscan(9) As Long Alias Masterscan(1) = Year 'assign the alias Year to Masterscan(1) Alias Masterscan(2) = Month 'assign the alias Month to Masterscan(2) Alias Masterscan(3) = Date 'assign the alias Date to Masterscan(3) Alias Masterscan(4) = Hour 'assign the alias Hour to Masterscan(4) Alias Masterscan(5) = Minute 'assign the alias Minute to Masterscan(5) Alias Masterscan(6) = Second 'assign the alias Second to Masterscan(6) Alias Masterscan(7) = uSecond 'assign the alias uSecond to Masterscan(7) Alias Masterscan(8) = WeekDay 'assign the alias WeekDay to Masterscan(8) Alias Masterscan(9) = Day_of_Year 'assign the alias Day_of_Year to Masterscan(9) '=========================== Data Tables Public Result(10) As Long '=========================================== DMM VARIABLES Public DMM_mode As String = "Auto" 'If CR6 Const DMM_Com_Port = ComC3 'If CR1000 'Const DMM_Com_Port = Com3 Const Number_of_DMMs As Long = 1 Dim DMM_Address(Number_of_DMMs) As Long = {1} ' Public DMM_Is_Installed(Number_of_DMMs) As Boolean = {false,false,false,false,false} Dim DMM_Zero(Number_of_DMMs) = {62.5} ' This is where you enter the zero Reading for the DMMS 'DMM Modbus scan interval Const DMM_Poll_Interval = 150 ' if faster than this, skip scans seems increasing Const DMM_Poll_Interval_Units = msec 'Logging interval Public DMM_Logging_Interval As Long = 900 ' in seconds Units DMM_Logging_Interval = Second Public PTemp, Batt_volt(4) Units PTemp = °C Units Batt_volt = Volt Alias Batt_volt(1) = BatteryV Alias Batt_volt(2) = ChargeIn Alias Batt_volt(3) = ChargeOut Alias Batt_volt(4) = LithiumV Dim Measure_DMMs_Trigger As Boolean = false Public Elapsed As Long Public stage As Long = 0 Public Solenoid_Power_On As Boolean = false Public DMM_Power_On As Boolean = false Public ModbusResultStr(Number_of_DMMs) As String Public DMM_Raw(Number_of_DMMs) As Long Public DMM_Reading(Number_of_DMMs) Units DMM_Reading(1) = mm Public DMM_Calc(Number_of_DMMs) Units DMM_Calc(1) = mm ' Public Laser_Switch As Boolean 'Public measureIsTriggered As Boolean Dim i As Long 'Dim j As Long, m As Long 'Public PROCESS_STAGE As String * 36 ' keeping processing stage Public SLOWSCAN_STAGE As String * 36 ' keeping processing stage '23:14 to 23:31, every day Public Trigger_StartHour1 As Long = 23 Public Trigger_StartMinute1 As Long = 15 Public TotalStartMinute1 As Long Public Trigger_EndHour1 As Long = 23 Public Trigger_EndMinute1 As Long = 30 Public TotalEndMinute1 As Long Public Trigger_StartHour2 As Long = 21 Public Trigger_StartMinute2 As Long = 15 Public TotalStartMinute2 As Long Public Trigger_EndHour2 As Long = 21 Public Trigger_EndMinute2 As Long = 15 Public TotalEndMinute2 As Long Public file_handle Public http_header As String * 100 Public http_post_response As String * 200 Public http_post_tx Const CRLF = CHR(13) + CHR(10) Public Message As String * 250 Public EmailSuccess Public ServerResponse As String * 50 Dim battVStr As String Dim PTempStr As String Dim dateStr As String Dim timeStr As String Dim DMM_CalcStr As String Dim LVDT_mm_CalcStr As String Dim DMM_Power_OnStr As String Public FTPResult(4) As Long Alias FTPResult(1) = FTP_Diagnostic Alias FTPResult(2) = FTP_DMM_Data Alias FTPResult(3) = FTP_LVDT_Data Alias FTPResult(4) = FTP_BattTemp Dim rootPath As String Dim strNotInstalled As String = "Not installed" Dim strSuccess As String = "Success" Dim strTimeout As String = "Timeout" Dim strError As String = "Error" Dim strNotPolling As String = "Not polling" Dim goodReading(10) Dim j Dim idx = 1 Dim k Dim sum Dim avg Public PeriodicMode As Boolean = false Dim ManualMode As Boolean Dim Update_DMM_Table As Boolean = false Dim strDateTimeFormat As String * 48 = "%04u-%02u-%02u %02u:%02u:%02u" 'Declare Private Variables 'Example: 'Public OutStat(6) 'Public LastFileName(6) As String * 36 'If CR6 Const pinRelaySolenoid = C2 Const pinRelayDMM = C1 'If CR1000 'Const pinRelaySolenoid = 7 'Const pinRelayDMM = 8 Sub READ_DMM For i = 1 To Number_of_DMMs DMM_Raw(i) = NAN DMM_Reading(i) = NAN DMM_Calc(i) = NAN If DMM_Address(i) <= 0 Then ModbusResultStr(i) = strNotInstalled ElseIf DMM_Address(i) > 0 Then If DMM_Power_On = true Then For j = 1 To 5 SerialFlush(DMM_Com_Port) Delay (0,100,mSec) ModbusMaster (Result(i),DMM_Com_Port,38400,DMM_Address(i),3,DMM_Raw(i),1,1,2,2,3) If Result(i) = 0 Then ModbusResultStr(i) = strSuccess DMM_Reading(i) = DMM_Raw(i)/2 If DMM_Reading(i) > 0 Then goodReading(idx) = DMM_Reading(i) idx = idx+1 'AvgRun (goodReading(1),1,DMM_Reading(i),1) EndIf ElseIf Result(i) > 0 Then ModbusResultStr(i) = strTimeout & " " & Result(i) ElseIf Result(i) < 0 Then ModbusResultStr(i) = strError & " " & Result(i) EndIf Next j For k = 1 To idx sum = sum + goodReading(k) Next k avg = sum/idx sum = 0 DMM_Reading(i) = avg DMM_Calc(i) = DMM_Reading(i) - DMM_Zero(i) ' reset idx idx = 1 Else ModbusResultStr(i) = strNotPolling EndIf EndIf Next i EndSub 'Define Data Tables DataTable (DMM_Data,1,-1) 'Set table size to # of records, or -1 to autoallocate. 'DataInterval (0,DMM_Poll_Interval * Number_of_DMMs,DMM_Poll_Interval_Units,10) 'DataInterval(0,30,Min,10) 'TableFile ("CRD:DMM_Param_",8,-1,5,30,Min,0,0) 'Minimum (1,Batt_volt,FP2,False,False) 'Sample (1,PTemp,FP2) 'Sample (1,Elapsed_Solenoid_Power_ON,IEEE4) 'Sample (1,counter,Long) 'Sample (Number_of_DMMs,ModbusResultStr(),String) 'FieldNames("Modbus_Result") Sample (1, DMM_Logging_Interval,FP2) FieldNames("Reading_Interval") Sample (Number_of_DMMs,DMM_Reading(),FP2) FieldNames("DMM_Reading") Sample (Number_of_DMMs,DMM_Calc(),FP2) FieldNames("DMM_Calc") EndTable DataTable (BattTemp,1,-1) 'Set table size to # of records, or -1 to autoallocate. 'DataInterval (0,DMM_Poll_Interval * Number_of_DMMs,DMM_Poll_Interval_Units,10) DataInterval(0,30,Min,10) 'TableFile ("CRD:DMM_Param_",8,-1,5,30,Min,0,0) Minimum (1,Batt_volt,FP2,False,False) FieldNames("Logger_Volt") Sample (1,PTemp,FP2) FieldNames("Logger_Temp") 'Sample (1,Elapsed_Solenoid_Power_ON,IEEE4) 'Sample (1,counter,Long) EndTable DataTable (Diagnostic,1,-1) 'Set table size to # of records, or -1 to autoallocate. Minimum (1,Batt_volt,FP2,False,False) FieldNames("Logger_Volt") Maximum (1,PTemp,FP2,False,False) FieldNames("Logger_Temp") Sample (Number_of_DMMs,ModbusResultStr(),String) FieldNames("DMM_Mbus_Result") EndTable Const Number_of_LVDT = 1 Public Measure_LVDT_Trigger As Boolean Public LVDT_mV(Number_of_LVDT) Units LVDT_mV(1) = mV Public LVDT_mm_Raw(Number_of_LVDT) Units LVDT_mm_Raw(1) = mm Public LVDT_mm_Calc(Number_of_LVDT) Units LVDT_mm_Calc(1) = mm Public LVDT_Cal(Number_of_LVDT) = {30.17} 'in mV/mm Units LVDT_Cal(1) = mV/mm Dim LVDT_Zero(Number_of_LVDT) = {-2.371} ' This is where you enter the zero Reading for the DMMS 'Dim LVDT_Measure_Interval ' LVDT Measuring interval 'Dim LVDT_Measure_Units DataTable (LVDT_Data,1,-1) 'Set table size to # of records, or -1 to autoallocate. 'Minimum (1,Batt_volt,FP2,False,False) 'Sample (1,PTemp,FP2) Sample (1, DMM_Logging_Interval,FP2) FieldNames("Reading_Interval") Sample (Number_of_LVDT,LVDT_mV(),FP2) FieldNames("LVDT_volt") Sample (Number_of_LVDT,LVDT_mm_Raw(),FP2) FieldNames("LVDT_mm_Raw") Sample (Number_of_LVDT,LVDT_mm_Calc(),FP2) FieldNames("LVDT_mm_Calc") EndTable Dim tsStr As String '2000-23-23 44:55:44 Function CombineYMDHMS(yLong As Long, moLong As Long, dLong As Long, hLong As Long, mLong As Long, sLong As Long) As String Sprintf(tsStr,"%04u-%02u-%02u %02u:%02u:%02u", yLong, moLong, dLong, hLong, mLong, sLong) Return tsStr EndFunction Dim ts As Long Function ConvertDateTimeToEpoch1990 (dtStr As String) As Long ts = SecsSince1990 (dtStr,4) Return ts EndSub Public loggerBootTimestampStr As String '2000-23-23 44:55:44 Sub loggerBootTimestampToString RealTime (Masterscan()) Sprintf(loggerBootTimestampStr,"%04u-%02u-%02u %02u:%02u:%02u", Year, Month, Date, Hour, Minute, Second) EndSub Public loggerBootEpoch1990 As Long Sub loggerBootTimestampToEpoch1990 Call loggerBootTimestampToString 'loggerBootEpoch1990 = SecsSince1990 (loggerBootTimestampStr,4) loggerBootEpoch1990 = ConvertDateTimeToEpoch1990(loggerBootTimestampStr) EndSub 'Main Program BeginProg ' check logger date & time ' should be between 1-Jan-2020 and 1-Jan-2050 Call loggerBootTimestampToEpoch1990 If loggerBootEpoch1990 > 946684800 AND loggerBootEpoch1990 < 1893456000 Then timeIsSynced = true Else timeIsSynced = false triggerSyncNTP = true EndIf 'SetStatus ("USRDriveSize",100000) '================== SETUP DMM ==================== ' Turn_ONOFF_Solenoid(false) ' Turn_ONOFF_DMM(false) 'Measure_DMMs_Trigger = false ' If CR6 'SerialOpen (DMM_Com_Port,38400,16,0,128,4) ' If CR1000 'SerialOpen (DMM_Com_Port,38400,16,0,128) '==================== END OF SETUP DMM Scan (1,Sec,0,0) ' Dim timerSecond, elapsedSecond ' elapsedSecond = Timer (timerSecond,Sec,2 ) ' reset & start 'Scan (DMM_Poll_Interval * Number_of_DMMs ,DMM_Poll_Interval_Units,3,0) RealTime (Masterscan()) PanelTemp (PTemp,50) Battery (Batt_volt()) ' --------------------------------- ' Logic to monitor battery voltage ' --------------------------------- If BatteryV < 12.0 Then If Timer(2,Sec,4) = 0 Then Timer(2,Sec,0) 'start ElseIf Timer(2,Sec,4) >= 604800 Then '604800 sec = 7 days Timer(2,Sec,1) 'stop EndIf Else Timer(2,Sec,3) 'stop & reset EndIf If Timer(2,Sec,4) >= 600 Then ' 600 sec = 10 minute Battery_Is_Low = true Else Battery_Is_Low = false EndIf ' Skip scan if batt voltage is low If Battery_Is_Low Then If TimeIntoInterval(15,24,Hr) Then BatteryAlarmTrigger = true EndIf If stage <> 0 OR Timer(1,Sec,4) > 0 Then PortSet (pinRelaySolenoid, true) Delay (1,5,Sec) stage = 0 Timer(1,Sec,3) ' stop & reset timer EndIf ' Turn On/Off the relays PortSet (pinRelaySolenoid, false) PortSet (pinRelayDMM, false) ContinueScan EndIf ' Skip scan if time is not synced via NTP If NOT timeIsSynced Then ContinueScan EndIf '----------------------- DMM SCAN SECTION TotalStartMinute1 = Trigger_StartHour1*60 + Trigger_StartMinute1-1 TotalEndMinute1 = Trigger_EndHour1*60 + Trigger_EndMinute1+1 TotalStartMinute2 = Trigger_StartHour2*60 + Trigger_StartMinute2-1 TotalEndMinute2 = Trigger_EndHour2*60 + Trigger_EndMinute2+1 If PeriodicMode Then If TimeIsBetween (TotalStartMinute1,TotalEndMinute1,1440,min) Then DMM_mode = "Manual" EndIf EndIf 'If DMM_mode = "Manual" OR DMM_mode = "1" OR DMM_Logging_Interval < 60 Then If DMM_mode = "Manual" OR DMM_mode = "1" Then ManualMode = true Else ManualMode = false EndIf Elapsed = Timer(1,Sec,4) ' Dim multiplier As Long ' multiplier = DMM_Logging_Interval / (DMM_Poll_Interval * Number_of_DMMs) 'If TimeIntoInterval(35,DMM_Poll_Interval * Number_of_DMMs * multiplier, Sec) Then Measure_DMMs_Trigger = true 'at 2 minute intervals, set PortOn to 1 'If TimeIntoInterval(DMM_Logging_Interval-35,DMM_Logging_Interval, Sec) Then Measure_DMMs_Trigger = true 'at 2 minute intervals, set PortOn to 1 If ManualMode Then DMM_Logging_Interval = 1 Measure_DMMs_Trigger = true Else DMM_Logging_Interval = 900 If TimeIntoInterval((DMM_Logging_Interval-60)+35,DMM_Logging_Interval, Sec) Then Measure_DMMs_Trigger = true EndIf EndIf 'If DMM_mode = "Manual" Then Measure_DMMs_Trigger = false If ManualMode Then DMM_Power_On = true If stage = 0 Then If Solenoid_Power_On = false Then Delay(1,5,sec) Solenoid_Power_On = true Timer (1,Sec,2) 'Reset & Start Off timer stage = 11 ElseIf Solenoid_Power_On = true Then Timer (1,Sec,2) 'Reset & Start Off timer stage = 11 EndIf ElseIf stage = 1 AND Timer (1,Sec,4 ) >= 1 Then stage = 12 Solenoid_Power_On = false ElseIf stage = 2 Then stage = 12 ElseIf stage = 3 Then stage = 12 ElseIf stage = 4 Then stage = 12 ElseIf stage = 5 AND Timer (1,Sec,4 ) >= 5 Then stage = 0 Solenoid_Power_On = false EndIf '------ STAGE 11 If stage = 11 AND Timer (1,Sec,4 ) >= 1 Then stage = 12 Solenoid_Power_On = false '------ STAGE 12 ElseIf stage = 12 AND Timer (1,Sec,4 ) >= 30 Then ' make sure the laser have been fully turned On at this stage ' because we want to take modbus reading Call READ_DMM 'CallTable DMM_Param Update_DMM_Table = true Measure_LVDT_Trigger = true EndIf '--------------------- AUTO MODE Else If stage >= 10 Then Measure_DMMs_Trigger = false stage = 5 Solenoid_Power_On = true DMM_Power_On = false Timer (1,Sec,2 ) 'Reset and Start timer '------ STAGE 0 And Mode is Auto ElseIf stage = 0 AND Measure_DMMs_Trigger Then Measure_DMMs_Trigger = false stage = 1 Solenoid_Power_On = true Timer (1,Sec,2) 'Reset & Start Off timer '------ STAGE 1 ElseIf stage = 1 AND Timer (1,Sec,4 ) >= 1 Then stage = 2 Solenoid_Power_On = false '------ STAGE 2 ElseIf stage = 2 AND Timer (1,Sec,4 ) >= 20 Then stage = 3 DMM_Power_On = true '------ STAGE 3 'ElseIf stage = 3 AND Timer (1,Sec,4 ) >= 25 Then ElseIf stage = 3 AND Second = 0 Then ' make sure the laser have been fully turned On at this stage ' because we want to take modbus reading Call READ_DMM ' CallTable DMM_Param Update_DMM_Table = true Measure_LVDT_Trigger = true stage = 4 '------ STAGE 4 'ElseIf stage = 4 AND Timer (1,Sec,4 ) >= 25 Then ElseIf stage = 4 Then 'Measure_DMMs_Trigger = false stage = 5 Solenoid_Power_On = true DMM_Power_On = false Timer (1,Sec,2 ) 'Reset and Start timer '------ STAGE 5 ElseIf stage = 5 AND Timer (1,Sec,4 ) >= 5 Then 'Measure_DMMs_Trigger = false stage = 0 Solenoid_Power_On = false Timer (1,Sec,3) 'Stop & Reset timer Else Measure_DMMs_Trigger = false EndIf EndIf If Update_DMM_Table Then If ManualMode Then Update_DMM_Table = false CallTable DMM_Data CallTable BattTemp CallTable Diagnostic Else Update_DMM_Table = false CallTable DMM_Data CallTable BattTemp CallTable Diagnostic EndIf EndIf If DMM_Power_On Then SerialOpen (DMM_Com_Port,38400,16,0,128,4) Else SerialClose(DMM_Com_Port) EndIf ' Turn On/Off the relays PortSet (pinRelaySolenoid,Solenoid_Power_On) PortSet (pinRelayDMM, DMM_Power_On) '================ END OF DMM SCAN SECTION ' LVDT_Measure_Interval = 60 ' LVDT_Measure_Units = sec 'If TimeIntoInterval(0,LVDT_Measure_Interval,sec) Then Measure_LVDT_Trigger = true If Measure_LVDT_Trigger Then Measure_LVDT_Trigger = false 'SW12 (SW12_1,1 ) 'Delay(0,5,Sec) For i = 1 To Number_of_LVDT VoltDiff (LVDT_mV(1),1,mV5000C,U1,True ,0,50,1,0) LVDT_mm_Raw(i)=(LVDT_mV(i)/LVDT_Cal(i)) LVDT_mm_Calc(i)= LVDT_mm_Raw(i) - LVDT_Zero(i) Next i 'SW12 (SW12_1,0 ) CallTable LVDT_Data EndIf SW12 (SW12_1,DMM_Power_On) NextScan SlowSequence ' SlowSequence for anything slow Do RealTime(Masterscan()) If timeIsSynced = false Then NTPSyncInterval = fastNTPSyncInterval Else NTPSyncInterval = slowNTPSyncInterval EndIf If IfTime (0,NTPSyncInterval,sec) Then triggerSyncNTP = true EndIf Sprintf(battVStr,"%.1f", BatteryV) Sprintf(PTempStr,"%.1f", PTemp) Sprintf(dateStr,"%04u-%02u-%02u", Year, Month, Date) Sprintf(timeStr,"%02u:%02u:%02u", Hour, Minute, Second) Sprintf(DMM_CalcStr,"%.2f", DMM_Data.DMM_Calc(1,1)) Sprintf(LVDT_mm_CalcStr,"%.2f", LVDT_Data.LVDT_mm_Calc(1,1)) If DMM_Power_On Then DMM_Power_OnStr = "DMM ON" Else DMM_Power_OnStr = "DMM OFF" EndIf If AlarmTriggerEnabled AND (BatteryAlarmTrigger OR Test_BatteryAlarmTrigger) Then 'Message = "PERHATIAN !" + CRLF + CRLF Message = Message + "[CR6 Logger] batt volt: " + battVStr + " V" + CRLF + CRLF Message = Message + "Pls check ASAP." + CRLF + CRLF Message = Message + "Logger date/time: " + Status.Timestamp + CRLF + CRLF EmailSuccess = EmailRelay("testemail@gmail.com","[SHMS Kebumen Bridge] Warning Low Batt",Message,ServerResponse) If EmailSuccess Then BatteryAlarmTrigger = false Test_BatteryAlarmTrigger = false EndIf EndIf Erase(Message) 'Erase the message after sending If triggerSyncNTP Then SLOWSCAN_STAGE = "Sync NTP" ' synct time via NTP on regular basis timeDiff = NetworkTimeProtocol ("pool.ntp.org", systemTimeZone * 3600, 1000) If timeDiff <> NAN Then triggerSyncNTP = false timeIsSynced = true NTPSyncInterval = slowNTPSyncInterval RealTime(Masterscan()) ' check datalogger time Sprintf(lastNTPSync, strDateTimeFormat, Year, Month, Date, Hour, Minute, Second) Else NTPSyncInterval = fastNTPSyncInterval EndIf EndIf If IfTime(0,1, Min) Then FTPEnabled = true EndIf If FTPEnabled Then FTPEnabled = false '1st attempt ' FTP 'Dim dt As String 'Sprintf(dt,"%04u-%02u-%02u.txt", Year, Month, Date) rootPath = "2004_wika_lukulo" dateStr = "test" SLOWSCAN_STAGE = "FTP Diagnostic" FTPResult(1) = FTPClient (FTP_HOST,FTP_USER,FTP_PASS,"Diagnostic",rootPath & "/Diagnostic/Diagnostic_" & dateStr & ".txt",9,0,0,Min,-1008) SLOWSCAN_STAGE = "FTP DMM_Data" FTPResult(2) = FTPClient (FTP_HOST,FTP_USER,FTP_PASS,"DMM_Data",rootPath & "/DMM/DMM_Data_" & dateStr & ".txt",9,0,0,Min,-1008) SLOWSCAN_STAGE = "FTP LVDT_Data" FTPResult(3) = FTPClient (FTP_HOST,FTP_USER,FTP_PASS,"LVDT_Data",rootPath & "/LVDT/LVDT_Data_" & dateStr & ".txt",9,0,0,Min,-1008) SLOWSCAN_STAGE = "FTP BattTemp" FTPResult(4) = FTPClient (FTP_HOST,FTP_USER,FTP_PASS,"BattTemp",rootPath & "/BattTemp/BattTemp_" & dateStr & ".txt",9,0,0,Min,-1008) 'This function returns: ' -1 if successful, ' 0 if it fails, or ' -2 if execution did not occur when the instruction was called ' (for instance, when using the optional parameters to stream data from a table and the number of records or time into interval conditions are not met). EndIf If IfTime(0,2, Sec) Then 'post current batt_volt to cosm.com (free service) 'see https://cosm.com/docs/ on API documentation http_header = "Content-Type:application/xml" 'enter unique ApiKey here file_handle = FileOpen("CPU:Batt_Volt.csv", "w", -1) FileWrite (file_handle, "1true" & DMM_CalcStr&"mm,"&LVDT_mm_CalcStr&"mm," & battVStr &"V,"& PTempStr &"°C,"& DMM_mode & "," & DMM_Power_OnStr&"" + CHR(10), 0) FileClose (file_handle) http_post_tx = HTTPPut ("http://admin:cctv1234@192.168.21.11/ISAPI/System/Video/inputs/channels/1/overlays/text/1", "CPU:Batt_Volt.csv", http_post_response, http_header,,,,,500) EndIf SLOWSCAN_STAGE = "End Of Slowscan" Loop EndSequence EndProg