1 #ifndef DomeSensorRing_h
2 #define DomeSensorRing_h
8 #ifdef USE_DOME_SENSOR_DEBUG
9 #define DOME_SENSOR_PRINT(s) DEBUG_PRINT(s)
10 #define DOME_SENSOR_PRINTLN(s) DEBUG_PRINTLN(s)
11 #define DOME_SENSOR_PRINT_HEX(s) DEBUG_PRINT_HEX(s)
12 #define DOME_SENSOR_PRINTLN_HEX(s) DEBUG_PRINTLN_HEX(s)
14 #define DOME_SENSOR_PRINT(s)
15 #define DOME_SENSOR_PRINTLN(s)
16 #define DOME_SENSOR_PRINT_HEX(s)
17 #define DOME_SENSOR_PRINTLN_HEX(s)
20 #if defined(ARDUINO_ARCH_RP2040)
21 static constexpr uint8_t SENSORS[] {27, 28, 29, 3, 4, 6, 25, 24, 26};
23 #elif defined(ESP32) && defined(PIN_NEOPIXEL)
24 static constexpr uint8_t SENSORS[] {27, 25, 26, 13, 12, 14, 33, 4, 15};
26 static constexpr uint8_t SENSORS[] {18, 19, 21, 22, 32, 33, 25, 26, 27};
34 #if defined(ESP32) || defined(ARDUINO_ARCH_RP2040)
36 pinMode(SENSORS[i], INPUT_PULLUP);
37 #elif defined(DOME_CONTROLLER_BOARD)
39 for (uint8_t pin = A0; pin <= A8; pin++)
40 pinMode(pin, INPUT_PULLUP);
43 for (uint8_t pin = 2; pin <= 10; pin++)
44 pinMode(pin, INPUT_PULLUP);
50 #if defined(ARDUINO_ARCH_RP2040)
54 mask |= (digitalRead(SENSORS[i]) << i);
58 portDISABLE_INTERRUPTS();
60 mask |= (digitalRead(SENSORS[i]) << i);
61 portENABLE_INTERRUPTS();
62 #elif defined(DOME_CONTROLLER_BOARD)
79 ((pinK & (1<<0)) << 8)
81 #elif defined(DOME_SENSOR_RING_FULL_SIZE)
84 unsigned pinD { PIND };
85 unsigned pinB { PINB };
88 (((pinB >> 2) & 1) << 0) |
89 (((pinB >> 1) & 1) << 1) |
90 (((pinB >> 0) & 1) << 2) |
91 (((pinD >> 7) & 1) << 3) |
92 (((pinD >> 6) & 1) << 4) |
93 (((pinD >> 5) & 1) << 5) |
94 (((pinD >> 4) & 1) << 6) |
95 (((pinD >> 3) & 1) << 7) |
96 (((pinD >> 2) & 1) << 8)
101 unsigned pinD { PIND };
102 unsigned pinB { PINB };
104 unsigned mask {uint16_t(pinD >> 2) | uint16_t((pinB & 0b111) << 6)};
112 if (mask != fLastMask || fSampleCount < 6)
114 #ifdef USE_DOME_SENSOR_DEBUG
115 if (fSampleCount > 0 && fLastMask != ~0u && countChangedBits(mask, fLastMask) > 1)
126 auto currentAngle = getDomeAngle(mask);
127 if (currentAngle != -1)
129 fSamples.
append(currentAngle);
130 if (fSampleCount < 6)
133 fLastPosition = currentAngle;
139 fLastPosition = fSamples.
median();
142 #ifdef USE_DOME_SENSOR_DEBUG
143 if (fSampleCount > 0)
149 printBinary(mask, 9);
156 if (currentAngle == -1)
165 return fLastPosition;
170 return (fSampleCount > 1);
174 int fSampleCount = 0;
175 unsigned fLastMask = ~0;
176 short fLastPosition = -1;
179 #ifdef USE_DOME_SENSOR_DEBUG
180 static unsigned countChangedBits(
unsigned a,
unsigned b)
183 for (
unsigned i = 0; i < 9; i++)
185 if ((a & (1 << i)) != (b & (1 << i)))
191 static void printBinary(
unsigned num,
unsigned places)
194 printBinary(num >> 1, places-1);
199 static short getDomeAngle(
unsigned sensorMask)
201 static const short sDomeAngle[] PROGMEM = {
202 -1, 0, 40, 39, 80, 1, 79, 38, 120, 129, 41, 42, 119, 86, 78, 37, 160, 171, 169, 170, 81, 84, 82, 83,
203 159, 128, 126, 127, 118, 85, 77, 76, 200, 11, 211, 212, 209, 214, 210, 213, 121, 216, 124, 217, 122, 215, 123, 218,
204 199, 12, 168, -1, 166, -1, 167, -1, 158, -1, 125, -1, 117, -1, 116, 115, 240, 9, 51, 8, 251, 96, 252, -1,
205 249, -1, 254, -1, 250, 261, 253, 260, 161, 14, 256, -1, 164, -1, 257, -1, 162, -1, 255, -1, 163, -1, 258, 259,
206 239, 10, 52, -1, 208, -1, -1, -1, 206, 21, -1, -1, 207, 262, -1, -1, 198, 13, -1, -1, 165, 264, -1, 265,
207 157, 20, -1, -1, 156, 263, 155, 154, 280, 281, 49, 6, 91, 4, 48, 5, 291, 134, 136, 135, 292, -1, -1, -1,
208 289, 16, -1, 181, 294, -1, -1, -1, 290, -1, 301, 182, 293, 184, 300, 183, 201, 284, 54, -1, 296, -1, -1, 104,
209 204, -1, -1, 28, 297, 108, -1, 107, 202, 17, -1, -1, 295, 188, -1, 189, 203, -1, -1, 191, 298, 187, 299, 190,
210 279, 282, 50, 7, 92, 97, -1, -1, 248, -1, -1, -1, -1, -1, -1, -1, 246, 15, 61, 62, -1, 268, -1, 71,
211 247, -1, 302, -1, -1, 269, -1, 72, 238, 283, 53, -1, -1, -1, -1, 105, 205, -1, 304, 29, -1, 271, 305, 106,
212 197, 18, 60, -1, -1, 267, -1, 266, 196, 19, 303, 192, 195, 270, 194, 193, 320, 359, 321, 358, 89, 2, 46, 357,
213 131, 130, 44, 43, 88, 87, 45, 36, 331, 172, 174, 173, 176, 177, 175, 178, 332, -1, -1, -1, -1, -1, -1, 75,
214 329, 328, 56, -1, -1, -1, 221, 220, 334, -1, -1, -1, -1, -1, -1, 219, 330, -1, -1, -1, 341, -1, 222, -1,
215 333, -1, 224, 225, 340, -1, 223, 114, 241, 326, 324, 325, 94, 95, -1, -1, 336, 141, -1, -1, -1, 142, 144, 143,
216 244, -1, -1, 64, -1, 348, 68, 67, 337, -1, 148, 149, -1, 151, 147, 150, 242, 327, 57, -1, -1, -1, -1, -1,
217 335, 22, 228, 31, -1, -1, 229, 32, 243, -1, -1, 65, -1, 349, 231, 66, 338, -1, 227, 226, 339, 152, 230, 153,
218 319, 318, 322, 317, 90, 3, 47, 356, 132, 133, 137, 138, -1, -1, -1, 35, 288, -1, -1, 180, -1, -1, -1, 179,
219 -1, -1, -1, -1, -1, 185, -1, 74, 286, 285, 55, -1, 101, -1, 102, 103, -1, 24, 308, 27, -1, 109, 111, 110,
220 287, -1, -1, -1, 342, 351, -1, 352, -1, 25, 309, 26, -1, 186, 112, 113, 278, 277, 323, 316, 93, 98, -1, 355,
221 -1, 140, -1, 139, -1, -1, 145, 34, 245, -1, -1, 63, 344, 347, 69, 70, -1, -1, 311, 312, 345, 346, 146, 73,
222 237, 276, 58, 315, 100, 99, -1, 354, -1, 23, 307, 30, -1, 272, 306, 33, 236, 275, 59, 314, 343, 350, 232, 353,
223 235, 274, 310, 313, 234, 273, 233, -1
225 return pgm_read_word(&sDomeAngle[sensorMask & 0x1FF]);