diff --git a/LiBoard.cpp b/LiBoard.cpp index 65658c0..12e62fd 100644 --- a/LiBoard.cpp +++ b/LiBoard.cpp @@ -71,6 +71,14 @@ unsigned long long LiBoard::getBinaryBoard(unsigned short threshold) { return binBoard; } +unsigned long long LiBoard::getBinaryBoard(unsigned short *thresholds) { + getData(); + unsigned long long binBoard = 0; + for (unsigned char i = 0; i<64; ++i) + binBoard |= (((unsigned long long) (values[i]<=thresholds[i])) << i); + return binBoard; +} + bool LiBoard::getSquareOccupancy(unsigned char file, unsigned char rank, long long binaryBoard) { return (bool)((binaryBoard>>getIndex(file, rank))&1); } diff --git a/LiBoard.h b/LiBoard.h index 2e618ab..608a9f5 100644 --- a/LiBoard.h +++ b/LiBoard.h @@ -30,6 +30,7 @@ class LiBoard { void getData(); unsigned char getIndex(unsigned char file, unsigned char rank); unsigned long long getBinaryBoard(unsigned short threshold); + unsigned long long getBinaryBoard(unsigned short *thresholds); bool getSquareOccupancy(unsigned char file, unsigned char rank, long long binaryBoard); private: void clockPulse(); diff --git a/README.md b/README.md index 806e741..0d6bce3 100644 --- a/README.md +++ b/README.md @@ -7,3 +7,45 @@ Clone this repo into `YOUR_ARDUINO_FOLDER/libraries/`. ## Usage If you're just interested in using the board with a script or the app, you'll want to run the `serial_binboard` sketch from the library's examples folder. + +## Thresholds +Each photoresistor requires a threshold value which triggers when each square is occupied or not. There are two options you can use to set the threshold values for each square. + +### Setting Threshold Mode +By default, Liboard is configured to use the Global threshold mode. If you want to change it Per-Square thresholds, then edit the following variable: + +``` C +// !!! choose mode: 1 = global single value, 0 = per-square array !!! +#define USE_GLOBAL_THRESHOLD 1 +``` + +### Option 1 - Global Threshold +Global Threshold mode applies the same threshold value to every photoresistor. If you need to change the sensitivity of the photoresistors, change the value of this variable: +```C +// Option 1 - Global Threshold (Applies to all photoresistors) +unsigned short THRESHOLD = 100; +``` + +### Option 2 - Per-square Thresholds +You can also set individual thresholds for each photoresisor. This is useful if not all your photoresistors are the same type. Per-square thresholds also has more accuracy. You can adjust each square threshold individually by editing each number. +```C +// Option 2 - Per-square threshold (Applies to each individual photoresistor) +unsigned short THRESHOLD[64] = { + // A1..H1 + 150, 150, 150, 150, 150, 150, 150, 150, + // A2..H2 + 150, 150, 150, 150, 150, 150, 150, 150, + // A3..H3 + 100, 100, 100, 100, 100, 100, 100, 100, + // A4..H4 + 100, 100, 100, 100, 100, 100, 100, 100, + // A5..H5 + 600, 600, 600, 600, 600, 600, 600, 600, + // A6..H6 + 600, 600, 600, 600, 600, 600, 600, 600, + // A7..H7 + 300, 300, 300, 300, 300, 300, 300, 300, + // A8..H8 + 300, 300, 300, 300, 300, 300, 300, 300 +}; +``` diff --git a/examples/serial_binboard/serial_binboard.ino b/examples/serial_binboard/serial_binboard.ino index 928c513..1e4c3ea 100644 --- a/examples/serial_binboard/serial_binboard.ino +++ b/examples/serial_binboard/serial_binboard.ino @@ -14,8 +14,39 @@ * along with this program. If not, see . */ #include "LiBoard.h" +#include -const unsigned short THRESHOLD = 100; +// !!! choose mode: 1 = global single value, 0 = per-square array !!! +#define USE_GLOBAL_THRESHOLD 0 + +#if USE_GLOBAL_THRESHOLD +// Option 1 - Global Threshold (Applies to all photoresistors) +unsigned short THRESHOLD = 100; + +#else +// Option 2 - Per-square threshold (Applies to each individual photoresistor) +unsigned short THRESHOLD[64] = { + // A1..H1 + 300, 300, 300, 300, 300, 300, 300, 300, + // A2..H2 + 300, 300, 300, 300, 300, 300, 300, 300, + // A3..H3 + 100, 100, 100, 100, 100, 100, 100, 100, + // A4..H4 + 100, 100, 100, 100, 100, 100, 100, 100, + // A5..H5 + 600, 600, 600, 600, 600, 600, 600, 600, + // A6..H6 + 600, 600, 600, 600, 600, 600, 600, 600, + // A7..H7 + 300, 300, 300, 300, 300, 300, 300, 300, + // A8..H8 + 300, 300, 300, 300, 300, 300, 300, 300, +}; +#endif + +bool calibrating = false; +bool quiet = false; LiBoard board = LiBoard(); unsigned long long lastBinBoard = 0; @@ -26,15 +57,102 @@ void writeBinaryBoard(unsigned long long binBoard) { Serial.write((unsigned char)(binBoard>>(8*(7-i)))); } +// print a single CSV snapshot of raw ADC values (A1..H8 in LiBoard order) +void printRawSnapshotCSV() { + board.getData(); // fills board.values[0..63] + for (int i = 0; i < 64; ++i) { + Serial.print(board.values[i]); + if (i < 63) Serial.print(','); + } + Serial.println(); +} + +// print current threshold values as CSV +void printCurrentThreshold() { +#if USE_GLOBAL_THRESHOLD + // Global Threshold - print one value + Serial.println(THRESHOLD); +#else + // Individual Thresholds - print 64 values + for (int i = 0; i < 64; ++i) { + Serial.print(THRESHOLD[i]); + if (i < 63) Serial.print(','); + } + Serial.println(); +#endif +} + void setup() { delay(3000); Serial.begin(9600); } void loop() { - currentBinBoard = board.getBinaryBoard(THRESHOLD); - if (currentBinBoard != lastBinBoard) { - writeBinaryBoard(currentBinBoard); - lastBinBoard = currentBinBoard; + // Serial Monitor arguements + if (Serial.available()) { + int c = Serial.read(); + // if host sends '?', reply with one CSV line of raw ADC values + if (c == '?') { + printRawSnapshotCSV(); + } + + // if host sends '!', reply with current threshold values + if (c == '!') { + printCurrentThreshold(); + } + + // Toggle quiet mode (Used to silence bitboard output) + if (c == 'q' && quiet == false) { + quiet = true; + Serial.println("Quiet Mode Activated!"); + } + else if (c == 'q' && quiet == true) { + quiet = false; + Serial.println("Exited Quiet Mode!"); + } + + // Calibration Mode for editing THRESHOLD + if (c == 'c') { + calibrating = true; + Serial.println("Calibration Mode Activated!"); + } + + while (calibrating) { + if (Serial.available()){ + // read a whole line the user pasted + String line = Serial.readStringUntil('\n'); + line.trim(); + if (line.length() == 0) continue; + +#if USE_GLOBAL_THRESHOLD + // Global Threshold Calibration + long newThreshold = line.toInt(); + THRESHOLD = (unsigned short)newThreshold; +#else + // Per-Square Calibration + char buf[1024]; + line.toCharArray(buf, 1024); + char* tok = strtok(buf, ","); + + int i = 0; + while (tok && i < 64) { + THRESHOLD[i++] = (unsigned short)atoi(tok); + tok = strtok(nullptr, ","); + } +#endif + calibrating = false; + // eat non-numeric to avoid getting stuck + while (Serial.available()) Serial.read(); + } + } + } + + // Bitboard logic for normal use + if (!quiet && !calibrating) { + currentBinBoard = board.getBinaryBoard(THRESHOLD); + if (currentBinBoard != lastBinBoard) { + writeBinaryBoard(currentBinBoard); + lastBinBoard = currentBinBoard; + } } }