0% found this document useful (0 votes)
63 views9 pages

Basic Starter Package - Tutorial #1: Note

The Basic Starter Package includes a number of tutorials. The intent is to teach the user how to effectively use The Stamp in the context of various applications. The tutorials become increasingly advanced.

Uploaded by

livre130
Copyright
© Attribution Non-Commercial (BY-NC)
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
63 views9 pages

Basic Starter Package - Tutorial #1: Note

The Basic Starter Package includes a number of tutorials. The intent is to teach the user how to effectively use The Stamp in the context of various applications. The tutorials become increasingly advanced.

Uploaded by

livre130
Copyright
© Attribution Non-Commercial (BY-NC)
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
You are on page 1/ 9

Basic Starter Package - Tutorial #1

copyright, Peter H. Anderson, Dept of EE,


Morgan State University, Baltimore, MD, Nov 25, '97

Note.

The Basic Starter Package includes a number of tutorials. The intent is to teach the user
how to effectively use the Stamp in the context of various applications.

Some may find this first tutorial rather trivial. However, what is trivial to an
experienced user may well be quite useful to a newcomer. The tutorials become
increasingly advanced.

Routines were verified and corrected on Dec 2, '97.

Initial Ouput Routines.

At this point you have assembled the power supply, made the necessary connections
from the serial port cable to the Stamp and have assembled and tested the logic probe.

Lets forge ahead and write some simple programs to flash a a single LED. In doing so, I
hope to get across many of the PBASIC commands in a simple context which is
understandable.

Please refer to Figure #1. Note that this consists of the addition of a single LED from P0
(Terminal 5) on the Stamp to ground. Note that the LEDs supplied with the Basic
Starter package have an integrated 330 Ohm resistor to limit the LED current to
nominally 10 mA.

The idea is to force a logic one on an ouput for a period of time, thus turning the LED
on. And then, output a zero for a period of time, causing the LED to turn off.

Program LED_1.BS2

' LED_1.BS2
'
' Flashes an LED on Output 0 on and off
'
' Peter H. Anderson, MSU, 25 November, '97
'

TOP:

DIR0=1 ' make P0 an output


OUT0=1 ' turn on the LED
PAUSE 500 ' pause for 500 msecs

OUT0=0 ' turn off the LED


PAUSE 500

GOTO TOP

Note that an "'" indicates that all that follows on the line is a comment. Although not
required, good programmers spend a bit of effort briefly describing the overall operation
of the program and include annotations within the code to give the reader a clear idea of
what the statements are doing.

The word TOP is a label, in this case, a place in the program. Labels can be virtually
anything other than specific key words.

Each of the 16 I/O pins on the Basic Stamp may be configured as an input or as an
output. The Stamp reserves a 16-bit variable DIRS with the state of each bit being used
to confgure that pin as either as an input or an output.

Specific bits, may be selectively configured using the DIRp nomenclature. That is,
DIR0 or DIR7 or DIR15. A one configures the bit as an output. Thus;

DIR0=1 ' make pin 0 an output


DIR7=0 ' make pin 7 an input
The Stamp reserves another 16-bit variable termed OUTS and here again, each of the
specific pins may be addressed using OUTp; e.g., OUT0.

In this case;

OUT0=1 ' copy a one into bit OUT0


OUT0=0 ' copy a zero into bit OUT0
Note that the pin will only assume the designated state if the associated DIR bit is
defined to be an output.

The PAUSE command is pretty obvious. Note that the time is in milliseconds. The
maximum value is 2^16-1 or 65,535. Thus, using the PAUSE, the largest delay one
could achieve is nominally 60.5 seconds.

The GOTO redirects the program flow to the designated label. Thus, in this case, the
program simply loops, continually flashing the LED.

Program LED_2.BS2

' LED_2.BS2
'
' Flashes an LED on Output 0 on and off. Simply another
implementation of
' LED_1.BS2.
'
' Peter H. Anderson, MSU, 25 November, '97
'

