From 780ba0ba0a3207a6ba3ce7e52bd220ff4fed2650 Mon Sep 17 00:00:00 2001 From: damage Date: Wed, 1 Jan 2025 19:15:12 +0100 Subject: [PATCH] added rotator handler --- rotator/rotator.ino | 160 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 160 insertions(+) create mode 100644 rotator/rotator.ino diff --git a/rotator/rotator.ino b/rotator/rotator.ino new file mode 100644 index 0000000..2c7b414 --- /dev/null +++ b/rotator/rotator.ino @@ -0,0 +1,160 @@ + +#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 4 + +#define ALTITUDE_DT_TRIGGER 8 +#define ALTITUDE_DT_HIGH 16 +#define ALTITUDE_SW_TRIGGER 32 + +#define MIN_DT_INPUT_DELAY 1000 // 1ms +#define MIN_SW_INPUT_DELAY 500000 // 500ms + +#define MIN_ALTITUDE 1 +#define MAX_ALTITUDE 60000 + +#define MIN_HEADING 1 +#define MAX_HEADING 360 + +uint8_t lastClk = HIGH; +uint16_t heading = 360; +uint16_t altitude = 0; + +// 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(uint16_t &cnt, uint8_t high, uint8_t fast, uint16_t miV, uint16_t miVR, uint16_t maV, uint16_t mavR) { + if (high) { + cnt++; + } else { + cnt--; + } + + if (cnt > maV) { + cnt = mavR; + } + + if (cnt < miV) { + cnt = miVR; + } +} + +void setup() { + Serial.begin(115200); + while (!Serial) { + ; // wait for serial port to connect. Needed for native USB port only + } + + 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(heading, dtHigh, 5, MIN_HEADING, MAX_HEADING, MAX_HEADING, MIN_HEADING); + Serial.print("Heading: "); + Serial.println(heading); + } else if (value & HEADING_SW_TRIGGER) { + Serial.println("Heading: pushed"); + } else if (value & ALTITUDE_DT_TRIGGER) { + uint8_t dtHigh = value & ALTITUDE_DT_HIGH; + dtTriggered(altitude, dtHigh, 5, MIN_ALTITUDE, MIN_ALTITUDE, MAX_ALTITUDE, MAX_ALTITUDE); + Serial.print("Altitude: "); + Serial.println(altitude); + } else if (value & ALTITUDE_SW_TRIGGER) { + Serial.println("Altitude: pushed"); + } else { + // never happen error... + } + } +}