POLLing commands on BASIC Stamp 2p, 2pe, 2px
 application notes

(c) 2004 EME Systems, Berkeley CA U.S.A.
<stamp index> <home>

Contents (updated 12/3/2005)



Special locations in Scratchpad RAM, for status and polling

top

The BS2pe, BS2p, and BS2px have 127 bytes of scratchpad RAM available for general purpose data storage. These are numbered from 0 to 126. There are additional read only locations past that last address. Those store information about the internal state of the Stamp.

Location 127 contains in the low nibble the number of the currently running eeprom program bank (0 to 7), and in the high nibble it contains the number of the currently selected STORE bank.

Locations 129 to 135 contain information about the state of the polling functions.  Reading past location 135 simply returns the value in location 135.   It is useful to understand these scratchpad locations.  The POLLing capabilties are a State Machine, and these are its State Variables.

How might you use those pieces of information in a real program?    It is useful to understand these scratchpad locations, in order to make better use of the Stamp.

Using location 127 and 134, state memory for return from context free subroutines

top

A subroutine might need to do its work using the AUXIO and it might need to switch over to another STORE bank. But on returning from the subroutine, you would like to have the original IO and storage banks restored. When the subroutine begins, it can read location 127 to find the current storage bank and location 134 to find the current I/O assignment. It can store those values, then switch over to AUXIO and to the storage bank it needs, and subsequently, before RETURNing, it can restore the values that were there at entry.


POLLing commands, POLLMODE, POLLIN, POLLOUT, POLLRUN, POLLWAIT

top

The BS2pe, BS2p, and BS2px have several commands collectively referred to as the POLLing commands.   They are kind of like interrupts, in the sense that the interpreter does certain tasks in the background, once the flags in scratchpad RAM described above are configured at RUN time using the POLLing commands.   The state is evaluated by the processor only between, and not during, execution of PBASIC commands.   For example, in this snippet:  
 : HIGH 0 : PAUSE 100 : LOW 0 : DEBUG "hello" : HIGH 0
the polled state is evaluated only at points where there is a colon, between instructions.   It is evaluated before and after, but not during the 100 millisecond pause, and before and after, but not during the roughly 5 milliseconds it takes to transmit the word "hello".   Thus for an event shorter than 100 milliseconds could possibly slip by without being detected in this sequence, if it happened to occur just as the execution of the PAUSE instruction began.   The message is, be sure external stimulus events are long enough to span every single instruction  time in the program.   If necessary, rewrite the program so that is true, or stretch the stimulus to satisfy the requirement.

The polling commands do take some getting used to. Using these commands in a program requires understanding how they work, but be assured they are powerful commands for some common tasks.  

There are 32 I/O pins on the BS2p-40 (and on the the BS2pe-40 and the OWL2pe data logger).   Scratchpad RAM locations 128 to 131 (4 bytes) contain 32 bits, and each bit corresponds to an i/o pin on the Stamp.    Bit 0 of location 128 to in0, bit 1 of location 128 to in1, and so on, up to bit 7 of location 131, which corresponds to bit 7 of x15 on the auxio bank.  On the 24 pin Stamps, there are still the same bytes, but only locations 128 and 129 correspond to active pins.  These bits show at any given time whether or not the corresponding pin has gone into its "target" state as defined by the POLLIN command.  It may be best to give an example.

Each bit in locations 128 to 131 corresponds to a BS2pe I/O pin. The bit becomes a 1 when the pin goes into its target state. For example, with polling looking for a 1 on mainio pin p5
  (POLLIN 5,1:POLLMODE 2),
 the bit 5 of location 128 goes to 1 when pin p5 goes to 1, and the bit goes to 0 when p5 goes to 0. The bit simply follows the pin. On the other hand,
 (POLLIN 5,0:POLLMODE 2),
 is polling for a 0 on pin p5. In this case, bit 5 of location 128 goes to 1 when the pin goes to 0, and vice versa; the bit is the inverse of the pin. The same behavior applies to the POLLMODE settings from 2 to 7.