OUT CON 1 ' define the word OUT to be the same as 1


DELAY_TIME CON 500

DIR0=OUT
TOP:

HIGH 0 ' turn on the LED

PAUSE DELAY_TIME' pause for 500 msecs

LOW 0 ' turn off the LED


PAUSE DELAY_TIME

GOTO TOP

Note that a number of changes have been made. However, the program does the same
thing.

The concept of constants has been introduced using the keyword CON. These are
nothing more than constants which are substituted into your code.

In the first program;

DIR0=1
forced pin 0 to be an output. However, I always tend to forget whether it is a zero or a
one and thus I use a standard set of constants that I cut and paste from one program to
another. Thus;
OUT CON 1
simply means, to substitute a "1" where the word OUT appears in the program.

Similarly, substitute 500 wherever the the word DELAY_TIME appears.

Note that the DIR0=1 has been pulled out of the loop, and is now executed only one
time when the program begins. Once the direction of a bit has been defined, there is no
need to continually do so as was done in the first program.

The commands HIGH and LOW followed by the pin number are simply alternative
representations of the OUT command;

HIGH 0 ' same as OUT0 = 1


LOW 0 ' same as OUT0 = 0
Program LED_3.BS2.
' LED_3.BS2
'
' Flashes an LED on Output 0 on and off 50 times
'
' Peter H. Anderson, MSU, 25 November, '97
'

TIMES VAR BYTE

OUT CON 1 ' define the word OUT to be the same as 1


LED CON 0 ' LED is on pin 0
DELAY_TIME CON 500

DIR0=OUT
TOP:

FOR TIMES = 1 TO 50
HIGH LED ' turn on the LED
PAUSE DELAY_TIME ' pause for 500 msecs

LOW LED ' turn off the LED


PAUSE DELAY_TIME
DEBUG ?TIMES
NEXT

DEBUG "Done!"

DONE:
GOTO DONE

In this program, the variable TIMES has been declared as a byte (8 bits). Note that a
byte may accommodate the numbers 0 through 255 and in this application where the
highest value is 50, a byte is sufficient. If I desired to flash the LED a 1000 times, the
variable would have been declared as a "word" which is two bytes. A word can
accommodate values from 0 to 65,535.

Note that an additional constant has been defined; LED. Rather than burdening one's
mind with the fact that the LED is on pin 0, this simple idea of a constant permits you to
make that connection just once and then refer to the pin as simply "LED". As we only
are using one lead at this point, the advantage may not be obvious, but it will when we
begin to use many of the 16 inputs and outputs.

Program LED_3 introduces the use of the FOR - NEXT command. In this context, the
commands between the FOR and the NEXT are executed with TIMES equal to 1, and
then with TIMES equal to 2, etc until TIMES is equal to 50. TIMES is then incremented
to 51, which is beyond the upper bound (50) and the program thus breaks from the FOR
loop.

Note that on each pass through the loop, the LED is flashed and, in addition the value of
TIMES is displayed on the terminal using the DEBUG command.

The DEBUG command allows you to print values and text to the terminal. Future
programs will treat this in much greater detail. For the moment;

DEBUG "Hello", CR ' prints Hello followed by a new line

DEBUG DEC TIMES ' prints the value of TIMES is decimal


' not there is no new line

DEBUG "N=", DEC TIMES CR


' prints TIMES=value. For example TIMES=33

DEBUG ?N ' this is a much simpler shorthand for the


above
After breaking from the FOR - NEXT loop, the program displays a "Done" message and
then continually loops doing nothing.

Program LED_4.BS2.
' LED_4.BS2
'
' Flashes an LED on Output 0 on and off 50 times. Uses a subroutine
'
' Peter H. Anderson, MSU, 25 November, '97
'

TIMES VAR BYTE

OUT CON 1 ' define the word OUT to be the same as 1


LED CON 0 ' LED is on pin 0
DELAY_TIME CON 500

DIR0=OUT

TOP:

