[CCC DEV] The third button problem
Steve Pretty
steve.g.pretty at btinternet.com
Sun Feb 6 19:34:31 GMT 2011
At present, the "plumbing" library has a significant limitation in that
it can only deal with two digital inputs (buttons). The current code
uses interrupt driven digital input. It uses the two external interrupts
provided by the Atmel chip, which are connected to pins 2 and 3 of the
arduino.
So what happens when the user wants 3 or more digital inputs? Here is a
sample use case:
Quiz controller - there are two teams, A and B. Each team has a button
and a lamp. The quiz master asks a question - first team to press the
button lights their lamp and blocks the other team. Once the winning
team has answered the question, the question master presses a button to
reset the system ready for the next question (note - the quiz controller
is also recording and displaying scores, so the arduino reset button
cannot be used for the quiz master button). I built a system like this
once (using TTL logic).
The existing digital.input proc can service the Team A and Team B
buttons. Because this routime is interrupt driven, it should have very
low latency and be able to accurately discriminate the winning team.
What can we do for the quiz master's button? One solution would be a
timed poll variant of digital.input. This would have some latency - but
that is not an issue for this button. timed poll is a widely used micro
controller strategy for handling multiple buttons - e.g. keyboard
scanning. Here is my test code, which test out OK:
#INCLUDE "plumbing.module"
--{{{ PROC digital.input.polled
--* Read digital levels on external pins using timed polling
-- This procedure will output a LEVEL (either LOW or HIGH) whenever the
-- pin changes value.
--
-- @param board.pin The pin number (any I/O pin).
-- @param period The time in milliseconds between polls
-- @param out The LEVEL, output when the pin changes level.
PROC digital.input.polled (VAL INT board.pin, period, CHAN LEVEL out!)
LEVEL last, level:
SEQ
digital.read (board.pin, level) -- find initial port level
out ! level
last := level
WHILE TRUE
SEQ
delay (period)
digital.read (board.pin, level)
IF
level <> last
SEQ
out ! level
last := level
TRUE
SKIP
:
--}}}
PROC main ()
CHAN LEVEL x:
SEQ
PAR
digital.input.polled (4, 100, x!)
digital.output (13, x?)
:
A nicer solution would be to keep with interrupts, I think. This would
mean supplying a PROC to deal with the three interrupts PCINT1, PCINT2,
PCINT3. These interrupts each deal with an 8 bit port, and will flag
an interrupt for a state change on selected pins on those ports.
With the current digital.input, there would be a separate PROC instance
running for pin 2 and pin 3 - i.e. a one to one relationship between an
interrupt, its interrupt vector and the handling PROC. I presume that a
one to one relationship would be needed for the PCINT1, PCINT2 and
PCINT3 ( or could one PROC wait on an ALT of the three interrupts?)
I am thinking a handler routine would have to deal with up to 8 pins.
It could have a signature:
PROC (VAL INT intID, mask, CHAN LEVEL out0, out1, out2, out3, out4,
out5, out6, out7)
where intID is the name of the interrupt (and hence the range of pins),
mask is used to flag which bits of the port are of interest and should
be reported, and then there are 8 CHANs for the output. This is not
very nice, as you would have to provide "black holes" for any unused
outputs?
Ideally, I would want a user interface identical to the current
digital.input - where I can set up a PROC to handle one pin and
associate it with one output CHAN. This would somehow have to register
the pin / CHAN with some underlaying helper PROC which is actually
managing the interrupts - I have no idea how to do that in occam (if it
is even possible). What I would really like to be able to do is pass a
list of pin / CHAN tuples to the handler - but again, I don't think
occam supports that kind of thing.
Could I start a handler and then use a protocol to pass in the pin/CHAN
pairs? If I did that, can I somehow save the set of CHANs I want to use
in an array, and then send on the CHAN references in the array. (Is
this what Mobile CHANs are for?)
There are probably a lot of basic occam pi questions here which I should
be answering myself - but I have yet to find comprehensive occam-pi
language documentation - is there anything more comprehensive that the
Peter Welch quick guide?
I would be interested to know what your thoughts are for the third
button problem.
Steve
More information about the developers
mailing list