Polling "interrupts" might come from any those 32 pins.If several are active at the same time, locations 128 to 131 can help to sort out which pin or pins actually went to its target state. Say there is a 1 second heartbeat pulse, a possible rain gage pulse, a possible traffic counter pulse, and 4 possible user pushbuttons, and the Stamp is in a low-power POLLWAIT loop. It is just sitting there waiting for an event to happen. When one of those events does happen, the Stamp wakes up, but how does it know which event caused it to wake up? PBASIC instructions that follow the POLLWAIT can read locations 128 to 131 as necessary to sort out the cause(s) of the wakeup. It might alternatively read the pins directly, but those might have changed state. It is possible to make the locations 128 to 131 latch the target events, so the program can take its time even if the events are relatively short in duration.

Things get interesting when the one of the latching modes is in effect. For example, with this setting,
 (MAINIO:POLLIN 5,1:POLLMODE 10),
if pin p5 goes to 1, then bit 5 of location 128 goes high and latches there, and stays high even when pin p5 goes low or repeatedly low or high. If the program needs to detect an event of short duration on pin p5, the polling can do that and store the result until the program gets around to reading location 128 to test that bit. The duration of the pulse only has to be long enough to span the boundary between any two PBASIC instructions, as emphasized above. Since most PBASIC instructions take less than one millisecond, that sets a minimum sufficient to detect the pulse.  In the latched mode, the scratchpad holds onto the fact that the event occured, even if the program waits for seconds before looking at the location 128.

The latched bit 5 in location 128 is reset to zero by issuing another POLLMODE command. (Any other POLLMODE command. will reset the bits. POLLIN or POLLOUT do _not_ reset the bits. Still need to test POLLWAIT). The actions taken (like setting outputs) under the latched modes are based on the status of the bits in locations 128-131, not on the present state of the pins, so be sure to reset the bits with a POLLMODE command after reading the states and when it is time to arm for another cycle. The POLLMODE affects all the pins at once, all 32 bits of mainio and auxio at once. It does not apply to individual pins or groups of pins.

Examples using POLLing and scratchpad flags to detect and count short events on one or more input channels.

top

The Stamp manual version 2._ gives a clever example at the end of the POLLOUT description, how to use the output register as a latch to hold the state of an input pin. For example, the sequence (MAINIO:POLLOUT 5,0:POLLIN 5,0:POLLMODE 10), sets pin p5 high briefly, then turns it into an input, polling for a zero input. When a zero input occurs, the event is stored (latched) in the out5 bit. The pin itself remains an input, since the POLLIN command followed the POLLOUT. Since mode 10 is a latched mode, the out5 bit holds the 1 state until the program gets around to looking at it. The action taken could be, say, to increment a counter to track the number of events on p5 as in a rain gage or traffic counter, example below. Once noted, the out5 bit has to be reset either by addressing the bit directly, (out5 = 1), or by issuing another (POLLOUT 5:POLLIN 5) command. The latching action must also be rearmed, by issuing another POLLMODE 10 command, which is what sets bit 5 in location 128 back to zero.

The method using the POLLOUT trick requires that the pin be turned into an output briefly, whereas reading the state of location 128 directly (without using POLLOUT) leaves the pin as an input throughout. That output condition may either be a good thing, as in the rain gage/capacitor example below, or it might be a bad thing if a sensitive device is connected to the input. The big difference is evident if you need to track more than one pin at a time. The connection between the polled input pins and multiple polled outputs is this, that any one of the polled inputs going to the target state causes _all_ of the polled outputs to go to their target state. So, if you want to use POLLIN to help count short duration events on several pins at once, you pretty much have to look at SCRAM locations 128 to 131.

Polling is turned off for POLLMODE settings of 0, 1, 8 and 9. In those modes, the SCRAM bytes 128 to 131 are all set to zero. I don't know if there e is any difference between modes 0, 1 compared to 8,9. Remains to explore. Also, I'm not sure that all POLLMODE commands reset the 128-131 bytes to zero. Still combinations to try. I have never used modes 3 to 7 and 11 to 15. Never used POLLRUN. I've only used modes 0 to 2 and 8 to 10.

Example 1.

