PDA

View Full Version : IF satement help



grasshopper
01-15-2008, 01:50 AM
'' Propeller "Hello, world input and output"


CON
_clkmode = xtal1 + pll16x ' use external crystal * 16
_xinfreq = 5_000_000 ' 5 MHz

obj
SER : "FullDuplexSerial"

PUB COMPUB
ser.start(31, 30, 0, 9600)

if ser.rx(string("[X1]")) then
ser.str(string("Hello World "))
ser.tx(13) 'line feed
ser.tx(10) 'carriage return
else goto COMPUB







Basically i want to pause the code until the serial string [X1] is recieved then say HELLO WORLD

Mike Green
01-15-2008, 02:01 AM
A lot depends on what other characters you're expecting on the serial input line. If "[" is always followed by "X1]", then it's easy:


repeat
if ser.rx == "["
if ser.rx == "X"
if ser.rx == "1"
if ser.rx == "]"
ser.str(string("Hello World ",13,10))


This always goes back to waiting for the "[" if any of the characters are incorrect. There are other, fancier ways of doing this that can do a smarter job of matching strings, but this would do what you asked.

grasshopper
01-15-2008, 02:25 AM
Yes thanks this did work but since i am learning i ask why this is not working?




'' Propeller "Hello, world input and output"


CON
_clkmode = xtal1 + pll16x ' use external crystal * 16
_xinfreq = 5_000_000 ' 5 MHz

obj
SER : "FullDuplexSerial"

PUB COMPUB
ser.start(31, 30, 0, 9600)
repeat
if ser.rx == (@DATAONE)
ser.str(string("Hello World ",13,10)) ' accept


DAT

DATAONE byte "[X1]"

deSilva
01-15-2008, 03:08 AM
Well, if you want to learn.. Tell me, what do you think this check shall do?


IF ser.rx == (@DATAONE)

hippy
01-15-2008, 03:09 AM
You probably need something like ...

if ser.rx == byte[ @DATAONE ]

grasshopper
01-15-2008, 03:10 AM
I though it would put the pointer at this (@DATAONE) address and if is true "[X1]" then complete the if statement.

Mike Green
01-15-2008, 03:27 AM
You can't make that kind of assumption.

Only some programming languages have the ability to work with strings of characters as basic values. Spin is not one of these. There is some minimal support in the compiler for string and floating point constants and some simple string operations (equality testing, length, and copying) implemented as efficient function/procedure calls, but that's it.

deSilva
01-15-2008, 03:30 AM
You are surely aware you will have to know - in all cases - what "it" will do..
So you say: "---"it" would put the pointer at this (@DATAONE) address..."
A better way to say this would be: " ... look at the memory cells pointed to by the pointer..."
You say:"... and if is true "[X1]" then complete the if statement."
A better way to say this would be: ".. and if those memory cells are equal to the bytes read in by the serial routine...."

Is this what you think?
It "yes", I shall tell you in the next posting why it is not so with SPIN...

grasshopper
01-15-2008, 03:43 AM
Yes this is what I was thinking. Ok, now that I am embarrassed will you tell me why? I have been reading other postings and cant seem to figure it out.

I really want to have a "serial data table" that I can look up when data is sent to the propeller via a computer. Once i find a specific match in the table i can execute code for that table.
Any help is appreciated even if I get embarrassed :)

Mike Green
01-15-2008, 03:57 AM
Spin works well with 8, 16, and 32 integers and you can easily take 1 to 4 input characters and convert them to integers, then look that up in a table. For example:


pub matchIt | name, t
name := 0
repeat until ser.rx == "[" ' wait for opening bracket
repeat until (t := ser.rx) == "]"
name := name << 8 + t ' pack the characters into a long
result := 0
repeat while t := table[ result++ ] ' check for end of table
if name == t ' look for a match in the table
return ' if a match, return zero-based index in table
return -1 ' indicate unknown






dat
table long "X" << 8 + "1" ' zero padded with LSB the last character
long 0 ' marks end of table

deSilva
01-15-2008, 04:16 AM
Mike did very advanced stuff here... We shall keep it simpler at the beginning:
(a) You have called a routine here, "rx". First find out as precise as possible what this routine delivers as a result! Is it a "string"? A pointer to a string? A number? What is the eaning of that number?

This can be difficult sometimes! The best way is to look into the object where that routine is defined! There are generally coments that tell you, but sometimes you have to look through its very code....

(b) You use an "operator", "==". What does the manual tell you what it does, again: What it "precisely" does...

Can you now put those things together? If not - after having done your "homework" (a) and (b) - call here again http://forums.parallax.com/images/smilies/smile.gif

grasshopper
01-15-2008, 04:21 AM
Mike the code look great but i am still a bit confused. here is what i understand from what you posted from line 1 - finish
1. "name" and "t" are variables (of what data type i do not know) in a pub called matchit (i understand naming a pub)
2. name alwys = 0
3. repeat until "[" is captured from serial port. (i understand this)
4. load into memory "name" until "]" is received or name is larger than 8? (kind of foggy here)
5. result = 0 (i think it returns a 0 to the pub)
6. repeat ehile t := table ( looking up the table for matches?)
7. the rest i am lost on.
if i find a match what then??
i still need to send through the serial port "hello world for X1 and say bye world for X2 etc...??

Thanks in advance.

grasshopper
01-15-2008, 04:30 AM
deSilva said...


(a) You have called a routine here, "rx". First find out as precise as possible what this routine delivers as a result! Is it a "string"? A pointer to a string? A number? What is the eaning of that number?


