Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit c6422c5

Browse files
committed
Add Pin-Change-Interrupt-Encoders example
1 parent 8de75b8 commit c6422c5

File tree

1 file changed

+76
-0
lines changed

1 file changed

+76
-0
lines changed
Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
/**
2+
* This example reads multiple encoders using pin change interrupts, on an
3+
* Arduino Uno or Nano.
4+
*
5+
* @boards AVR
6+
*
7+
* The ATmega328P microcontroller only has two interrupt pins (2 and 3), so if
8+
* you want to use more than two interrupt-driven encoders, you'll either have
9+
* to use a timer interrupt to continuously poll the encoders, or use the chip's
10+
* pin change interrupts. This example demonstrates the latter.
11+
*
12+
* Connections
13+
* -----------
14+
*
15+
* Connect three encoders to the pins of port C as follows:
16+
*
17+
* - A0: pin A of encoder #0
18+
* - A1: pin B of encoder #0
19+
* - A2: pin A of encoder #1
20+
* - A3: pin B of encoder #1
21+
* - A4: pin A of encoder #2
22+
* - A5: pin B of encoder #2
23+
*
24+
* Connect the common pins to ground, the internal pull-up resistors will be
25+
* enabled.
26+
*
27+
* Behavior
28+
* --------
29+
*
30+
* When the position of one of the encoders changes, it is printed to the Serial
31+
* monitor.
32+
*
33+
* Written by PieterP, 2021-08-11
34+
* https://github.com/tttapa/Arduino-Helpers
35+
*/
36+
37+
#include <Arduino_Helpers.h>
38+
#include <AH/Hardware/RegisterEncoders.hpp>
39+
40+
// The number of encoders to read:
41+
constexpr uint8_t num_enc = 3;
42+
// Mask the bottom 6 bits of the GPIO registers (2 pins × 3 encoders).
43+
// This determines which pins are used:
44+
const uint8_t pin_mask = 0x3F;
45+
// The actual encoder object that keeps track of the encoder state:
46+
RegisterEncoders<uint8_t, num_enc, int32_t, true> encoders;
47+
// AVR uses 8-bit GPIO registers, so the register type is uint8_t.
48+
// Then we specify the number of encoders, the position type,
49+
// and whether the encoders should be interrupt-safe: since we'll
50+
// be calling `encoders.update()` in an interrupt handler, it is
51+
// important that this is set to true.
52+
53+
// Pin change interrupt handler that reads the pins and updates the state:
54+
ISR (PCINT1_vect) { encoders.update(PINC & pin_mask); } // read port C
55+
56+
void setup() {
57+
PCMSK1 |= pin_mask; // enable pin change interrupt for given pins in port C
58+
DDRC &= ~pin_mask; // input mode for port C
59+
PORTC |= pin_mask; // enable pull-up resistors for port C
60+
PCICR |= 1 << 1; // enable pin change interrupt for port C
61+
Serial.begin(115200);
62+
}
63+
64+
void loop() {
65+
// The previous position of each encoder, to detect changes:
66+
static int32_t prevPos[num_enc] {};
67+
68+
// Read the encoder positions and print if they changed:
69+
for (uint8_t i = 0; i < num_enc; ++i) {
70+
int32_t newPos = encoders[i].read();
71+
if (newPos != prevPos[i]) {
72+
Serial << '[' << i << "] " << newPos << endl;
73+
prevPos[i] = newPos;
74+
}
75+
}
76+
}

0 commit comments

Comments
 (0)