commit 60e6368992709c8fa3507120440c36c6dc930c02
Author: d3fault <d3fault@d3fault.net>
Date:   Sun May 21 13:14:05 2017 -0700

    wasdf: add some glue pieces to support testing calibration of right index finger

diff --git a/.gitignore b/.gitignore
index 699e2e0..f0f5771 100644
--- a/.gitignore
+++ b/.gitignore
@@ -4,3 +4,6 @@
build-*-Debug/
build-*-Release/
autogeneratedrpccodefor*/

#TODOreq: update QuickDirtyAutoBackupHalper so that .lastModifiedTimestamps ignores entries based on the following (which is valid/ready for .gitignore use, just uncomment it). for now I'll build Arduino sketches out of tree (copy/paste xD)
#**/ArduinoSketches/**/build-*/
diff --git a/.lastModifiedTimestamps b/.lastModifiedTimestamps
index 7a32b2f..db80f3b 100644
--- a/.lastModifiedTimestamps
+++ b/.lastModifiedTimestamps
@@ -4111,9 +4111,10 @@ Projects/MouseOrMotionOrMySexyFaceViewMaker/src/mouseormotionormysexyfaceviewmak
Projects/MouseOrMotionOrMySexyFaceViewMaker/src/qtCreatorBlinkingCursorToExcludeFromMotionDetectionChecks.png:1424755814
Projects/MouseOrMotionOrMySexyFaceViewMaker/src/systemTrayIcon.svg:1424596976
Projects/MusicFingers/:1438697230
Projects/MusicFingers/assets/:1495250246
Projects/MusicFingers/assets/0_ArduinoWriteChangesOnAnalogPinstoSerial_WithCalibration/:1495237291
Projects/MusicFingers/assets/0_ArduinoWriteChangesOnAnalogPinstoSerial_WithCalibration/0_ArduinoWriteChangesOnAnalogPinstoSerial_WithCalibration.cpp:1428920701Projects/MusicFingers/assets/:1463107503
Projects/MusicFingers/assets/ArduinoSketches/:1463107568
Projects/MusicFingers/assets/ArduinoSketches/ArduinoWriteChangesOnAnalogPinsToSerial_WithCalibration/:1463107577
Projects/MusicFingers/assets/ArduinoSketches/ArduinoWriteChangesOnAnalogPinsToSerial_WithCalibration/ArduinoWriteChangesOnAnalogPinsToSerial_WithCalibration.ino:1495394544
Projects/MusicFingers/design/:1438697274
Projects/MusicFingers/design/maybe.version.2.andor.the.commercial.version.svg:1438727885
Projects/MusicFingers/src/:1428303545
@@ -5881,23 +5882,27 @@ Projects/libAvGraphicsItem3/src/frontend/videoplayerwidget.h:1327005797
Projects/libAvGraphicsItem3/src/libAvGraphicsItem3.pro:1327004311
Projects/libAvGraphicsItem3/src/main.cpp:1327003410
Projects/wasdf/:1495333245
Projects/wasdf/assets/:1495250258
Projects/wasdf/assets/ArduinoWriteChangesOnAnalogPinstoSerial/:1495337967
Projects/wasdf/assets/ArduinoWriteChangesOnAnalogPinstoSerial/ArduinoWriteChangesOnAnalogPinstoSerial.cpp:1495337967Projects/wasdf/assets/:1463107603
Projects/wasdf/assets/ArduinoSketches/:1463107625
Projects/wasdf/assets/ArduinoSketches/ArduinoWriteChangesOnAnalogPinsToSerial/:1463107670
Projects/wasdf/assets/ArduinoSketches/ArduinoWriteChangesOnAnalogPinsToSerial/ArduinoWriteChangesOnAnalogPinsToSerial.ino:1495395654
Projects/wasdf/assets/ArduinoSketches/ArduinoWriteChangesOnAnalogPinsToSerial/Makefile:1495394559
Projects/wasdf/design/:1495255816
Projects/wasdf/design/pin.detection.and.finger.mapping.are.same.step.as.calibration.txt:1495315077
Projects/wasdf/design/renaming.from.MusicFingers.txt:1495250184
Projects/wasdf/src/:1495333599
Projects/wasdf/src/cli/:1495318115
Projects/wasdf/src/cli/main.cpp:1495318115
Projects/wasdf/src/lib/:1495333560
Projects/wasdf/src/lib/wasdf.cpp:1495323646
Projects/wasdf/src/lib/wasdf.h:1495323646
Projects/wasdf/src/lib/wasdfarduino.cpp:1495333560
Projects/wasdf/src/lib/wasdfarduino.h:1495333423
Projects/wasdf/src/lib/wasdfcalibrator.cpp:1495322369Projects/wasdf/src/:1495397541
Projects/wasdf/src/cli/:1495395081
Projects/wasdf/src/cli/main.cpp:1495395081
Projects/wasdf/src/cli/wasdfcli.cpp:1495394570
Projects/wasdf/src/cli/wasdfcli.h:1495394574
Projects/wasdf/src/lib/:1495397502
Projects/wasdf/src/lib/wasdf.cpp:1495397502
Projects/wasdf/src/lib/wasdf.h:1495394681
Projects/wasdf/src/lib/wasdfarduino.cpp:1495396272
Projects/wasdf/src/lib/wasdfarduino.h:1495395595
Projects/wasdf/src/lib/wasdfcalibrator.cpp:1495396148
Projects/wasdf/src/lib/wasdfcalibrator.h:1495322369
Projects/wasdf/src/wasdf-cli.pro:1495319518Projects/wasdf/src/wasdf-cli.pro:1495396931
Projects/wasdf/src/wasdf.pri:1495320067
Solutions/:1417412538
Solutions/Abc2PessimisticStateMonitorAndRecoverer/:1427380549
@@ -6407,7 +6412,7 @@ scripts/best.rsync.command.txt:1427098358
scripts/cleanAptEtc.sh:1350618598
scripts/cmd.to.make.torrent.with.lots.of.relevant.trackers.txt:1426427907
scripts/copy.ldd.dependencies.automatically.woot.txt:1442694424
scripts/d3faults.superior.unattended-upgrades.sh:1495389393scripts/d3faults.superior.unattended-upgrades.sh:1495397470
scripts/debian.squeeze.dell.mini.9.post.install.instructions.txt:1368042665
scripts/dedicated.server.domain.name.associating.txt:1409246698
scripts/design.for.new.auto-commit.infrastructure.that.is.basic.incremement.of.current.auto-commit.but.nowhere.near.what.i.want.ultimately.txt:1343536975
@@ -6439,7 +6444,7 @@ scripts/virtualbox.networking.how.do.these.blogs.say.so.little.in.so.much.txt:13
scripts/vnc.over.ssh.simple.howto.just.like.virtualbox.instructions.so.many.blog.posts.sucked.at.explaining.this.txt:1413396089
scripts/yumDownloadOnly.sh:1350716657
scripts/zoom.backup.and.shred.sh:1351237228
.gitignore:1432417463.gitignore:1495394480
copyright.txt:1388203681
license.dpl.txt:1388242176
pseudo.git.submodules.temphack.txt:1442777728
diff --git a/Projects/MusicFingers/assets/0_ArduinoWriteChangesOnAnalogPinstoSerial_WithCalibration/0_ArduinoWriteChangesOnAnalogPinstoSerial_WithCalibration.cpp b/Projects/MusicFingers/assets/0_ArduinoWriteChangesOnAnalogPinstoSerial_WithCalibration/0_ArduinoWriteChangesOnAnalogPinstoSerial_WithCalibration.cpp
deleted file mode 100644
index 5077bd0..0000000
--- a/Projects/MusicFingers/assets/0_ArduinoWriteChangesOnAnalogPinstoSerial_WithCalibration/0_ArduinoWriteChangesOnAnalogPinstoSerial_WithCalibration.cpp
+++ /dev/null
@@ -1,102 +0,0 @@
int sensorValue = 0;
#define MUSIC_FINGERS_CALIBRATION_MAX 127 //TODOreq: this should be 1023. The value should be mapped to 0-127 only JUST before being sent to stk-demo's stdin (MAYBE a tiny bit earlier, so we 'know' what stk-demo currently has as a value... but definitely not here on the arduino). I think, though, that calibration has to be moved off of the Arduino in order for that to happen (which requires a more robust serial protocol (so fuck that for now. KISS))

