PDA

View Full Version : Array of string to send with TX int ?



amgen
- 11th August 2011, 14:44
I am trying to come up with a method to :
-at run time
-load an array with differing strings, pulled from prog. mem, EEmem and variables.
-and when ready, send with TX interrupts up to an ending char

HSERout sucks up much processing time when you send 1,2 or 400 chars even at 115200 bps and 20MHZ.

I'm stuck on how to index and add to the array (to build the array) with a mixture of strings and variables.

Incomming RCVieves request the differing data to be sent back.

thanks for ideas.
don
amgen

amgen
- 14th August 2011, 12:56
Hello,
Narrowing down my question, PBP 2.6 has ARRAYWRIYTE with all the modifiers and will create a string all formatted to an array.
Is there access to the index pointer used by a 'differing legnth' ARRAYWRITE uses so another ARRAYWRITE can add chars directly to the end of the first write ?

ARRAYWRITE snd_array , [str str1 ,10,13]

(str1 may vary in legnth, takes chars up to a 0-zero)
(add to snd_array directly at the end of first ARRAYWRITE)
( find the index to where to start ?)

ARRAYWRITE snd_array(????) , [str str2 , 00]

thanks,
don
amgen

mister_e
- 14th August 2011, 13:03
Not sur filling an array will be better than Hserout, it still take some time to fill it. What I would do is to use a variant of Darrel's embedded string in your codespace for the known data, then maybe you could have an array to store your unknown data into a run time.

Depending how you format your thing, it may also take some time to process it. Usually we use a NULL character to specify a string/set of data end. This assume you need to check each character, test it and then send it... duh.

BUT you may have a String/Data start AND end address and loop from the start to the end.. still it always test if you're at the end address.

Not sure of your requirement, but sure enough, I don't see many advantage over a simple HSEROUT line, code size appart.

Circular buffer...mmm.....

Explain your exact requirement, post your code here, we will have a look at that.

amgen
- 14th August 2011, 15:17
Hi Steve,

Quick overview,
-18f2525 3k ram
- DT ints for main timing loop 10X/sec
-after main loop of code for up to .1 sec, wait for int flag to loop,
then, the time in wait is idle time, (indicates if using up processing available between interrupts to remain in accurate timing.)
-Recieve ints work in backround

-HSEROUT takes up about 80% processing for the loop to send 600 some-odd chars. More hserout will make error for the main timing loops...If you want to count on the main loop for timing. See image of serout.