FOR TIMES = 1 TO 50
GOSUB FLASH
NEXT

DEBUG "Done!"

DONE:
GOTO DONE

FLASH: ' winks LED on and off one time

HIGH LED ' turn on the LED


PAUSE DELAY_TIME ' pause for 500 msecs

TOGGLE LED ' turn off the LED


PAUSE DELAY_TIME
DEBUG ?TIMES
RETURN
Note that the FOR loop is now reduced to simply a "call" or GOSUB to subroutine
FLASH. In the subroutine, the LED is turned on, there is a pause, and then the LED
lead is toggled. That is, as the current state of the LED lead is high, the TOGGLE
results in bringing it low. If it were low, TOGGLE would bring the lead high.

The RETURN statement then causes the program to return to the statement after the
GOSUB.

In calling (GOSUB) a subroutine, the return address is pushed on to a stack. When the
RETURN is executed this return address is pulled from the top of the stack. Fortunately,
this is all hidden from the Stamp user, but the general mechanics are important in
appreciating the following limitations.

A subroutine must be called (GOSUB). You cannot GOTO a subroutine, as with a


GOTO, the return address is not pushed on to the stack. Thus, in executing the
RETURN, whatever junk happens to be on the top of the stack will be pulled and the
program will, in theory, continue at that junk address and your program will not work
properly.
Along the same line, your subroutine must not be in the program flow of other routines.
An example is illustrated in LED_4A.

' LED_4A.BS2 (This routine illustrates a common error. It will not


work).
'
' Flashes an LED on Output 0 on and off 50 times. Uses a subroutine
'
' Peter H. Anderson, MSU, 25 November, '97
'

TIMES VAR BYTE

OUT CON 1 ' define the word OUT to be the same as 1


LED CON 0 ' LED is on pin 0
DELAY_TIME CON 500

DIR0=OUT

TOP:

FOR TIMES = 1 TO 50
GOSUB FLASH
NEXT

FLASH: ' winks LED on and off one time

HIGH LED ' turn on the LED


PAUSE DELAY_TIME ' pause for 500 msecs

TOGGLE LED ' turn off the LED


PAUSE DELAY_TIME
DEBUG ?TIMES
RETURN

DEBUG "Done!"

DONE:
GOTO DONE
Note that this program is wrong. The LED will indeed flash the 50 times. However, on
exiting the FOR - NEXT loop, the program will enter the subroutine. Note that there has
been no call (GOSUB). The LED will again flash (for the 51st time). However, on
executing the RETURN, the top of the stack does not contain a valid return address and
your program will go to off to "never never land".

Finally, you must RETURN from a subroutine. Consider the following very incorrect
routine.

' LED_4B.BS2 (This routine illustrates another common error. It will


not
' work.)
'
' Flashes an LED on Output 0 on and off 50 times. Uses a subroutine
'
' Peter H. Anderson, MSU, 25 November, '97
'

TIMES VAR BYTE


OUT CON 1 ' define the word OUT to be the same as 1
LED CON 0 ' LED is on pin 0
DELAY_TIME CON 500

DIR0=OUT

TOP:
FOR TIMES = 1 TO 50
GOSUB FLASH
AGAIN:
NEXT

DEBUG "Done!"

DONE:
GOTO DONE

FLASH: ' winks LED on and off one time

HIGH LED ' turn on the LED


PAUSE DELAY_TIME ' pause for 500 msecs

TOGGLE LED ' turn off the LED


PAUSE DELAY_TIME
DEBUG ?TIMES
GOTO AGAIN ' !!!!!!!!!! wrong!

In ths incorrect routine, the FLASH routine is called with a GOSUB and the return
address is pushed on to the top of the stack. However, at the conclusion of the FLASH
routine, I have erroneously used a GOTO. Thus, the return address is not pulled off the
top of the stack. The routine is again called, but there is no corresponding pull in the
subroutine. Thus, the stack is growing and growing and eventually, your program will
stop working.

