Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
*.o
*.a
testCalculator
4 changes: 3 additions & 1 deletion MakerCalc/.gitignore
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
build
.vscode
.kceHelpers.cpp
.kceHelperrs.h
.kceHelperrs.h
**/*.o
test/testCalculator
8 changes: 2 additions & 6 deletions MakerCalc/MakerCalc.ino
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
#include "Arduino.h"
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
//#include <LiquidCrystal_I2C.h>
#include <TimerOne.h>
#include <ClickEncoder.h>
#include <Adafruit_Keypad.h>
Expand Down Expand Up @@ -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);

}
Expand All @@ -216,4 +213,3 @@ void unitDebug() {
Serial.print("\tResult: "); Serial.println(unit->result);

}

114 changes: 82 additions & 32 deletions MakerCalc/calculator.cpp
Original file line number Diff line number Diff line change
@@ -1,47 +1,97 @@
#include "Arduino.h"
#include "calculator.h"
#include <ctype.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.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
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
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();
}
} else if(key == '=') { // Equals.

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;
}
}
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];
}
40 changes: 24 additions & 16 deletions MakerCalc/calculator.h
Original file line number Diff line number Diff line change
@@ -1,27 +1,35 @@
#ifndef calculator_h
#define calculator_h

#include "Arduino.h"
#include <stdint.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;

Calculator();
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:
char operators[5] = "+-*/";
void init();
void input(char key);
void calculate();

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
99 changes: 56 additions & 43 deletions MakerCalc/display.cpp
Original file line number Diff line number Diff line change
@@ -1,68 +1,81 @@
#include "display.h"
#include "Arduino.h"
#include <LiquidCrystal_I2C.h>
#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;
}
Loading