A 0.01uF capacitor is connected from p5 to common. A switch is connected across the capacitor. The switch will occasionally close for a brief time and short out the capacitor. The objective is to count how many times the switch closes. This might be a rain gage or a traffic counter. When the program detects that the capacitor has been discharged, it takes an action (adding 1 to the rain count) and recharges the capacitor for the next round. Note that the there are other ways to wire the switch. For example, a simple pullup resistor to +5 volts will work, if the program is running and the switch stays closed long enough to span the boundary between two Stamp instructions. For example, if there a PAUSE 1000 command, the switch might close exactly at the instant that the PAUSE command starts, and the switch would have to remain closed for 1 full second before the Stamp would recognize it. The trick with the capacitor is that it acts like an external memory. I quite often use the NAP and SLEEP instructions, and the capacitor trick holds the state until the Stamp wakes up and recognizes the event. It is also possible to use a capacitor in parallel with a pullup resistor, to stretch the pulse.

' example capacitor & switch from p5 to ground, resistor for safety in series with switch:
' p5 --o---/\/\---;
' | 330 |
' === .01 <|switch
' | |
' com -o----------'
'
' using ad hoc trick similar to manual in the POLLOUT description
'{$STAMP BS2pe}
'{$PBASIC 2.5}

x VAR Word
z VAR Word
bx VAR Byte
DEBUG CLS,BELL ' top of program
POLLOUT 5,0 ' charge capacitor high on p5
' polling affects out5, it will go to zero when
POLLIN 5,0 ' p5 is input, polled
POLLMODE 10 ' enable latched polling

DO
FOR x=0 TO 2000 ' about 2 second
DEBUG x//26+66 ' busywork, polling is active
NEXT
GOSUB CheckRainGage
DEBUG ? z
LOOP

CheckRainGage:
GET 128,bx
DEBUG CR,? IN5,? OUT5 ,? bx.bit5 ' show states of the input, output bit, and SP latch bit
IF OUT5=0 THEN z=z+1 ' the out5 bit may have changed due to action of POLLout command
IF IN5=0 THEN
POLLOUT 5,0 : POLLIN 5,0 ' refresh charge C high, instruct to wait for low on p5
ELSE
POLLMODE 10 ' rearms the latching action, and debounces switch, don't rearm if switch is still down!
ENDIF
RETURN

Example 2.

Same as above example 1, except this uses the SCRAM location 128 instead of the POLLOUT trick, and it counts on both p4 and p5. A 0.01uF capacitor is connected from p4 and also from p5 to common. A switch is connected across each capacitor. The switch will occasionally close for a brief time and short out the capacitor. The objective is to count how many times the switch closes. This might be a rain gage or a traffic counter. The circuit is duplicated on p4 and p5. The trick used in example 1 will not work here, because an event on _either _p4 or p5 would affect _both_ out4 and out5.  POLLout affects all pins at once.

' example capacitor & switch from p4 & p5 to ground, resistor for safety in series with switch:
' p5 --o---/\/\---;
' | 330 |
' === .01 <| switch identical circuit repeated on p4
' | |
' com -o----------'
'
' counting pulses on p4 and p5 using SCRAM location 128
'{$STAMP BS2pe}
'{$PBASIC 2.5}

x VAR Word
z4 VAR Word
z5 VAR Word
bx VAR Byte
DEBUG CLS,BELL ' top of program
HIGH 4 : HIGH 5
POLLIN 4,0 ' p4 is input, polled
POLLIN 5,0 ' p5 is input, polled
POLLMODE 10 ' enable latched polling

DO
FOR x=0 TO 1000 ' about 1 second
DEBUG x//26+66 ' busywork, polling is active
NEXT
DEBUG CR,BIN IN5,BIN IN4 ' show state of input pin p5 and p4
GET 128,bx
DEBUG CR, bx.bit5 ,bx.bit4 ' show state of latch bits (1 if inputs went to 0)
IF bx.bit4 THEN z4=z4+1 : HIGH 4 : INPUT 4
IF bx.bit5 THEN z5=z5+1 : HIGH 5 : INPUT 5
POLLMODE 10 ' rearms the latching action
DEBUG DEC5 z2, TAB,DEC5 z1,HOME
LOOP


