#include <Keypad.h>
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#define SCREEN_WIDTH 128
#define SCREEN_HEIGHT 64
Adafruit_SSD1306 lcd(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire);
const byte ROWS = 4;
const byte COLS = 4;
char hexaKeys[ROWS][COLS] = {
{'1','2','3','A'},
{'4','5','6','B'},
{'7','8','9','C'},
{'*','0','#','D'}
};
byte rowPinsR[ROWS] = {7, 6, 5, 4};
byte colPinsR[COLS] = {3, 2, A2, A3};
byte rowPinsL[ROWS] = {13, 12, 11, A0};
byte colPinsL[COLS] = {10, 9, 8, A1};
Keypad KeypadL = Keypad(makeKeymap(hexaKeys), rowPinsL, colPinsL, ROWS, COLS);
Keypad KeypadR = Keypad(makeKeymap(hexaKeys), rowPinsR, colPinsR, ROWS, COLS);
char currentTask[16] = "11";
char currentAnswer[16] = "";
char textL[16] = "";
char textR[16] = "";
int lPoints = 0;
int rPoints = 0;
void generateTask() {
int num1 = random(1, 10);
int num2 = random(1, 10);
char operators[] = {'+', '*'};
char op = operators[random(0, 2)];
snprintf(currentTask, sizeof(currentTask), "%d%c%d", num1, op, num2);
if (op == '+') snprintf(currentAnswer, sizeof(currentAnswer), "%d", num1 + num2);
else if (op == '-') snprintf(currentAnswer, sizeof(currentAnswer), "%d", num1 - num2);
else if (op == '*') snprintf(currentAnswer, sizeof(currentAnswer), "%d", num1 * num2);
Serial.println(currentTask);
}
void displayTask() {
lcd.fillRect(0, 0, SCREEN_WIDTH, 10, SSD1306_BLACK);
lcd.setCursor(1, 1);
lcd.setTextSize(1);
lcd.print(currentTask);
lcd.display();
}
void setup() {
Serial.begin(9600);
lcd.begin(SSD1306_SWITCHCAPVCC, 0x3C);
lcd.setRotation(0);
lcd.clearDisplay();
lcd.setTextColor(SSD1306_WHITE);
drawStaticLayout();
generateTask();
displayTask();
displayPoints();
}
void loop() {
char customKeyL = KeypadL.getKey();
if (customKeyL) {
if (customKeyL == 'C') {
removeLastCharFromText(textL, sizeof(textL));
} else {
addCharToText(textL, customKeyL, sizeof(textL));
}
updateInputArea(3, 30, textL);
Serial.print("Left: ");
Serial.println(textL);
}
char customKeyR = KeypadR.getKey();
if (customKeyR) {
if (customKeyR == 'C') {
removeLastCharFromText(textR, sizeof(textR));
} else {
addCharToText(textR, customKeyR, sizeof(textR));
}
updateInputArea(68, 30, textR);
Serial.print("Right: ");
Serial.println(textR);
}
if (strcmp(textL, currentAnswer) == 0) {
lPoints++;
Serial.println(lPoints);
if (lPoints >= 15) {
reset();
}
resetForNextTask();
} else if (strcmp(textR, currentAnswer) == 0) {
rPoints++;
Serial.println(rPoints);
if (rPoints >= 15) {
reset();
}
resetForNextTask();
}
displayPoints();
}
void displayPoints() {
lcd.fillRect(0, 55, 30, 34, SSD1306_BLACK);
lcd.fillRect(65, 55, 30, 34, SSD1306_BLACK);
lcd.setTextSize(1);
lcd.setCursor(0, 55);
lcd.print(lPoints);
lcd.setCursor(66, 55);
lcd.print(rPoints);
lcd.display();
}
void reset() {
asm volatile ("jmp 0");
}
void resetForNextTask() {
lcd.fillRect(0, 12, 30, 34, SSD1306_BLACK);
lcd.fillRect(65, 12, 30, 34, SSD1306_BLACK);
generateTask();
displayTask();
textL[0] = '\0';
textR[0] = '\0';
}
void updateInputArea(int x, int y, const char* text) {
lcd.fillRect(x, y, 60, 20, SSD1306_BLACK);
lcd.setCursor(x, y);
lcd.setTextSize(2);
lcd.print(text);
lcd.display();
}
void addCharToText(char* text, char key, size_t maxSize) {
size_t len = strlen(text);
if (len < maxSize - 1) {
text[len] = key;
text[len + 1] = '\0';
}
}
void drawStaticLayout() {
lcd.drawLine(0, 10, 128, 10, SSD1306_WHITE);
lcd.drawLine(64, 10, 64, 64, SSD1306_WHITE);
lcd.drawLine(0, 50, 128, 50, SSD1306_WHITE);
}
void removeLastCharFromText(char* text, size_t maxSize) {
if (strlen(text) > 0) {
text[strlen(text)-1] = '\0';
}
}