strcomp with Local Variable
I'm working on something that is running on another cog and using a local variable to compare two strings. I really have no clue what the rules are on this and I've searched the Propeller manual and can't find anything. Here's my code that I have so far.
The red statement should continue repeating until the readBuffer variable is changed, but it doesn't ever change at this point. As soon as the program is started the Pin 16 LED lights up. What could I be doing wrong?
PUB main
cognew(readSerial, @stack)
PUB readSerial | readBuffer
repeat
readBuffer := string("0")
[COLOR=#ff0000] repeat while strcomp(@readBuffer, string("0"))[/COLOR]
dira[16] := 1
outa[16] := 1
The red statement should continue repeating until the readBuffer variable is changed, but it doesn't ever change at this point. As soon as the program is started the Pin 16 LED lights up. What could I be doing wrong?

Comments
That fixed my problem. I don't know if you can help me with the next one or not.
I've added code that is supposed to read the serial port and check to see if it equals something.. Here's my code I have now.
PUB main cognew(readSerial, @stack) PUB readSerial | readBuffer repeat dira[16] := 1 outa[16] := 1 readBuffer := string("0") repeat while strcomp(readBuffer, string("0")) serial.RxStr(readBuffer) dira[17] := 1 outa[17] := 1 [COLOR=#ff0000] if strcomp(readBuffer, string("ABC")) 'tell the computer to RESET me.[/COLOR] serial.str(string("RESET")) dira[18] := 1 outa[18] := 1The red line should be where the problem is. I know for a fact the computer is sending the correct string and the repeat loop is stopping at the correct time (when the readBuffer variable changes - or the serial port contains a value). Why is the serial port sending RESET to the computer/Lighting LED 18.
your readbuffer is one long - 4 bytes.
not much but ok for "0" and ok for "ABC"
but you need to provide the address of the readbuffer to RxStr
readBuffer := "0" ' this puts the value "0" into readbuffers first byte out of four (all others are 0 thus terminating the string in the bytearray repeat while strcomp(@readBuffer, string("0")) ' compare string (bytearray) at address of readbuffer with string at address provided by string("0") serial.RxStr(@readBuffer) ' will read string into the first 4 bytes at address readbuffer, using a one long (4 byte) destination dira[17] := 1 outa[17] := 1 [COLOR=#ff0000] if strcomp(@readBuffer, string("ABC")) 'tell the computer to RESET me. - and now it will work[/COLOR] ...Enjoy!
Mike
PUB readSerial | readBuffer, buffer[20] readBuffer := @buffer repeat dira[16] := 1 outa[16] := 1 serial.RxStr(readBuffer) dira[17] := 1 outa[17] := 1 if strcomp(readBuffer, string("ABC")) 'tell the computer to RESET me. serial.str(string("RESET")) dira[18] := 1 outa[18] := 1You could just use @buffer instead of readBuffer. Also, you need to make sure that you stack is large enough to accommodate buffer[20], of you could define buffer in a DAT or VAR section. I used the size of 20 longs to allow for accepting a string of up to 80 characters. You could use a smaller buffer if you can ensure that the input string will always fit in the buffer.http://forums.parallax.com/showthread.php/149956-Extended-Full-Duplex-Serial-RxStr-Question
Jeff T.
VAR LONG stack[50] LONG startc PUB main startc := string("0") serial.start(31,30,0,9600) repeat until strcomp(@startc, string("ABC")) serial.RxStr(@startc) serial.str(string("PB1")) 'PB1 is the name of this board serial.rxflush cognew(readSerial, @stack) 'the above code works just fine, it's when we get to this readSerial cog that nothing works. PUB readSerial | readBuffer repeat readBuffer := string("0") repeat while strcomp(readBuffer, string("0")) serial.RxStr(readBuffer) if strcomp(readBuffer, string("ABC")) 'tell the computer to RESET me. serial.str(string("RESET"))I still think it's in that if statement. Because when I had the LEDs lighting up along with everything, you could see when as soon as I hit the button that sent "ABC" on the computer, that LED lit up (indicating that the readBuffer no longer equaled 0.). The only problem was that it would never send "RESET" to the computer. This absolutely makes no sense to me. (By the way - I made a typo in my second post. It should be that it does NOT send the "RESET" string. - I forgot the word NOT if anyone didn't catch that).
I just had another thought. Local variables are not initialized to zero. Try using readBuffer := 0 early in the method to make sure the long has a terminating zero for the string in stick in it. Though I'm betting the "string" statement puts one in for you.
I think the RxStr method is expecting a buffer location. I think you want to use ".RxStr(@readBuffer)" if you want the incoming data stored in the long. Otherwise it will stor it where the "0" string was stored. You'll then be storing four bytes (including terminating zero) where previously two bytes had been stored. This may cause you trouble.
I still think you'd be better off using some temporary global byte array to hold your strings. I think the way you're doing it now make it very easy to make an error in manipulating strings.
Edit: IIRC, the rxStr method uses a terminating carriage return. That with a terminating zero will put you over the four bytes of a long.
Edit again: It looks like rxStr overwrites the carriage return with a zero so nevermind about the above edit.
The Extended FDS object receives max. 15 characters, but copies always 16 bytes to the string. So you need to define a bytearray with min. 16 bytes.
startc := string("0") does not copy the string into startc. string("") builds the string in memory and returns a pointer to it. Because it makes no sense to have "0" in the string I just make the string empty with startc[0] := 0. The [0] is not really needed but makes it clear that the first character is set to zero, which marks the end of the string. So the string is empty.
You can use the same string in the main routine and the readSerial cog, as long as you don't use it at the same time.
VAR LONG stack[30] BYTE startc[16] 'define a string with max 15 chars PUB main startc[0] := 0 serial.start(31,30,0,9600) repeat serial.RxStr(@startc) until strcomp(@startc, string("ABC")) serial.str(string("PB1")) 'PB1 is the name of this board serial.rxflush cognew(readSerial, @stack) PUB readSerial | readBuffer repeat startc[0] := 0 repeat serial.RxStr(@startc) until strcomp(@startc, string("ABC")) serial.str(string("RESET"))AndyAndy, you broke the rules. Didn't you read the thread title?
FWIW, I think Andy's way makes much more sense.
It was unclear in the original code if the local variable was used to store the characters or if was to be used to store the location generated by the "string("0")" command. If the latter, then the "string("0")" wasn't reserving enough room for your three character input. If the former, then the code had other problems.
sometimes you have to break the rules to get ahead
Andy