kneeAngleDataLogger.ino
#include <arduino-timer.h>
int pinA = 4; // Pin for Encoder Channel A.
int pinB = 2; // Pin for Encoder Channel B.
bool oldA; // Old Encoder Channel A signal.
bool oldB; // Old Encoder Channel B signal.
bool newA; // New Encoder Channel A signal.
bool newB; // New Encoder Channel B signal.
float numDegrees = 0; // Current knee angle (relative — incremental encoder) (0.5° resolution).
// strDegrees = "±XXX.X\n"
char strDegrees[7]; // charsPerMessage = 7
int bitsPerSecond = 9600; // Default baud (data transfer) rate.
// Reliable over Bluetooth.
\(\small \; \vdots\)
\(\small \: \bullet \quad \quad \text{bits per second} = 9\,600\)
\(\small \: \bullet \quad \quad \text{start bits per character} = 1\)
\(\small \: \bullet \quad \quad \; \! \text{data bits per character} = 8\)
\(\small \: \bullet \quad \quad \: \text{stop bits per character} = 1\)
\(\small \: \bullet \quad \quad \text{bits per character} = ( \text{start bits} + \text{data bits} + \text{stop bits} ) \ \text{per character} = 10\)
\(\small \: \bullet \quad \quad \text{seconds per character ($\,T_\textsf{character}$)} = \text{bits per character} \: / \: \text{bits per second} \approx 0.001\,04\)
\(\small \: \bullet \quad \quad \text{characters per message} = 7\)
\(\small \: \bullet \quad \quad \text{seconds per message ($\,T_\textsf{message}$)} = \text{seconds per character} \, \cdot \: \text{characters per message} \approx 0.007\,3\)
\(\small \: \bullet \quad \quad \text{milliseconds per message} = \lceil \, \text{seconds per message} \: \cdot \, 10^3 \, \rceil = \lceil \, 7.3 \, \rceil = 8 \longrightarrow \boxed{10}\)
\(\small \; \vdots\)
/*
* int startBitsPerChar = 1;
* int dataBitsPerChar = 8;
* int stopBitsPerChar = 1;
*
* int bitsPerChar = startBitsPerChar + dataBitsPerChar + stopBitsPerChar;
*
* float secondsPerChar = bitsPerChar / bitsPerSecond;
*
* int charsPerMessage = 7;
*
* float secondsPerMessage = secondsPerChar * charsPerMessage;
*
* int millisPerMessage = ceil(secondsPerMessage * 1e3);
*
*/
int millisPerMessage = 10;
Timer<1, millis, char *> timer;
void setup()
{
pinMode(pinA, INPUT_PULLUP);
pinMode(pinB, INPUT_PULLUP);
pinMode(5, INPUT_PULLUP);
oldA = digitalRead(pinA);
oldB = digitalRead(pinB);
Serial.begin(bitsPerSecond);
timer.every(millisPerMessage, [](char *strDegrees) -> bool { Serial.println(strDegrees); return true; }, strDegrees);
}
void loop()
{
if (digitalRead(5))
{
timer.tick();
}
dtostrf(numDegrees, 3, 1, strDegrees);
newA = digitalRead(pinA);
newB = digitalRead(pinB);
if ((!oldA && newB || oldA && !newB) &&
(!oldB && !newA || oldB && newA))
{
numDegrees += 0.5;
}
if ((oldA && newB || !oldA && !newB) &&
(!oldB && newA || oldB && !newA))
{
numDegrees -= 0.5;
}
oldA = newA;
oldB = newB;
}