HSEROUT["<name=IDLE_TIME,value=",dec L2,".",dec w1,"%>, _
","<name=LONG,value=",dec L1,">",10,13]
HSEROUT["IN DATA ARRAY "] ' pin 14 on F2525

for ax=1 to 'SEND ALL IN MEM BY INDEX
indx
DAT = RCVDATA[AX]
HSEROUT[DAT]
next ax

HSEROUT [", INDEX COUNT=" , DEC INDX ,10,13]


5867
So, TX int will work in backround and not interfere with timing.
I can post code but I program on my old XP computer and this Vista laptop to internet and the vista blocks my network at times, so I have to get code files to post here.

thanks for your thoughts
don

HenrikOlsson
- 14th August 2011, 16:35
Hi,
It's not really processing power it's just that HSEROUT sits there waiting for the for TXBuffer to free up before it can put the next byte in. 600 bytes is 6000 bits at 8N1 so at 115200 it should take around 1/115200*6000=52ms. The PIC oscillator frequency has little impact on that as the actuall processing involved in the HSEROUT is quite small (though I guess it increases a bit with the all the modifiers).

ARRAYWRITE should work exactly the same as HSEROUT except it will put all your data in an array in RAM. So if if you have enough RAM (600 bytes?) simply replace HSEROUT with ARRAYWRITE and write your complete string to memory (or do it parts if you don't have the RAM). At the very end you pad a NULL or other character that you can use to identify the end of the string.

Then, to have the transmit interrupt driven, have a look at this post (http://www.picbasic.co.uk/forum/showthread.php?t=13984&p=96160#post96160)

I'm sure the ARRAYWRITE index counter is available in one of the system variables but I have no idea which. You should be able to handle it by multiple arraywrites and "send-sessions". Load array, send, reload array send etc. Have a semaphore that the ISR cleares when it finds the end of the current outgoing string, that way the main routine knows when it can reload the array with the next part of the message.

But, like I said, it's not going to take less time to send 600bytes either way but you're going to have access to the processor during the time it takes to actually get the byte from the TXReg and out of the PIC which is like 87us or there abouts for 115200.

/Henrik.

amgen
- 15th August 2011, 14:35
Thanks Henrik,
It seems that ArrayWrite can't access program mem directly, this code didn't work, probably same for EEprom . Looks like it only works for ram to ram functioning.




arraywrite snd_array ,[str str2,0] (Didn't work)


asm ;test tables at top of program mem

str1 org 0xb100
db "<name=IDLE_TIME,value=",0

str2 org 0xb200
db "<name=LONG,value=",0

str3 org 0xb300
db "<name=IP Address,value= 192.168.1.3>",0

endasm



like you said, I would have to build string-array piece by piece and send when done or send piece by piece out TX.
I understand that the time it takes to send 600 chars @ 115200 is the same no matter how its sent, but the machine instructions to send by TX should be much less than HSER or SER. The main loop of 10X per second (100 milli sec per loop) should allow for about 300,000 instructions each .1sec loop without overrunning timer interrupt. The use of interrupts keeps all that constant.
I think....

don

HenrikOlsson
- 15th August 2011, 19:11
Hi Don,
It's not clear to me exactly what your trying to do. You say that ARRAYWRITE doesn't access porgram space but that's exactly what it does. It takes data stored in program space and moves it to and array in RAM. It can also copy data from RAM to the array using one of many modifiers, like STR.


String_1 VAR BYTE 128
String_2 VAR BYTE 64
Value VAR BYTE

Value = 123

ARRAYWRITE, String_2, [" and this is the second part of the string.",0]
ARRAYWRITE, String_1, ["This is the first part,", STR String_2, " The variable value is: ", DEC Value, 0]

The STR modifer writes the contents of String_2 in this case to String_1. It stops when it sees the 0 padded to the end of String_2. I don't think it actually writes that 0 in which case we're in trouble....

However, since I don't fully understand your problem I'm not sure this helps at all. If you have enough RAM to store the full 600+ bytes string you could build the string with a single ARRAYWRITE statement, pad a zero at the end and then enable the TX interrupt to have it sent in the background.

I'm sorry if I'm completely missing the point here....

/Henrik.

HenrikOlsson
- 16th August 2011, 13:32
Hi Don,
Following up on my previous post.


String_1 VAR BYTE 100
String_2 VAR BYTE 32
Value VAR BYTE

Value = 123

HSEROUT["Program start",13,13]

ArrayWrite String_1, ["This is the first part ",0]
ArrayWrite String_2, ["and this is the second part.",0]

'Now join the two strings back and add the ASCII representaion of Value at the end.
ArrayWrite String_1, [STR String_1, Str String_2, " The value is: ", DEC Value,13,0]

HSEROUT[STR String_1]
Pause 2000

END

The above gives the followin output:


Program start
This is the first part and this is the second part. The value is: 123
This shows that you can "build" strings (arrays) of data from constant data (program space), other arrays (RAM) and ordinary variables (RAM). I'm pretty sure you won't be able to move data from EEPROM to an array like this so you need to load that "manually" (FOR-NEXT loop or whatever).

/Henrik.

amgen
- 16th August 2011, 14:54
OK,
I see you did it but, I don't know how string_1 re-writes itself while reading itself .
If it works, then it works ! That will be how I will build an assorted string to send on TX int.
Like you did on other post, its simple to: turn on TXint, send 1 complete array up to say, 0 then turn off TX.

1 point of differ, to my understanding, all those arrays srt_1 and 2 are in RAM mem.

strings and numbers stored in program mem is done with pokecode or writecode or in asm with dw,db or de.
Those items need to be retrieved with peekcode or readcode into PB 1 char or word at a time.




asm ;strings placed at top of program mem if there is room
str1 org 0xb100 ;this has to be placed at the end of code
db "<name=IDLE_TIME,value=",0
str2 org 0xb200
db "<name=LONG,value=",0
str3 org 0xb300
db "<name=IP Address,value= 192.168.1.3>",0
endasm


this code places at lable str1, location B200 hex , db (data byte) <nam......etc
I think, these strings, or which ever ones you wanted, would need to be loaded, 1 char at a time into somearray[] then acted on with arraywrite to make final send like you have done.
don

HenrikOlsson
- 16th August 2011, 15:16
Hi don,
I wasn't sure rewriting String_1 like that was going to work but it does. I guess it's pretty much the same thing as doing

A VAR BYTE
A = A + 1


1 point of differ, to my understanding, all those arrays srt_1 and 2 are in RAM mem.

Yes, the arrays String_1 and String_2 are strored in RAM but when you do

ArrayWrite String_1, ["This is a string"]
The actual, literal string (This is a string) which is loaded into the array is stored in program memory (where else would it be) and loaded from there into the array. So you can do:

ArrayWrite String_1,["<name=IDLE_TIME,value=",0]
HSEROUT String_1
ArrayWrite String_1 ["<name=LONG,value=",0]
HSEROUT String_1

Or manipulate it any way you see fit.

The drawback with ArrayWrite and HSEROUT when using literal strings is the IMHO hugh space each charcter occupies. Each byte/character added to an ArrayWrite statement eats away 6 bytes of program space while the @db approach apparently bitpacks two charcters in each byte meaning it only takes 1/12 of the space. Obviously the drawback with THAT is you can't use ArrayWrite to move it from flash to RAM.

/Henrik.

amgen
- 16th August 2011, 15:20
back to string_1 and 2, still wondering,
5874

if you switch the order, will string still be made correctly,
the way you have it coded, it just has to leave itself alone and add to it,
but if it is moved in place then what ?

don

amgen
- 16th August 2011, 15:39
Yes, to prog mem..........easier to program

then, to create different callable strings to use in PB,

LabelA:
ARRAYWRITE string_1,[string_1, "<more string added to string 1 etc"]
Return

LabelB:
ARRAYWRITE string_1,[string_1, "<more other string added to string 1 etc"]
Return

etc

use gosub to build up string, check string legnth somehow so don't overflow
Zero out string_1 when want to start a new one

Takes a little mem but f2525 has 48k

don

HenrikOlsson
- 16th August 2011, 15:49
Hi,
No, you're right, moving them around seems to create havoc.
But still, it does allow you you concatenate multiple arrays into one, you can have one "master array" which is the one you eventually are going to send out and one smaller "working array" to which you fetch strings from code space (stored with db or whatever) and one by one add them to the "master array" before finally sending it.

That is if the message sent is going to be different each time. If all the literal strings are the same and it's only data that changes them of course you there's no use in messing around with all this.

I'm still not sure what exaclty you're trying to do (except sending arrays over a serial line) so I'm not sure if all this even helps.

/Henrik.

EDIT: When concatenting String_1 don't forget the STR modifier! And always add a 0 to the end, that's how the STR modifier knows when to stop.

amgen
- 16th August 2011, 16:07
Helps very much, this setup will allow a remote terminal, of some type to request selected information and how often to send it out. So string parts may change, and parts may stay the same. It's a flexable layout with communication in the backround and a timing base type template.

Thanks
don

mister_e
- 17th August 2011, 17:31
I still don't get what you're trying to sove with this arfraywrite thing, but maybe the following may give you so idea?


ADDR VAR WORD
CHAR VAR BYTE
CLEAR

goto OVERDT
string1 CON EXT
string2 CON EXT
string3 CON EXT

eostring1 CON EXT
eostring2 CON EXT
eostring3 CON EXT

string4 CON EXT
stringend con ext
asm
string1 dt "_this is string1"
eostring1 =$-1

string2 dt "_this is string2"
eostring2 =$-1

string3 dt "_this is string3"
eostring3 =$-1

stringend
#define s4 "yaya dada String 4 "
#define s5 "Plah plah plah string 5 "
string4 dt s4,s5, 0
endasm
OVERDT:
ADDR=string4
MAIN:
READCODE ADDR, CHAR
IF CHAR THEN
hserout [char]
ADDR=ADDR+1
GOTO MAIN
ENDIF

HSEROUT [13,10,REP "-"\80,13,10]

for addr = string1 to eostring1
readcode ADDR, CHAR
HSEROUT [CHAR]
next

HSEROUT [13,10,REP "-"\80,13,10,"DONE !"]
SPIN: GOTO SPIN
Case not, well, sorry :(

amgen
- 17th August 2011, 18:08
ok,
basically, the following is a responce to an HTTP request, just a string stuff, not impossible to assemble, and that will display on a web page through a TCP thing.

HTTP/1.0 200 OK
Date: Fri, 31 Dec 1999 23:59:59 GMT
Content-Type: text/html
Content-Length: 1354
<html>
<body>
<h1>Happy New Millennium!</h1>
(more file contents)
.
...........try to add some PIC data stuff in here
.
</body>
</html>

so thats that part of being able to make string array and be able to send out when ready ????

5880
don

mister_e
- 17th August 2011, 18:37
Well you definitely don't need any array to do that, it sucks way too much RAM for absolutely nothing. What I feel you should do is a kind of template
Header
extrastuff
footer

send the header, then the extra stuff and finally the footer. A flag for each part sent should do the trick... At least, from what I feel.

And still, it shouldn't be faster than a couple of HSEROUT line... but more flexible if you're using asm DT/DB/DATA/DA.

I'll continue to follow this thread, it's interesting while I'm not sure I still understand the requirement :D

amgen
- 18th August 2011, 16:35
Steve,
That is good but for 1 or 2 issues,
In the header, you need to know the 'total length' of bytes you are sending because that will 'finish off the transmission and stop IE from continuing to wait for more.
The 18f2525 and other's have 4K bytes ram so an array or 2 of [1000] still leaves plenty or ram.....

don

mister_e
- 18th August 2011, 16:56
That's the kind of missing info I needed ;) But it's still doable using the DT/DATA thing at running time.

Oh well. Keep us inform