summaryrefslogtreecommitdiff
path: root/src/rotaryencoder.cpp
diff options
context:
space:
mode:
authorNikita Kostovsky <nikita@kostovsky.me>2025-02-21 07:27:00 +0100
committerNikita Kostovsky <nikita@kostovsky.me>2025-02-21 07:27:00 +0100
commitd12498504c279a0a85bbfb024f7903e34dbe07db (patch)
tree0df9f3f8bf27470ac211a57bb8e44be0aa2f6138 /src/rotaryencoder.cpp
parent27637ab117d8738236f6ab155300ff6e79e4843b (diff)
broken img calc; change dir struct
Diffstat (limited to 'src/rotaryencoder.cpp')
-rw-r--r--src/rotaryencoder.cpp125
1 files changed, 125 insertions, 0 deletions
diff --git a/src/rotaryencoder.cpp b/src/rotaryencoder.cpp
new file mode 100644
index 0000000..62ca33d
--- /dev/null
+++ b/src/rotaryencoder.cpp
@@ -0,0 +1,125 @@
+#include "rotaryencoder.h"
+
+#include <cstdint>
+#include <cstdio>
+#include <cstdlib>
+#include <vector>
+
+#include <QDebug>
+#include <QElapsedTimer>
+
+#include <wiringPi.h>
+
+// got from https://gist.github.com/ast/a19813fce9d34c7240091db11b8190dd
+// https://gist.github.com/ast
+// Inspired by Paul Stoffregen's excellent Arduino library Encoder:
+// https://github.com/PaulStoffregen/Encoder
+
+constexpr int gpioA = 17;
+constexpr int gpioB = 27;
+// constexpr int gpioA = 0;
+// constexpr int gpioB = 2;
+// constexpr int gpioA = 11;
+// constexpr int gpioB = 13;
+
+const std::vector<int> encoderTable = {
+ 0, 1, -1, 0, -1, 0, 0, 1, 1, 0, 0, -1, 0, -1, 1, 0
+};
+
+volatile int32_t positionSteps;
+volatile uint8_t state;
+
+void pin_isr(void) {
+ uint8_t p1val = digitalRead(gpioA);
+ uint8_t p2val = digitalRead(gpioB);
+ uint8_t s = state & 3;
+
+ if (p1val) s |= 4;
+ if (p2val) s |= 8;
+
+ state = (s >> 2);
+
+ switch (s) {
+ case 1: case 7: case 8: case 14:
+ positionSteps = positionSteps + 1;
+ return;
+ case 2: case 4: case 11: case 13:
+ positionSteps = positionSteps - 1;
+ return;
+ case 3: case 12:
+ positionSteps = positionSteps + 2;
+ return;
+ case 6: case 9:
+ positionSteps = positionSteps - 2;
+ return;
+ }
+}
+
+RotaryEncoder::RotaryEncoder()
+{
+ if (!m_self) {
+ m_self = this;
+ } else {
+ qWarning() << "normally there should be only one instance of RotaryEncoder";
+ }
+
+ QElapsedTimer t;
+ t.start();
+
+ if (wiringPiSetupGpio()) {
+ perror("wiringPiSetupGpio");
+ exit(EXIT_FAILURE);
+ }
+
+ qDebug() << "msecs to setup wiringPi:" << t.elapsed();
+
+ if ( wiringPiISR (gpioA, INT_EDGE_BOTH, &pin_isr) < 0 ) {
+ perror("wiringPiISR");
+ exit(EXIT_FAILURE);
+ }
+
+ qDebug() << "msecs to register interruption A:" << t.elapsed();
+
+ if ( wiringPiISR (gpioB, INT_EDGE_BOTH, &pin_isr) < 0 ) {
+ perror("wiringPiISR");
+ exit(EXIT_FAILURE);
+ }
+
+ qDebug() << "msecs to register interruption B:" << t.elapsed();
+
+ // pinMode (gpioA, INPUT) ;
+ // pinMode (gpioB, INPUT) ;
+ // pullUpDnControl(gpioA, PUD_UP);
+ // pullUpDnControl(gpioB, PUD_UP);
+
+ qDebug() << "encoder is ok";
+
+ // // Show position every second
+ // while ( 1 ) {
+ // constexpr double stepsPerMm = 200;
+ // const double positionMm = ::positionSteps / stepsPerMm;
+ // qDebug() << ::positionSteps
+ // << '-'
+ // << QString::number(positionMm, 'f', 3)
+ // << "(mm)";
+ // // printf( "%ld\n", ::position);
+ // usleep( 100 * 1000 ); // wait 1 second
+ // }
+}
+
+RotaryEncoder::~RotaryEncoder()
+{
+ if (m_self == this) {
+ m_self = nullptr;
+ }
+}
+
+RotaryEncoder *RotaryEncoder::instance()
+{
+ return m_self;
+}
+
+int32_t RotaryEncoder::position() const
+{
+ return ::positionSteps;
+}