#define PIN_HEADING_CLK D7 #define PIN_HEADING_DT D5 #define PIN_HEADING_SW D6 #define PIN_ALTITUDE_CLK D1 #define PIN_ALTITUDE_DT D2 #define PIN_ALTITUDE_SW D3 #define PIN_LED D4 #define VALUE_BUFFER 30 #define HEADING_DT_TRIGGER 1 #define HEADING_DT_HIGH 2 #define HEADING_SW_TRIGGER 2 #define ALTITUDE_DT_TRIGGER 4 #define ALTITUDE_DT_HIGH 8 #define ALTITUDE_SW_TRIGGER 8 #define MIN_DT_INPUT_DELAY 1000 // 1ms #define MIN_SW_INPUT_DELAY 500000 // 500ms const char PREFIX_HEADING[5] = "head"; const char PREFIX_ALTITUDE[5] = "altd"; uint8_t lastClk = HIGH; // ringbuffer of trigger and direction values uint8_t valueBuffer[VALUE_BUFFER] = { 0 }; uint8_t readerPos, writerPos = 0; long lastInput = 0; // prevent bouncing input bool useInput(long minInputDelay) { long now = micros(); long diff = now - lastInput; // < 0 because of long overruns bool ret = diff < 0 || diff > minInputDelay; if (ret) { lastInput = now; } return ret; } void addValue(uint8_t value) { valueBuffer[writerPos++] = value; if (writerPos >= VALUE_BUFFER) { writerPos = 0; } } void clkFalling(uint8_t PIN_DT, uint8_t DT_TRIGGER, uint8_t DT_HIGH) { if (useInput(MIN_DT_INPUT_DELAY)) { uint8_t dt = digitalRead(PIN_DT); uint8_t value = DT_TRIGGER; if (dt) { value |= DT_HIGH; } else { // value is already "DT_LOW" } addValue(value); } } void swFalling(uint8_t SW_TRIGGER) { if (useInput(MIN_SW_INPUT_DELAY)) { addValue(SW_TRIGGER); } } void ICACHE_RAM_ATTR headingClkFalling(); void headingClkFalling() { clkFalling(PIN_HEADING_DT, HEADING_DT_TRIGGER, HEADING_DT_HIGH); } void ICACHE_RAM_ATTR altitudeClkFalling(); void altitudeClkFalling() { clkFalling(PIN_ALTITUDE_DT, ALTITUDE_DT_TRIGGER, ALTITUDE_DT_HIGH); } void ICACHE_RAM_ATTR headingSwFalling(); void headingSwFalling() { swFalling(HEADING_SW_TRIGGER); } void ICACHE_RAM_ATTR altitudeSwFalling(); void altitudeSwFalling() { swFalling(ALTITUDE_SW_TRIGGER); } void dtTriggered(uint8_t high, uint8_t fast, const char prefix[5]) { Serial.print(prefix); if (high) { Serial.println(1); } else { Serial.println(-1); } } void setup() { Serial.begin(115200); pinMode(PIN_HEADING_SW, INPUT_PULLUP); pinMode(PIN_HEADING_DT, INPUT_PULLUP); pinMode(PIN_HEADING_CLK, INPUT_PULLUP); attachInterrupt(digitalPinToInterrupt(PIN_HEADING_CLK), headingClkFalling, FALLING); attachInterrupt(digitalPinToInterrupt(PIN_HEADING_SW), headingSwFalling, FALLING); attachInterrupt(digitalPinToInterrupt(PIN_ALTITUDE_CLK), altitudeClkFalling, FALLING); attachInterrupt(digitalPinToInterrupt(PIN_ALTITUDE_SW), altitudeSwFalling, FALLING); } void loop() { while (writerPos != readerPos) { uint8_t value = valueBuffer[readerPos++]; if (readerPos >= VALUE_BUFFER) { readerPos = 0; } if (value & HEADING_DT_TRIGGER) { uint8_t dtHigh = value & HEADING_DT_HIGH; dtTriggered(dtHigh, 5, PREFIX_HEADING); } else if (value & HEADING_SW_TRIGGER) { Serial.print(PREFIX_HEADING); Serial.println("push"); } else if (value & ALTITUDE_DT_TRIGGER) { uint8_t dtHigh = value & ALTITUDE_DT_HIGH; dtTriggered(dtHigh, 5, PREFIX_ALTITUDE); } else if (value & ALTITUDE_SW_TRIGGER) { Serial.print(PREFIX_ALTITUDE); Serial.println("push"); } else { // never happen error... } } }