Aktualisiert

This commit is contained in:
starcalc 2018-04-26 23:10:18 +02:00
parent 6540b2f2f0
commit f2a56d66a3
3 changed files with 183 additions and 4 deletions

View File

@ -0,0 +1,108 @@
#include "RotaryDialer.h"
#if defined(ARDUINO) && ARDUINO >= 100
#include "Arduino.h"
#else
#include "WProgram.h"
#endif
#define NO_NUMBER -1
// Require DEBOUNCE_DELAY milliseconds between state changes. This value is
// noted in the class documentation.
#define DEBOUNCE_DELAY 15
RotaryDialer::RotaryDialer(int readyPin, int pulsePin) :
pinReady(readyPin), pinPulse(pulsePin), hasCompletedNumber(false),
state(WAITING)
{ }
void RotaryDialer::setup() {
pinMode(pinReady, INPUT);
pinMode(pinPulse, INPUT);
digitalWrite(pinReady, HIGH);
digitalWrite(pinPulse, HIGH);
lastStateChangeMillis = millis();
}
bool RotaryDialer::changeStateIfDebounced(enum State newState) {
unsigned long currentMillis = millis();
if (currentMillis < lastStateChangeMillis) {
// clock wrapped; ignore (but could figure it out in this case)
lastStateChangeMillis = currentMillis;
return false;
} else if (currentMillis - lastStateChangeMillis > DEBOUNCE_DELAY) {
state = newState;
lastStateChangeMillis = currentMillis;
return true;
} else {
return false;
}
}
void RotaryDialer::completeDial() {
if (!changeStateIfDebounced(WAITING)) {
return;
}
if (number > 0 && number <= 10) {
if (number == 10) {
number = 0;
}
hasCompletedNumber = true;
}
}
bool RotaryDialer::update() {
int readyStatus = digitalRead(pinReady);
int pulseStatus = digitalRead(pinPulse);
if ((readyStatus == 0) && (pulseStatus==1))
{
//Serial.print("Ready: ");
//Serial.print(readyStatus);
//Serial.print(" Pulse: ");
//Serial.print(pulseStatus);
//Serial.print(" State: ");
//Serial.println(state);
}
switch(state) {
case WAITING:
if (readyStatus == LOW
&& changeStateIfDebounced(LISTENING_NOPULSE))
{
hasCompletedNumber = false;
number = 0;
}
break;
case LISTENING_NOPULSE:
if (readyStatus == HIGH) {
completeDial();
} else if (pulseStatus == HIGH) {
changeStateIfDebounced(LISTENING_PULSE);
}
break;
case LISTENING_PULSE:
if (readyStatus == HIGH) {
completeDial();
} else if (pulseStatus == LOW
&& changeStateIfDebounced(LISTENING_NOPULSE))
{
number++;
}
break;
}
return hasCompletedNumber;
}
bool RotaryDialer::hasNextNumber() {
return hasCompletedNumber;
}
int RotaryDialer::getNextNumber() {
if (hasCompletedNumber) {
hasCompletedNumber = false;
return number;
} else {
return NO_NUMBER;
}
}

View File

@ -0,0 +1,71 @@
#pragma once
/**
* Read numbers from a rotary dial (or otherwise using pulse dialing; see
* http://en.wikipedia.org/wiki/Rotary_dial ).
*
* See the README for further documentation.
*/
class RotaryDialer {
private:
int pinReady;
int pinPulse;
bool hasCompletedNumber;
int number;
enum State {
WAITING,
LISTENING_NOPULSE,
LISTENING_PULSE
};
enum State state;
unsigned long lastStateChangeMillis;
/**
* Change state, but only if enough time has elapsed since
* the last state change (to protect from noise).
*/
bool changeStateIfDebounced(enum State newState);
/**
* To be called when ready returns HIGH (when the rotor returns
* to its rest position); save the number, if valid.
*/
void completeDial();
public:
/**
* Create a new RotaryDialer listening on the given pins.
* @param readyPin connected to a NO (HIGH) switch on the rotor
* which is closed (LOW) during dialing
* @param pulsePin connected to a NC (LOW) switch on the rotor
* which is opened (HIGH) during each pulse
*/
RotaryDialer(int readyPin, int pulsePin);
/**
* Initialize the pins; digital read pins, held HIGH.
*/
void setup();
/**
* Check the pins and update state (in or out of a pulse,
* dialing complete, etc). This must be called at least as
* pulses; assuming 10 pulses per second, every 50ms.
*/
bool update();
/**
* @return whether a new number has been dialed since the last
* getNextNumber call
*/
bool hasNextNumber();
/**
* Get the most recently dialed number. After this is called,
* hasNextNumber will return false until a new number is dialed.
* @return the most recently dialed number, and clear
* hasNextNumber
*/
int getNextNumber();
};

View File

@ -3,15 +3,15 @@
* See the README for detailed documentation. * See the README for detailed documentation.
*/ */
#include <RotaryDialer.h> #include "RotaryDialer.h"
#define PIN_READY 8 #define PIN_READY D6
#define PIN_PULSE 9 #define PIN_PULSE D5
RotaryDialer dialer = RotaryDialer(PIN_READY, PIN_PULSE); RotaryDialer dialer = RotaryDialer(PIN_READY, PIN_PULSE);
void setup() { void setup() {
Serial.begin(28800); Serial.begin(115200);
dialer.setup(); dialer.setup();
} }