--- I thought it to be a string but maybe a number not sure


deSilva said...

[quote](b) You use an "operator", "==". What does the manual tell you what it does, again: What it "precisely" does...


--- == is boolean: is equal

I still need to do my homework... i will call many many more times :)

Mike Green
01-15-2008, 05:07 AM
1. "name" and "t" are variables (of what data type i do not know) in a pub called matchit (i understand naming a pub)
Read the documentation on PRI / PUB. You'll see that local variables are all longs.
2. name alwys = 0
No. Look at the repeat loop
3. repeat until "[" is captured from serial port. (i understand this)
4. load into memory "name" until "]" is received or name is larger than 8? (kind of foggy here)
Look up the "<<" operator. Work through an example on paper.
5. result = 0 (i think it returns a 0 to the pub)
Look up the unary "++" operator. Again, work through an example on paper.
6. repeat ehile t := table ( looking up the table for matches?)
You can put an assignment statement in parentheses and the value assigned is used. Here it's the result of ser.rx.
7. the rest i am lost on.
Again, you'll learn a lot working through an example on paper. I usually make columns for each variable and
step through each statement (or part of a statement) on each row, writing down what changes.
if i find a match what then??
This subroutine returns the number of the table entry where there was a match (0 to n) or -1 if there was no match.
In your main program, you'd have something like:


repeat
case matchIt
-1: exit
0: ' here's the first choice
1: ' now the second choice

grasshopper
01-15-2008, 06:27 AM
i understand most of this now. However i poss a new question. What if i wanted to store the data coming in through the serial port and send it through another serial port. For example i list in my table with [X1] and so on to [X9]. if non are listed then i pass the serial data through a different serial port. any ideas?

Mike Green
01-15-2008, 06:45 AM
You can certainly do that. I suggest that you get something working and gain some experience with the language (Spin) and the programming environment (Propeller Tool and the Propeller). Basically, what you want to do is create a buffer in which you store all the incoming characters until you either get a successful match or an unsuccessful one. If successful, you do whatever action is called for and clear the buffer. If unsuccessful (something unknown between brackets), you retransmit the buffer, then clear it. Think about how you might do that, but get something going first.

grasshopper
01-16-2008, 12:21 AM
I would love to learn more but i am not sure where to start. I need to get this programed soon. I have about 3 weeks before my project is due. Can you point me in the right direction on this BUFFER. I do understand your code more and appreciate your guidance.

grasshopper
01-16-2008, 12:57 AM
Here is what i have done so far




'' Propeller "Hello, world input and output"


CON
_clkmode = xtal1 + pll16x ' use external crystal * 16
_xinfreq = 5_000_000 ' 5 MHz

obj
SER : "256_FullDuplexSerial"

PUB START
ser.start(31, 30, 0, 9600) 'INPUT PORT
repeat
MatchIt
SendIt

PUB SendIt
CASE MatchIt
0: ser.str(string("NO COMMAND"))
1: ser.str(string("X1"))
2: ser.str(string("X2"))
3: ser.str(string("X3"))
10: PassIt

PUB MatchIt | name, t
name := 0
repeat until ser.rx == "[" ' wait for opening bracket
repeat until (t := ser.rx) == "]"
name := name << 8 + t ' pack the characters into a long
result := 0
repeat while t := table[ result++ ] ' check for end of table
if name == t ' look for a match in the table
return ' if a match, return zero-based index in table
return 10 ' indicate unknown

PUB PassIt | str

SER.start(0,1, 0, 9600) 'OUTPUT PORT
repeat
str := name
if str <> 0
SER.tx(str)

dat
table long "X" << 8 + "1" ' zero padded with LSB the last character
long "X" << 8 + "2" ' zero padded with LSB the last character
long "X" << 8 + "3" ' zero padded with LSB the last character
long "X" << 8 + "4" ' zero padded with LSB the last character
long 0 ' marks end of table





But the name needs to be global variable i think. Alos why do i have to input the commands twice before it will send it back through the port?

Mike Green
01-16-2008, 02:23 AM
You have to input the commands twice because you call MatchIt twice (once in Start and once again in SendIt).
PassIt won't work the way you've done it (you're reinitializing the serial port rather than setting up a new one).

1) You need two separate serial ports, one for input and one for your output. You can declare multiple instances
of the serial object. Keep SER as one name and maybe use OUTPUT as the other. The OUTPUT.start call needs to
be in your START routine so that it's only called once during initialization.

2) Sure, make "name" a global variable (in a VAR section ... declare it as a long). To transmit it, use the following:


PRI sendName ' use the implicit result variable as a temporary value
result := name ' the first character is in the high order byte
OUTPUT.tx("[") ' send the opening bracket
repeat until result == 0 ' stop when there are no more characters
if (result >> 24) <> 0 ' don't send a zero byte
OUTPUT.tx(result >> 24) ' send the leading character of the name
result := result << 8 ' shift the next character into position
OUTPUT.tx("]") ' send the closing bracket


Post Edited (Mike Green) : 1/15/2008 7:31:19 PM GMT

Mike Cook
01-16-2008, 07:13 AM
Grasshopper,

Take a look at the attached *.spin code, probably not the best example, but works for what I need it to do. Demonstrates receiving a 'canned' string and then acting upon what was received.

Please remember I code for a 'relaxation hobby' like some that play Xbox or whatever as a relaxation!

Always learning!

Hope this helps,

Mike

▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Mike (http://www.allsurplus.net/)

grasshopper
01-16-2008, 10:23 PM
Thanks ill take a look.