#define MUSIC_FINGRERS_ANALOG_PIN_VAR(pin) analogInPin_##pin
#define MUSIC_FINGERS_NEW_SENSOR_VALUE_VAR(pin) pin##_newSensorValue
#define MUSIC_FINGERS_OLD_SENSOR_VALUE_VAR(pin) pin##_oldSensorValue
#define MUSIC_FINGERS_MIN_SENSOR_VALUE_VAR(pin) pin##_minSensorValue
#define MUSIC_FINGERS_MAX_SENSOR_VALUE_VAR(pin) pin##_maxSensorValue

#define MUSIC_FINGER_GLOBALS(pin) \
const int MUSIC_FINGRERS_ANALOG_PIN_VAR(pin) = pin; \
int MUSIC_FINGERS_NEW_SENSOR_VALUE_VAR(pin) = 0; \
int MUSIC_FINGERS_OLD_SENSOR_VALUE_VAR(pin) = 0; \
int MUSIC_FINGERS_MIN_SENSOR_VALUE_VAR(pin) = 1023; \
int MUSIC_FINGERS_MAX_SENSOR_VALUE_VAR(pin) = 0;


/* EX:
int analogPin_A0 = 0;
int A0_newSensorValue = 0;
int A0_oldSensorValue = 0;
int A0_minSensorValue = 1023;
int A0_maxSensorValue = 0;
*/
MUSIC_FINGER_GLOBALS(A0)
MUSIC_FINGER_GLOBALS(A1)
MUSIC_FINGER_GLOBALS(A2)
MUSIC_FINGER_GLOBALS(A3)
MUSIC_FINGER_GLOBALS(A4)
MUSIC_FINGER_GLOBALS(A5)
MUSIC_FINGER_GLOBALS(A8)
MUSIC_FINGER_GLOBALS(A9)
MUSIC_FINGER_GLOBALS(A10)
MUSIC_FINGER_GLOBALS(A11)


#define MUSIC_FINGERS_CALIBRATE(pin) \
sensorValue = analogRead(pin); \
if(sensorValue > MUSIC_FINGERS_MAX_SENSOR_VALUE_VAR(pin)) \
{ \
  MUSIC_FINGERS_MAX_SENSOR_VALUE_VAR(pin) = sensorValue; \
} \
if(sensorValue < MUSIC_FINGERS_MIN_SENSOR_VALUE_VAR(pin)) \
{ \
  MUSIC_FINGERS_MIN_SENSOR_VALUE_VAR(pin) = sensorValue; \
}


#define MUSIC_FINGERS_MAIN_LOOP(pinQuoted, pin) \
MUSIC_FINGERS_NEW_SENSOR_VALUE_VAR(pin) = analogRead(MUSIC_FINGRERS_ANALOG_PIN_VAR(pin)); \
if(MUSIC_FINGERS_NEW_SENSOR_VALUE_VAR(pin) < (MUSIC_FINGERS_OLD_SENSOR_VALUE_VAR(pin)-halfThresholdForNotifyingOfChange) || MUSIC_FINGERS_NEW_SENSOR_VALUE_VAR(pin) > (MUSIC_FINGERS_OLD_SENSOR_VALUE_VAR(pin)+halfThresholdForNotifyingOfChange)) \
{ \
  Serial.print(pinQuoted); \
  Serial.print(":"); \
  int sensorValueMappedAkaCalibrated = map(MUSIC_FINGERS_NEW_SENSOR_VALUE_VAR(pin), MUSIC_FINGERS_MIN_SENSOR_VALUE_VAR(pin), MUSIC_FINGERS_MAX_SENSOR_VALUE_VAR(pin), 0, MUSIC_FINGERS_CALIBRATION_MAX); /* 0-127 corresponds to the typical synthesis toolkit min/max ranges it accepts for the frequency on stdin....*/ \
  sensorValueMappedAkaCalibrated = constrain(sensorValueMappedAkaCalibrated, 0, MUSIC_FINGERS_CALIBRATION_MAX); \
  Serial.println(sensorValueMappedAkaCalibrated); /*TODOoptimization: pretty sure i don't need newlines, but I can't be fucked atm. edit: newlines cost just as much as any other delimiter, so what gives? i think now that i have a colon-separated-protocol, this optimization can no longer happen*/ \
  MUSIC_FINGERS_OLD_SENSOR_VALUE_VAR(pin) = MUSIC_FINGERS_NEW_SENSOR_VALUE_VAR(pin); \
}


int halfThresholdForNotifyingOfChange = 2; //plus OR minus, hence 'half'

