From 5cea555e775155a2c636de085a246f24d3c01dc3 Mon Sep 17 00:00:00 2001 From: damage Date: Sun, 11 May 2025 16:01:57 +0200 Subject: [PATCH] i2c communication use optic rotary encoder --- master/master.ino | 62 +++++++++++++++ rotator/rotator.ino | 184 ++++++++++++++++++-------------------------- 2 files changed, 139 insertions(+), 107 deletions(-) create mode 100644 master/master.ino diff --git a/master/master.ino b/master/master.ino new file mode 100644 index 0000000..e64ac66 --- /dev/null +++ b/master/master.ino @@ -0,0 +1,62 @@ +#include + +#define READ_BYTES_FROM_WIRE 1 + +// needs global define +#define DATA_STOP_BYTE 0x00 +#define HEADING_TRIGGER_BIT 1 +#define HEADING_HIGH_BIT 2 +#define ALTITUDE_TRIGGER_BIT 4 +#define ALTITUDE_HIGH_BIT 8 + +struct device { + byte address; + String name; +}; + +struct device devices[] = { + {0x01, "althead"} +}; + +int numDevices = -1; + +void setup() { + numDevices = sizeof(devices) / sizeof(device); + + Wire.begin(); + + pinMode(LED_TX, OUTPUT); + digitalWrite(LED_TX, HIGH); + pinMode(LED_RX, OUTPUT); + digitalWrite(LED_RX, HIGH); +} + +void loop() { + // loop through devices and ask for data + for (int i = 0; i < numDevices; i++) { + Wire.requestFrom(devices[i].address, READ_BYTES_FROM_WIRE); + while (Wire.available()) { + // device has data, ask as long for data as it sends + // if it never stops sending, we are fucked :) + byte data = Wire.read(); + if (data != DATA_STOP_BYTE) { + if (data & ALTITUDE_TRIGGER_BIT) { + if (data & ALTITUDE_HIGH_BIT) { + Serial.println("Altitude up"); + } else { + Serial.println("Altitude down"); + } + } else if (data & HEADING_TRIGGER_BIT) { + if (data & HEADING_HIGH_BIT) { + Serial.println("Heading right"); + } else { + Serial.println("Heading left"); + } + } else { + // who are you? + } + Wire.requestFrom(devices[i].address, READ_BYTES_FROM_WIRE); + } + } + } +} diff --git a/rotator/rotator.ino b/rotator/rotator.ino index 6428bf6..592ba17 100644 --- a/rotator/rotator.ino +++ b/rotator/rotator.ino @@ -1,142 +1,112 @@ -#define PIN_HEADING_CLK D7 -#define PIN_HEADING_DT D5 -#define PIN_HEADING_SW D6 +#include -#define PIN_ALTITUDE_CLK D1 -#define PIN_ALTITUDE_DT D2 -#define PIN_ALTITUDE_SW D3 +#define PIN_HEADING_WHITE PD3 +#define PIN_HEADING_RED PD6 -#define PIN_LED D4 +#define PIN_ALTITUDE_WHITE PD2 +#define PIN_ALTITUDE_RED PD5 #define VALUE_BUFFER 30 -#define HEADING_DT_TRIGGER 1 -#define HEADING_DT_HIGH 2 -#define HEADING_SW_TRIGGER 2 +#define SKIP_ROTARY_INPUTS 50 -#define ALTITUDE_DT_TRIGGER 4 -#define ALTITUDE_DT_HIGH 8 -#define ALTITUDE_SW_TRIGGER 8 +// needs global define +#define DATA_STOP_BYTE 0x00 +#define HEADING_TRIGGER_BIT 1 +#define HEADING_HIGH_BIT 2 +#define ALTITUDE_TRIGGER_BIT 4 +#define ALTITUDE_HIGH_BIT 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; +int lastClk = HIGH; // ringbuffer of trigger and direction values -uint8_t valueBuffer[VALUE_BUFFER] = { 0 }; +byte valueBuffer[VALUE_BUFFER] = { 0 }; uint8_t readerPos, writerPos = 0; -long lastInput = 0; +void addValue(uint8_t value) { + valueBuffer[writerPos++] = value; + if (writerPos >= VALUE_BUFFER) { + writerPos = 0; + } +} -// prevent bouncing input -bool useInput(long minInputDelay) { - long now = micros(); - long diff = now - lastInput; +void falling(uint8_t pin, byte triggerBit, byte highBit) { + uint8_t dt = digitalRead(pin); + byte value = triggerBit; - // < 0 because of long overruns - bool ret = diff < 0 || diff > minInputDelay; - if (ret) { - lastInput = now; + // read direction of pin + if (dt) { + value |= highBit; + } else { + // value is already "lowBit" } - 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" - } - + if (useInput(value)) { addValue(value); } } -void swFalling(uint8_t SW_TRIGGER) { - if (useInput(MIN_SW_INPUT_DELAY)) { - addValue(SW_TRIGGER); - } +void headingFalling() { + falling(PIN_HEADING_RED, HEADING_TRIGGER_BIT, HEADING_HIGH_BIT); } -void ICACHE_RAM_ATTR headingClkFalling(); -void headingClkFalling() { - clkFalling(PIN_HEADING_DT, HEADING_DT_TRIGGER, HEADING_DT_HIGH); +void altitudeFalling() { + falling(PIN_ALTITUDE_RED, ALTITUDE_TRIGGER_BIT, ALTITUDE_HIGH_BIT); } -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); +int eventCount = 0; +byte lastValue = 0; +bool useInput(byte value) { + if (lastValue == value) { + // same event as last event + // check if already SKIP_ROTARY_INPUTS happend + if (eventCount > SKIP_ROTARY_INPUTS) { + eventCount = 0; + return true; + } else { + eventCount++; + return false; + } } else { - Serial.println(-1); + // not same event as last event + // reset counter + lastValue = value; + eventCount = 0; + return false; + } +} + + +void i2cRequest() { + // if write is ahead, send data + if (writerPos != readerPos) { + byte value = valueBuffer[readerPos++]; + + if (readerPos >= VALUE_BUFFER) { + readerPos = 0; + } + + Wire.write(value); + } else { + Wire.write(DATA_STOP_BYTE); } } void setup() { Serial.begin(115200); - pinMode(PIN_HEADING_SW, INPUT_PULLUP); - pinMode(PIN_HEADING_DT, INPUT_PULLUP); - pinMode(PIN_HEADING_CLK, INPUT_PULLUP); + pinMode(PIN_HEADING_WHITE, INPUT_PULLUP); + pinMode(PIN_HEADING_RED, INPUT_PULLUP); + pinMode(PIN_ALTITUDE_WHITE, INPUT_PULLUP); + pinMode(PIN_ALTITUDE_RED, 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); + attachInterrupt(digitalPinToInterrupt(PIN_ALTITUDE_WHITE), altitudeFalling, FALLING); + attachInterrupt(digitalPinToInterrupt(PIN_HEADING_WHITE), headingFalling, FALLING); + + Wire.begin(0x01); + Wire.onRequest(i2cRequest); } 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... - } - } + delay(10000); }