From 758ca3cf5463fdba9483707b4f3d7897b23b2493 Mon Sep 17 00:00:00 2001 From: Robert Diamond Date: Tue, 21 Jul 2020 19:28:30 -0700 Subject: [PATCH 1/5] implement the calculator and a test --- MakerCalc/MakerCalc.ino | 8 +--- MakerCalc/calculator.cpp | 98 ++++++++++++++++++++++++++++------------ MakerCalc/calculator.h | 30 +++++++----- test/Makefile | 13 ++++++ test/test.cpp | 27 +++++++++++ 5 files changed, 130 insertions(+), 46 deletions(-) create mode 100644 test/Makefile create mode 100644 test/test.cpp diff --git a/MakerCalc/MakerCalc.ino b/MakerCalc/MakerCalc.ino index e91177d..bd82c75 100644 --- a/MakerCalc/MakerCalc.ino +++ b/MakerCalc/MakerCalc.ino @@ -1,6 +1,6 @@ #include "Arduino.h" #include -#include +//#include #include #include #include @@ -202,10 +202,7 @@ void menuDebug() { void calcDebug() { Serial.println("Calculator Debug======================================"); - Serial.print("IB("); Serial.print(calc->ib_idx); Serial.print("): "); Serial.println(calc->input_buffer); - Serial.print("C1: "); Serial.println(calc->c1); - Serial.print("OPR: "); Serial.println(calc->oper); - Serial.print("C2: "); Serial.println(calc->c2); + Serial.print("IB("); Serial.print("): "); Serial.println(calc->input_buffer); Serial.print("RES: "); Serial.println(calc->result); } @@ -216,4 +213,3 @@ void unitDebug() { Serial.print("\tResult: "); Serial.println(unit->result); } - diff --git a/MakerCalc/calculator.cpp b/MakerCalc/calculator.cpp index b65d6dc..9c13818 100644 --- a/MakerCalc/calculator.cpp +++ b/MakerCalc/calculator.cpp @@ -1,47 +1,89 @@ -#include "Arduino.h" +#include +#include +#include +#include +#include #include "calculator.h" -Calculator::Calculator() { - -} +char const * Calculator::operators = "+-/*"; +uint8_t Calculator::operator_precedence[] = {0,0,1,1}; void Calculator::init() { - memset(this->input_buffer, 0, 19); - memset(this->c1, 0, 19); - memset(this->c2, 0, 19); - memset(this->result, 0, 19); - this->ib_idx = 0; + this->input_buffer[0] = '\0'; + this->result[0] = '\0'; + this->saw_decimal = false; + input_pos = 0; + num_pos = 0; + oper_pos = 0; } /* * Handle Keyboard input */ void Calculator::input(char key) { - // Valid chars to add to input_buffer: [0-9], '.' - if(isDigit(key) || key == '.') { // Regular Input - this->input_buffer[ib_idx] = key; - this->input_buffer[ib_idx+1] = '\0'; - this->ib_idx++; - } else if(strchr(this->operators, key)) { // Operator Input - // Store Operator - this->oper = key; - - // Check to see if this is first value. Store it if it is. - // If not store in second value. - if(strlen(this->c1) == 0 && strlen(this->c2) == 0) { - strncpy(this->input_buffer, this->c1, sizeof(this->input_buffer)); - memset(this->input_buffer, 0, 19); - this->ib_idx = 0; - } else if(strlen(this->c2) == 0) { - strncpy(this->input_buffer, this->c2, sizeof(this->input_buffer)); - this->calculate(); + if(isdigit(key) || key == '.') { // Regular Input + if (key == '.') { + if (saw_decimal) return; + saw_decimal = true; + } + if (input_pos < INPUT_BUFFER_SIZE) { + this->input_buffer[input_pos++] = key; + this->input_buffer[input_pos] = '\0'; } - } else if(key == '=') { // Equals. + } else { + // Store Operand + double value = strtod(input_buffer, nullptr); + if (num_pos < NUM_STACK_LENGTH) { + num_stack[num_pos++] = value; + } + saw_decimal = false; + input_pos = 0; + if (index(operators, key) != nullptr) { // Operator Input + int keyPrecedence = precedence(key); + if ((oper_pos > 0 && + precedence(oper_stack[oper_pos - 1]) >= + keyPrecedence)) { + collapse_stack(); + } + oper_stack[oper_pos++] = key; + } else if(key == '=') { // Equals. + collapse_stack(); + } } } void Calculator::calculate() { } + +void Calculator::collapse_stack() { + double calc_result = 0; + while (oper_pos > 0) { + char key = oper_stack[--oper_pos]; + if (num_pos < 2) { + num_pos = 0; + oper_pos = 0; + break; + } + double op2 = num_stack[--num_pos]; + double op1 = num_stack[--num_pos]; + switch (key) { + case '+': calc_result = op1 + op2; break; + case '-': calc_result = op1 - op2; break; + case '*': calc_result = op1 * op2; break; + case '/': calc_result = op1 / op2; break; + } + if (num_pos < NUM_STACK_LENGTH) { + num_stack[num_pos++] = calc_result; + } + } + snprintf(result, RESULT_SIZE, "%g", calc_result); +} + +int Calculator::precedence(char op) { + char *idx = index((char *)operators, op); + if (idx == nullptr) { return -1; } + return operator_precedence[idx - operators]; +} \ No newline at end of file diff --git a/MakerCalc/calculator.h b/MakerCalc/calculator.h index 9535a57..75f9ecf 100644 --- a/MakerCalc/calculator.h +++ b/MakerCalc/calculator.h @@ -1,27 +1,33 @@ #ifndef calculator_h #define calculator_h -#include "Arduino.h" - -#endif +#define INPUT_BUFFER_SIZE 32 +#define RESULT_SIZE 32 +#define NUM_STACK_LENGTH 20 +#define OP_STACK_LENGTH 20 class Calculator { public: - char c1[19]; - char c2[19]; - char oper; - char result[19]; - char input_buffer[19]; - int ib_idx; + char result[RESULT_SIZE+1]; + char input_buffer[INPUT_BUFFER_SIZE+1]; + uint16_t input_pos; - Calculator(); + Calculator() {init(); } void init(); void input(char key); void calculate(); private: - char operators[5] = "+-*/"; - + static char const *operators; + static uint8_t operator_precedence[]; + bool saw_decimal; + double num_stack[NUM_STACK_LENGTH]; + uint8_t num_pos; + char oper_stack[OP_STACK_LENGTH]; + uint8_t oper_pos; + void collapse_stack(); + int precedence(char op); }; +#endif diff --git a/test/Makefile b/test/Makefile new file mode 100644 index 0000000..62d3324 --- /dev/null +++ b/test/Makefile @@ -0,0 +1,13 @@ +CPPFLAGS := -I../MakerCalc -I. +CXXFLAGS := -g + +.PHONY: all +all: testCalculator + +testCalculator: calculator.o test.o + $(CXX) $(CXXFLAGS) -o $@ $^ + +calculator.o: ../MakerCalc/calculator.h ../MakerCalc/calculator.cpp + $(CXX) $(CPPFLAGS) $(CXXFLAGS) -c -o $@ ../MakerCalc/calculator.cpp + +test.o: ../MakerCalc/calculator.h test.cpp \ No newline at end of file diff --git a/test/test.cpp b/test/test.cpp new file mode 100644 index 0000000..710df61 --- /dev/null +++ b/test/test.cpp @@ -0,0 +1,27 @@ +#include +#include + +#include "calculator.h" + +bool driveCalc(std::string inputStr, std::string result); + +int main(void) { + std::cout << "add test " << (driveCalc("2+2=","4") ? "pass" : "fail") << std::endl; + std::cout << "multiadd test " << (driveCalc("2+3+4=","9") ? "pass" : "fail") << std::endl; + std::cout << "mult test " << (driveCalc("2*3=","6") ? "pass" : "fail") << std::endl; + std::cout << "multmult test " << (driveCalc("2*3*4=","24") ? "pass" : "fail") << std::endl; + std::cout << "div test " << (driveCalc("6/3=","2") ? "pass" : "fail") << std::endl; + std::cout << "multidiv test " << (driveCalc("12/2/3=","2") ? "pass" : "fail") << std::endl; + std::cout << "precedence test 1 " << (driveCalc("2*3+4=","10") ? "pass" : "fail") << std::endl; + std::cout << "precedence test 2 " << (driveCalc("2+3*4=","14") ? "pass" : "fail") << std::endl; + std::cout << "precedence test 2 " << (driveCalc("2+3/4=","2.75") ? "pass" : "fail") << std::endl; +} + +bool driveCalc(std::string inputStr, std::string result) { + Calculator calculator; + for (char c : inputStr) { + calculator.input(c); + } + std::cout << "result for " << inputStr << ": " << calculator.result << " expected " << result << std::endl; + return calculator.result == result; +} \ No newline at end of file From 92698b7bfb0c0d28123a92deb525a3c1c9e15ecb Mon Sep 17 00:00:00 2001 From: Robert Diamond Date: Wed, 22 Jul 2020 17:24:38 -0700 Subject: [PATCH 2/5] gitignore --- MakerCalc/.gitignore | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/MakerCalc/.gitignore b/MakerCalc/.gitignore index bdc89dd..226a5ca 100644 --- a/MakerCalc/.gitignore +++ b/MakerCalc/.gitignore @@ -1,4 +1,6 @@ build .vscode .kceHelpers.cpp -.kceHelperrs.h \ No newline at end of file +.kceHelperrs.h +**/*.o +test/testCalculator \ No newline at end of file From cf9173ee1798c65c4844e8874eefe12b07830e92 Mon Sep 17 00:00:00 2001 From: Robert Diamond Date: Sat, 19 Jun 2021 15:59:46 -0700 Subject: [PATCH 3/5] fixes --- .gitignore | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 .gitignore diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..be593f8 --- /dev/null +++ b/.gitignore @@ -0,0 +1,3 @@ +*.o +*.a +testCalculator From 6ec7da28566482990ef9ce6b6c12d82a57a5d4dc Mon Sep 17 00:00:00 2001 From: Robert Diamond Date: Sat, 19 Jun 2021 16:02:40 -0700 Subject: [PATCH 4/5] format files --- MakerCalc/calculator.cpp | 138 ++++++------ MakerCalc/calculator.h | 38 ++-- MakerCalc/display.cpp | 99 +++++---- MakerCalc/display.h | 102 +++++---- MakerCalc/kceHelpers.cpp | 2 +- MakerCalc/unitconv.cpp | 447 ++++++++++++++++++++------------------- MakerCalc/unitconv.h | 63 +++--- 7 files changed, 454 insertions(+), 435 deletions(-) diff --git a/MakerCalc/calculator.cpp b/MakerCalc/calculator.cpp index 9c13818..7fab23b 100644 --- a/MakerCalc/calculator.cpp +++ b/MakerCalc/calculator.cpp @@ -1,89 +1,97 @@ +#include "calculator.h" #include #include #include #include #include -#include "calculator.h" -char const * Calculator::operators = "+-/*"; -uint8_t Calculator::operator_precedence[] = {0,0,1,1}; +char const *Calculator::operators = "+-/*"; +uint8_t Calculator::operator_precedence[] = {0, 0, 1, 1}; void Calculator::init() { - this->input_buffer[0] = '\0'; - this->result[0] = '\0'; - this->saw_decimal = false; - input_pos = 0; - num_pos = 0; - oper_pos = 0; + this->input_buffer[0] = '\0'; + this->result[0] = '\0'; + this->saw_decimal = false; + input_pos = 0; + num_pos = 0; + oper_pos = 0; } /* * Handle Keyboard input - */ + */ void Calculator::input(char key) { - // Valid chars to add to input_buffer: [0-9], '.' - if(isdigit(key) || key == '.') { // Regular Input - if (key == '.') { - if (saw_decimal) return; - saw_decimal = true; - } - if (input_pos < INPUT_BUFFER_SIZE) { - this->input_buffer[input_pos++] = key; - this->input_buffer[input_pos] = '\0'; - } - } else { - // Store Operand - double value = strtod(input_buffer, nullptr); - if (num_pos < NUM_STACK_LENGTH) { - num_stack[num_pos++] = value; - } - saw_decimal = false; - input_pos = 0; + // Valid chars to add to input_buffer: [0-9], '.' + if (isdigit(key) || key == '.') { // Regular Input + if (key == '.') { + if (saw_decimal) + return; + saw_decimal = true; + } + if (input_pos < INPUT_BUFFER_SIZE) { + this->input_buffer[input_pos++] = key; + this->input_buffer[input_pos] = '\0'; + } + } else { + // Store Operand + double value = strtod(input_buffer, nullptr); + if (num_pos < NUM_STACK_LENGTH) { + num_stack[num_pos++] = value; + } + saw_decimal = false; + input_pos = 0; - if (index(operators, key) != nullptr) { // Operator Input - int keyPrecedence = precedence(key); - if ((oper_pos > 0 && - precedence(oper_stack[oper_pos - 1]) >= - keyPrecedence)) { - collapse_stack(); - } - oper_stack[oper_pos++] = key; - } else if(key == '=') { // Equals. - collapse_stack(); - } + if (index(operators, key) != nullptr) { // Operator Input + int keyPrecedence = precedence(key); + if ((oper_pos > 0 && + precedence(oper_stack[oper_pos - 1]) >= keyPrecedence)) { + collapse_stack(); + } + oper_stack[oper_pos++] = key; + } else if (key == '=') { // Equals. + collapse_stack(); } + } } -void Calculator::calculate() { - -} +void Calculator::calculate() {} void Calculator::collapse_stack() { - double calc_result = 0; - while (oper_pos > 0) { - char key = oper_stack[--oper_pos]; - if (num_pos < 2) { - num_pos = 0; - oper_pos = 0; - break; - } - double op2 = num_stack[--num_pos]; - double op1 = num_stack[--num_pos]; - switch (key) { - case '+': calc_result = op1 + op2; break; - case '-': calc_result = op1 - op2; break; - case '*': calc_result = op1 * op2; break; - case '/': calc_result = op1 / op2; break; - } - if (num_pos < NUM_STACK_LENGTH) { - num_stack[num_pos++] = calc_result; - } + double calc_result = 0; + while (oper_pos > 0) { + char key = oper_stack[--oper_pos]; + if (num_pos < 2) { + num_pos = 0; + oper_pos = 0; + break; + } + double op2 = num_stack[--num_pos]; + double op1 = num_stack[--num_pos]; + switch (key) { + case '+': + calc_result = op1 + op2; + break; + case '-': + calc_result = op1 - op2; + break; + case '*': + calc_result = op1 * op2; + break; + case '/': + calc_result = op1 / op2; + break; + } + if (num_pos < NUM_STACK_LENGTH) { + num_stack[num_pos++] = calc_result; } - snprintf(result, RESULT_SIZE, "%g", calc_result); + } + snprintf(result, RESULT_SIZE, "%g", calc_result); } int Calculator::precedence(char op) { - char *idx = index((char *)operators, op); - if (idx == nullptr) { return -1; } - return operator_precedence[idx - operators]; + char *idx = index((char *)operators, op); + if (idx == nullptr) { + return -1; + } + return operator_precedence[idx - operators]; } \ No newline at end of file diff --git a/MakerCalc/calculator.h b/MakerCalc/calculator.h index 75f9ecf..1886363 100644 --- a/MakerCalc/calculator.h +++ b/MakerCalc/calculator.h @@ -7,27 +7,27 @@ #define OP_STACK_LENGTH 20 class Calculator { - public: - char result[RESULT_SIZE+1]; - char input_buffer[INPUT_BUFFER_SIZE+1]; - uint16_t input_pos; - - Calculator() {init(); } +public: + char result[RESULT_SIZE + 1]; + char input_buffer[INPUT_BUFFER_SIZE + 1]; + uint16_t input_pos; - void init(); - void input(char key); - void calculate(); + Calculator() { init(); } - private: - static char const *operators; - static uint8_t operator_precedence[]; - bool saw_decimal; - double num_stack[NUM_STACK_LENGTH]; - uint8_t num_pos; - char oper_stack[OP_STACK_LENGTH]; - uint8_t oper_pos; + void init(); + void input(char key); + void calculate(); - void collapse_stack(); - int precedence(char op); +private: + static char const *operators; + static uint8_t operator_precedence[]; + bool saw_decimal; + double num_stack[NUM_STACK_LENGTH]; + uint8_t num_pos; + char oper_stack[OP_STACK_LENGTH]; + uint8_t oper_pos; + + void collapse_stack(); + int precedence(char op); }; #endif diff --git a/MakerCalc/display.cpp b/MakerCalc/display.cpp index becf2d0..2f08106 100644 --- a/MakerCalc/display.cpp +++ b/MakerCalc/display.cpp @@ -1,68 +1,81 @@ +#include "display.h" #include "Arduino.h" #include -#include "display.h" Display::Display(uint16_t addr, uint16_t cols, uint16_t rows) { - _lcd = new LiquidCrystal_I2C(addr, cols, rows); - num_units = NUM_UNITS; - um_rows = UM_ROWS; - um_cols = UM_COLS; + _lcd = new LiquidCrystal_I2C(addr, cols, rows); + num_units = NUM_UNITS; + um_rows = UM_ROWS; + um_cols = UM_COLS; } void Display::init() { - _lcd->init(); - _lcd->backlight(); - _lcd->clear(); - this->metric_unit_idx = 0; - memset(this->input_buffer, 0, 19); - memset(this->result_buffer, 0, 19); - // memset(this->calc_input, 0, 19); - // this->calc_input[0] = 0; + _lcd->init(); + _lcd->backlight(); + _lcd->clear(); + this->metric_unit_idx = 0; + memset(this->input_buffer, 0, 19); + memset(this->result_buffer, 0, 19); + // memset(this->calc_input, 0, 19); + // this->calc_input[0] = 0; } void Display::draw() { - int unit_from_idx = unit_matrix[this->enc_val][0]; - int unit_to_idx = unit_matrix[this->enc_val][1]; - int flip_bit = unit_matrix[this->enc_val][2]; + int unit_from_idx = unit_matrix[this->enc_val][0]; + int unit_to_idx = unit_matrix[this->enc_val][1]; + int flip_bit = unit_matrix[this->enc_val][2]; - // If we are in calculator mode, draw calculator. - if(unit_from_idx == 0 || unit_to_idx == 0) { this->drawCalc(); return; } + // If we are in calculator mode, draw calculator. + if (unit_from_idx == 0 || unit_to_idx == 0) { + this->drawCalc(); + return; + } - // Clear and draw statics - _lcd->clear(); + // Clear and draw statics + _lcd->clear(); - _lcd->setCursor(0, 2); _lcd->print(">"); - _lcd->setCursor(0, 3); _lcd->print("Res: "); + _lcd->setCursor(0, 2); + _lcd->print(">"); + _lcd->setCursor(0, 3); + _lcd->print("Res: "); - // Draw to/From - _lcd->setCursor(0, 0); - _lcd->print(units[unit_from_idx].name); _lcd->print(" -> "); _lcd->print(units[unit_to_idx].name); + // Draw to/From + _lcd->setCursor(0, 0); + _lcd->print(units[unit_from_idx].name); + _lcd->print(" -> "); + _lcd->print(units[unit_to_idx].name); - // Draw variable data + // Draw variable data - _lcd->setCursor(2, 2); _lcd->print(this->input_buffer); - //_lcd->setCursor(18, 2); _lcd->print(metric_units[this->metric_unit_idx].name); - _lcd->setCursor(5, 3); _lcd->print(this->result_buffer); + _lcd->setCursor(2, 2); + _lcd->print(this->input_buffer); + //_lcd->setCursor(18, 2); + //_lcd->print(metric_units[this->metric_unit_idx].name); + _lcd->setCursor(5, 3); + _lcd->print(this->result_buffer); } void Display::drawCalc() { - _lcd->clear(); - _lcd->setCursor(0, 0); _lcd->print("Basic Calculator"); + _lcd->clear(); + _lcd->setCursor(0, 0); + _lcd->print("Basic Calculator"); } bool Display::flipUnits() { - // Store in temp var to not overwrite. - int tmp_to = unit_matrix[this->enc_val][0]; - int tmp_from = unit_matrix[this->enc_val][1]; - - // Swap indexes in unit matrix. - unit_matrix[this->enc_val][0] = tmp_from; - unit_matrix[this->enc_val][1] = tmp_to; + // Store in temp var to not overwrite. + int tmp_to = unit_matrix[this->enc_val][0]; + int tmp_from = unit_matrix[this->enc_val][1]; + + // Swap indexes in unit matrix. + unit_matrix[this->enc_val][0] = tmp_from; + unit_matrix[this->enc_val][1] = tmp_to; - // Flip the flip flipper bit - if(unit_matrix[this->enc_val][2] == 0) { unit_matrix[this->enc_val][2] = 1; } else - if(unit_matrix[this->enc_val][2] == 1) { unit_matrix[this->enc_val][2] = 0; } + // Flip the flip flipper bit + if (unit_matrix[this->enc_val][2] == 0) { + unit_matrix[this->enc_val][2] = 1; + } else if (unit_matrix[this->enc_val][2] == 1) { + unit_matrix[this->enc_val][2] = 0; + } - return true; - + return true; } \ No newline at end of file diff --git a/MakerCalc/display.h b/MakerCalc/display.h index e8821ba..1d2d4ea 100644 --- a/MakerCalc/display.h +++ b/MakerCalc/display.h @@ -12,67 +12,65 @@ typedef struct { char name[2]; long mult; } Metric_Units; - + #define NUM_UNITS 10 #define UM_ROWS 11 #define UM_COLS 3 -class Display{ - public: - int enc_val; - int um_rows; - int um_cols; - int num_units; - int metric_unit_idx; - char input_buffer[19]; - char result_buffer[19]; - char calc_input[19]; - - Display(uint16_t addr, uint16_t cols, uint16_t rows); - - Unit units[NUM_UNITS] = { - {"Calculator", 0}, // 0 - {"Metric", 1}, // 1 - {"Frac", 0}, // 2 - {"Tenths", 0}, // 3 - {"Lumen", 0}, // 4 - {"Candela", 0}, // 5 - {"MPH", 0}, // 6 - {"KPH", 0}, // 7 - {"in/s", 0}, // 8 - {"mm/s", 0}, // 9 - }; +class Display { +public: + int enc_val; + int um_rows; + int um_cols; + int num_units; + int metric_unit_idx; + char input_buffer[19]; + char result_buffer[19]; + char calc_input[19]; + Display(uint16_t addr, uint16_t cols, uint16_t rows); - Metric_Units metric_units[4] = { - {"mm", 1}, // 0 - {"cm", 10}, // 1 - {"m", 1000}, // 2 - {"km", 1000000}, // 3 - }; + Unit units[NUM_UNITS] = { + {"Calculator", 0}, // 0 + {"Metric", 1}, // 1 + {"Frac", 0}, // 2 + {"Tenths", 0}, // 3 + {"Lumen", 0}, // 4 + {"Candela", 0}, // 5 + {"MPH", 0}, // 6 + {"KPH", 0}, // 7 + {"in/s", 0}, // 8 + {"mm/s", 0}, // 9 + }; - int unit_matrix[UM_ROWS][UM_COLS] = { - // | IDX | Conversion | Flipped | - { 0, 0, 0 }, // | 0 | ---- Calculator ---- | - { 1, 2, 0 }, // | 1 | Metric->Frac | Frac->Metric | - { 1, 3, 0 }, // | 2 | Metric->Tenths | Tenths->Metric | - { 2, 3, 0 }, // | 3 | Frac->Tenths | Tenths->Frac | - { 4, 5, 0 }, // | 4 | Lumen->Candela | Candela->Lumen | - { 6, 7, 0 }, // | 5 | MPH->KPH | KPH->MPH | - { 6, 8, 0 }, // | 6 | MPH->in/s | in/s->MPH | - { 6, 9, 0 }, // | 7 | MPH->mm/s | mm/s->MPH | - { 7, 8, 0 }, // | 8 | KPH->in/s | in/s->KPH | - { 7, 9, 0 }, // | 9 | KPH->mm/s | mm/s->KPH | - { 8, 9, 0 } // | 10 | in/s->mm/s | mm/s->in/s | - }; - void init(); - void draw(); - void drawCalc(); - bool flipUnits(); + Metric_Units metric_units[4] = { + {"mm", 1}, // 0 + {"cm", 10}, // 1 + {"m", 1000}, // 2 + {"km", 1000000}, // 3 + }; + int unit_matrix[UM_ROWS][UM_COLS] = { + // | IDX | Conversion | Flipped | + {0, 0, 0}, // | 0 | ---- Calculator ---- | + {1, 2, 0}, // | 1 | Metric->Frac | Frac->Metric | + {1, 3, 0}, // | 2 | Metric->Tenths | Tenths->Metric | + {2, 3, 0}, // | 3 | Frac->Tenths | Tenths->Frac | + {4, 5, 0}, // | 4 | Lumen->Candela | Candela->Lumen | + {6, 7, 0}, // | 5 | MPH->KPH | KPH->MPH | + {6, 8, 0}, // | 6 | MPH->in/s | in/s->MPH | + {6, 9, 0}, // | 7 | MPH->mm/s | mm/s->MPH | + {7, 8, 0}, // | 8 | KPH->in/s | in/s->KPH | + {7, 9, 0}, // | 9 | KPH->mm/s | mm/s->KPH | + {8, 9, 0} // | 10 | in/s->mm/s | mm/s->in/s | + }; + void init(); + void draw(); + void drawCalc(); + bool flipUnits(); - private: - LiquidCrystal_I2C* _lcd; +private: + LiquidCrystal_I2C *_lcd; }; #endif \ No newline at end of file diff --git a/MakerCalc/kceHelpers.cpp b/MakerCalc/kceHelpers.cpp index 2376f55..f6a91ef 100644 --- a/MakerCalc/kceHelpers.cpp +++ b/MakerCalc/kceHelpers.cpp @@ -1,2 +1,2 @@ -#include "Arduino.h" #include "kceHelpers.h" +#include "Arduino.h" diff --git a/MakerCalc/unitconv.cpp b/MakerCalc/unitconv.cpp index 5f2fd41..2ce30a4 100644 --- a/MakerCalc/unitconv.cpp +++ b/MakerCalc/unitconv.cpp @@ -1,316 +1,316 @@ -#include #include "unitconv.h" +#include - -UnitConvertor::UnitConvertor() { - -} +UnitConvertor::UnitConvertor() {} void UnitConvertor::init() { - memset(this->input_buffer, 0, 19); - memset(this->result, 0, 19); - this->ib_idx = 0; - this->flip = 0; + memset(this->input_buffer, 0, 19); + memset(this->result, 0, 19); + this->ib_idx = 0; + this->flip = 0; } void UnitConvertor::input(char key) { - // Check if Equals or input. - if(key == '=') { // Do Conversion - this->convert(); - } else if(key == 'C') { // Clear - this->init(); - } else { // Read values into buffer - this->input_buffer[ib_idx] = key; - this->input_buffer[ib_idx+1] = '\0'; - this->ib_idx++; - } + // Check if Equals or input. + if (key == '=') { // Do Conversion + this->convert(); + } else if (key == 'C') { // Clear + this->init(); + } else { // Read values into buffer + this->input_buffer[ib_idx] = key; + this->input_buffer[ib_idx + 1] = '\0'; + this->ib_idx++; + } } void UnitConvertor::convert() { - switch(this->matrix_idx) { - case 1: - // TODO: START - this->metricFrac(); - break; - case 2: - this->metricTenths(); - break; - case 3: - this->fractTenths(); - break; - case 4: - // TODO: FINISH - this->lumenCandela(); - break; - case 5: - this->mphKph(); - break; - case 6: - this->mphIns(); - break; - case 7: - this->mphMms(); - break; - case 8: - this->kphIns(); - break; - case 9: - this->kphMms(); - break; - case 10: - this->insMms(); - break; - } + switch (this->matrix_idx) { + case 1: + // TODO: START + this->metricFrac(); + break; + case 2: + this->metricTenths(); + break; + case 3: + this->fractTenths(); + break; + case 4: + // TODO: FINISH + this->lumenCandela(); + break; + case 5: + this->mphKph(); + break; + case 6: + this->mphIns(); + break; + case 7: + this->mphMms(); + break; + case 8: + this->kphIns(); + break; + case 9: + this->kphMms(); + break; + case 10: + this->insMms(); + break; + } } void UnitConvertor::metricFrac() { - float input = atof(this->input_buffer); + float input = atof(this->input_buffer); + + if (this->flip) { // Fractional -> Metric + char tmp_input[19]; + strcpy(tmp_input, this->input_buffer); + char *token = strtok(tmp_input, " "); + long whole_number = atol(token); + token = strtok(NULL, "/"); + long numerator = atol(token); + token = strtok(NULL, "/"); + long denominator = atol(token); - if(this->flip) { // Fractional -> Metric - char tmp_input[19]; - strcpy(tmp_input, this->input_buffer); - char* token = strtok(tmp_input, " "); long whole_number = atol(token); - token = strtok(NULL, "/"); long numerator = atol(token); - token = strtok(NULL, "/"); long denominator = atol(token); + // Do the math + float dec = (float)numerator / (float)denominator; + float res = (float)whole_number + dec; + res = (res * 25.4); - // Do the math - float dec = (float)numerator / (float)denominator; - float res = (float)whole_number + dec; - res = (res * 25.4); + // TODO: Add metric unit designator - // TODO: Add metric unit designator + dtostrf(res, 0, 7, this->result); - dtostrf(res, 0, 7, this->result); + } else { // Metric -> Fractional + // Convert to mm + float metric_input = (input / 25.4); - } else { // Metric -> Fractional - - // Convert to mm - float metric_input = (input / 25.4); - - this->dectofrac(metric_input); - } + this->dectofrac(metric_input); + } } void UnitConvertor::metricTenths() { - float input = atof(this->input_buffer); - float res; - if(this->flip) { // Tenths -> Metric - res = (input * 25.4); - } else { // Metric -> Tenths - res = (input / 25.4); - } - - dtostrf(res, 0, 4, this->result); + float input = atof(this->input_buffer); + float res; + if (this->flip) { // Tenths -> Metric + res = (input * 25.4); + } else { // Metric -> Tenths + res = (input / 25.4); + } + + dtostrf(res, 0, 4, this->result); } void UnitConvertor::fractTenths() { - float input = atof(this->input_buffer); - - if(this->flip) { - dectofrac(input); - } else { - // Split fraction into whole, numerator, denominator. - char tmp_input[19]; - strcpy(tmp_input, this->input_buffer); - char* token = strtok(tmp_input, " "); long whole_number = atol(token); - token = strtok(NULL, "/"); long numerator = atol(token); - token = strtok(NULL, "/"); long denominator = atol(token); - - // Serial.print("WN: "); Serial.println(whole_number); - // Serial.print("NU: "); Serial.println(numerator); - // Serial.print("DE: "); Serial.println(denominator); - - // Do the math - float dec = (float)numerator / (float)denominator; - float res = (float)whole_number + dec; + float input = atof(this->input_buffer); + + if (this->flip) { + dectofrac(input); + } else { + // Split fraction into whole, numerator, denominator. + char tmp_input[19]; + strcpy(tmp_input, this->input_buffer); + char *token = strtok(tmp_input, " "); + long whole_number = atol(token); + token = strtok(NULL, "/"); + long numerator = atol(token); + token = strtok(NULL, "/"); + long denominator = atol(token); + // Serial.print("WN: "); Serial.println(whole_number); + // Serial.print("NU: "); Serial.println(numerator); + // Serial.print("DE: "); Serial.println(denominator); - dtostrf(res, 0, 7, this->result); + // Do the math + float dec = (float)numerator / (float)denominator; + float res = (float)whole_number + dec; - } + dtostrf(res, 0, 7, this->result); + } } void UnitConvertor::lumenCandela() { - float input = atof(this->input_buffer); - float res; - if(this->flip) { // Candela -> Lumens - res = input / ((2*PI) - cos(0/2)); - } else { // Lumens -> Candela - - } + float input = atof(this->input_buffer); + float res; + if (this->flip) { // Candela -> Lumens + res = input / ((2 * PI) - cos(0 / 2)); + } else { // Lumens -> Candela + } - dtostrf(res, 0, 4, this->result); + dtostrf(res, 0, 4, this->result); } void UnitConvertor::mphKph() { - float input = atof(this->input_buffer); - float res; - if(this->flip) { // KPH -> MPH - res = (input / 1.60934); - } else { // MPH -> KPH - res = (input * 1.60934); - } - - dtostrf(res, 0, 4, this->result); + float input = atof(this->input_buffer); + float res; + if (this->flip) { // KPH -> MPH + res = (input / 1.60934); + } else { // MPH -> KPH + res = (input * 1.60934); + } + + dtostrf(res, 0, 4, this->result); } void UnitConvertor::mphIns() { - float input = atof(this->input_buffer); - float res; - if(this->flip) { // inch/sec -> MPH - res = (input / 17.6); - } else { // MPH -> inch/sec - res = (input * 17.6); - } - - dtostrf(res, 0, 4, this->result); + float input = atof(this->input_buffer); + float res; + if (this->flip) { // inch/sec -> MPH + res = (input / 17.6); + } else { // MPH -> inch/sec + res = (input * 17.6); + } + + dtostrf(res, 0, 4, this->result); } void UnitConvertor::mphMms() { - float input = atof(this->input_buffer); - float res; - if(this->flip) { // mm/s -> MPH - res = (input / 447.04); - } else { // MPH -> mm/s - res = (input * 447.04); - } - - dtostrf(res, 0, 4, this->result); + float input = atof(this->input_buffer); + float res; + if (this->flip) { // mm/s -> MPH + res = (input / 447.04); + } else { // MPH -> mm/s + res = (input * 447.04); + } + + dtostrf(res, 0, 4, this->result); } void UnitConvertor::kphIns() { - float input = atof(this->input_buffer); - float res; - if(this->flip) { // Inch/Sec -> KPH - res = (input / 10.9361); - } else { // KPH -> Inch/Sec - res = (input * 10.9361); - } - - dtostrf(res, 0, 4, this->result); + float input = atof(this->input_buffer); + float res; + if (this->flip) { // Inch/Sec -> KPH + res = (input / 10.9361); + } else { // KPH -> Inch/Sec + res = (input * 10.9361); + } + + dtostrf(res, 0, 4, this->result); } void UnitConvertor::kphMms() { - float input = atof(this->input_buffer); - float res; - if(this->flip) { // mm/s -> KPH - res = (input / 277.778); - } else { // KPH -> mm/s - res = (input * 277.778); - } - - dtostrf(res, 0, 4, this->result); + float input = atof(this->input_buffer); + float res; + if (this->flip) { // mm/s -> KPH + res = (input / 277.778); + } else { // KPH -> mm/s + res = (input * 277.778); + } + + dtostrf(res, 0, 4, this->result); } void UnitConvertor::insMms() { - float input = atof(this->input_buffer); - float res; - if(this->flip) { // mm/s -> Inch/Sec - res = (input / 25.4); - } else { // Inch/Sec -> mm/s - res = (input * 25.4); - } - - dtostrf(res, 0, 4, this->result); -} + float input = atof(this->input_buffer); + float res; + if (this->flip) { // mm/s -> Inch/Sec + res = (input / 25.4); + } else { // Inch/Sec -> mm/s + res = (input * 25.4); + } + dtostrf(res, 0, 4, this->result); +} // Utility Functions /* * getMultiplier() * This function separates the number to the right - * of the decimal place, counts the digits and + * of the decimal place, counts the digits and * returns the multiplier factor for converting * decimal to fractions. */ long UnitConvertor::getMultiplier(char *input) { - char* charDec = strtok(input, "."); - charDec = strtok(NULL, "."); - int i = strlen(charDec); - long multiplier = pow(10, (i + 0.000005)); + char *charDec = strtok(input, "."); + charDec = strtok(NULL, "."); + int i = strlen(charDec); + long multiplier = pow(10, (i + 0.000005)); - return multiplier; + return multiplier; } /* * gcd() - * Returns the greatest common denominator from the + * Returns the greatest common denominator from the * provided numberator and denominator. */ int UnitConvertor::gcd(int a, int b) { int R; - while((a % b) > 0) { + while ((a % b) > 0) { R = a % b; a = b; b = R; } - return b; + return b; } void UnitConvertor::dectofrac(float input) { - static char res[19]; + static char res[19]; - // Split whole number and decimal - int whole_number = (int)input; - float decimal = input - whole_number; + // Split whole number and decimal + int whole_number = (int)input; + float decimal = input - whole_number; - long multiplier = this->getMultiplier(this->input_buffer); + long multiplier = this->getMultiplier(this->input_buffer); - long numerator = ((decimal + 0.000001) * multiplier); - long denominator = (1 * multiplier); + long numerator = ((decimal + 0.000001) * multiplier); + long denominator = (1 * multiplier); - int gcd_val = gcd(numerator, denominator); + int gcd_val = gcd(numerator, denominator); - // Serial.println("DECTOFRAC"); - // Serial.print("Whole Number: "); Serial.println(whole_number); - // Serial.print("Decimal: "); Serial.println(decimal, 7); - // Serial.print("Multiplier: "); Serial.println(multiplier); - // Serial.print("GCD: "); Serial.println(gcd_val); - // Serial.print("Numerator: "); Serial.println(numerator); - // Serial.print("Denominator: "); Serial.println(denominator); + // Serial.println("DECTOFRAC"); + // Serial.print("Whole Number: "); Serial.println(whole_number); + // Serial.print("Decimal: "); Serial.println(decimal, 7); + // Serial.print("Multiplier: "); Serial.println(multiplier); + // Serial.print("GCD: "); Serial.println(gcd_val); + // Serial.print("Numerator: "); Serial.println(numerator); + // Serial.print("Denominator: "); Serial.println(denominator); - // Reduce! - numerator = numerator / gcd_val; - denominator = denominator / gcd_val; + // Reduce! + numerator = numerator / gcd_val; + denominator = denominator / gcd_val; - // Serial.print("\tNumerator: "); Serial.println(numerator); - // Serial.print("\tDenominator: "); Serial.println(denominator); + // Serial.print("\tNumerator: "); Serial.println(numerator); + // Serial.print("\tDenominator: "); Serial.println(denominator); - sprintf(res, "%d %ld/%ld", whole_number, numerator, denominator); - Serial.print("result: "); Serial.println(res); + sprintf(res, "%d %ld/%ld", whole_number, numerator, denominator); + Serial.print("result: "); + Serial.println(res); - strcpy(this->result, res); + strcpy(this->result, res); } -long* UnitConvertor::splitFraction() { - char input[19]; - long whole_number; - long numerator; - long denominator; - long ret[2]; - strcpy(input, this->input_buffer); - char* token = strtok(input, " "); // WHOLE Number - whole_number = atol(token); - token = strtok(NULL, "/"); - numerator = atol(token); - token = strtok(NULL, "/"); - denominator = atol(token); - - // Serial.print("FIRST: "); Serial.println(whole_number); - // Serial.print("SECOND: "); Serial.println(numerator); - // Serial.print("THIRD: "); Serial.println(denominator); - - ret[0] = whole_number; - ret[1] = numerator; - ret[2] = denominator; - - return ret; +long *UnitConvertor::splitFraction() { + char input[19]; + long whole_number; + long numerator; + long denominator; + long ret[2]; + strcpy(input, this->input_buffer); + char *token = strtok(input, " "); // WHOLE Number + whole_number = atol(token); + token = strtok(NULL, "/"); + numerator = atol(token); + token = strtok(NULL, "/"); + denominator = atol(token); + + // Serial.print("FIRST: "); Serial.println(whole_number); + // Serial.print("SECOND: "); Serial.println(numerator); + // Serial.print("THIRD: "); Serial.println(denominator); + + ret[0] = whole_number; + ret[1] = numerator; + ret[2] = denominator; + + return ret; } // This works and its magic. No touchy -char* UnitConvertor::subStr(char* input_string, char separator, int segment_number) { +char *UnitConvertor::subStr(char *input_string, char separator, + int segment_number) { char *act, *sub, *ptr; static char copy[100]; int i; @@ -318,7 +318,8 @@ char* UnitConvertor::subStr(char* input_string, char separator, int segment_numb strcpy(copy, input_string); for (i = 1, act = copy; i <= segment_number; i++, act = NULL) { sub = strtok_r(act, separator, &ptr); - if (sub == NULL) break; + if (sub == NULL) + break; } return sub; } diff --git a/MakerCalc/unitconv.h b/MakerCalc/unitconv.h index 2b124f2..232a923 100644 --- a/MakerCalc/unitconv.h +++ b/MakerCalc/unitconv.h @@ -4,38 +4,37 @@ #include "Arduino.h" class UnitConvertor { - public: - char input_buffer[19]; - int ib_idx; - int matrix_idx; - bool flip; - char result[19]; - - UnitConvertor(); - - void init(); - void input(char key); - void convert(); - void metricFrac(); - void metricTenths(); - void fractTenths(); - void lumenCandela(); - void mphKph(); - void mphIns(); - void mphMms(); - void kphIns(); - void kphMms(); - void insMms(); - long getMultiplier(char *input); - char* subStr(char* input_string, char separator, int segment_number); - long* splitFraction(); - - private: - int gcd(int a, int b); - void dectofrac(float input); - - //char* subStr(char* input_string, char separator, int segment_number); - +public: + char input_buffer[19]; + int ib_idx; + int matrix_idx; + bool flip; + char result[19]; + + UnitConvertor(); + + void init(); + void input(char key); + void convert(); + void metricFrac(); + void metricTenths(); + void fractTenths(); + void lumenCandela(); + void mphKph(); + void mphIns(); + void mphMms(); + void kphIns(); + void kphMms(); + void insMms(); + long getMultiplier(char *input); + char *subStr(char *input_string, char separator, int segment_number); + long *splitFraction(); + +private: + int gcd(int a, int b); + void dectofrac(float input); + + // char* subStr(char* input_string, char separator, int segment_number); }; #endif \ No newline at end of file From ed4739bb77b73be24f0b1cd45a1d7f8ddd7ca86c Mon Sep 17 00:00:00 2001 From: Robert Diamond Date: Sat, 19 Jun 2021 16:04:10 -0700 Subject: [PATCH 5/5] add necessary include --- MakerCalc/calculator.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/MakerCalc/calculator.h b/MakerCalc/calculator.h index 1886363..25b9dfd 100644 --- a/MakerCalc/calculator.h +++ b/MakerCalc/calculator.h @@ -1,6 +1,8 @@ #ifndef calculator_h #define calculator_h +#include + #define INPUT_BUFFER_SIZE 32 #define RESULT_SIZE 32 #define NUM_STACK_LENGTH 20