Files
HardwareAdapter/rotator/rotator.ino

141 lines
3.0 KiB
Arduino
Raw Normal View History

#include <Wire.h>
2025-01-01 19:15:12 +01:00
2025-05-11 19:31:07 +02:00
#define PIN_ROTATOR1_WHITE 2
#define PIN_ROTATOR1_GREEN 4
2025-01-01 19:15:12 +01:00
2025-05-11 19:31:07 +02:00
#define PIN_ROTATOR2_WHITE 3
#define PIN_ROTATOR2_GREEN 5
2025-01-01 19:15:12 +01:00
#define VALUE_BUFFER 30
#define SKIP_ROTARY_INPUTS 50
2025-01-01 19:15:12 +01:00
// needs global define
#define DATA_STOP_BYTE 0x00
#define DATA_RESET_BYTE 0xFF
2025-05-11 19:31:07 +02:00
#define ROTATOR1_TRIGGER_BIT 1
#define ROTATOR1_HIGH_BIT 2
#define ROTATOR2_TRIGGER_BIT 4
#define ROTATOR2_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
int lastClk = HIGH;
2025-01-01 19:15:12 +01:00
// ringbuffer of trigger and direction values
byte valueBuffer[VALUE_BUFFER] = { 0 };
2025-01-01 19:15:12 +01:00
uint8_t readerPos, writerPos = 0;
void addValue(uint8_t value) {
valueBuffer[writerPos++] = value;
if (writerPos >= VALUE_BUFFER) {
writerPos = 0;
}
2025-01-01 19:15:12 +01: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
// read direction of pin
if (dt) {
value |= highBit;
} else {
// value is already "lowBit"
2025-01-01 19:15:12 +01:00
}
if (useInput(value)) {
addValue(value);
2025-01-01 19:15:12 +01:00
}
}
2025-05-11 19:31:07 +02:00
void rotator1Falling() {
falling(PIN_ROTATOR1_GREEN, ROTATOR1_TRIGGER_BIT, ROTATOR1_HIGH_BIT);
2025-01-01 19:15:12 +01:00
}
2025-05-11 19:31:07 +02:00
void rotator2Falling() {
falling(PIN_ROTATOR2_GREEN, ROTATOR2_TRIGGER_BIT, ROTATOR2_HIGH_BIT);
2025-01-01 19:15:12 +01: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
}
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 {
Wire.write(DATA_STOP_BYTE);
2025-01-01 19:15:12 +01:00
}
}
void i2cReceive(int bytes) {
for (int i = 0; i < bytes && Wire.available(); i++) {
byte data = Wire.read();
if (data == DATA_RESET_BYTE) {
writerPos = readerPos = 0;
} else {
// nothing else yet implemented
}
}
}
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 19:31:07 +02:00
pinMode(PIN_ROTATOR1_WHITE, INPUT_PULLUP);
pinMode(PIN_ROTATOR1_GREEN, INPUT_PULLUP);
pinMode(PIN_ROTATOR2_WHITE, INPUT_PULLUP);
pinMode(PIN_ROTATOR2_GREEN, 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 19:31:07 +02:00
attachInterrupt(digitalPinToInterrupt(PIN_ROTATOR1_WHITE), rotator1Falling, FALLING);
attachInterrupt(digitalPinToInterrupt(PIN_ROTATOR2_WHITE), rotator2Falling, FALLING);
2025-01-01 19:15:12 +01:00
2025-05-11 19:19:32 +02:00
Wire.begin(address);
Wire.onRequest(i2cRequest);
Wire.onReceive(i2cReceive);
2025-01-01 19:15:12 +01:00
}
void loop() {
delay(10000);
2025-01-01 19:15:12 +01:00
}