This idea presents a piece of firmware that has proven to be both compact and extremely useful in several field applications involving embedded controllers.
The concept originated when one of our embedded-system customers had problems in the field with a programmable indexer for a stepping motor. It turned out that an inverter mounted into the main electrical box was emitting significant electrical noise. This noise emission was so powerful that it would occasionally activate the digital input of our indexer.
What the customer requested was an increase in the time constant of the filter on the indexer board. Due to the physical dimensions of the required capacitor, however, this was impossible. Another option was to increase the software filtering. But while a large filter time constant was acceptable for this client’s application, it wasn’t suitable for all installations.
Writing a filter routine would be the ideal solution. It would have to be small, fast, and programmable for a range of values that customers could adapt to their applications. A small but quite powerful routine resulted.
Using a time constant ranging from 1 to 16 ms, the algorithm (implemented in assembly on an MC68332-based embedded system) filters 16 digital inputs. Listed below is the algorithm’s goal:
- Set the n-th bit of exit_input_status if and only if all n bits of the filter_body elements are logic-one.
- Reset the n-th bit of exit_input_status if and only if all the n bits of the filter_body elements are logic-zero.
- In all other cases, the contents of exit_input_status are left unaltered.
The algorithm defines a buffer of 16 unsigned 16-bit integers (UINT16) as a filter shift register, a 16-bit integer (UINT16) to store the previous filtered status of the input, and an unsigned 8-bit byte (UBYTE) to store the time constant of the filter as follows:
UINT16 filter_body (16)
Algorithm operations for a 16-ms time-constant:
- AND the entry_input_status and each of the filter_body elements
- OR the entry_input_status and each of the filter_body elements
- XOR the result of #1 and #2
- NOT the result of #3
- OR the result of #1 and #3
- AND the result of #2 and #4
- AND previous_state and result of #5
- OR the result of #7 and #6
- Save result of #8 into previous_state
- Shift all filter_body elements down by one position to push out the oldest input reading from the filter and insert the newest input reading.
To accomplish this functionality in my MC68332 embedded system, the routine shown in the listing is called every 1 ms.