The "Button" library routine usage.


1. Function Definition

The "Button" library routine defined as follows:
Prototype: function Button(var port : byte; pin, time, active_state : byte) : byte;
 
Returns:   Returns 0 or 255 (= "false" or "true": boolean)

Description:
Function eliminates the influence of contact flickering upon pressing a button (debouncing).
Parameter "port" specifies the location of the button; 
parameter "pin" is the pin number on designated port and goes from 0..7; 
parameter "time" is a debounce period in milliseconds; 
parameter "active_state" can be either 0 or 1, and it determines if the button is active upon logical zero or logical one.
About the parameters: The routine is not blocking: it always returns a result (it doesn' wait for the button to be pushed). However the throughput time can differ considerably, depending on the button state (see above).

2. Function Usage

Normally this function is called regurarly to check if the button is pressed or not. "Regurarly" means mostly in the main loop of the program. This is what we assume in the following examples.

a. Simple usage: actions as long the button is pushed

[code]
while true do // main program loop
begin
  ...

  if Button(PortB, 0 ,50, 1) then
  begin
    PortB.1 := NotBit(PortB.1);				// actions to perform when button pushed
    ...
  end;
  
  // other main loop activities
 
end; // end of main program loop
[/code]
In the above code, of course nothing happens if the button is not in its active state. But: while it is in its active state (the user presses the button) every time the routine is called it returns true and the "action" is executed. Keep in mind that the routine is not blocking.
So, actions are repeatedly done as long as the button is pushed.
The frequency at which the actions occur is the same as the frequency the main loop runs in, and is maximum (1/debouncing "time")). One can influence that frequency by inserting e.g. extra delays in the "actions to perform" part to slow down the execution rate.

b. One action every button push, blocking

[code]
while true do // main program loop
begin
  ...

  if Button(PortB, 0 ,50, 1) then
  begin
    PortB.1 := NotBit(PortB.1);				// actions to perform when button pushed
    ...
  end;
  repeat until PortB.0 = 0;				// wait for button release --> this blocks the main loop
  
  // other main loop activities
 
end; // end of main program loop
[code]
If repeated execution of "actions" as long as the button is pushed is not wanted, then the easiest way to do that is the above code: simply wait until the user releases the button.
But: this blocks the main loop as long as the user does not release the button. This can be sometimes acceptable, but sometimes it is not. In the latter case the next code snippet can be used.

c. One action every button push, non blocking

[code]
  ...
  Flag := false;
  ...
while true do // main program loop
begin

  ...
  if Button(PortB, 0 ,50, 1) and (Flag = False) then
  begin
    Flag := true;
    PortB.1 := NotBit(PortB.1);				// actions to perform when button pushed
    ...
  end;
  if PortB.0 = 0 then Flag := False;
  
  // other main loop activities
 
end; // end of main program loop
[/code]
The above code makes sure, whith the help of the boolean "Flag" variable, the button has been released before the actions are executed again. This code is of course more complicated than the previous one, but it is not blocking, and the desired result, one action per button push, is still there.
-------------------------------------------