Serial communcation question
I'd like to detect a carriage return, then send the cached bytes (prior to the carriage return) to a delimiter routine.
So let's say I typed into the Parallax Serial Terminal forum=65 and then a carriage return.
After carriageReturnCheck equaled 13, it would then send "forum=65" to my delimiter routine ... but I don't know how to do the cached bytes storage, stringIn := (stringIn + debug.rx) does not work.
I can post the additional code routines if it would make answer the question easier.
Thanks!
So let's say I typed into the Parallax Serial Terminal forum=65 and then a carriage return.
After carriageReturnCheck equaled 13, it would then send "forum=65" to my delimiter routine ... but I don't know how to do the cached bytes storage, stringIn := (stringIn + debug.rx) does not work.
I can post the additional code routines if it would make answer the question easier.
Thanks!
stringIn := (stringIn + debug.rx)
carriageReturnCheck := debug.rx
if (carriageReturnCheck == 13)
debug.str(string("Carriage return detected"))
debug.tx(13)
debug.str(@stringIn)
debug.tx(13)
debug.StrIn(@stringIn)
DelimiterFinder(@stringIn)

Comments
As a good sample of string manipulation, see Kye's string routines in OBEX.
You will also have to replace the cr with $0 in the stringIn or you will overrun the buffer until a null is found ( a null=$0 is the string terminator)
Instead, use an index designator to store each byte in a seperate element of the array: stringIn[0] := debug.rx stores the byte in the first element. Remember that arrays start at 0.
Use a variable for the index to advance through the array as each byte is received: stringIn[i++] := debug.rx
The ++ operator increments the index after the byte has been stored, so you need to loop until the byte at the previous index is a carriage return.
i := 0 repeat until stringIn[i - 1] == 13 stringIn[i++] := debug.rx stringIn[i - 1] := 0 ' replace the carriage return with a null debug.str(@stringIn)You of course need to make sure that the array is large enough or have some way of limiting the index or otherwise controlling the length of the string.I cannot seem to get this to work, I had to add the rxcheck statement because my cog was hung in the repeat loop ... what am I missing?
if (debug.rxcheck <> -1) 'repeat until stringIn[i - 1] == 13 stringIn[i++] := debug.rx debug.str(string("Character is - ")) debug.str(@stringIn[i]) debug.tx(13) if (@stringIn[i] == 13) stringIn[i - 1] := 0 ' replace the carriage return with a null 'debug.str(@stringIn) debug.str(string("Carriage return detected (main)")) debug.tx(13)EDIT: You are also incrementing i when reading the character, and then referring to stringIn later on. You should either increment i after doing everything else, or use stringIn[i-1] to compensate for having incremented i.
if (debug.rxcheck <> -1) debug.str(string("Character detected ", 13)) stringIn[i] := debug.rx debug.str(string("Character is - ")) debug.str(@stringIn[i]) debug.tx(13) if (stringIn[i] == 13) stringIn[i - 1] := 0 ' replace the carriage return with a null debug.str(stringIn) debug.tx(13) debug.str(string("Carriage return detected (main)")) debug.tx(13) i++with the result of
[code]
bCharacter detected
oCharacter is - o
bCharacter detected
=Character is - =
1Character detected
0Character is - 0
0Character detected
Character is -
ˆP,
PUB RxCheck : rxByte {{ Check if a byte is waiting in the receive buffer and return the byte if one is there, does NOT block (never waits). Parameters: none return: [COLOR="#FF0000"]If no byte, then return(-1). If byte, then return(byte).[/COLOR] example usage: serial.RxCheck expected outcome of example usage call: Return a byte if one is available, but dont wait for a byte to come in. }}IOW you should remember the character returned in if (debug.rxcheck <> -1), e.g. if ((c := debug.rxcheck) <> -1) and then consume the character, not throw it away.receivedByte := debug.RxCheck if (receivedByte <> -1) debug.str(string("Character detected ", 13)) stringIn[i] := receivedByte debug.str(string("Character is - ")) debug.str(@stringIn[i]) debug.tx(13) if (stringIn[i] == 13) stringIn[i] := 0 ' replace the carriage return with a null debug.str(stringIn) debug.tx(13) debug.str(string("Carriage return detected (main)")) debug.tx(13) i := 0 i++but the debug.str(stringIn) still prints nonsense to the terminal.
I just read your message after my latest code and I believe I've gotten that part correct. Any idea why I can't write the final value ( debug.str(stringIn) ) as confirmation I've ingested it and stored it in ram?
CON _clkmode = XTAL1|PLL16X _xinfreq = 5_000_000 OBJ debug: "FullDuplexSerial" VAR byte stringIn[32] PUB null : i | c debug.start(31, 30, %0000, 115200) waitcnt(clkfreq*3 + cnt) debug.tx(0) repeat if (c := debug.rxcheck) <> -1 stringIn[i] := c if (stringIn[i++] == 13) stringIn[--i] := 0 ' replace the carriage return with a null [COLOR="#FF0000"]debug.str(@stringIn{0})[/COLOR] debug.tx(13) i := 0 DATI did not work in my code at first, but then I noticed you had stringIn defined as a 32bit byte array and I had it as a long.
Can you explain why you knew to do that so I can understand why that the correct choice over a 32bit long?
Strings in SPIN are zero terminated byte arrays. There is nothing else to it. You can use a long array if you want but still have to fill it with bytes e.g.
VAR long stringIn[16[COLOR="#A9A9A9"]{64 bytes}[/COLOR]] PUB null ... stringIn.byte[i] := c ...