void setup()
{
  Serial.begin(9600);

  //BEGIN Calibrate
  pinMode(13, OUTPUT);
  digitalWrite(13, HIGH);
  while(millis() < 5000)
  {
    MUSIC_FINGERS_CALIBRATE(A0)
    MUSIC_FINGERS_CALIBRATE(A1)
    MUSIC_FINGERS_CALIBRATE(A2)
    MUSIC_FINGERS_CALIBRATE(A3)
    MUSIC_FINGERS_CALIBRATE(A4)
    MUSIC_FINGERS_CALIBRATE(A5)
    MUSIC_FINGERS_CALIBRATE(A8)
    MUSIC_FINGERS_CALIBRATE(A9)
    MUSIC_FINGERS_CALIBRATE(A10)
    MUSIC_FINGERS_CALIBRATE(A11)
  }
  digitalWrite(13, LOW);
  //END Calibrate
}
void loop()
{
  MUSIC_FINGERS_MAIN_LOOP("0", A0)
  MUSIC_FINGERS_MAIN_LOOP("1", A1)
  MUSIC_FINGERS_MAIN_LOOP("2", A2)
  MUSIC_FINGERS_MAIN_LOOP("3", A3)
  MUSIC_FINGERS_MAIN_LOOP("4", A4)
  MUSIC_FINGERS_MAIN_LOOP("5", A5)
  MUSIC_FINGERS_MAIN_LOOP("8", A8)
  MUSIC_FINGERS_MAIN_LOOP("9", A9)
  MUSIC_FINGERS_MAIN_LOOP("10", A10)
  MUSIC_FINGERS_MAIN_LOOP("11", A11)
  
  delay(2);
}

diff --git a/Projects/MusicFingers/assets/ArduinoSketches/ArduinoWriteChangesOnAnalogPinsToSerial_WithCalibration/ArduinoWriteChangesOnAnalogPinsToSerial_WithCalibration.ino b/Projects/MusicFingers/assets/ArduinoSketches/ArduinoWriteChangesOnAnalogPinsToSerial_WithCalibration/ArduinoWriteChangesOnAnalogPinsToSerial_WithCalibration.ino
new file mode 100644
index 0000000..5077bd0
--- /dev/null
+++ b/Projects/MusicFingers/assets/ArduinoSketches/ArduinoWriteChangesOnAnalogPinsToSerial_WithCalibration/ArduinoWriteChangesOnAnalogPinsToSerial_WithCalibration.ino
@@ -0,0 +1,102 @@
int sensorValue = 0;
#define MUSIC_FINGERS_CALIBRATION_MAX 127 //TODOreq: this should be 1023. The value should be mapped to 0-127 only JUST before being sent to stk-demo's stdin (MAYBE a tiny bit earlier, so we 'know' what stk-demo currently has as a value... but definitely not here on the arduino). I think, though, that calibration has to be moved off of the Arduino in order for that to happen (which requires a more robust serial protocol (so fuck that for now. KISS))

#define MUSIC_FINGRERS_ANALOG_PIN_VAR(pin) analogInPin_##pin
#define MUSIC_FINGERS_NEW_SENSOR_VALUE_VAR(pin) pin##_newSensorValue
#define MUSIC_FINGERS_OLD_SENSOR_VALUE_VAR(pin) pin##_oldSensorValue
#define MUSIC_FINGERS_MIN_SENSOR_VALUE_VAR(pin) pin##_minSensorValue
#define MUSIC_FINGERS_MAX_SENSOR_VALUE_VAR(pin) pin##_maxSensorValue

#define MUSIC_FINGER_GLOBALS(pin) \
const int MUSIC_FINGRERS_ANALOG_PIN_VAR(pin) = pin; \
int MUSIC_FINGERS_NEW_SENSOR_VALUE_VAR(pin) = 0; \
int MUSIC_FINGERS_OLD_SENSOR_VALUE_VAR(pin) = 0; \
int MUSIC_FINGERS_MIN_SENSOR_VALUE_VAR(pin) = 1023; \
int MUSIC_FINGERS_MAX_SENSOR_VALUE_VAR(pin) = 0;


/* EX:
int analogPin_A0 = 0;
int A0_newSensorValue = 0;
int A0_oldSensorValue = 0;
int A0_minSensorValue = 1023;
int A0_maxSensorValue = 0;
*/
MUSIC_FINGER_GLOBALS(A0)
MUSIC_FINGER_GLOBALS(A1)
MUSIC_FINGER_GLOBALS(A2)
MUSIC_FINGER_GLOBALS(A3)
MUSIC_FINGER_GLOBALS(A4)
MUSIC_FINGER_GLOBALS(A5)
MUSIC_FINGER_GLOBALS(A8)
MUSIC_FINGER_GLOBALS(A9)
MUSIC_FINGER_GLOBALS(A10)
MUSIC_FINGER_GLOBALS(A11)


#define MUSIC_FINGERS_CALIBRATE(pin) \
sensorValue = analogRead(pin); \
if(sensorValue > MUSIC_FINGERS_MAX_SENSOR_VALUE_VAR(pin)) \
{ \
  MUSIC_FINGERS_MAX_SENSOR_VALUE_VAR(pin) = sensorValue; \
} \
if(sensorValue < MUSIC_FINGERS_MIN_SENSOR_VALUE_VAR(pin)) \
{ \
  MUSIC_FINGERS_MIN_SENSOR_VALUE_VAR(pin) = sensorValue; \
}


#define MUSIC_FINGERS_MAIN_LOOP(pinQuoted, pin) \
MUSIC_FINGERS_NEW_SENSOR_VALUE_VAR(pin) = analogRead(MUSIC_FINGRERS_ANALOG_PIN_VAR(pin)); \
if(MUSIC_FINGERS_NEW_SENSOR_VALUE_VAR(pin) < (MUSIC_FINGERS_OLD_SENSOR_VALUE_VAR(pin)-halfThresholdForNotifyingOfChange) || MUSIC_FINGERS_NEW_SENSOR_VALUE_VAR(pin) > (MUSIC_FINGERS_OLD_SENSOR_VALUE_VAR(pin)+halfThresholdForNotifyingOfChange)) \
{ \
  Serial.print(pinQuoted); \
  Serial.print(":"); \
  int sensorValueMappedAkaCalibrated = map(MUSIC_FINGERS_NEW_SENSOR_VALUE_VAR(pin), MUSIC_FINGERS_MIN_SENSOR_VALUE_VAR(pin), MUSIC_FINGERS_MAX_SENSOR_VALUE_VAR(pin), 0, MUSIC_FINGERS_CALIBRATION_MAX); /* 0-127 corresponds to the typical synthesis toolkit min/max ranges it accepts for the frequency on stdin....*/ \
  sensorValueMappedAkaCalibrated = constrain(sensorValueMappedAkaCalibrated, 0, MUSIC_FINGERS_CALIBRATION_MAX); \
  Serial.println(sensorValueMappedAkaCalibrated); /*TODOoptimization: pretty sure i don't need newlines, but I can't be fucked atm. edit: newlines cost just as much as any other delimiter, so what gives? i think now that i have a colon-separated-protocol, this optimization can no longer happen*/ \
  MUSIC_FINGERS_OLD_SENSOR_VALUE_VAR(pin) = MUSIC_FINGERS_NEW_SENSOR_VALUE_VAR(pin); \
}


