View previous topic :: View next topic |
Author |
Message |
njepsen
Joined: 13 Aug 2007 Posts: 469
|
Posted: Fri Sep 24, 2021 1:21 am Post subject: overlay - MWS |
|
|
MWS,
some time ago you commented in another post about the follies of building a string with string = String + newcharacter, for reasons that make really good sense, and you advised overlaying an array over the string.
I am doing what you advised against - is this what you had in mind?
I know you hate people posting code that won't complile but this function is hardware dependent and is 8000 lines long.
Code: | Function Getmeterresponse(byval metercommandstr As String) As String
dim sTemp as string * 250
dim bArray(250) as byte at sTemp overlay 'overlay the array at the string address
local Index as byte
local rxbyte as byte
Index = 1 'arrays are a based
sTemp = ""
Print #3 , "" 'clear meter buffer
Print #3 , metercommandstr 'command to meter
Do
waitms 100 'allow meter time to respond
While Ischarwaiting(#3) <> 0
rxbyte = inkey(3)
bArray(Index) = rxbyte 'save the byte overtop of the string
incr index
bArray(index) = &H0 'write new string terminator
Wend
Loop Until Rxbyte = 10 '10 = LF from Nor140
Getmeterresponse = sTemp
End Function
|
(BASCOM-AVR version : 2082 , Latest : 2.0.8.4 ) _________________ Neil |
|
Back to top |
|
|
Paulvk
Joined: 28 Jul 2006 Posts: 1257 Location: SYDNEY
|
Posted: Fri Sep 24, 2021 5:47 am Post subject: |
|
|
I did this with the webserver code I created a 250 character string and overlaid the bytes as you have done,
I needed to pull bytes from the wiznet chip , once the bytes were put into the overlay I could then
use string functions to search the bytes (HTTP requests/posts). Note the MEGA1284p was good for this with its 16k of ram.
Also you can use more than one overlay , you could overlay a word , long , double onto the string or all of these at a time
overlay is a very powerful thing.
Regards Paul |
|
Back to top |
|
|
EDC
Joined: 26 Mar 2014 Posts: 971
|
Posted: Fri Sep 24, 2021 9:18 am Post subject: |
|
|
I dont know how your incomming data is transferred and looks like but in your code a &H10 will be added to the string. So maybe..
Code: |
Do
Waitms 100
While Ischarwaiting(#3) <> 0
rxbyte = inkey(3)
If rxbyte = &H10 Then
bArray(index) = &H0 'write new string terminator
Exit Do
Else
bArray(Index) = rxbyte 'save the byte overtop of the string
incr index
End If
Wend
Loop
|
You can swallow &H0D (CR) by simple Elseif or Select Case rxbyte.
I also think that some Timeout should be used for this Do loop if LF never arrive.
Code: |
LoopCnt = 0
Do
Waitms 100
While Ischarwaiting(#3) <> 0
rxbyte = inkey(3)
Select Case rxbyte
Case &H10
bArray(index) = &H0 'write new string terminator
Exit Do
Case &H0D
nop 'swallow
Case Else
bArray(Index) = rxbyte 'save the byte overtop of the string
incr index
End Select
End If
Wend
Incr LoopCnt
Loop Until LoopCnt = 5 'Timeout
|
|
|
Back to top |
|
|
albertsm
Joined: 09 Apr 2004 Posts: 5921 Location: Holland
|
Posted: Fri Sep 24, 2021 9:51 am Post subject: |
|
|
you also need to check that you do not keep writing in case of spurious data arrives.
and instead of inkey() use waitkey() since you already checked that there is data with ischarwaiting() _________________ Mark |
|
Back to top |
|
|
njepsen
Joined: 13 Aug 2007 Posts: 469
|
Posted: Fri Sep 24, 2021 9:47 pm Post subject: |
|
|
Thanks for the comments chaps. This was an edited version of what i have running, and I do have a 2 sec timeout in the do loop in case nothing arrives, but you are correct - the LF does get added to the string and I remove it and spaces after the loop with delchars.
Mark you suggest using waitkey rather than inkey but I don't understand the difference in this context - don't they effectively give the same result after the ischarwaiting?
You make a good point if 'continuous' spurious data arrives and i had not though of that, but the timeout would exit after 2 secs.
I have this running at present. Code: |
'*************************************************************************************
Function Getmeterresponse(byval metercommandstr As String) As String
'meter response looks like E<space>57.9<cr><lf>
'Note that return to SU0 is 155 bytes long.
'note - if inner loop gets stuck, AIU watchdogs or times out.
'
#if isnoise=1
Local Timedelay As Long
local Index as byte
Index = 1 'arrays are 1 based
Tempstr2 = ""
Clear Serialin 'clear ser buffer
Print #3 , "" 'clear meter buffer
Print #3 , metercommandstr ' CRLF is added automatically
Timedelay = Local_secl + 2
Do
While Ischarwaiting(#3) <> 0
rxbyte = inkey(#3)
bArray(Index) = rxbyte 'save the byte overtop of the string
incr index
bArray(index) = &H0 'write new string terminator
if rxbyte = 85 or rxbyte = 10 then exit do
Wend
Loop Until Local_secl >= Timedelay
Delchars tempstr2 , 10 'LF
Delchars tempstr2 , 13 'CR
delchars tempstr2 , 32 'spaces
delchars tempstr2 , "E" 'valid response
delchars tempstr2 , "M" 'overload
print #1,">> meter said ";tempstr2
Getmeterresponse = Tempstr2
#endif
End Function
|
_________________ Neil |
|
Back to top |
|
|
EDC
Joined: 26 Mar 2014 Posts: 971
|
Posted: Sat Sep 25, 2021 6:32 am Post subject: |
|
|
Why dont select them when they arrives? It is tudious job to search for the delchar function. I dont get it.
Seriously? |
|
Back to top |
|
|
EDC
Joined: 26 Mar 2014 Posts: 971
|
Posted: Sat Sep 25, 2021 6:43 am Post subject: |
|
|
You are a happy men. You have plenty of time for your code
I appreciate this |
|
Back to top |
|
|
MWS
Joined: 22 Aug 2009 Posts: 2262
|
Posted: Sat Sep 25, 2021 8:28 am Post subject: Re: overlay - MWS |
|
|
njepsen wrote: | I am doing what you advised against - is this what you had in mind? |
Yes, this is leaner, as it uses a dedicated pointer to the next char, while the concat '+' always needs to seek the end of string first.
Quote: | I know you hate people posting code that won't complile but this function is hardware dependent and is 8000 lines long. |
I don't need the book, if everything's available in a chapter. If code is easy to read and it doesn't need to be simulated, I'm fine with that.
Some minor suggestions:
Code: | ' sTemp = "" <-- can be left out, if the following is applied
'...
' bArray(index) = &H0 <-- saves also some cycles to move it from here
Wend
bArray(index) = &H0 ' <-- to there |
|
|
Back to top |
|
|
MWS
Joined: 22 Aug 2009 Posts: 2262
|
Posted: Sat Sep 25, 2021 8:58 am Post subject: |
|
|
Code: | While Ischarwaiting(#3) <> 0
rxbyte = waitkey(#3)
Select Case rxbyte
Case 10:
Case 13:
Case 32:
Case "E":
Case "M":
Case Else:
If Index < 251 Then
bArray(Index) = rxbyte
incr index
End If
End Select
Wend
bArray(index) = &H0 |
|
|
Back to top |
|
|
albertsm
Joined: 09 Apr 2004 Posts: 5921 Location: Holland
|
Posted: Sat Sep 25, 2021 12:51 pm Post subject: |
|
|
Quote: | you suggest using waitkey rather than inkey but I don't understand the difference in this context |
iskey first doest a check to see if any data is waiting. while waiting simply wait till data arrives. it uses less cycles/code when you know the data must be there since ischarwaiting is basically the same as inkey with the difference that it does not empty the buffer. _________________ Mark |
|
Back to top |
|
|
njepsen
Joined: 13 Aug 2007 Posts: 469
|
Posted: Wed Oct 13, 2021 6:45 am Post subject: overlay |
|
|
Further to this discussion.
I have been doing some testing.
Because arrays cannot be locals, the declaration must take the form
Code: |
dim somestring as string * 255 'must be declared before the array
dim bArray (250) as byte at somestring overlay
|
This means that "somestring" must also be declared as a global?
Now I have just got myself into trouble because I used "somestring" elsewhere in a program as a general purpose string variable , and and it caused a crash after 5 days, which I have not yet got to the bottom of. Being cautious tells me I should use "somestring" only in functions where I use overlay, and to not nest these functions.
comments anyone? _________________ Neil |
|
Back to top |
|
|
albertsm
Joined: 09 Apr 2004 Posts: 5921 Location: Holland
|
Posted: Wed Oct 13, 2021 11:59 am Post subject: |
|
|
yes both need to be global which is the default.
from a technical point of view, it should be possible to use overlay on locals as well. never gave it much thought since using on a normal global var is dangerous enough already.
and no it is not a good idea to use the same name for a variable. only reuse them when both code is not running at the same time.
to save memory it is common practice to have some temp variables you reuse. but then you need to make sure that each time you access that this is allowed.
using the code explorer you can find all instances.
in order to see how to fix it best i would need to see the code. _________________ Mark |
|
Back to top |
|
|
njepsen
Joined: 13 Aug 2007 Posts: 469
|
Posted: Thu Oct 14, 2021 6:10 am Post subject: |
|
|
Hi Mark,
thanks for your input. That pretty much confirms my conclusion that both the array and the overlaid string need to be global.
My fix was really easy My mistake was in using the string var where i should not have used it, so i just declared an array and a 200byte string var that are both used only for the overlay method of receiving serial data. _________________ Neil |
|
Back to top |
|
|
|