2025-05-11 16:01:57 +02:00
|
|
|
#include <Wire.h>
|
2025-01-01 19:15:12 +01:00
|
|
|
|
2025-05-11 19:19:32 +02:00
|
|
|
#define PIN_HEADING_WHITE 3
|
|
|
|
#define PIN_HEADING_RED 5
|
2025-01-01 19:15:12 +01:00
|
|
|
|
2025-05-11 19:19:32 +02:00
|
|
|
#define PIN_ALTITUDE_WHITE 2
|
|
|
|
#define PIN_ALTITUDE_RED 4
|
2025-01-01 19:15:12 +01:00
|
|
|
|
|
|
|
#define VALUE_BUFFER 30
|
|
|
|
|
2025-05-11 16:01:57 +02:00
|
|
|
#define SKIP_ROTARY_INPUTS 50
|
2025-01-01 19:15:12 +01:00
|
|
|
|
2025-05-11 16:01:57 +02:00
|
|
|
// 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
|
2025-05-11 19:19:32 +02:00
|
|
|
#define PIN_ADDRESS_1 11
|
|
|
|
#define PIN_ADDRESS_2 12
|
|
|
|
#define PIN_ADDRESS_3 13
|
2025-01-01 19:15:12 +01:00
|
|
|
|
2025-05-11 16:01:57 +02:00
|
|
|
int lastClk = HIGH;
|
2025-01-01 19:15:12 +01:00
|
|
|
|
|
|
|
// ringbuffer of trigger and direction values
|
2025-05-11 16:01:57 +02:00
|
|
|
byte valueBuffer[VALUE_BUFFER] = { 0 };
|
2025-01-01 19:15:12 +01:00
|
|
|
uint8_t readerPos, writerPos = 0;
|
|
|
|
|
|
|
|
void addValue(uint8_t value) {
|
2025-05-11 16:01:57 +02:00
|
|
|
valueBuffer[writerPos++] = value;
|
|
|
|
if (writerPos >= VALUE_BUFFER) {
|
|
|
|
writerPos = 0;
|
|
|
|
}
|
2025-01-01 19:15:12 +01:00
|
|
|
}
|
|
|
|
|
2025-05-11 16:01:57 +02:00
|
|
|
void falling(uint8_t pin, byte triggerBit, byte highBit) {
|
|
|
|
uint8_t dt = digitalRead(pin);
|
|
|
|
byte value = triggerBit;
|
2025-01-01 19:15:12 +01:00
|
|
|
|
2025-05-11 16:01:57 +02:00
|
|
|
// read direction of pin
|
|
|
|
if (dt) {
|
|
|
|
value |= highBit;
|
|
|
|
} else {
|
|
|
|
// value is already "lowBit"
|
2025-01-01 19:15:12 +01:00
|
|
|
}
|
|
|
|
|
2025-05-11 16:01:57 +02:00
|
|
|
if (useInput(value)) {
|
|
|
|
addValue(value);
|
2025-01-01 19:15:12 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2025-05-11 16:01:57 +02:00
|
|
|
void headingFalling() {
|
|
|
|
falling(PIN_HEADING_RED, HEADING_TRIGGER_BIT, HEADING_HIGH_BIT);
|
2025-01-01 19:15:12 +01:00
|
|
|
}
|
|
|
|
|
2025-05-11 16:01:57 +02:00
|
|
|
void altitudeFalling() {
|
|
|
|
falling(PIN_ALTITUDE_RED, ALTITUDE_TRIGGER_BIT, ALTITUDE_HIGH_BIT);
|
2025-01-01 19:15:12 +01:00
|
|
|
}
|
|
|
|
|
2025-05-11 16:01:57 +02:00
|
|
|
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 {
|
|
|
|
// not same event as last event
|
|
|
|
// reset counter
|
|
|
|
lastValue = value;
|
|
|
|
eventCount = 0;
|
|
|
|
return false;
|
|
|
|
}
|
2025-01-01 19:15:12 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2025-05-11 16:01:57 +02:00
|
|
|
void i2cRequest() {
|
|
|
|
// if write is ahead, send data
|
|
|
|
if (writerPos != readerPos) {
|
|
|
|
byte value = valueBuffer[readerPos++];
|
|
|
|
|
|
|
|
if (readerPos >= VALUE_BUFFER) {
|
|
|
|
readerPos = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
Wire.write(value);
|
2025-01-01 19:15:12 +01:00
|
|
|
} else {
|
2025-05-11 16:01:57 +02:00
|
|
|
Wire.write(DATA_STOP_BYTE);
|
2025-01-01 19:15:12 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2025-05-11 19:19:32 +02:00
|
|
|
uint8_t address = 0;
|
2025-01-01 19:15:12 +01:00
|
|
|
void setup() {
|
|
|
|
Serial.begin(115200);
|
|
|
|
|
2025-05-11 19:19:32 +02:00
|
|
|
// setup rotator GPIOs
|
2025-05-11 16:01:57 +02:00
|
|
|
pinMode(PIN_HEADING_WHITE, INPUT_PULLUP);
|
|
|
|
pinMode(PIN_HEADING_RED, INPUT_PULLUP);
|
|
|
|
pinMode(PIN_ALTITUDE_WHITE, INPUT_PULLUP);
|
|
|
|
pinMode(PIN_ALTITUDE_RED, INPUT_PULLUP);
|
|
|
|
|
2025-05-11 19:19:32 +02:00
|
|
|
// setup address selector GPIOs
|
|
|
|
pinMode(PIN_ADDRESS_1, INPUT_PULLUP);
|
|
|
|
pinMode(PIN_ADDRESS_2, INPUT_PULLUP);
|
|
|
|
pinMode(PIN_ADDRESS_3, INPUT_PULLUP);
|
|
|
|
|
|
|
|
// calculate address by LOW GPIOs
|
|
|
|
address = digitalRead(PIN_ADDRESS_1) == LOW;
|
|
|
|
address |= (digitalRead(PIN_ADDRESS_2) == LOW) << 1;
|
|
|
|
address |= (digitalRead(PIN_ADDRESS_3) == LOW) << 2;
|
|
|
|
|
2025-05-11 16:01:57 +02:00
|
|
|
attachInterrupt(digitalPinToInterrupt(PIN_ALTITUDE_WHITE), altitudeFalling, FALLING);
|
|
|
|
attachInterrupt(digitalPinToInterrupt(PIN_HEADING_WHITE), headingFalling, FALLING);
|
2025-01-01 19:15:12 +01:00
|
|
|
|
2025-05-11 19:19:32 +02:00
|
|
|
Wire.begin(address);
|
2025-05-11 16:01:57 +02:00
|
|
|
Wire.onRequest(i2cRequest);
|
2025-01-01 19:15:12 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
void loop() {
|
2025-05-11 16:01:57 +02:00
|
|
|
delay(10000);
|
2025-01-01 19:15:12 +01:00
|
|
|
}
|