scroll wheel is now done with a stochastic algorithm to make up for the inherent noise in the phototransistor
This commit is contained in:
parent
fc9cd621b1
commit
26bcddb623
|
@ -17,6 +17,9 @@
|
||||||
* 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
* 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#if defined(ARDUINO) && ARDUINO >= 100
|
||||||
|
#include "Arduino.h"
|
||||||
|
#endif
|
||||||
#include "Scroller.h"
|
#include "Scroller.h"
|
||||||
|
|
||||||
Scroller::Scroller(void) {
|
Scroller::Scroller(void) {
|
||||||
|
@ -25,15 +28,29 @@ Scroller::Scroller(void) {
|
||||||
hilof = false;
|
hilof = false;
|
||||||
lowA = 1023;
|
lowA = 1023;
|
||||||
highA = 0;
|
highA = 0;
|
||||||
|
cLowA = false;
|
||||||
|
cHighA = false;
|
||||||
|
lowIndexA = 0;
|
||||||
|
highIndexA = 0;
|
||||||
|
lowOverflowA = false;
|
||||||
|
highOverflowA = false;
|
||||||
lowB = 1023;
|
lowB = 1023;
|
||||||
highB = 0;
|
highB = 0;
|
||||||
|
cLowB = false;
|
||||||
|
cHighB = false;
|
||||||
|
lowIndexB = 0;
|
||||||
|
highIndexB = 0;
|
||||||
|
lowOverflowB = false;
|
||||||
|
highOverflowB = false;
|
||||||
scrollThresholdA = 0;
|
scrollThresholdA = 0;
|
||||||
scrollThresholdB = 0;
|
scrollThresholdB = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int Scroller::scroll(int curA, int curB) {
|
int Scroller::scroll(int curA, int curB) {
|
||||||
calculateThresholdA(curA);
|
if (lowOverflowA == false || highOverflowA == false)
|
||||||
calculateThresholdB(curB);
|
calculateThresholdA(curA);
|
||||||
|
if (lowOverflowB == false || highOverflowB == false)
|
||||||
|
calculateThresholdB(curB);
|
||||||
|
|
||||||
bool LO = false;
|
bool LO = false;
|
||||||
bool HI = true;
|
bool HI = true;
|
||||||
|
@ -109,36 +126,147 @@ int Scroller::scroll(int curA, int curB) {
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
int Scroller::getScrollThresholdA(void) {
|
|
||||||
return scrollThresholdA;
|
|
||||||
}
|
|
||||||
|
|
||||||
int Scroller::al(void) {
|
|
||||||
return lowA;
|
|
||||||
}
|
|
||||||
|
|
||||||
int Scroller::ah(void) {
|
|
||||||
return highA;
|
|
||||||
}
|
|
||||||
|
|
||||||
int Scroller::getScrollThresholdB(void) {
|
|
||||||
return scrollThresholdB;
|
|
||||||
}
|
|
||||||
|
|
||||||
int Scroller::calculateThresholdA(int curA) {
|
int Scroller::calculateThresholdA(int curA) {
|
||||||
if (curA < lowA)
|
scrollThresholdA = calculateThreshold(curA, lowA, highA,
|
||||||
lowA = curA;
|
cLowA, cHighA, arLowA, arHighA, lowIndexA, highIndexA,
|
||||||
else if (curA > highA)
|
lowOverflowA, highOverflowA);
|
||||||
highA = curA;
|
|
||||||
|
|
||||||
scrollThresholdA = ((highA - lowA) / 3) + lowA;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int Scroller::calculateThresholdB(int curB) {
|
int Scroller::calculateThresholdB(int curB) {
|
||||||
if (curB < lowB)
|
scrollThresholdB = calculateThreshold(curB, lowB, highB,
|
||||||
lowB = curB;
|
cLowB, cHighB, arLowB, arHighB, lowIndexB, highIndexB,
|
||||||
else if (curB > highB)
|
lowOverflowB, highOverflowB);
|
||||||
highB = curB;
|
}
|
||||||
|
|
||||||
scrollThresholdB = ((highB - lowB) / 3) + lowB;
|
int Scroller::calculateThreshold(int cur, int &low, int &high,
|
||||||
|
bool &cLow, bool &cHigh, int arLow[], int arHigh[],
|
||||||
|
int &lowIndex, int &highIndex, bool &lowOverflow,
|
||||||
|
bool &highOverflow) {
|
||||||
|
|
||||||
|
if (cur < low)
|
||||||
|
low = cur;
|
||||||
|
if (cur > high)
|
||||||
|
high = cur;
|
||||||
|
|
||||||
|
int curThresh = thresholdEquation(low, high);
|
||||||
|
int range = high - low;
|
||||||
|
|
||||||
|
// The range is enforced to be over a certain limit because noise
|
||||||
|
// can cause erroneous readings, making these calculations unstable.
|
||||||
|
if (range >= THRESH_RANGE_LIM) {
|
||||||
|
if (cur < curThresh) {
|
||||||
|
if (cHigh == true) {
|
||||||
|
// We were just high, and now we crossed to low.
|
||||||
|
// high reflects a sample of a high reading.
|
||||||
|
arHigh[highIndex] = high;
|
||||||
|
incrementIndex(highIndex, highOverflow);
|
||||||
|
int midpoint = ((high - low) / 2) + low;
|
||||||
|
low = midpoint;
|
||||||
|
high = midpoint;
|
||||||
|
cLow = false;
|
||||||
|
cHigh = false;
|
||||||
|
} else {
|
||||||
|
cLow = true;
|
||||||
|
}
|
||||||
|
} if (cur > curThresh) {
|
||||||
|
if (cLow == true) {
|
||||||
|
// We were just low, and now we crossed to high.
|
||||||
|
// low reflects a sample of a low reading.
|
||||||
|
arLow[lowIndex] = low;
|
||||||
|
incrementIndex(lowIndex, lowOverflow);
|
||||||
|
int midpoint = ((high - low) / 2) + low;
|
||||||
|
low = midpoint;
|
||||||
|
high = midpoint;
|
||||||
|
cLow = false;
|
||||||
|
cHigh = false;
|
||||||
|
} else {
|
||||||
|
cHigh = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int calcHigh = 0;
|
||||||
|
if (highOverflow == true) {
|
||||||
|
for (int i = 0; i < SCROLLER_AR_SIZE; i++) {
|
||||||
|
calcHigh += arHigh[i];
|
||||||
|
}
|
||||||
|
calcHigh = calcHigh / SCROLLER_AR_SIZE;
|
||||||
|
} else if (highIndex != 0) {
|
||||||
|
for (int i = 0; i < highIndex; i++) {
|
||||||
|
calcHigh += arHigh[i];
|
||||||
|
}
|
||||||
|
calcHigh = calcHigh / highIndex;
|
||||||
|
} else {
|
||||||
|
calcHigh = high;
|
||||||
|
}
|
||||||
|
|
||||||
|
int calcLow = 0;
|
||||||
|
if (lowOverflow == true) {
|
||||||
|
for (int i = 0; i < SCROLLER_AR_SIZE; i++) {
|
||||||
|
calcLow += arLow[i];
|
||||||
|
}
|
||||||
|
calcLow = calcLow / SCROLLER_AR_SIZE;
|
||||||
|
} else if (lowIndex != 0) {
|
||||||
|
for (int i = 0; i < lowIndex; i++) {
|
||||||
|
calcLow += arLow[i];
|
||||||
|
}
|
||||||
|
calcLow = calcLow / lowIndex;
|
||||||
|
} else {
|
||||||
|
calcLow = low;
|
||||||
|
}
|
||||||
|
|
||||||
|
return thresholdEquation(calcLow, calcHigh);
|
||||||
|
}
|
||||||
|
|
||||||
|
int Scroller::thresholdEquation(int lo, int hi) {
|
||||||
|
return ((hi - lo) / 3) + lo;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Scroller::incrementIndex(int &index, bool &ovflw) {
|
||||||
|
if (index < SCROLLER_AR_SIZE - 1)
|
||||||
|
index++;
|
||||||
|
else {
|
||||||
|
index = 0;
|
||||||
|
ovflw = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Scroller::debug(void) {
|
||||||
|
/*
|
||||||
|
Serial.print(F("lowA: "));
|
||||||
|
Serial.print(lowA);
|
||||||
|
Serial.print(F(", highA: "));
|
||||||
|
Serial.print(highA);
|
||||||
|
Serial.print(F(", cLowA: "));
|
||||||
|
Serial.print(cLowA ? "true" : "false");
|
||||||
|
Serial.print(F(", cHighA: "));
|
||||||
|
Serial.print(cHighA ? "true" : "false");
|
||||||
|
Serial.print(F(", lowIndexA: "));
|
||||||
|
Serial.print(lowIndexA);
|
||||||
|
Serial.print(F(", highIndexA: "));
|
||||||
|
Serial.print(highIndexA);
|
||||||
|
Serial.print(F(", lowOverflowA: "));
|
||||||
|
Serial.print(lowOverflowA ? "true" : "false");
|
||||||
|
Serial.print(F(", highOverflowA: "));
|
||||||
|
Serial.println(highOverflowA ? "true" : "false");
|
||||||
|
|
||||||
|
Serial.print(F("arLowA: "));
|
||||||
|
for (int i = 0; i < SCROLLER_AR_SIZE; i++) {
|
||||||
|
Serial.print(arLowA[i]);
|
||||||
|
Serial.print(F(","));
|
||||||
|
}
|
||||||
|
Serial.println(".");
|
||||||
|
|
||||||
|
Serial.print(F("arHighA: "));
|
||||||
|
for (int i = 0; i < SCROLLER_AR_SIZE; i++) {
|
||||||
|
Serial.print(arHighA[i]);
|
||||||
|
Serial.print(F(","));
|
||||||
|
}
|
||||||
|
Serial.println(".");
|
||||||
|
*/
|
||||||
|
|
||||||
|
Serial.print(F(", thB: "));
|
||||||
|
Serial.print(scrollThresholdB);
|
||||||
|
Serial.print(F(", thA: "));
|
||||||
|
Serial.print(scrollThresholdA);
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,30 +17,51 @@
|
||||||
* 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
* 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#ifndef SCROLLER_AR_SIZE
|
||||||
|
#define SCROLLER_AR_SIZE 40
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifndef SCROLLER_h
|
#ifndef SCROLLER_h
|
||||||
#define SCROLLER_h
|
#define SCROLLER_h
|
||||||
|
|
||||||
class Scroller {
|
class Scroller {
|
||||||
private:
|
private:
|
||||||
|
const int THRESH_RANGE_LIM = 10;
|
||||||
enum State { HIHI, HILO, LOLO, LOHI };
|
enum State { HIHI, HILO, LOLO, LOHI };
|
||||||
State state;
|
State state;
|
||||||
bool lohif;
|
bool lohif;
|
||||||
bool hilof;
|
bool hilof;
|
||||||
int lowA;
|
int lowA;
|
||||||
int highA;
|
int highA;
|
||||||
|
bool cLowA;
|
||||||
|
bool cHighA;
|
||||||
|
int lowIndexA;
|
||||||
|
int highIndexA;
|
||||||
|
bool lowOverflowA;
|
||||||
|
bool highOverflowA;
|
||||||
int lowB;
|
int lowB;
|
||||||
int highB;
|
int highB;
|
||||||
|
bool cLowB;
|
||||||
|
bool cHighB;
|
||||||
|
int lowIndexB;
|
||||||
|
int highIndexB;
|
||||||
|
bool lowOverflowB;
|
||||||
|
bool highOverflowB;
|
||||||
int scrollThresholdA;
|
int scrollThresholdA;
|
||||||
int scrollThresholdB;
|
int scrollThresholdB;
|
||||||
|
int arLowA[SCROLLER_AR_SIZE];
|
||||||
|
int arHighA[SCROLLER_AR_SIZE];
|
||||||
|
int arLowB[SCROLLER_AR_SIZE];
|
||||||
|
int arHighB[SCROLLER_AR_SIZE];
|
||||||
int calculateThresholdA(int);
|
int calculateThresholdA(int);
|
||||||
int calculateThresholdB(int);
|
int calculateThresholdB(int);
|
||||||
|
int calculateThreshold(int, int&, int&, bool&, bool&, int*, int*, int&, int&, bool&, bool&);
|
||||||
|
int thresholdEquation(int, int);
|
||||||
|
void incrementIndex(int&, bool&);
|
||||||
public:
|
public:
|
||||||
Scroller(void);
|
Scroller(void);
|
||||||
int scroll(int, int);
|
int scroll(int, int);
|
||||||
int getScrollThresholdA(void);
|
void debug(void);
|
||||||
int getScrollThresholdB(void);
|
|
||||||
int al(void);
|
|
||||||
int ah(void);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -393,15 +393,14 @@ signed char moveWheel() {
|
||||||
if (middleButtonPin == LOW) {
|
if (middleButtonPin == LOW) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
lastScroll = micros();
|
lastScroll = micros();
|
||||||
|
|
||||||
int d1 = analogRead(OPT_ENC_PIN1);
|
int d1 = analogRead(OPT_ENC_PIN1);
|
||||||
int d2 = analogRead(OPT_ENC_PIN2);
|
int d2 = analogRead(OPT_ENC_PIN2);
|
||||||
|
|
||||||
if (debugMode) {
|
if (debugMode) {
|
||||||
Serial.print(F("th: "));
|
scroller.debug();
|
||||||
Serial.print(scroller.getScrollThreshold());
|
|
||||||
Serial.print(F(", d1: "));
|
Serial.print(F(", d1: "));
|
||||||
Serial.print(d1);
|
Serial.print(d1);
|
||||||
Serial.print(F(", d2: "));
|
Serial.print(F(", d2: "));
|
||||||
|
|
Loading…
Reference in New Issue