In summary, when using subroutines, be certain that the only way the program enters
the subroutine is with a GOSUB. No GOTOs and no "walk-ins" as illustrated in routine
LED_4B. Be certain to use a RETURN to go back to the calling program.

Note that in program LED_4, the DEBUG ?TIMES was included in the subroutine to
make a point. All variables in PBASIC are global. That is, the variables are known to all
subroutines.

Program LED_5.BS2.

Consider rolling a die. This generates a random number in the range of 1 to 6. Roll a
second die, generating a second number. Sum them and wink the LED that number of
times. This might be used as a rather expensive and inferior replacement for rolling dice
as in playing Monopoly, Parchesi and other less redeeming games of chance. I say all of
this with tongue in cheek, but the routine helps to make a number of points.

' LED_5.BS2
'
' Flashes an LED on Output 0 on and off the number of times "rolled"
by
' two dice.
'
' Peter H. Anderson, MSU, 25 November, '97
'

DIE_1 VAR BYTE ' first DIE


DIE_2 VAR BYTE ' second DIE
DICE VAR BYTE ' total

R VAR WORD ' random number in range 0-65,535

TIMES VAR BYTE ' flash counter

OUT CON 1 ' define the word OUT to be the same as 1


LED CON 0 ' LED is on pin 0
DELAY_TIME CON 500

DIR0=OUT

TOP:

LOW LED ' be sure the LED is off

RANDOM R ' R is now 0 - 65,535


DIE_1 = (R // 6) + 1 ' roll first die
RANDOM R
DIE_2 = (R // 6) + 1 ' roll the second

DICE = DIE_1 + DIE_2

GOSUB WINK ' wink LED DICE times

DEBUG "Done!"

DONE:
GOTO DONE

WINK: ' flashes LED DICE times

FOR TIMES=1 TO DICE


GOSUB FLASH
NEXT
RETURN

FLASH: ' winks LED on and off one time

HIGH LED ' turn on the LED


PAUSE DELAY_TIME ' pause for 500 msecs

TOGGLE LED ' turn off the LED


PAUSE DELAY_TIME

RETURN
The RANDOM command generates a number in the range of 0 - 65,535 and places the
result in variable R. Note that R has been declared as a word to accommodate this.

The "//" is the mod operator. Somewhere back in junior high, you probably had such
exercises as 12323 divided by 6 = 2053 with a remainder of 5. The mod operation is
simply the remainder. Thus R // 6 generates a number in the range of 0 to 5. Adding one
gives a random number in the range of 1 to 6.

This operation is performed twice to provide values for DIE_1 and DIE_2. The results
are summed (DICE) and subroutine WINK is called which in turn calls subroutine
FLASH, DICE times.

Note that in this example, the FOR loop takes a variable.

There is a flaw in this program in that it will always produce the same "random"
numbers. The command RANDOM takes the arguement, in this case variable R and
operates on it so as to produce a pseudo random number. In this program, the initial
value of R is 0 and thus the RANDOM command will always produce the same random
R, and thus DIE_1 will always be the same. This value of R is then used to calculate
another value of R, but it will also always be the same and thus DIE_2 will always be
the same. None too practical, but I like the program as it shows the use of the
RANDOM function, the mod operator, nested subroutines and the use of a variable in a
FOR-NEXT loop.

This problem of lack of randomness can be corrected by intializing R to some random


value. A common technique is to use time and this will be presented in a future tutorial.

Summary.

All of this has used only one LED which is none too interesting.

However, I am hopeful you have an appreciation for the direction control DIRS, and
controlling the direction of a specific bit (DIR0). You know how to define a constant
using CON, how to declare a variable using VAR and the difference between a byte and
a word. You should know what a label is. All outputs are referred to as OUTS, but a
specific bit may be referenced as OUT0. The commands GOTO, FOR-NEXT, HIGH,
LOW, TOGGLE and PAUSE have been treated. The commands GOSUB and RETURN
have been discussed and hopefully you appreciate the mechanics of subroutines.

You might also like