Skip to content

Commit 450c712

Browse files
committed
Rotary encoder driver.
1 parent 6523dbf commit 450c712

File tree

5 files changed

+203
-1
lines changed

5 files changed

+203
-1
lines changed
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
#include <PciManager.h>
2+
#include <Debouncer.h>
3+
#include <Rotary.h>
4+
5+
#define ROT_PIN_A A4
6+
#define ROT_PIN_B A5
7+
#define ROT_PUSH A3
8+
9+
Rotary r(ROT_PIN_A, ROT_PIN_B, onRotate, true);
10+
Debouncer rotPushDebouncer(ROT_PUSH, MODE_CLOSE_ON_PUSH, onRotPushPress, onRotPushRelease, true);
11+
12+
void setup() {
13+
Serial.begin(9600);
14+
PciManager.registerListener(ROT_PUSH, &rotPushDebouncer);
15+
16+
Serial.println("Ready.");
17+
}
18+
19+
void onRotate(short direction, Rotary* rotary) {
20+
if(direction == DIRECTION_CW) {
21+
Serial.println("cw");
22+
}
23+
if(direction == DIRECTION_CCW) {
24+
Serial.println("ccw");
25+
}
26+
}
27+
28+
void onRotPushPress() {
29+
Serial.println("pushed");
30+
}
31+
void onRotPushRelease(unsigned long pressTime) {
32+
Serial.println("released");
33+
}
34+

keywords.txt

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,3 +35,6 @@ getUpperLimit KEYWORD2
3535

3636
FrequencyTask KEYWORD1
3737
setFrequency KEYWORD2
38+
39+
Rotary KEYWORD1
40+
pciHandleChange KEYWORD2

library.properties

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
name=SoftTimer
2-
version=3.0.0
2+
version=3.1.0
33
author=Balazs Kelemen <prampec+arduino@gmail.com>
44
maintainer=Balazs Kelemen <prampec+arduino@gmail.com>
55
sentence=SoftTimer is a lightweight pseudo multitasking solution for Arduino.

src/Rotary.cpp

Lines changed: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,94 @@
1+
/**
2+
* File: Rotary.cpp
3+
* Description:
4+
* SoftTimer library is a lightweight but effective event based timeshare solution for Arduino.
5+
*
6+
* Author: Balazs Kelemen
7+
* Contact: prampec+arduino@gmail.com
8+
* Copyright: 2015 Balazs Kelemen
9+
* Copying permission statement:
10+
This file is part of SoftTimer.
11+
12+
SoftTimer is free software: you can redistribute it and/or modify
13+
it under the terms of the GNU General Public License as published by
14+
the Free Software Foundation, either version 3 of the License, or
15+
(at your option) any later version.
16+
17+
This program is distributed in the hope that it will be useful,
18+
but WITHOUT ANY WARRANTY; without even the implied warranty of
19+
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20+
GNU General Public License for more details.
21+
22+
You should have received a copy of the GNU General Public License
23+
along with this program. If not, see <http://www.gnu.org/licenses/>.
24+
25+
*/
26+
27+
#include "Arduino.h"
28+
#include "Rotary.h"
29+
#include <Task.h>
30+
#include <PciManager.h>
31+
32+
#define IDDLE_TIME_MICROS -1L
33+
34+
#define EVENT_NOTIFIED 0
35+
#define EVENT_OCCURRED 1
36+
#define EVENT_CLEARED 2
37+
38+
39+
Rotary::Rotary(int pinA, int pinB, void (*onRotation)(short direction, Rotary* rotary), bool pullUp)
40+
: Task(IDDLE_TIME_MICROS, &(Rotary::step)) {
41+
this->_listenerA.init(pinA, this, pullUp);
42+
this->_listenerB.init(pinB, this, pullUp);
43+
this->_stateCW = EVENT_NOTIFIED;
44+
this->_stateCCW = EVENT_NOTIFIED;
45+
this->_onRotation = onRotation;
46+
47+
PciManager.registerListener(pinA, &this->_listenerA);
48+
PciManager.registerListener(pinB, &this->_listenerB);
49+
50+
SoftTimer.add(this);
51+
}
52+
53+
void Rotary::pciHandleChange(byte changedTo, PciListenerImp2* listener) {
54+
if(listener == &this->_listenerB) {
55+
// -- pinB changes
56+
if((changedTo == HIGH) && (this->_listenerA.lastVal == LOW)) {
57+
if(this->_stateCW == EVENT_CLEARED) {
58+
this->_stateCW = EVENT_OCCURRED;
59+
this->periodMicros = 0;
60+
}
61+
}
62+
else if((changedTo == LOW) && (this->_listenerA.lastVal == HIGH)) {
63+
this->_stateCW = EVENT_CLEARED;
64+
}
65+
}
66+
if(listener == &this->_listenerA) {
67+
// -- pinA changes
68+
if((changedTo == HIGH) && (this->_listenerB.lastVal == LOW)) {
69+
if(this->_stateCCW == EVENT_CLEARED) {
70+
this->_stateCCW = EVENT_OCCURRED;
71+
this->periodMicros = 0;
72+
}
73+
}
74+
else if((changedTo == LOW) && (this->_listenerB.lastVal == HIGH)) {
75+
this->_stateCCW = EVENT_CLEARED;
76+
}
77+
}
78+
}
79+
80+
81+
void Rotary::step(Task* task) {
82+
Rotary* me = (Rotary*)task;
83+
84+
if(me->_stateCW == EVENT_OCCURRED) {
85+
me->_onRotation(DIRECTION_CW, me);
86+
me->_stateCW = EVENT_NOTIFIED;
87+
}
88+
if(me->_stateCCW == EVENT_OCCURRED) {
89+
me->_onRotation(DIRECTION_CCW, me);
90+
me->_stateCCW = EVENT_NOTIFIED;
91+
}
92+
me->periodMicros = IDDLE_TIME_MICROS;
93+
}
94+

