Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
84 changes: 84 additions & 0 deletions src/hal/components/momentary2nist.comp
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
component momentary2nist "momentary button to nist logic";

description
"""
Momentary2nist can be used with a momentary push button
to control a device that has separate on and off inputs
and an is-on output.
A debounce delay in cycles can be set for 'in'. (default = 2)
A maximum output pulse length in cycles can be set for 'on' and 'off'. (default = 100)

* On a rising edge on pin *in* when *is-on* is low: It sets *on* until *is-on* becomes high.
* On a rising edge on pin *in* when *is-on* is high: It sets *off* until *is-on* becomes low.
* Pins *on* and *off* remain high until *is-on* confirms the respective state or until *max-pulse-length* is reached.
....
┐ ┌─────xxxxxxxxxxxx┐ ┌─────xxxxxxxxxxxx┐
in : └─────┘ xxxxxxxxxxxx└───────────┘ xxxxxxxxxxxx└─────

┐ ┌───────────┐
on : └─────┘ └─────────────────────────────────────────

┐ ┌───────────┐
off : └───────────────────────────────────┘ └───────────

┐ ┌─────────────────────────────┐
is-on: └─────────────────┘ └───────────
....

""";

pin in bool in "momentary button in";
pin in bool is_on "current state of device";
pin in ui32 debounce = 2 "debounce delay for 'in'-pin in cycles";
pin in ui32 max_pulse_length = 100 "max output pulse length";
pin out bool on "turn device on";
pin out bool off "turn device off";
variable int debounce_cntr;
variable unsigned debounce_val;
variable unsigned pulse_length;
Comment on lines +37 to +38

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

debounce_val is unconditionally overwritten in the function. Having it as as variable here is expensive. Better use a local variable (see also other comment).

variable int state;

Comment on lines +39 to +40

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

statefollows in, which is a bool. Why isn't state a bool? Is there a specific reason for state to be an integer?

option period no;
function _;
license "GPL";
author "David Mueller";
;;
FUNCTION(_) {

if (( debounce < 1 ) || ( debounce > 10000 )) {
debounce_val = 2; // set a sane value
} else {
debounce_val = debounce;
}
Comment on lines +48 to +52

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

May I suggest (reads debounce only once):

rtapi_u32 debounce_val = debounce;
if(debounce_val < 1 || debounce_val > 10000) {
    debounce_val = 2; // set a sane value
}

You may also want to cache is_on and in:

rtapi_bool inval = in;
rtapi_bool isonval = is_on;

and then use the cached values.


if (in && state == 0 ) { // input has changed from debounced 0 -> 1
debounce_cntr++;
if ( debounce_cntr >= (int)debounce_val ) {
if (!is_on) { // turn ON if it's off
on_set(1);
off_set(0);
} else { // turn OFF if it's on
on_set(0);
off_set(1);
}
state = 1;
debounce_cntr = 0;
}
} else if (!in && state == 1) { // input has changed from debounced 1 -> 0
debounce_cntr++;
if ( debounce_cntr >= (int)debounce_val ) {
state = 0;
debounce_cntr = 0;
}
} else if ((!is_on && off) || (is_on && on) || (pulse_length > max_pulse_length)) {
// reset outputs once device has switched or maximum pulse length is reached
on_set(0);
off_set(0);
debounce_cntr = 0;
pulse_length = 0;
} else {
debounce_cntr = 0;
pulse_length ++;
}
}

30 changes: 19 additions & 11 deletions src/hal/components/toggle2nist.comp
Original file line number Diff line number Diff line change
Expand Up @@ -2,17 +2,19 @@ component toggle2nist "toggle button to nist logic";

description
"""
Toggle2nist can be used with a momentary push button
Toggle2nist can be used with a latching switch or push button
to control a device that has separate on and off inputs
and an is-on output.
A debounce delay in cycles can be set for 'in'. (default = 2)
A maximum output pulse length in cycles can be set for 'on' and 'off'. (default = 100)

* On a rising edge on pin *in* when *is-on* is low: It sets *on* until *is-on* becomes high.
* On a rising edge on pin *in* when *is-on* is high: It sets *off* until *is-on* becomes low.
* On a falling edge on pin *in* when *is-on* is high: It sets *off* until *is-on* becomes low.
* Pins *on* and *off* remain high until *is-on* confirms the respective state or until *max-pulse-length* is reached.

....
       ┐     ┌─────xxxxxxxxxxxx┐           ┌─────xxxxxxxxxxxx
in   : └─────┘     xxxxxxxxxxxx└───────────┘     xxxxxxxxxxxx└─────
       ┐     ┌─────────────────────────────
in   : └─────┘                             └───────────────────────

       ┐     ┌───────────┐
on   : └─────┘           └─────────────────────────────────────────
Expand All @@ -26,19 +28,21 @@ is-on: └─────────────────┘       

""";

pin in bool in "momentary button in";
pin in bool in "toggle button in";
pin in bool is_on "current state of device";
pin in ui32 debounce = 2 "debounce delay for 'in'-pin in cycles";
pin in ui32 max_pulse_length = 100 "max output pulse length";
pin out bool on "turn device on";
pin out bool off "turn device off";
variable int debounce_cntr;
variable unsigned debounce_val;
variable unsigned pulse_length;
variable int state;

option period no;
function _;
license "GPL";
author "Anders Wallin, David Mueller";
author "Anders Wallin";
;;
FUNCTION(_) {

Expand All @@ -54,24 +58,28 @@ FUNCTION(_) {
if (!is_on) { /* turn ON if it's off */
on_set(1);
off_set(0);
} else { /* turn OFF if it's on */
on_set(0);
off_set(1);
}
state = 1;
debounce_cntr = 0;
}
} else if (!in && state == 1) { /* input has changed from debounced 1 -> 0 */
debounce_cntr++;
if ( debounce_cntr >= (int)debounce_val ) {
if (is_on) { /* turn OFF if it's on */
on_set(0);
off_set(1);
}
state = 0;
debounce_cntr = 0;
}
} else if ((!is_on && off) || (is_on && on)) { /* reset outputs once device has switched*/
} else if ((!is_on && off) || (is_on && on) || (pulse_length > max_pulse_length)) {
// reset outputs once device has switched or maximum pulse length is reached
on_set(0);
off_set(0);
debounce_cntr = 0;
pulse_length = 0;
} else {
debounce_cntr = 0;
debounce_cntr = 0;
pulse_length ++;
}
}
Loading