This shoud be easy, but...
Archiver
Posts: 46,084
This is a code style question. I know how to drive a pin low on the BS2. In3
= 0 or LOW 3 does the trick for pin 3. But if I want to be clear, I write
MyOutputPin CON 3
...
LOW MyOutputPin
Ok.. but if I want it to set to an arbitrary value, it's not so clear what
to do. What I want is...
SETPIN MyOutputPin, newValue 'SETPIN doesn't exist, but I wish it did
Now I know I can do
OUT3 = newValue
or even
MyOutputPinIs VAR IN3 'alias
MyOutputPinIs = newValue
but that leaves me with two definitions
MyOutputPin CON 3 '3
MyOutputPinIs VAR IN3 '3 again
to be tweaked whenever I move things around. That's not exactly the end of
the world, but it's still ugly. Is there an elegant solution?
Unrelated question: is there a document that describes the bytecode that the
BS2 interprets? I'd like to look into writing a compiler for a language less
like Basic that works with a BS2...
= 0 or LOW 3 does the trick for pin 3. But if I want to be clear, I write
MyOutputPin CON 3
...
LOW MyOutputPin
Ok.. but if I want it to set to an arbitrary value, it's not so clear what
to do. What I want is...
SETPIN MyOutputPin, newValue 'SETPIN doesn't exist, but I wish it did
Now I know I can do
OUT3 = newValue
or even
MyOutputPinIs VAR IN3 'alias
MyOutputPinIs = newValue
but that leaves me with two definitions
MyOutputPin CON 3 '3
MyOutputPinIs VAR IN3 '3 again
to be tweaked whenever I move things around. That's not exactly the end of
the world, but it's still ugly. Is there an elegant solution?
Unrelated question: is there a document that describes the bytecode that the
BS2 interprets? I'd like to look into writing a compiler for a language less
like Basic that works with a BS2...
Comments
is found in the new compiler, version 2.1 beta available on the
Parallax web site.
MyOutputPin PIN 3
with that established you can do
high MyOutputPin ' makes it high output
or
MyOutputPin=1 ' makes it high output
or
INPUT MyOutputPin ' makes it an input
or
IF MyOutputPin=1 THEN .... ' tests it as an input
or
x = MyOutputPin ' an input value to a variable
or
pulsout MyOutputPin,1000 ' a constant 3 for pin number
or
pulseout 5+MyOutputPin,1000 ' either pin 5 or 6 depending on in3
etc.
note that the last one is tricky. It uses the input state of the pin
when it is asked to reference it as part of a computation.
The compiler figures out from the context whether to treat is as a
variable reflecting the input state of the pin or as a constant
referring to the pin number.
There could be weird situations where you are not doing the obvious,
In this form,
MyOutputPin pin 3
INPUT MyOutputPin
the compiler will treat MyOutputPin as a constant. But suppose you
really want to read the input state of p3, and then use that to turn
either p0 or p1 into an input. Then you would have to do it this way:
INPUT in3 ' would you ever want to do this?!!! maybe
or this way
MyOutputPin pin 3
INPUT MyOutputPin+0 ' treats MyOutputPin as an input
the computation forces the compiler to treat it as an input. That is
like the last PULSOUT example above.
On the other had, the compiler will treat
MyOutputPin pin 3
x = MyOutputPin
as a request to read the input state of pin 3, not as x=3.
If a pin is configured as an output, command executes that reads the
pin, it will still actually read the state of the pin, not the state
of the output register. So if something is forcing the pin
externally, that is what you will see. The bottom line is, the
compiler wizard will almost always get it right what you want to do.
But think about it.
If you are interested in the bytecode, take a look at Brian Forbes' book.
http://members.aol.com/stamp2book/
Also Chuck McManis' essay on the BS1 codes is still a good read, and
especially so now that Parallax has given the BS1 new life in the new
compiler.
http://www.mcmanis.com/chuck/robotics/stamp-decode.html
It is not as simple as you might think. It is variable length
bitcode, not bytecode. These documents will let you appreciate the
condensed thinking that went into cramming the whole interpreter into
the limited memory of the PIC.
-- Tracy
>This is a code style question. I know how to drive a pin low on the BS2. In3
>= 0 or LOW 3 does the trick for pin 3. But if I want to be clear, I write
>
>MyOutputPin CON 3
>...
>LOW MyOutputPin
>
>Ok.. but if I want it to set to an arbitrary value, it's not so clear what
>to do. What I want is...
>
>SETPIN MyOutputPin, newValue 'SETPIN doesn't exist, but I wish it did
>
>Now I know I can do
> OUT3 = newValue
>or even
> MyOutputPinIs VAR IN3 'alias
> MyOutputPinIs = newValue
>
>but that leaves me with two definitions
>
>MyOutputPin CON 3 '3
>MyOutputPinIs VAR IN3 '3 again
>
>to be tweaked whenever I move things around. That's not exactly the end of
>the world, but it's still ugly. Is there an elegant solution?
>
>
>Unrelated question: is there a document that describes the bytecode that the
>BS2 interprets? I'd like to look into writing a compiler for a language less
>like Basic that works with a BS2...
it supports PBASIC 2.5 syntax which has a new definition: PIN. The
compiler is "smart" to know what you're doing when you use PIN. For
example:
MyOutputPin PIN 3
You can do this:
LOW MyOutputPin --> the compiler treats as LOW 3
You can also do this:
MyOutputPin = 1 --> the compiler treats as OUT3 = 1
And this:
status = MyOutputPin --> the compiler treats as status = IN3
As you noted, you can't pass parameters to your own subroutines in
PBASIC. But as pointed out in the second example above, you get that
functionality with PBASIC 2.5.
Instead of...
SETPIN MyOutputPin, newValue
You would use...
MyOutputPin = newValue
The only thing you have to make sure of is that DIRS bit for that pin is
set to 1 to make it an output. Because of the way PIN works, you can
even do this to handle the DIRS bit:
DIRS.LOWBIT(MyOutputPin) = 1 --> using your example is the same as
DIR3 = 1, making the pin an output.
This is useful if your design changes and you move an output pin. By
making a single change to your PIN definition, the rest of the program
follows.
-- Jon Williams
-- Applications Engineer, Parallax
-- Dallas Office
Original Message
From: Scott [noparse]/noparse]mailto:[url=http://forums.parallaxinc.com/group/basicstamps/post?postID=gXxRfy2bDOd9mANyROzRl7djJXFfsWfeqyHxBLUMs8CR6Cxg99edlIHMUp8iNOABhU2lB-8vvxao]scott@m...[/url
Sent: Wednesday, December 03, 2003 11:45 AM
To: basicstamps@yahoogroups.com
Subject: [noparse][[/noparse]basicstamps] This shoud be easy, but...
This is a code style question. I know how to drive a pin low on the BS2.
In3 = 0 or LOW 3 does the trick for pin 3. But if I want to be clear, I
write
MyOutputPin CON 3
...
LOW MyOutputPin
Ok.. but if I want it to set to an arbitrary value, it's not so clear
what to do. What I want is...
SETPIN MyOutputPin, newValue 'SETPIN doesn't exist, but I wish it did
Now I know I can do
OUT3 = newValue
or even
MyOutputPinIs VAR IN3 'alias
MyOutputPinIs = newValue
but that leaves me with two definitions
MyOutputPin CON 3 '3
MyOutputPinIs VAR IN3 '3 again
to be tweaked whenever I move things around. That's not exactly the end
of the world, but it's still ugly. Is there an elegant solution?
Unrelated question: is there a document that describes the bytecode that
the BS2 interprets? I'd like to look into writing a compiler for a
language less like Basic that works with a BS2...
To UNSUBSCRIBE, just send mail to:
basicstamps-unsubscribe@yahoogroups.com
from the same email address that you subscribed. Text in the Subject
and Body of the message will be ignored.
Your use of Yahoo! Groups is subject to
http://docs.yahoo.com/info/terms/
This message has been scanned by WebShield. Please report SPAM to
abuse@p....
has been a long day...):
Instead of:
DIRS.LOWBIT(MyOutputPin) = 1
use...
OUTPUT MyOutputPin
Dang ... I hate when I make things harder than they need to be....
-- Jon Williams
-- Parallax
Original Message
From: Jon Williams
Sent: Wednesday, December 03, 2003 4:46 PM
To: basicstamps@yahoogroups.com
Subject: RE: [noparse][[/noparse]basicstamps] This shoud be easy, but...
You might want to download our latest compiler (Version 2.1, Beta 1) as
it supports PBASIC 2.5 syntax which has a new definition: PIN. The
compiler is "smart" to know what you're doing when you use PIN. For
example:
MyOutputPin PIN 3
You can do this:
LOW MyOutputPin --> the compiler treats as LOW 3
You can also do this:
MyOutputPin = 1 --> the compiler treats as OUT3 = 1
And this:
status = MyOutputPin --> the compiler treats as status = IN3
As you noted, you can't pass parameters to your own subroutines in
PBASIC. But as pointed out in the second example above, you get that
functionality with PBASIC 2.5.
Instead of...
SETPIN MyOutputPin, newValue
You would use...
MyOutputPin = newValue
The only thing you have to make sure of is that DIRS bit for that pin is
set to 1 to make it an output. Because of the way PIN works, you can
even do this to handle the DIRS bit:
DIRS.LOWBIT(MyOutputPin) = 1 --> using your example is the same as
DIR3 = 1, making the pin an output.
This is useful if your design changes and you move an output pin. By
making a single change to your PIN definition, the rest of the program
follows.
-- Jon Williams
-- Applications Engineer, Parallax
-- Dallas Office
Original Message
From: Scott [noparse]/noparse]mailto:[url=http://forums.parallaxinc.com/group/basicstamps/post?postID=E1XjpB2VIKR5jQOFRuOZCUdu3hFlaitZiJVmS_t-Ep3pAX5JGB1ucNxNAV4kFZpDUzo_G-Bm2A]scott@m...[/url
Sent: Wednesday, December 03, 2003 11:45 AM
To: basicstamps@yahoogroups.com
Subject: [noparse][[/noparse]basicstamps] This shoud be easy, but...
This is a code style question. I know how to drive a pin low on the BS2.
In3 = 0 or LOW 3 does the trick for pin 3. But if I want to be clear, I
write
MyOutputPin CON 3
...
LOW MyOutputPin
Ok.. but if I want it to set to an arbitrary value, it's not so clear
what to do. What I want is...
SETPIN MyOutputPin, newValue 'SETPIN doesn't exist, but I wish it did
Now I know I can do
OUT3 = newValue
or even
MyOutputPinIs VAR IN3 'alias
MyOutputPinIs = newValue
but that leaves me with two definitions
MyOutputPin CON 3 '3
MyOutputPinIs VAR IN3 '3 again
to be tweaked whenever I move things around. That's not exactly the end
of the world, but it's still ugly. Is there an elegant solution?
Unrelated question: is there a document that describes the bytecode that
the BS2 interprets? I'd like to look into writing a compiler for a
language less like Basic that works with a BS2...
To UNSUBSCRIBE, just send mail to:
basicstamps-unsubscribe@yahoogroups.com
from the same email address that you subscribed. Text in the Subject
and Body of the message will be ignored.
Your use of Yahoo! Groups is subject to
http://docs.yahoo.com/info/terms/
This message has been scanned by WebShield. Please report SPAM to
abuse@p....
To UNSUBSCRIBE, just send mail to:
basicstamps-unsubscribe@yahoogroups.com
from the same email address that you subscribed. Text in the Subject
and Body of the message will be ignored.
Your use of Yahoo! Groups is subject to
http://docs.yahoo.com/info/terms/
This message has been scanned by WebShield. Please report SPAM to
abuse@p....
MyOutputPin Pin 3
HIGH MyOutputPin ' makes p3 high output
HIGH MyOutputPin+5 ' makes p8 high output
I had said incorrectly, in the second case, the calculation would
trick the compiler into reading MyOutputPin as an input with a value
of 0 or 1, and end up making either p5 or p6 high, but that is not
true. The compiler treats MyOutputPin as a constant=3, in the
addition and makes p8 high.
The same thing is true of a command like
PULSOUT 5+MyOutputPin,1000.
Where the compiler will treat MyOutputPin as a constant=3 and the
pulse will appear on p8. If you really want the pulse to be output
on a pin that depends on the state of a switch attached to
MyOutputPin, you have to do this:
MyOutputPin Pin 3
INPUT MyOutputPin ' it is an input
x =MyOutputPin ' either 0 or 1 depending on input level
PULSOUT 5+x,1000 ' outputs the pulse on either p5 or p6
or
PULSOUT 5+in3,1000 ' that forces it to use the variable in3 and
put the pulse on either p5 or p6.
But consider this:
MyOutputPin Pin 3
INPUT MyOutputPin ' it is an input
PULSOUT 5,1000*MyOutputPin+100
In that usage the compiler does in fact treat MyOutputPin as in input
and reads the 0 or 1 state of the pin and puts out either a short or
a long pulse on p5.
The compiler rule seems to be to use the PIN as a constant in
locations where a pin reference is clearly called for by the syntax,
but use PIN as a [noparse][[/noparse]0,1] input variable otherwise. But that is not
quite the rule, I think. Jon pointed out that it is also treated as
a CONstant when the PIN is an array index.
For example, Jon pointed out this one:
MyOutputPin PIN 3
DIRS.LOWBIT(MyOutputPin) = 1
A priori, it could either use MyOutputPin=3 and set p3 as an output
(which is in fact what it does), or it could read p3 as an input and
set either p0 or p1 as an output (but that is not the way it works).
Similarly, if you have an array of variables, what happens when a PIN
reference is used as the index?
x var byte(16)
MyOutputPin PIN 3
x(MyOutputPin)=124 ' puts 124 into x(3)
x(MyOutputPin+5)=124 ' puts 124 into x(8)
It treats the PIN as a CONstant when used as the array index. If
instead you want a program to select an array element depending on
the state of a pin, you have to do something like this:
MyOutputPin Pin 3
INPUT MyOutputPin ' it is an input
idx = MyOutputPin ' reads the state of the pin
x(idx+5)=124 ' puts 124 into either x(5) or x(6) depending on
the input from MyOutputPin.
How about this one?...
MyOutputPin PIN 3
lookup
MyOutputPin,[noparse][[/noparse]0,10,20,30,40,50,60,70,80,90,100,110,120,130,140,150],x
does in fact treat MyOutputPin as an input, and the lookup will
return either x=0 or x=10.
And how about this?...
switchA PIN 4
switchB PIN 5
switchC PIN 6
For i=0 to 2
INPUT switchA(i) ' does it use CONstant values 4,5,6?
I don't know.
debug dec switchA(i),cr ' it does read INput values in4,in5,in6
next
And the same on the output side:
ledA PIN 4
ledB PIN 5
ledC PIN 6
For i=0 to 2
OUTPUT ledA(i) ' does it use values 4,5,6?
ledA(i)=0 ' does it refer to out4, out5 and out6, like
out4(i), & make all leds low?
next
' I haven't tried this one yet, but I wouldn't count on it one way
or the other without testing
Enough. Like the subject says, this should be easy. And most of the
time it is. I really like the new PIN directive. Still, you have
to think about it, especially if you are doing some kind of indirect
reference, and like Jon pointed out, you still have to set the
direction of the pin correctly for assignment statements and for
commands like IF or BRANCH that don't set the pin direction
automatically.
-- Tracy
'{$STAMP BS2}
'{$PBASIC 2.5}
Led1 PIN 0
Led2 PIN 1
Led3 PIN 2
Test:
HIGH Led1
PAUSE 500
HIGH Led1 + 1
PAUSE 500
HIGH Led1 + 2
END
... does what I expected: it lights LEDs on P0 - P2 in sequence. What I
found (noting a comment near the bottom of Tracy's post) is that you
can't use an array index with PIN. Hence,
'{$STAMP BS2}
'{$PBASIC 2.5}
Led1 PIN 0
Led2 PIN 1
Led3 PIN 2
idx VAR Nib
Test:
FOR idx = 0 TO 2
HIGH Led1(idx) ' <-- ERROR
PAUSE 500
NEXT
END
... won't compiler or download. But, of course, you can achieve the same
result like this:
'{$STAMP BS2}
'{$PBASIC 2.5}
Led1 PIN 0
Led2 PIN 1
Led3 PIN 2
idx VAR Nib
Test:
FOR idx = 0 TO 2
HIGH Led1 + idx
PAUSE 500
NEXT
END
-- Jon Williams
-- Applications Engineer, Parallax
-- Dallas Office
Original Message
From: Tracy Allen [noparse]/noparse]mailto:[url=http://forums.parallaxinc.com/group/basicstamps/post?postID=1jLpJxmT5q6eylg5nk6FN1lKFTFCSI_GbXNS0WTkGz2nONJPpd31c8vY9vQHaGkWI7gCyzTR-mSzupzq]tracy@e...[/url
Sent: Thursday, December 04, 2003 10:22 AM
To: basicstamps@yahoogroups.com
Subject: Re: [noparse][[/noparse]basicstamps] This shoud be easy, but...
This sequence:
MyOutputPin Pin 3
HIGH MyOutputPin ' makes p3 high output
HIGH MyOutputPin+5 ' makes p8 high output
I had said incorrectly, in the second case, the calculation would
trick the compiler into reading MyOutputPin as an input with a value
of 0 or 1, and end up making either p5 or p6 high, but that is not
true. The compiler treats MyOutputPin as a constant=3, in the
addition and makes p8 high.
The same thing is true of a command like
PULSOUT 5+MyOutputPin,1000.
Where the compiler will treat MyOutputPin as a constant=3 and the
pulse will appear on p8. If you really want the pulse to be output
on a pin that depends on the state of a switch attached to
MyOutputPin, you have to do this:
MyOutputPin Pin 3
INPUT MyOutputPin ' it is an input
x =MyOutputPin ' either 0 or 1 depending on input level
PULSOUT 5+x,1000 ' outputs the pulse on either p5 or p6
or
PULSOUT 5+in3,1000 ' that forces it to use the variable in3 and
put the pulse on either p5 or p6.
But consider this:
MyOutputPin Pin 3
INPUT MyOutputPin ' it is an input
PULSOUT 5,1000*MyOutputPin+100
In that usage the compiler does in fact treat MyOutputPin as in input
and reads the 0 or 1 state of the pin and puts out either a short or
a long pulse on p5.
The compiler rule seems to be to use the PIN as a constant in
locations where a pin reference is clearly called for by the syntax,
but use PIN as a [noparse][[/noparse]0,1] input variable otherwise. But that is not
quite the rule, I think. Jon pointed out that it is also treated as
a CONstant when the PIN is an array index.
For example, Jon pointed out this one:
MyOutputPin PIN 3
DIRS.LOWBIT(MyOutputPin) = 1
A priori, it could either use MyOutputPin=3 and set p3 as an output
(which is in fact what it does), or it could read p3 as an input and
set either p0 or p1 as an output (but that is not the way it works).
Similarly, if you have an array of variables, what happens when a PIN
reference is used as the index?
x var byte(16)
MyOutputPin PIN 3
x(MyOutputPin)=124 ' puts 124 into x(3)
x(MyOutputPin+5)=124 ' puts 124 into x(8)
It treats the PIN as a CONstant when used as the array index. If
instead you want a program to select an array element depending on
the state of a pin, you have to do something like this:
MyOutputPin Pin 3
INPUT MyOutputPin ' it is an input
idx = MyOutputPin ' reads the state of the pin
x(idx+5)=124 ' puts 124 into either x(5) or x(6) depending on
the input from MyOutputPin.
How about this one?...
MyOutputPin PIN 3
lookup
MyOutputPin,[noparse][[/noparse]0,10,20,30,40,50,60,70,80,90,100,110,120,130,140,150],x
does in fact treat MyOutputPin as an input, and the lookup will
return either x=0 or x=10.
And how about this?...
switchA PIN 4
switchB PIN 5
switchC PIN 6
For i=0 to 2
INPUT switchA(i) ' does it use CONstant values 4,5,6?
I don't know.
debug dec switchA(i),cr ' it does read INput values in4,in5,in6
next
And the same on the output side:
ledA PIN 4
ledB PIN 5
ledC PIN 6
For i=0 to 2
OUTPUT ledA(i) ' does it use values 4,5,6?
ledA(i)=0 ' does it refer to out4, out5 and out6, like
out4(i), & make all leds low?
next
' I haven't tried this one yet, but I wouldn't count on it one way
or the other without testing
Enough. Like the subject says, this should be easy. And most of the
time it is. I really like the new PIN directive. Still, you have
to think about it, especially if you are doing some kind of indirect
reference, and like Jon pointed out, you still have to set the
direction of the pin correctly for assignment statements and for
commands like IF or BRANCH that don't set the pin direction
automatically.
-- Tracy
To UNSUBSCRIBE, just send mail to:
basicstamps-unsubscribe@yahoogroups.com
from the same email address that you subscribed. Text in the Subject
and Body of the message will be ignored.
Your use of Yahoo! Groups is subject to
http://docs.yahoo.com/info/terms/
This message has been scanned by WebShield. Please report SPAM to
abuse@p....