int halfThresholdForNotifyingOfChange = 2; //plus OR minus, hence 'half'

void setup()
{
  Serial.begin(9600);

  //BEGIN Calibrate
  pinMode(13, OUTPUT);
  digitalWrite(13, HIGH);
  while(millis() < 5000)
  {
    MUSIC_FINGERS_CALIBRATE(A0)
    MUSIC_FINGERS_CALIBRATE(A1)
    MUSIC_FINGERS_CALIBRATE(A2)
    MUSIC_FINGERS_CALIBRATE(A3)
    MUSIC_FINGERS_CALIBRATE(A4)
    MUSIC_FINGERS_CALIBRATE(A5)
    MUSIC_FINGERS_CALIBRATE(A8)
    MUSIC_FINGERS_CALIBRATE(A9)
    MUSIC_FINGERS_CALIBRATE(A10)
    MUSIC_FINGERS_CALIBRATE(A11)
  }
  digitalWrite(13, LOW);
  //END Calibrate
}
void loop()
{
  MUSIC_FINGERS_MAIN_LOOP("0", A0)
  MUSIC_FINGERS_MAIN_LOOP("1", A1)
  MUSIC_FINGERS_MAIN_LOOP("2", A2)
  MUSIC_FINGERS_MAIN_LOOP("3", A3)
  MUSIC_FINGERS_MAIN_LOOP("4", A4)
  MUSIC_FINGERS_MAIN_LOOP("5", A5)
  MUSIC_FINGERS_MAIN_LOOP("8", A8)
  MUSIC_FINGERS_MAIN_LOOP("9", A9)
  MUSIC_FINGERS_MAIN_LOOP("10", A10)
  MUSIC_FINGERS_MAIN_LOOP("11", A11)
  
  delay(2);
}

diff --git a/Projects/wasdf/assets/ArduinoSketches/ArduinoWriteChangesOnAnalogPinsToSerial/ArduinoWriteChangesOnAnalogPinsToSerial.ino b/Projects/wasdf/assets/ArduinoSketches/ArduinoWriteChangesOnAnalogPinsToSerial/ArduinoWriteChangesOnAnalogPinsToSerial.ino
new file mode 100644
index 0000000..55aeaa9
--- /dev/null
+++ b/Projects/wasdf/assets/ArduinoSketches/ArduinoWriteChangesOnAnalogPinsToSerial/ArduinoWriteChangesOnAnalogPinsToSerial.ino
@@ -0,0 +1,197 @@
//rewriting the first version of this instead of just removing calibration because I also want to try to not to use pp defines/macros. pure C++ is cleaner and easier to read/modify. aside from that it's just a functionally equivalent rewrite (with the calibration stripped out since that's going to be done on the PC side)

static const int NUM_ANALOG_PINS_TOTAL = 15; //TODOreq: find a good maximum. maybe use whatever my mega 2560 uses (and cross fingers that boards with fewer analog pins don't crash (could always patch arduino sauce so it returns 0 when requested pin DNE))

static const int NUM_HANDS = 2;
static const int NUM_FINGERS_PER_HAND = 5;

static const int HALF_THRESHOLD_FOR_NOTIFYING_OF_CHANGE = 2; //TODOoptional: this could be determined during 'calibration' (so it'd be received from PC over serial). example instructions to uesr for determining it: "move your right index finger as little as possible until you see on screen that it's registered" or some such (haven't thought this through very much, maybe it's dumb idea)

//TODOmb: when in calibrating mode maybe I should blink pin 13 rapidly, and when normal mode starts I should do 3 long pulses and then disable it (because leaving it on is dumb)
bool newSensorValueHasChangedEnoughThatWeWantToReportIt(int oldSensorValue, int newSensorValue)
{
    /*if(NewSensorValue == OldSensorValue)
        return false;
    return true;*/

    if(newSensorValue < (oldSensorValue-HALF_THRESHOLD_FOR_NOTIFYING_OF_CHANGE))
        return true;

    if(newSensorValue > (oldSensorValue+HALF_THRESHOLD_FOR_NOTIFYING_OF_CHANGE))
        return true;

    return false;
}
class Finger_aka_AnalogPin
{
public:
    explicit Finger_aka_AnalogPin()
        : NewSensorValue(0)
        , OldSensorValue(0)
    { }
    void setStringAndIntPinIds(const char *stringPinId, int intPinId)
    {
        StringPinId = stringPinId;
        IntPinId = intPinId;
    }
    void reportMovementOverSerialPort()
    {
        NewSensorValue = analogRead(IntPinId);
        if(newSensorValueHasChangedEnoughThatWeWantToReportIt(OldSensorValue, NewSensorValue))
        {
            Serial.print(StringPinId);
            Serial.print(":");
            Serial.println(NewSensorValue);
            OldSensorValue = NewSensorValue;
        }
    }
    ~Finger_aka_AnalogPin() { }

    const char *StringPinId;
    int IntPinId;
    int NewSensorValue;
    int OldSensorValue;

private:
    explicit Finger_aka_AnalogPin(const Finger_aka_AnalogPin &other) { } //delete
};

struct Hand
{
    void setupHand(bool leftTrue_rightFalse)
    {
        //TODOreq: the arduino micro doesn't use analog pins 0-9 (note that finger 9 below maps to pin A11), so the following mappings are arduino micro specific. there should obviously be some way to use this code with other boards of course (even a mapping 'file' is better than hardcoding it here). the BEST solution is to, before/during calibration, 'probe' every analog port to see if it's wired, and then to have the user tell us which finger that pin corresponds to.. then to yea save it in some ~/.config 'profile' thingo. for now I'm fine with hardcoding the pin mappings since my target is to get range-of-fingers realtime-with-feedback calibration working [first]. I wonder what happens when you read an analog pin that has nothing attached... it returns 0. in any case and whatever value it is, it shouldn't "move" (I hope)
        //TODOreq:^I also need to change the MusicFingers serial READ code (runs on PC) to use 0-9 and not the whacky micro-specific mapping like in the previous version of this code

        //TODOreq: this obviously needs to be refactored to use the calibration data received from the PC
        if(leftTrue_rightFalse)
        {
            //left hand
            Fingers[0].setStringAndIntPinIds("0", A0);
            Fingers[1].setStringAndIntPinIds("1", A1);
            Fingers[2].setStringAndIntPinIds("2", A2);
            Fingers[3].setStringAndIntPinIds("3", A3);
            Fingers[4].setStringAndIntPinIds("4", A4);
        }
        else
        {
            //right hand
            Fingers[0].setStringAndIntPinIds("5", A5);
            Fingers[1].setStringAndIntPinIds("6", A8);
            Fingers[2].setStringAndIntPinIds("7", A9);
            Fingers[3].setStringAndIntPinIds("8", A10);
            Fingers[4].setStringAndIntPinIds("9", A11);
        }
    }
    void reportFingerMovementOverSerialPort()
    {
        for(int i = 0; i < NUM_FINGERS_PER_HAND; ++i)
        {
            Fingers[i].reportMovementOverSerialPort();
        }
    }

