Aktualisiert
This commit is contained in:
parent
6540b2f2f0
commit
f2a56d66a3
|
@ -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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -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();
|
||||||
|
};
|
||||||
|
|
|
@ -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();
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue