Fan Controller - PWM HF (25kHz) Type, w/ a Two Button Escalator & a 4-LED Binary State-Display for UI.

The Circuit, as Built on an Universal PCB, Ready For Installation (in a '3.5 Drive-Slot) - Using a Thermoplastic Carrier :

/media/uploads/mzcs/img_20181108_073655_hdr-a.jpg

Revision:
0:437bb8e2f8a7
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/DebounceIn.h	Sun Nov 04 16:49:49 2018 +0000
@@ -0,0 +1,208 @@
+/*
+    Copyright (c) 2010 Andy Kirkham
+ 
+    Permission is hereby granted, free of charge, to any person obtaining a copy
+    of this software and associated documentation files (the "Software"), to deal
+    in the Software without restriction, including without limitation the rights
+    to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+    copies of the Software, and to permit persons to whom the Software is
+    furnished to do so, subject to the following conditions:
+ 
+    The above copyright notice and this permission notice shall be included in
+    all copies or substantial portions of the Software.
+ 
+    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+    IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+    FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+    AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+    LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+    OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+    THE SOFTWARE.
+*/
+ 
+#ifndef AJK_DEBOUNCEIN_H
+#define AJK_DEBOUNCEIN_H
+ 
+#include "mbed.h"
+
+/** DebounceIn adds mechanical switch debouncing to DigitialIn.
+ *
+ * Example:
+ * @code
+ * #include "mbed.h"
+ * #include "DebounceIn.h"
+ *
+ * DebounceIn  d(p5);
+ * DigitialOut led1(LED1);
+ * DigitialOut led2(LED2);
+ *
+ * int main() {
+ *     while(1) {
+ *         led1 = d;
+ *         led2 = d.read();
+ *     }
+ * }
+ * @endcode
+ *
+ * @see set_debounce_us() To change the sampling frequency.
+ * @see set_samples() To alter the number of samples.
+ *
+ * Users of this library may also be interested in PinDetect library:-
+ * @see http://mbed.org/users/AjK/libraries/PinDetect/latest
+ *
+ * This example shows one input displayed by two outputs. The input
+ * is debounced by the default 10ms.
+ */
+
+namespace AjK {
+ 
+class DebounceIn {
+    public:
+    
+    friend class DigitalIn;
+    friend class Ticker;
+        
+        /** set_debounce_us
+         *
+         * Sets the debounce sample period time in microseconds, default is 25000 (25ms)
+         *
+         * @param uint32_t i The debounce sample period time to set.
+         */        
+//        void set_debounce_us(int i) { _ticker.attach_us(this, &DebounceIn::_callback, i); }
+        void set_debounce_us(uint32_t i) { _debounce_us = i; _ticker->attach_us(callback(this, &DebounceIn::_callback), i); }
+        
+        /** get_debounce_us
+         *
+         * Gets the debounce sample period time in microseconds
+         *
+         */        
+        uint32_t get_debounce_us(void) { return _debounce_us; } // // //
+        
+        /** set_samples
+         *
+         * Defines the number of samples before switching the shadow 
+         * definition of the pin. 
+         *
+         * @param int i The number of samples.
+         */        
+        void set_samples(uint8_t i) { _samples = i; }
+
+        /** get_samples
+         *
+         * Gets the number of samples before switching the shadow 
+         * definition of the pin. 
+         *
+         */        
+        uint8_t get_samples(void) { return _samples; }
+        
+        /** read
+         *
+         * Read the value of the debounced pin.
+         */
+        int8_t read(void) { return this->_shadow; }
+        
+#ifdef MBED_OPERATORS
+        /** operator int()
+         *
+         * Read the value of the debounced pin.
+         */
+        operator int() { return read(); }
+#endif  
+
+        /** Set the pin mode.
+        *
+        * @see http://mbed.org/projects/libraries/api/mbed/trunk/DigitalInOut#DigitalInOut.mode
+        * @param PinMode m The mode to pass on to the DigitalIn
+        */
+        void mode(PinMode m) { _digital_in->mode( m ); }
+
+        /** get_edge_direction
+         *
+         * Gets the value of the debounced pin' edge direction (rising/falling).
+         */
+        int8_t get_edge_direction(void) { return _edge_direction; } // // //
+
+        /** get_edge_direction_acted_upon
+         *
+         * Gets the debounced pin edge direction' usage status (used/unused)
+         */
+        bool get_edge_direction_acted_upon(void) { return _edge_direction_acted_upon; } // // //
+
+        /** set_edge_direction_acted_upon
+         *
+         * Sets the status of the debounced pin edge direction' as used
+         */
+        void set_edge_direction_acted_upon(void) { _edge_direction_acted_upon = 1; } // // //
+
+        /** Constructor
+         * 
+         * @param PinName pin The pin to assign as an input.
+         */
+        DebounceIn() { error("DebounceIn: You must supply a PinName"); }
+
+        DebounceIn(PinName pin) { _init(pin, PullNone); };
+        
+        DebounceIn(PinName pin, PinMode mode) { _init(pin, mode); };
+
+        /** DebounceIn destructor
+        */    
+        ~DebounceIn() {
+            if ( _ticker ) { delete( _ticker ); }
+            if ( _digital_in ) { delete( _digital_in ); }
+        }
+
+    protected:
+    
+        /** initialise class
+     *
+     * @param PinName p is a valid pin that supports DigitalIn
+     * @param PinMode m The mode the DigitalIn should use.
+     */
+    void _init(PinName p, PinMode m) {
+        
+        _counter = 0;
+        _samples = 10;
+        _shadow = -1;
+        _edge_direction = -1;
+        _edge_direction_acted_upon = 1;
+                
+        _digital_in = new DigitalIn( p, m );
+        _ticker = new Ticker;
+        
+        set_debounce_us(25000);        
+    }
+    
+        void _callback(void) {
+
+            if (_digital_in->read() == 1) { 
+                if (_counter < _samples) _counter++; 
+                if (_counter == _samples) {
+                    if (_shadow == 0) { _edge_direction = 1; _edge_direction_acted_upon = 0; } // // //
+                    _shadow = 1;
+                    }
+            }
+            else { 
+                if (_counter > 0) _counter--; 
+                if (_counter == 0) {
+                    if (_shadow == 1) { _edge_direction = 0; _edge_direction_acted_upon = 0; } // // //
+                    _shadow = 0; 
+                    }
+            }
+        }
+        
+        DigitalIn   *_digital_in;
+        Ticker      *_ticker;
+        int8_t    _shadow;
+        uint32_t    _debounce_us; // // //
+        int8_t    _edge_direction; // // //
+        bool    _edge_direction_acted_upon; // // //
+        uint8_t    _counter;
+        uint8_t    _samples;
+};
+
+}; // namespace AjK ends.
+
+using namespace AjK;
+ 
+#endif
+ 
\ No newline at end of file