    Finger_aka_AnalogPin Fingers[NUM_FINGERS_PER_HAND];
};

struct Hands
{
    explicit Hands()
    {
        hands[0].setupHand(true);
        hands[1].setupHand(false);
    }

    void reportFingerMovementOverSerialPort()
    {
        for(int i = 0; i < NUM_HANDS; ++i)
        {
            hands[i].reportFingerMovementOverSerialPort();
        }
    }

    Hand hands[NUM_HANDS];
};

struct Mode
{
    enum ModeEnum //TODOreq: I forget how to properly set up 'flags' that can be combined, this might be wrong (also calibrating can never be used with any other modes, but eh)
    {
          DoNothingMode = 0x000
        , Calibrating = 0x001
        , Sending10FingerMovementsMode = 0x010
        , KeyboardAndMouseMode = 0x100
    };
};

//Globals
int CalibrationDataOldSensorValues[NUM_ANALOG_PINS_TOTAL];
String inputCommandString;
Mode::ModeEnum CurrentMode;
Hands hands;

void setup()
{
    Serial.begin(9600);
    for(int i = 0; i < NUM_ANALOG_PINS_TOTAL; ++i)
        CalibrationDataOldSensorValues[i] = 0;
    CurrentMode = Mode::DoNothingMode;
    inputCommandString.reserve(512); //TODOreq: ensure command strings never grow beyond 512 bytes
    while(!Serial) ; //wait for serial port to connect. Needed for Leonardo/Micro only. I intentionally put the String::reserve command (and other cmds) in between this and Serial.begin() in case the connect happens asynchronously (idfk tbh, but it might), in which case I may have saved an entire millisecond!!!
}
void calibrationLoop()
{
    for(int i = A0, j = 0; i < NUM_ANALOG_PINS_TOTAL; ++i, ++j)
    {
        int oldSensorValue = CalibrationDataOldSensorValues[j];
        int newSensorValue = analogRead(i);
        if(newSensorValueHasChangedEnoughThatWeWantToReportIt(oldSensorValue, newSensorValue))
        {
            Serial.print(i);
            Serial.print(":");
            Serial.println(newSensorValue);
            CalibrationDataOldSensorValues[j] = newSensorValue;
        }
    }
}
void loop()
{
    switch(CurrentMode) //TODOreq: this switch case doesn't support simultaneous 10-fingers and keyboardMouse modes
    {
        case Mode::Sending10FingerMovementsMode:
            hands.reportFingerMovementOverSerialPort(); //tell, don't ask ;-)
        break;
        case Mode::KeyboardAndMouseMode:
            //TODOreq
        break;
        case Mode::Calibrating:
            calibrationLoop();
        break;
        case Mode::DoNothingMode:
            delay(50); //mb this saves battery? w/e lol
        break;
    }

    delay(2); //TODOreq: this might fuck up MOUSE MOVEMENT, everything else should be fine with it tho
}
void processInputCommandString()
{
    if(inputCommandString == "calibrate")
    {
        CurrentMode = Mode::Calibrating;
        return;
    }
}
void serialEvent()
{
    while(Serial.available())
    {
        char inChar = (char)Serial.read();
        inputCommandString += inChar;
        if(inChar == '\n')
        {
            processInputCommandString();
            inputCommandString = "";
        }
    }
}
diff --git a/Projects/wasdf/assets/ArduinoSketches/ArduinoWriteChangesOnAnalogPinsToSerial/Makefile b/Projects/wasdf/assets/ArduinoSketches/ArduinoWriteChangesOnAnalogPinsToSerial/Makefile
new file mode 100644
index 0000000..3af5993
--- /dev/null
+++ b/Projects/wasdf/assets/ArduinoSketches/ArduinoWriteChangesOnAnalogPinsToSerial/Makefile
@@ -0,0 +1,4 @@
BOARD_TAG    = micro
ARDUINO_LIBS =

include /usr/share/arduino/Arduino.mk
diff --git a/Projects/wasdf/assets/ArduinoWriteChangesOnAnalogPinstoSerial/ArduinoWriteChangesOnAnalogPinstoSerial.cpp b/Projects/wasdf/assets/ArduinoWriteChangesOnAnalogPinstoSerial/ArduinoWriteChangesOnAnalogPinstoSerial.cpp
deleted file mode 100644
index c3c6f50..0000000
--- a/Projects/wasdf/assets/ArduinoWriteChangesOnAnalogPinstoSerial/ArduinoWriteChangesOnAnalogPinstoSerial.cpp
+++ /dev/null
@@ -1,197 +0,0 @@
//rewriting the first version of this instead of just removing calibration because I also want to try to not to use pp defines/macros. pure C++ is cleaner and easier to read/modify. aside from that it's just a functionally equivalent rewrite (with the calibration stripped out since that's going to be done on the PC side)

static const int NUM_ANALOG_PINS_TOTAL = 15; //TODOreq: find a good maximum. maybe use whatever my mega 2560 uses (and cross fingers that boards with fewer analog pins don't crash (could always patch arduino sauce so it returns 0 when requested pin DNE))

static const int NUM_HANDS = 2;
static const int NUM_FINGERS_PER_HAND = 5;

static const int HALF_THRESHOLD_FOR_NOTIFYING_OF_CHANGE = 2; //TODOoptional: this could be determined during 'calibration' (so it'd be received from PC over serial). example instructions to uesr for determining it: "move your right index finger as little as possible until you see on screen that it's registered" or some such (haven't thought this through very much, maybe it's dumb idea)

