Skip to content

Commit

Permalink
Rotary encoder driver.
Browse files Browse the repository at this point in the history
  • Loading branch information
prampec committed Oct 26, 2015
1 parent 6523dbf commit 450c712
Show file tree
Hide file tree
Showing 5 changed files with 203 additions and 1 deletion.
34 changes: 34 additions & 0 deletions examples/SoftTimer6Rotary/SoftTimer6Rotary.ino
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
#include <PciManager.h>
#include <Debouncer.h>
#include <Rotary.h>

#define ROT_PIN_A A4
#define ROT_PIN_B A5
#define ROT_PUSH A3

Rotary r(ROT_PIN_A, ROT_PIN_B, onRotate, true);
Debouncer rotPushDebouncer(ROT_PUSH, MODE_CLOSE_ON_PUSH, onRotPushPress, onRotPushRelease, true);

void setup() {
Serial.begin(9600);
PciManager.registerListener(ROT_PUSH, &rotPushDebouncer);

Serial.println("Ready.");
}

void onRotate(short direction, Rotary* rotary) {
if(direction == DIRECTION_CW) {
Serial.println("cw");
}
if(direction == DIRECTION_CCW) {
Serial.println("ccw");
}
}

void onRotPushPress() {
Serial.println("pushed");
}
void onRotPushRelease(unsigned long pressTime) {
Serial.println("released");
}

3 changes: 3 additions & 0 deletions keywords.txt
Original file line number Diff line number Diff line change
Expand Up @@ -35,3 +35,6 @@ getUpperLimit KEYWORD2

FrequencyTask KEYWORD1
setFrequency KEYWORD2

Rotary KEYWORD1
pciHandleChange KEYWORD2
2 changes: 1 addition & 1 deletion library.properties
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
name=SoftTimer
version=3.0.0
version=3.1.0
author=Balazs Kelemen <[email protected]>
maintainer=Balazs Kelemen <[email protected]>
sentence=SoftTimer is a lightweight pseudo multitasking solution for Arduino.
Expand Down
94 changes: 94 additions & 0 deletions src/Rotary.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
/**
* File: Rotary.cpp
* Description:
* SoftTimer library is a lightweight but effective event based timeshare solution for Arduino.
*
* Author: Balazs Kelemen
* Contact: [email protected]
* Copyright: 2015 Balazs Kelemen
* Copying permission statement:
This file is part of SoftTimer.
SoftTimer is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/

#include "Arduino.h"
#include "Rotary.h"
#include <Task.h>
#include <PciManager.h>

#define IDDLE_TIME_MICROS -1L

#define EVENT_NOTIFIED 0
#define EVENT_OCCURRED 1
#define EVENT_CLEARED 2


Rotary::Rotary(int pinA, int pinB, void (*onRotation)(short direction, Rotary* rotary), bool pullUp)
: Task(IDDLE_TIME_MICROS, &(Rotary::step)) {
this->_listenerA.init(pinA, this, pullUp);
this->_listenerB.init(pinB, this, pullUp);
this->_stateCW = EVENT_NOTIFIED;
this->_stateCCW = EVENT_NOTIFIED;
this->_onRotation = onRotation;

PciManager.registerListener(pinA, &this->_listenerA);
PciManager.registerListener(pinB, &this->_listenerB);

SoftTimer.add(this);
}

void Rotary::pciHandleChange(byte changedTo, PciListenerImp2* listener) {
if(listener == &this->_listenerB) {
// -- pinB changes
if((changedTo == HIGH) && (this->_listenerA.lastVal == LOW)) {
if(this->_stateCW == EVENT_CLEARED) {
this->_stateCW = EVENT_OCCURRED;
this->periodMicros = 0;
}
}
else if((changedTo == LOW) && (this->_listenerA.lastVal == HIGH)) {
this->_stateCW = EVENT_CLEARED;
}
}
if(listener == &this->_listenerA) {
// -- pinA changes
if((changedTo == HIGH) && (this->_listenerB.lastVal == LOW)) {
if(this->_stateCCW == EVENT_CLEARED) {
this->_stateCCW = EVENT_OCCURRED;
this->periodMicros = 0;
}
}
else if((changedTo == LOW) && (this->_listenerB.lastVal == HIGH)) {
this->_stateCCW = EVENT_CLEARED;
}
}
}


void Rotary::step(Task* task) {
Rotary* me = (Rotary*)task;

if(me->_stateCW == EVENT_OCCURRED) {
me->_onRotation(DIRECTION_CW, me);
me->_stateCW = EVENT_NOTIFIED;
}
if(me->_stateCCW == EVENT_OCCURRED) {
me->_onRotation(DIRECTION_CCW, me);
me->_stateCCW = EVENT_NOTIFIED;
}
me->periodMicros = IDDLE_TIME_MICROS;
}

71 changes: 71 additions & 0 deletions src/Rotary.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
/**
* File: Rotary.h
* Description:
* SoftTimer library is a lightweight but effective event based timeshare solution for Arduino.
*
* Author: Balazs Kelemen
* Contact: [email protected]
* Copyright: 2012 Balazs Kelemen
* Copying permission statement:
This file is part of SoftTimer.
SoftTimer is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/

#ifndef ROTARY_H
#define ROTARY_H

#include <SoftTimer.h>
#include <PciListener.h>
#include <Arduino.h>
#include <PciListenerImp2.h>
#include <IPciChangeHandler.h>

#define DIRECTION_CW 1
#define DIRECTION_CCW -1

class Rotary : public Task, public IPciChangeHandler
{
public:
/**
* Create a debouncing task with the following parameters.
* pin - Checking pin for input.
* pushMode - CLOSE_ON_PUSH / OPEN_ON_PUSH - Your button are normally wired to be NO (Normally Openned), so USE CLOSE_ON_PUSH.
* But sometimes it is NC (Normally Closed), in this case use OPEN_ON_PUSH.
* onPressed() - A callback function pointer. This function is called when the bouncing button is really pushed. (Optional,
* pass NULL, if you do not want to use this feature.)
* onReleased(pressTimespan) - A callback function pointer. This function is called when the bouncing button is really
* released. (Optional, pass NULL, if you do not want to use this feature.)
* The callback receives the pressTimespan parameter that is the time in milliseconds the button was hold down before
* it was released.
*/
Rotary(int pinA, int pinB, void (*onRotation)(short direction, Rotary* rotary), bool pullUp=false);

/**
* Please call this function on interrupt.
*/
virtual void pciHandleChange(byte changedTo, PciListenerImp2* listener);

private:
PciListenerImp2 _listenerA = PciListenerImp2();
PciListenerImp2 _listenerB = PciListenerImp2();
volatile int _stateCW;
volatile int _stateCCW;
void (*_onRotation)(short direction, Rotary* rotary);
static void step(Task* me);
};

#endif

0 comments on commit 450c712

Please sign in to comment.