View previous topic :: View next topic |
Author |
Message |
sshorter
Joined: 07 Dec 2004 Posts: 12
|
Posted: Thu Jul 01, 2021 10:39 pm Post subject: Problem with Delchar |
|
|
I am having an issue with using Delchar to clear the contents of a string that is built from characters received through USART0. I've been fighting this for a while and thought I would ask if there is something that I am missing.
I've included my whittled down code and a screen shot of the output to the computer. I've added some print statements to show what is going on.
Here's what is happening:
When the code is run for the first time, everything works and looks right on the screen. The string is built as it should be with each character received. When the full message has been received and acknowledged, the delchar statement is used to clear any of remaining string contents from memory to prepare for the next message arrival.
However, after more messages are sent, it seems as if all of the characters have not been cleared from the string. Looks as if every other character is cleared and the rest remain. Eventually, enough of the wrong chars are present that a valid message is considered invalid because of lingering chars.
If I insert a print statement (which I did remove, sorry) after the delchar statements it will show an empty string. But somehow when the next message arrives there are some "old" characters mixed in with the new as shown in the screen grab.
Here's a screen grab of what I'm seeing
[/img]
Code Listing:
Code: | $regfile = "m128def.dat"
$hwstack = 160 ' default use 32 for the hardware stack
$swstack = 160 'default use 10 for the SW stack
$framesize = 160 'default use 40 for the frame space
$crystal = 16000000
Dim Case_check_0 as byte
Dim Char_count0 As Byte
Dim Eval_string_0 As String * 15 'Dimension for 15 bytes but use around 10 (See Max_String_Length constant)
Dim A(14) As Byte
Dim A_text As String * 1
Dim char_present as byte
'These should already be there...
Config Serialin = Buffered , Size = 200 'Allow 200 bytes of storage for incoming data
Config Serialin1 = Buffered , Size = 200
Config Serialout = Buffered , Size = 200 'USART 0
Config Serialout1 = Buffered , Size = 200 'USART1
Open "COM1:" For Random As #1
Open "COM2:" For Random As #2
Enable Interrupts
Print "Running..."
char_count0 = 1 'set initial value on startup
'************** Main Prog Loop ********************
Do
'Running main program loop
'check if chars are in buffer, jump to sub and retrieve chars
Char_present = IsCharWaiting ()
If Char_present = 1 then
Char_count0 = 1 'set initial value before reading chars
Gosub Read_Serial
End If
Loop
'************************************************
Adjust_RTC:
Print "Adjust RTC"
'Do cool stuff here......
Gosub Delete_Eval_string_0
Return
Delete_Eval_string_0:
'clear chars from string when finished
delchar eval_string_0, 1
delchar eval_string_0, 2
delchar eval_string_0, 3
delchar eval_string_0, 4
delchar eval_string_0, 5
delchar eval_string_0, 6
delchar eval_string_0, 7
delchar eval_string_0, 8
delchar eval_string_0, 9
delchar eval_string_0, 10
delchar eval_string_0, 11
delchar eval_string_0, 12
delchar eval_string_0, 13
delchar eval_string_0, 14
delchar eval_string_0, 15
'Reset these values back to a "Ready to Process" state.
Char_count0 = 1
Case_check_0 = 0
A_Text =""
Clear SerialIn0
Return
Display_ETI:
Print "Show ETI"
'Do cool stuff here......
Gosub Delete_Eval_string_0
Return
Invalid_message_0:
Clear Serialin
Case_check_0 = 0
Print "Invalid Command"
'Delete characters from string if an invalid message is received.
'otherwise chars will remain in memory and keep giving invalid messages
'This allows recovery in the event of data corruption.
Gosub Delete_Eval_string_0
Return
Read_serial:
Do
A(Char_count0) = Inkey()
If A(Char_count0) = 10 Then
'CR LF has been received, assume message is complete at this point.
'Exit Do-Loop and evaluate what has been received.
Case_check_0 = 1 'LF received, now time to evaluate message below
Char_count0 = 1
Exit do
End If
'Build a string with the received chars.
If A(char_count0) > 10 Then 'For chars with an ASCII value greater than 10
A_text = Chr(a(Char_count0))
Mid(eval_string_0 , Char_count0 , 1) = A_text
Print Char_count0;" "; chr (A(Char_Count0)); " "; Eval_String_0 'debugging only
Incr Char_count0
End If
Loop until char_present = 0
If Case_check_0 = 1 Then 'evaluate received strings
Select Case Eval_string_0
Case "reti": Gosub Reset_ETI
Case "Show ETI": Gosub Display_ETI
Case "Adjust RTC": Gosub Adjust_RTC
Case Else : Gosub Invalid_message_0
End Select
End If
Clear Serialin0
Return
Reset_ETI:
'Reset value of Elapsed Time Indicator.
Print "Resetting ETI"
'Do cool stuff here......
Gosub Delete_Eval_string_0
Return
End 'of code listing
|
Thanks in advance... ](*,)
(BASCOM-AVR version : 2.0.8.2 , Latest : 2.0.8.3 ) |
|
Back to top |
|
|
AdrianJ
Joined: 16 Jan 2006 Posts: 2483 Location: Queensland
|
Posted: Fri Jul 02, 2021 1:00 am Post subject: |
|
|
When you build a string by inserting characters with the mid statement, the next character will be whatever is left over from when the string was last used. But bascom assumes that the end of the string is where the next null character is. One way to fix this is to insert a null one character count beyond where you are now. That way the current string always ends with a null, and does not 'run over' into old remmnants. _________________ Adrian Jansen
Computer language is a framework for creativity |
|
Back to top |
|
|
MWS
Joined: 22 Aug 2009 Posts: 2262
|
Posted: Fri Jul 02, 2021 3:42 pm Post subject: Re: Problem with Delchar |
|
|
sshorter wrote: | Code: |
delchar eval_string_0, 1
delchar eval_string_0, 2
...
delchar eval_string_0, 15
|
|
I'd say if your intention is to write maximal inefficient code, you're on your way.
To solve the puzzle about delchar: it does not do what you expect.
Removing the 1st char, 2nd char becomes 1st char.
Removing 2nd char, 3rd char becomes 2nd char.
After removing the 8th char, the string-end moved thus far to the front, that the remaining delchar's actually do not have any effect.
If you want to keep your code, simply replace the whole delchar block against:
Code: | Memfill eval_string_0, 15 , 0 |
Not tested, but should work ok. |
|
Back to top |
|
|
sshorter
Joined: 07 Dec 2004 Posts: 12
|
Posted: Fri Jul 02, 2021 4:42 pm Post subject: |
|
|
I know the code was inefficient in the operations. There was a better way...just trying to easily show what I was trying to do.
That being said, thanks for letting me know that the chars were "shifted" when using delchar. That explains everything.
I'll make some changes and give it a shot.
Thanks guys. |
|
Back to top |
|
|
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum You cannot attach files in this forum You cannot download files in this forum
|
|