' the above routine will count multiple times,
' once each time thru the loop if the switch is held down.
' debounce requires more work. E.g., using OUT4 as a debounce bit:
' z4=z4+(bx.bit4 & ~OUT4): HIGH 4 : INPUT 4 : OUT4=IN4
' forces in4 to go back to 1 before another count can occur.


Example 3.

Switches are connected to inputs p0 to p7, and each one has a pullup resistor to Vdd, and the other side of the switch is connected to Vss. The signal goes low when a switch is pressed. Objective to note which buttons were pressed even briefly during busywork period. All switches must be released before proceeding.

' example switches to ground with pullups to Vdd
' Vdd ----/\/\----;
' 10k |
' |
' p5 ------/\/\---;
' 330 |
' <| switch
' |
' com -o----------'
'
' identical circuit repeated on p4
'
' counting pulses on p4 and p5 using SCRAM location 128
'{$STAMP BS2pe}
'{$PBASIC 2.5}

x VAR Word
bx VAR Byte
DEBUG CLS,BELL ' top of program
POLLIN 0,0 ' p0 is input, polled
POLLIN 1,0 ' p1 is input, polled
POLLIN 2,0 ' p2 is input, polled
POLLIN 3,0 ' p3 is input, polled
POLLIN 4,0 ' p4 is input, polled
POLLIN 5,0 ' p5 is input, polled
POLLIN 6,0 ' p6 is input, polled
POLLIN 7,0 ' p7 is input, polled
POLLMODE 10 ' enable latched polling

DO
FOR x=0 TO 9000 ' about 10 seconds
DEBUG x//26+66 ' busywork, polling is active
NEXT
DEBUG CR,BIN8 inL ' show state of input pins
GET 128,bx
DEBUG CR, BIN8 bx ' show state of latch bits (1 if inputs went to 0)
DO:LOOP UNTIL INL=255 ' hold here until all switches are up
POLLMODE 10 ' rearms the latching action
LOOP

Example 4.

Similar to example 3, but POLLWAIT with a 60 millisecond nap period is used to detect switches as they are pressed. Switches are connected to inputs p0 to p7, and each one has a pullup resistor to Vdd, and the other side of the switch is connected to Vss. The signal goes low when a switch is pressed. Objective to note which buttons were pressed even briefly during busywork period. All switches must be released before proceeding.

' example switches to ground with pullups to Vdd
' Vdd ----/\/\----;
' 10k |
' |
' p5 ------/\/\---;
' 330 |
' <| switch identical circuit repeated on p4
' |
' com -o----------'
'
' counting pulses on p4 and p5 using SCRAM location 128
'{$STAMP BS2pe}
'{$PBASIC 2.5}

x VAR Word
bx VAR Byte
DEBUG CLS,BELL ' top of program
POLLIN 0,0 ' p0 is input, polled
POLLIN 1,0 ' p1 is input, polled
POLLIN 2,0 ' p2 is input, polled
POLLIN 3,0 ' p3 is input, polled
POLLIN 4,0 ' p4 is input, polled
POLLIN 5,0 ' p5 is input, polled
POLLIN 6,0 ' p6 is input, polled
POLLIN 7,0 ' p7 is input, polled
POLLMODE 10 ' enable latched polling

DO
POLLWAIT 2 ' program loops here until a switch is pressed
'PAUSE 1000 ' if this is here, the input pin state and the latch state are more likely to differ
DEBUG CR,BIN8 inL ' show state of input pins
GET 128,bx
DEBUG CR, BIN8 bx ' show state of latch bits (1 if inputs went to 0)
DO:LOOP UNTIL INL=255 ' hold here until all switches are up
POLLMODE 10 ' rearms the latching action
LOOP

A debounce action similar to the note after example 2 can be implemented. These loops are not foolproof. An event can occur at certain instants where it will not be detected due to the rearming action occurring just at that instant. Or one event can be counted twice because it is long enough to span the interval from detection to rearming for another round. Debouncing and thoughtful consideration of the timing in the program can minimize these difficulties.

 


<top> <index> <home> logo < mailto:info@emesystems.com>