//TODOmb: when in calibrating mode maybe I should blink pin 13 rapidly, and when normal mode starts I should do 3 long pulses and then disable it (because leaving it on is dumb)
bool newSensorValueHasChangedEnoughThatWeWantToReportIt(int oldSensorValue, int newSensorValue)
{
    /*if(NewSensorValue == OldSensorValue)
        return false;
    return true;*/

    if(newSensorValue < (oldSensorValue-HALF_THRESHOLD_FOR_NOTIFYING_OF_CHANGE))
        return true;

    if(newSensorValue > (oldSensorValue+HALF_THRESHOLD_FOR_NOTIFYING_OF_CHANGE))
        return true;

    return false;
}
class Finger_aka_AnalogPin
{
public:
    explicit Finger_aka_AnalogPin()
        : NewSensorValue(0)
        , OldSensorValue(0)
    { }
    void setStringAndIntPinIds(const char *stringPinId, int intPinId)
    {
        StringPinId = stringPinId;
        IntPinId = intPinId;
    }
    void reportMovementOverSerialPort()
    {
        NewSensorValue = analogRead(IntPinId);
        if(newSensorValueHasChangedEnoughThatWeWantToReportIt(OldSensorValue, NewSensorValue))
        {
            Serial.print(StringPinId);
            Serial.print(":");
            Serial.println(NewSensorValue);
            OldSensorValue = NewSensorValue;
        }
    }
    ~Finger_aka_AnalogPin() { }

    const char *StringPinId;
    int IntPinId;
    int NewSensorValue;
    int OldSensorValue;

private:
    explicit Finger_aka_AnalogPin(const Finger_aka_AnalogPin &other) { } //delete
};

struct Hand
{
    void setupHand(bool leftTrue_rightFalse)
    {
        //TODOreq: the arduino micro doesn't use analog pins 0-9 (note that finger 9 below maps to pin A11), so the following mappings are arduino micro specific. there should obviously be some way to use this code with other boards of course (even a mapping 'file' is better than hardcoding it here). the BEST solution is to, before/during calibration, 'probe' every analog port to see if it's wired, and then to have the user tell us which finger that pin corresponds to.. then to yea save it in some ~/.config 'profile' thingo. for now I'm fine with hardcoding the pin mappings since my target is to get range-of-fingers realtime-with-feedback calibration working [first]. I wonder what happens when you read an analog pin that has nothing attached... it returns 0. in any case and whatever value it is, it shouldn't "move" (I hope)
        //TODOreq:^I also need to change the MusicFingers serial READ code (runs on PC) to use 0-9 and not the whacky micro-specific mapping like in the previous version of this code

        //TODOreq: this obviously needs to be refactored to use the calibration data received from the PC
        if(leftTrue_rightFalse)
        {
            //left hand
            Fingers[0].setStringAndIntPinIds("0", A0);
            Fingers[1].setStringAndIntPinIds("1", A1);
            Fingers[2].setStringAndIntPinIds("2", A2);
            Fingers[3].setStringAndIntPinIds("3", A3);
            Fingers[4].setStringAndIntPinIds("4", A4);
        }
        else
        {
            //right hand
            Fingers[0].setStringAndIntPinIds("5", A5);
            Fingers[1].setStringAndIntPinIds("6", A8);
            Fingers[2].setStringAndIntPinIds("7", A9);
            Fingers[3].setStringAndIntPinIds("8", A10);
            Fingers[4].setStringAndIntPinIds("9", A11);
        }
    }
    void reportFingerMovementOverSerialPort()
    {
        for(int i = 0; i < NUM_FINGERS_PER_HAND; ++i)
        {
            Fingers[i].reportMovementOverSerialPort();
        }
    }

    Finger_aka_AnalogPin Fingers[NUM_FINGERS_PER_HAND];
};

struct Hands
{
    explicit Hands()
    {
        hands[0].setupHand(true);
        hands[1].setupHand(false);
    }

    void reportFingerMovementOverSerialPort()
    {
        for(int i = 0; i < NUM_HANDS; ++i)
        {
            hands[i].reportFingerMovementOverSerialPort();
        }
    }

    Hand hands[NUM_HANDS];
};

struct Mode
{
    enum ModeEnum
    {
          DoNothingMode = 0x000
        , Calibrating = 0x001
        , Sending10FingerMovementsMode = 0x010
        , KeyboardAndMouseMode = 0x100
    };
};

//Globals
int CalibrationDataOldSensorValues[NUM_ANALOG_PINS_TOTAL];
String inputCommandString;
Mode::ModeEnum CurrentMode;
Hands hands;

void setup()
{
    Serial.begin(9600);
    for(int i = 0; i < NUM_ANALOG_PINS_TOTAL; ++i)
        CalibrationDataOldSensorValues[i] = 0;
    CurrentMode = Mode::DoNothingMode;
    inputCommandString.reserve(512); //TODOreq: ensure command strings never grow beyond 512 bytes
    while(!Serial) ; //wait for serial port to connect. Needed for Leonardo/Micro only. I intentionally put the String::reserve command (and other cmds) in between this and Serial.begin() in case the connect happens asynchronously (idfk tbh, but it might), in which case I may have saved an entire millisecond!!!
}
void calibrationLoop()
{
    for(int i = A0, j = 0; i < NUM_ANALOG_PINS_TOTAL; ++i, ++j)
    {
        int oldSensorValue = CalibrationDataOldSensorValues[j];
        int newSensorValue = analogRead(i);
        if(newSensorValueHasChangedEnoughThatWeWantToReportIt(oldSensorValue, newSensorValue))
        {
            Serial.print(i);
            Serial.print(":");
            Serial.println(newSensorValue);
            CalibrationDataOldSensorValues[j] = newSensorValue;
        }
    }
}
void loop()
{
    switch(CurrentMode) //TODOreq: this switch case doesn't support simultaneous 10-fingers and keyboardMouse modes
    {
        case Mode::Sending10FingerMovementsMode:
            hands.reportFingerMovementOverSerialPort(); //tell, don't ask ;-)
        break;
        case Mode::KeyboardAndMouseMode:
            //TODOreq
        break;
        case Mode::Calibrating:
            calibrationLoop();
        break;
        case Mode::DoNothingMode:
            delay(50); //mb this saves battery? w/e lol
        break;
    }

    delay(2); //TODOreq: this might fuck up MOUSE MOVEMENT, everything else should be fine with it tho
}
void processInputCommandString()
{
    if(inputCommandString == "calibrate")
    {
        CurrentMode = Mode::Calibrating;
        return;
    }
}
void serialEvent()
{
    while(Serial.available())
    {
        char inChar = (char)Serial.read();
        inputCommandString += inChar;
        if(inChar == '\n')
        {
            processInputCommandString();
            inputCommandString = "";
        }
    }
}
diff --git a/Projects/wasdf/src/cli/main.cpp b/Projects/wasdf/src/cli/main.cpp
index 19fa8c1..1bb8b5f 100644
--- a/Projects/wasdf/src/cli/main.cpp
+++ b/Projects/wasdf/src/cli/main.cpp
@@ -1,11 +1,13 @@
#include <QCoreApplication>

#include "wasdfcli.h"