src/Rotary.h

Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
/**
2+
* File: Rotary.h
3+
* Description:
4+
* SoftTimer library is a lightweight but effective event based timeshare solution for Arduino.
5+
*
6+
* Author: Balazs Kelemen
7+
* Contact: prampec+arduino@gmail.com
8+
* Copyright: 2012 Balazs Kelemen
9+
* Copying permission statement:
10+
This file is part of SoftTimer.
11+
12+
SoftTimer is free software: you can redistribute it and/or modify
13+
it under the terms of the GNU General Public License as published by
14+
the Free Software Foundation, either version 3 of the License, or
15+
(at your option) any later version.
16+
17+
This program is distributed in the hope that it will be useful,
18+
but WITHOUT ANY WARRANTY; without even the implied warranty of
19+
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20+
GNU General Public License for more details.
21+
22+
You should have received a copy of the GNU General Public License
23+
along with this program. If not, see <http://www.gnu.org/licenses/>.
24+
25+
*/
26+
27+
#ifndef ROTARY_H
28+
#define ROTARY_H
29+
30+
#include <SoftTimer.h>
31+
#include <PciListener.h>
32+
#include <Arduino.h>
33+
#include <PciListenerImp2.h>
34+
#include <IPciChangeHandler.h>
35+
36+
#define DIRECTION_CW 1
37+
#define DIRECTION_CCW -1
38+
39+
class Rotary : public Task, public IPciChangeHandler
40+
{
41+
public:
42+
/**
43+
* Create a debouncing task with the following parameters.
44+
* pin - Checking pin for input.
45+
* pushMode - CLOSE_ON_PUSH / OPEN_ON_PUSH - Your button are normally wired to be NO (Normally Openned), so USE CLOSE_ON_PUSH.
46+
* But sometimes it is NC (Normally Closed), in this case use OPEN_ON_PUSH.
47+
* onPressed() - A callback function pointer. This function is called when the bouncing button is really pushed. (Optional,
48+
* pass NULL, if you do not want to use this feature.)
49+
* onReleased(pressTimespan) - A callback function pointer. This function is called when the bouncing button is really
50+
* released. (Optional, pass NULL, if you do not want to use this feature.)
51+
* The callback receives the pressTimespan parameter that is the time in milliseconds the button was hold down before
52+
* it was released.
53+
*/
54+
Rotary(int pinA, int pinB, void (*onRotation)(short direction, Rotary* rotary), bool pullUp=false);
55+
56+
/**
57+
* Please call this function on interrupt.
58+
*/
59+
virtual void pciHandleChange(byte changedTo, PciListenerImp2* listener);
60+
61+
private:
62+
PciListenerImp2 _listenerA = PciListenerImp2();
63+
PciListenerImp2 _listenerB = PciListenerImp2();
64+
volatile int _stateCW;
65+
volatile int _stateCCW;
66+
void (*_onRotation)(short direction, Rotary* rotary);
67+
static void step(Task* me);
68+
};
69+
70+
#endif
71+

0 commit comments

Comments
 (0)