Standardowo wtedy do wykrycia tego czy w buforze znajdują się jakieś znaki używamy funkcji Ischarwaiting()
Niestety często jest tak że znaki faktycznie czekają, ale nie są to wszystkie znaki na które czekamy
Często czekamy na znaki CR i LF albo przynajmniej na znak kończący string
Różne rozwiązania już widziałem i najcześciej jest to odbiór pojedynczych znaków i składanie z nich stringów
Sprawę można bardzo sobie uprościć konfigurując Serialin tak by reagował po odebraniu jakiegoś konkretnego znaku, na przykład 10 to LF i nawet tak to można zapisać, 13 to Carriage Return (CR) czyli popularny Enter
Mamy wtedy prawie pewność że do odebrania jest cała linia tekstu.
Charmatch obsługiwane jest jako przedłużenie obsługi przerwania.
W Helpie przeczytasz, że trzeba zadbać o zachowanie rejestrów których używasz w obsłudze swojego Charmatch
Może tam być przecież tylko zwykłe Input String, ale też widziałem bardziej rozbudowane konstrukcje
W Helpie pisze też, że jeśli nie wiesz jakie rejestry zachować to musisz zachować wszystkie czyli
na wejściu piszesz Pushall a przed wyjściem z Charmatch piszesz Popall
Narzędzie listuje użyte rejestry i od tej pory używam Charmatch coraz częściej czego dowodem jest poniższy kod, który przepisałem względem poprzedniej wersji o obsługę odbioru danych z jego użyciem
Kod z założenia nie miał posiadać żadnych Wait i Waitms
Ten który tu zamieszczam jest tylko takim najprostszym przykładem. Można by tu też wiele poskracać, jednak jako przykład miał być przejrzysty.
'**************************************************************** '* UPDATING THINGSPEAK FIELD WITH ESP8266 AND XMEGA * '* ESP8266 AT COMMANDS V.051 SDK 1.5.0 * '* BARTek niveasoft(at)tlen.pl ver.2016.07.31 * '**************************************************************** $regfile = "xm128a3udef.dat" $crystal = 32000000 '32MHz $hwstack = 80 'this is for my other tasks so $swstack = 100 'you can modify values to your needs $framesize = 200 Config Submode = New Const Api_key = "ABCDEFGHIJKLP" '' <<<<< YOUR API WRITE KEY Const Debuging = 1 ' ***************** SYSTEM CLOCK CONFIG ************************** ' INTERNAL 32MHz NO PRESCALE ' Config Osc = Disabled , 32mhzosc = Enabled , 32khzosc = Enabled Config Sysclock = 32mhz , Prescalea = 1 , Prescalebc = 1_1 ' ' ENABLING AUTOMATIC OSCILLATOR CALIBRATION Osc_dfllctrl.0 = 1 Dfllrc32m_ctrl.0 = 1 ' '***************************************************************** '************ CONFIGURATION FOR COM1 ON PORTC ******************** ' ESP8266 ON COM1 Config Com1 = 115200 , Mode = Asynchroneous , Parity = None , Stopbits = 1 , Databits = 8 'Tx-PC3 Rx-PC2 Open "COM1:" For Binary As #1 Config Serialin0 = Buffered , Size = 150 , Bytematch = 10 'for COM1 Config Input1 = Crlf , Echo = Cr Echo Off ' Const Max_str_len = 150 : Dim Com1_str As String * Max_str_len '***************************************************************** #if Debuging = 1 '*********** CONFIGURATION FOR COM2 ON PORTC ********************* ' COM2 IS FOR DEBUG SO SEPARATE CONFIG Config Com2 = 115200 , Mode = Asynchroneous , Parity = None , Stopbits = 1 , Databits = 8 'Tx-PC7 Rx-PC6 Open "COM2:" For Binary As #2 Config Serialin1 = Buffered , Size = 50 'for COM2 Config Input2 = Cr , Echo = Cr ' Dim Com2_str As String * 50 '***************************************************************** #endif '********************** CLOCK CONFIG ***************************** ' we select the internal 1 KHz clock from the 32khz Internal Oscillator Config Clock = Soft , Rtc = 1khz_int32khz_rcosc Config Priority = Static , Vector = Application , Lo = Enabled , Med = Enabled ' the RTC uses LO priority '***************************************************************** Dim 15s As Byte , Send_time As Byte Dim Got_match As Byte Dim Cmd As String * 100 , Cmd_len As String * 15 Dim Field1 As String * 5 , Lenght As Byte Dim State As Byte , Old_state As Byte , Mem_state As Byte Const Startup = 0 Const Waiting = 1 Const Send_len = 2 Const Sending = 3 Led Alias Portf.0 : Config Led = Output '*** SUB FOR DEBUG ON COM2 *** Sub Show_state Local St_str As String * 10 Select Case State Case 0 : St_str = "Startup" Case 1 : St_str = "Waiting" Case 2 : St_str = "Send_len" Case 3 : St_str = "Sending" End Select Old_state = State Print #2 , "Now State=" ; St_str End Sub '*** SUB FOR ESP8266 *** Sub Esp8266 Select Case State Case Startup If Instr(com1_str , "WIFI GOT IP") > 0 Then 'AT+CIPSTART="TCP","184.106.153.149",80 Cmd = "AT+CIPSTART={034}TCP{034},{034}184.106.153.149{034},80" Print #1 , Cmd Field1 = Str(rnd(100)) ' <<<<<< random value for Testing #if Debuging = 1 : Print #2 , "Field value=" ; Field1 : #endif Cmd = "GET http://api.thingspeak.com/update?api_key=" Cmd = Cmd + Api_key Cmd = Cmd + "&field1=" Cmd = Cmd + Field1 Cmd = Cmd + "{010}{010}" Mem_state = State 'memorize that we starting State = Waiting Else #if Debuging = 1 : Print #2 , Com1_str : #endif End If Case Waiting ' if we waiting for answear Select Case Com1_str 'Case "CONNECT" Case "OK" ' if we see OK Select Case Mem_state Case Startup 'previous was Startup so this is first "OK" Mem_state = Send_len Lenght = Len(cmd) : Cmd_len = Str(lenght) Cmd_len = "AT+CIPSEND=" + Cmd_len Print #1 , Cmd_len Case Send_len 'second "OK" so we send Len of data we want send Print #1 , Cmd State = Sending Mem_state = Sending 'memorize that we send data to server ' ( for Error handling ) End Select #if Debuging = 1 : Print #2 , Com1_str : #endif Case "ERROR" #if Debuging = 1 : Print #2 , Com1_str : #endif State = Startup : Send_time = 0 Case "CLOSED" #if Debuging = 1 : Print #2 , Com1_str : #endif State = Startup : Send_time = 0 Case Else #if Debuging = 1 : Print #2 , Com1_str : #endif End Select Case Sending Select Case Com1_str Case "SEND OK" State = Startup : Send_time = 0 Case "CLOSED" #if Debuging = 1 : Print #2 , Com1_str : #endif State = Startup : Send_time = 0 Case "SEND FAIL" #if Debuging = 1 : Print #2 , Com1_str : #endif State = Startup : Send_time = 0 End Select #if Debuging = 1 : Print #2 , Com1_str : #endif End Select End Sub Enable Interrupts #if Debuging = 1 : Print #2 , "Program started. Debug active!" : #endif ' *** MAIN LOOP START HERE **** Do If Rtc_intflags.1 = 1 Then Set Rtc_intflags.1 'Clear the Int Flag If Send_time = 0 Then If 15s < 15 Then Incr 15s #if Debuging = 1 : Print #2 , 15s ; "{032}" ; : #endif Else 15s = 0 : Send_time = 1 #if Debuging = 1 : Print #2 , "Start ESP" : #endif Print #1 , "AT+RST" End If End If Toggle Led 'blink LED End If If Got_match = 1 Then Got_match = 0 Call Esp8266 End If #if Debuging = 1 If Old_state <> State Then Call Show_state #endif Loop End Serial0charmatch: $asm !PUSH R6 !PUSH R16 !PUSH R17 !PUSH R18 !PUSH R19 !PUSH R22 !PUSH R24 !PUSH R25 !PUSH R26 !PUSH R27 !PUSH R28 !PUSH R29 !PUSH R30 !in R24, sreg !PUSH R24 $end Asm $timeout = 3000 Input #1 , Com1_str Clear Serialin0 Got_match = 1 ' Tuned with NoSave Tool $asm !POP R24 !out sreg, r24 !POP R30 !POP R29 !POP R28 !POP R27 !POP R26 !POP R25 !POP R24 !POP R22 !POP R19 !POP R18 !POP R17 !POP R16 !POP R6 $end Asm Return