int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);

    //WasdfCliWasdfCli cli;
    //Q_UNUSED(cli)Q_UNUSED(cli)

    return a.exec();
}
diff --git a/Projects/wasdf/src/cli/wasdfcli.cpp b/Projects/wasdf/src/cli/wasdfcli.cpp
new file mode 100644
index 0000000..3803739
--- /dev/null
+++ b/Projects/wasdf/src/cli/wasdfcli.cpp
@@ -0,0 +1,25 @@
#include "wasdfcli.h"

#include <QCoreApplication>

#include "wasdf.h"

WasdfCli::WasdfCli(QObject *parent)
    : QObject(parent)
    , m_StdErr(stderr)
    , m_StdOut(stdout)
{
    Wasdf *wasdf = new Wasdf(this);
    connect(wasdf, &Wasdf::e, this, &WasdfCli::handleE);
    connect(wasdf, &Wasdf::o, this, &WasdfCli::handleO);
    connect(wasdf, &Wasdf::wasdfFinished, qApp, QCoreApplication::quit);
    wasdf->startWasdf();
}
void WasdfCli::handleE(const QString &msg)
{
    m_StdErr << msg << endl;
}
void WasdfCli::handleO(const QString &msg)
{
    m_StdOut << msg << endl;
}
diff --git a/Projects/wasdf/src/cli/wasdfcli.h b/Projects/wasdf/src/cli/wasdfcli.h
new file mode 100644
index 0000000..55bedcf
--- /dev/null
+++ b/Projects/wasdf/src/cli/wasdfcli.h
@@ -0,0 +1,21 @@
#ifndef WASDFCLI_H
#define WASDFCLI_H

#include <QObject>

#include <QTextStream>

class WasdfCli : public QObject
{
    Q_OBJECT
public:
    explicit WasdfCli(QObject *parent = 0);
private:
    QTextStream m_StdErr;
    QTextStream m_StdOut;
private slots:
    void handleE(const QString &msg);
    void handleO(const QString &msg);
};

#endif // WASDFCLI_H
diff --git a/Projects/wasdf/src/lib/wasdf.cpp b/Projects/wasdf/src/lib/wasdf.cpp
index f4f7b84..8fd9ac6 100644
--- a/Projects/wasdf/src/lib/wasdf.cpp
+++ b/Projects/wasdf/src/lib/wasdf.cpp
@@ -15,6 +15,8 @@ Wasdf::Wasdf(QObject *parent)
    QCoreApplication::setOrganizationName("wasdf organization");
    QCoreApplication::setOrganizationDomain("wasdf.com");
    QCoreApplication::setApplicationName("wasdf");

    connect(m_Arduino, &WasdfArduino::e, this, &Wasdf::e);
}
void Wasdf::startWasdfActualSinceCalibrated()
{
@@ -29,6 +31,11 @@ void Wasdf::startWasdf()
    {
        m_Arduino->startInCalibrationMode();
        m_Calibrator = new WasdfCalibrator(this);

        //TODOreq: wtf for some reason this doesn't work with qt5-style syntax, which is weird because the WasdfArduino::e signal connects just fine to Wasdf::e signal. I also confirmed that the QPointer isn't the problem
        //connect(m_Calibrator.data(), &WasdfCalibrator::o, this &Wasdf::o);
        connect(m_Calibrator.data(), SIGNAL(o(QString)), this, SIGNAL(o(QString))); //qt4-style connect for now

        connect(m_Arduino, &WasdfArduino::analogPinReadingChangedDuringCalibration, m_Calibrator.data(), &WasdfCalibrator::handleAnalogPinReadingChanged);
        connect(m_Calibrator.data(), &WasdfCalibrator::calibrationComplete, this, &Wasdf::handleCalibrationComplete);
        m_Calibrator->startCalibrating();
@@ -37,7 +44,7 @@ void Wasdf::startWasdf()
    {
        //TODOreq: read WasdfCalibrationConfiguration out of the settings (or maybe just read values on-demand when needed)
        //m_WasdfCalibrationConfiguration = ;
        qDebug("Calibrated!");qDebug("Calibration read from settings");
        startWasdfActualSinceCalibrated();
    }
}
@@ -54,6 +61,44 @@ void Wasdf::handleCalibrationComplete(const WasdfCalibrationConfiguration &calib
}
void Wasdf::handleFingerMoved(Finger finger, int newPosition)
{
    emit o("Finger '" + fingerEnumToHumanReadableString(finger) + "' moved to position: " + QString::number(newPosition));
    emit wasdfFinished(true); //TODOreq: it's business time
    qDebug("I have stripped downthis is only here for testing
}
QString fingerEnumToHumanReadableString(Finger finger)
{
    //optimized for most commonly used fingers (middle fingers vs thumbs is a tie if you ask me xD. I'd say thumb beats middle for DAILY (normal non-wasdf) USE, but this isn't going to be daily use now is it? ex: when using your mouse you use your middle finger to my business socks");right click a lot)
    switch(finger)
    {
        case Finger::Finger6_RightIndex:
            return "right index";
        break;
        case Finger::Finger3_LeftIndex:
            return "left index";
        break;
        case Finger::Finger7_RightMiddle:
            return "right middle";
        break;
        case Finger::Finger2_LeftMiddle:
            return "left middle";
        break;
        case Finger::Finger5_RightThumb:
            return "right thumb";
        break;
        case Finger::Finger4_LeftThumb:
            return "left thumb";
        break;
        case Finger::Finger8_RightRing:
            return "right ring";
        break;
        case Finger::Finger1_LeftRing:
            return "left ring";
        break;
        case Finger::Finger9_RightPinky:
            return "right pinky";
        break;
        case Finger::Finger0_LeftPinky:
            return "left pinky"; //rip left pinky, nobody loves/uses him (jk I hope to)
        break;
    }
    return "#error finger#"; //should (will) never get here
}
diff --git a/Projects/wasdf/src/lib/wasdf.h b/Projects/wasdf/src/lib/wasdf.h
index 2eb1fbc..67f6a63 100644
--- a/Projects/wasdf/src/lib/wasdf.h
+++ b/Projects/wasdf/src/lib/wasdf.h
@@ -41,6 +41,7 @@ enum class Finger
  , RightPinky_Finger9 = 9
  , Finger9_RightPinky = RightPinky_Finger9
};
QString fingerEnumToHumanReadableString(Finger finger);
inline uint qHash(const Finger &key, uint seed)
{
    return qHash(static_cast<uint>(key), seed);
@@ -60,12 +61,15 @@ class Wasdf : public QObject
public:
    explicit Wasdf(QObject *parent = 0);
private:

    void startWasdfActualSinceCalibrated();

    WasdfArduino *m_Arduino;
    QPointer<WasdfCalibrator> m_Calibrator;
    WasdfCalibrationConfiguration m_Calibration;
signals:
    void e(const QString &msg);
    void o(const QString &msg);
    void wasdfFinished(bool success);
public slots:
    void startWasdf();
private slots:
diff --git a/Projects/wasdf/src/lib/wasdfarduino.cpp b/Projects/wasdf/src/lib/wasdfarduino.cpp
index 7b27f49..d716454 100644
--- a/Projects/wasdf/src/lib/wasdfarduino.cpp
+++ b/Projects/wasdf/src/lib/wasdfarduino.cpp
@@ -30,16 +30,16 @@ void WasdfArduino::openSerialPortIfNotOpen()
{
    if(m_SerialPort->isOpen())
    {
        if(!m_SerialPort->open(QIODevice::ReadWrite /*QIODevice::Text <-- apparently not supported, but I guess it's text by default?*/))default? <- nope it's binary but eh ascii isn't so hard to work with anyways. my protocol will be pure ascii*/))
        {
            emit e("failed to open serial port \"" + m_SerialPort->portName() + "\" for reading/writing");//TODOreq: connect all output/error signals (not just this class)
            //TODOreq: error out, return false or emit finished(false) etc
        }
    }
}
void WasdfArduino::startInCalibrationMode()
{
    //in calibration mode, arduino sends _ALL_ (not just 10) analog pin readings over serial (TODOmb: user can pass an --exclude-analog-pins flag in case they're using the other analog pins for something else (but then they'd need to modify the sketch anyways, so maybe this isn't necessary?)

    disconnect(m_SerialPort, SIGNAL(readyRead())); //TODOreq: for some reason this fails with qt5-style pmf syntax. maybe a newer version of Qt doesn't (otherwise file a bugreport)
    connect(m_SerialPort, &QSerialPort::readyRead, this, &WasdfArduino::handleSerialPortReadyReadCalibrationMode);
diff --git a/Projects/wasdf/src/lib/wasdfarduino.h b/Projects/wasdf/src/lib/wasdfarduino.h
index 647a4f4..80a4bb4 100644
--- a/Projects/wasdf/src/lib/wasdfarduino.h
+++ b/Projects/wasdf/src/lib/wasdfarduino.h
@@ -15,14 +15,6 @@ class WasdfArduino : public QObject
public:
    explicit WasdfArduino(QObject *parent = 0);
private:
#if 0 //different readyRead handlers is better/cleaner :)
    enum class WasdfArduinoMode
    {
          Calibrating = 0x001
        , Report10fingerMovements = 0x010
        , ControlMouseAndKeyboard = 0x100 //TODOreq: I forget how to properly set up 'flags' that can be combined, this might be wrong (also calibrating can never be used with any other modes, but eh)
    };
#endif
    void openSerialPortIfNotOpen();

    QSerialPort *m_SerialPort;
diff --git a/Projects/wasdf/src/lib/wasdfcalibrator.cpp b/Projects/wasdf/src/lib/wasdfcalibrator.cpp
index 6a5783b..b52b61d 100644
--- a/Projects/wasdf/src/lib/wasdfcalibrator.cpp
+++ b/Projects/wasdf/src/lib/wasdfcalibrator.cpp
@@ -5,6 +5,7 @@

#include "wasdf.h"

//Calibrator or Calibrater? fuggit~
//need to write this somewhere to remember/understand it better: DURING calibration there's information pertaining to every pin (>= 10) on the arduino, but AFTER calibration we only want to emit/deliver information pertaining to exactly 10 pins. it's our job as the calibrator to figure out which 10. it is (was) slightly confusing that there are 2 sets of "configutations"
WasdfCalibrator::WasdfCalibrator(QObject *parent)
    : QObject(parent)
@@ -46,7 +47,7 @@ void WasdfCalibrator::handleAnalogPinReadingChanged(int pinNumberOnArduino, int
{
    PinNumDetectionAndCalibrationData currentPinData = m_AccumulatedDistancesEachAnalogPinMoved_ByAnalogPinId.value(pinNumberOnArduino, PinNumDetectionAndCalibrationData());

    //this line of code is to enablefacilitate analog pin number detection:
    currentPinData.AccumulatedDistanceThePinHasMoved += static_cast<long>(abs(currentPinData.PreviousPinPosition - newPinPosition));

    //these next few lines of code are for finger movement range calibration:
diff --git a/Projects/wasdf/src/wasdf-cli.pro b/Projects/wasdf/src/wasdf-cli.pro
index 6674a4c..d2f34ac 100644
--- a/Projects/wasdf/src/wasdf-cli.pro
+++ b/Projects/wasdf/src/wasdf-cli.pro
@@ -13,6 +13,9 @@ CONFIG   -= app_bundle

TEMPLATE = app

SOURCES += cli/main.cpp \
    cli/wasdfcli.cpp

include(wasdf.pri)

HEADERS += cli/wasdfcli.h
diff --git a/scripts/d3faults.superior.unattended-upgrades.sh b/scripts/d3faults.superior.unattended-upgrades.sh
index d67e356..4b86cca 100644
--- a/scripts/d3faults.superior.unattended-upgrades.sh
+++ b/scripts/d3faults.superior.unattended-upgrades.sh
@@ -14,3 +14,6 @@ exit 1
#4) Kill the process launched in (2) so that the email in (2b) never gets sent (note: the process may have already exitted, so the script needs to make sure not to crash in that case -- if we store a PID, can't that PID be used by a different process at a later date? TO DOnereq wtfz -- one solution is to add a `pause` after (2b) so that the process DOESN'T exit and we know the PID won't be re-used by some arbitrary 3rd party process)

#alternatively, you can omit the "-y" flag from the apt-get upgrade in (3) so that you are asked to confirm EVERY upgrade, not just ones that ask questions... and you still won't be bothered when there's nothing to upgrade

#TODOmb: instead of running once every 24 hours, run on an event: whenever a DSA is posted. all I'd have to do is subscribe to the mailing list :). I'm not sure if backports has it's own DSA mailing list, it might (and don't backports get upgraded differently anyways (by specifying install again? I forget)) -- doing this would [probably] be less bandwidth wasteful (might be more wasteful xD) and would [definitely] pull in security patches MUCH faster
#TODOoptimization: optimization of above comment^ ... I could parse the relevant packages from the DSA and then determine (systematically) if it even affects me (or my dependencies). I'm not sure exactly how to do that (apt and/or dpkg magic), but I'm 99% sure it's possible. This would cause me to only ever use bandwidth when I need it (aside from polling an email server a bunch LoLoL (or being an email server (fuck that..... but maybe)))