13-01-2019, 21:10
Dziękuję za pomoc. Po formatowaniu zadziałało.
Jeśli ktoś potrzebuje to poniżej działający kod.
Jeśli ktoś potrzebuje to poniżej działający kod.
Kod:
/*
Arduino calculator with keypad and LCD, and quiz
Tom Tobback Oct 2017
keypad library:
|| @version 1.0
|| @author Andrew Mascolo
|| @date May 15, 2013
|| @description
|| Simple use of keypad and LCD
taken from https://playground.arduino.cc/Main/KeypadCalculator
use LCD 16x2 with pot
buzzer on D13
keypad on D2-D9
use * as decimal point
starts as normal calculator
enter magic number to start quiz: 60 seconds
enter reset code to reset high score
*/
#include <EEPROM.h> // for high score
#include <Keypad.h>
#include <LiquidCrystal.h>
// initialize the library with the numbers of the interface pins
LiquidCrystal lcd(12, 11, A5, A4, A3, A2);
float first = 0;
float second = 0;
float total = 0;
boolean mult = false; // multiplication flag to avoid overflow
boolean first_decimal = false; // does the first number have a decimal point
int first_decimal_pos = 0; // how many digits after decimal point
boolean second_decimal = false; // does the second number have a decimal point
int second_decimal_pos = 0; // how many digits after decimal point
int digits_first = 0;
int digits_second = 0;
const long magic_number = 321; // to enter the quiz state
const long magic_reset = 332211; // to reset high score
boolean quiz = false; // quiz state
int answer; // quiz answer
int correct_answer; // correct quiz answer
int digits_answer = 0; // count digits of answer
int score = 0;
unsigned long timestamp = 0; // start of quiz
int high_score;
char customKey;
const byte ROWS = 4;
const byte COLS = 4;
char keys[ROWS][COLS] = {
{'1', '2', '3', '+'},
{'4', '5', '6', '-'},
{'7', '8', '9', '*'},
{'.', '0', '=', '/'}
};
byte rowPins[ROWS] = {2, 3, 4, 5}; //connect to the row pinouts of the keypad
byte colPins[COLS] = {6, 7, 8, 9}; //connect to the column pinouts of the keypad
//initialize an instance of class NewKeypad
Keypad customKeypad = Keypad( makeKeymap(keys), rowPins, colPins, ROWS, COLS);
void setup()
{
// EEPROM.write(10, 0); // OPTIONAL reset high score to 0
high_score = EEPROM.read(10);
if (high_score == 255) {
EEPROM.write(10, 0); // reset high score to 0
high_score = 0;
}
randomSeed(analogRead(A0));
Serial.begin(9600);
lcd.begin(16, 2);
lcd.setCursor(2, 0);
lcd.print("BuffaloLabs");
lcd.setCursor(0, 1);
lcd.print("Calculator+Quiz");
tone(13, 500);
delay(100);
tone(13, 1000);
delay(100);
noTone(13);
delay(2000);
lcd.clear();
}
void loop()
{
customKey = customKeypad.getKey();
if (quiz) { // quiz waiting for answer
lcd.setCursor(14, 1);
int remaining = 60 - (millis() - timestamp) / 1000;
if (remaining < 10) lcd.print(" "); lcd.print(remaining); if (remaining == 0) { // quiz FINISHED
if (score > high_score) { // new high score
high_score = score;
EEPROM.write(10, high_score);
lcd.clear();
lcd.print("NEW HIGH SCORE= ");
lcd.setCursor(0, 1);
lcd.print(high_score);
for (int i = 1000; i < 4000; i += 5) { // siren
tone(13, i);
delay(1);
}
for (int i = 4000; i > 1000; i -= 5) {
tone(13, i);
delay(1);
}
noTone(13);
}
else { // no new high score
for (int i = 0; i < 10; i++) {
tone(13, 2000);
delay(50);
noTone(13);
delay(50);
}
}
customKeypad.waitForKey(); // new quiz
beep();
score = 0;
showHighscore();
correct_answer = quizQuestion();
timestamp = millis();
}
switch (customKey)
{
case '0' ... '9':
if (digits_answer < 4) { answer = answer * 10 + (customKey - '0'); // if integer (from ascii to numerical
value)
lcd.setCursor(digits_answer, 1);
lcd.print(customKey);
digits_answer++;
beep();
Serial.println(answer, 6);
}
else
{
lowBeep();
}
break;
case '=': if (digits_answer > 0) {
if (answer == correct_answer) {
beepYes();
score++;
}
else {
beepNo();
score--;
if (score < 0) score = 0;
}
correct_answer = quizQuestion();
}
else {
lowBeep();
}
break;
case '+':
lowBeep();
break;
case '-':
lowBeep();
break;
case '*':
lowBeep();
break;
case '/':
lowBeep();
break;
case '.':
lowBeep();
break;
}
}
else { // normal calculator
switch (customKey)
{
case '0' ... '9': // This keeps collecting the first value until a operator is pressed "+-*/"
if (digits_first == 0) lcd.clear();
if (digits_first < 6) { if (first_decimal) {
first_decimal_pos++;
float divider = pow(10, first_decimal_pos);
first = first + (customKey - '0') / divider;
} else {
first = first * 10 + (customKey - '0'); // if integer (from ascii to numerical value)
}
lcd.print(customKey);
digits_first++; beep();
Serial.println(first, 6);
}
else {
lowBeep();
}
if (first == magic_number) { // escape to quiz
showHighscore();
correct_answer = quizQuestion();
quiz = true;
timestamp = millis();
}
if (first == magic_reset) { // reset quiz high score
showReset();
char rst = customKeypad.waitForKey();
if (rst == '0') {
EEPROM.write(10, 0);
high_score = 0;
longBeep();
}
else {
lowBeep();
}
showHighscore();
correct_answer = quizQuestion();
quiz = true;
timestamp = millis();
}
break;
case '+': if (digits_first == 0) {
lowBeep();
break;
}
lcd.print("+");
beep();
second = SecondNumber(); // get the collected the second number
lcd.print("=");
beep();
total = first + second;
printTotal();
break;
case '-': if (digits_first == 0) {
lowBeep();
break;
}
lcd.print("-");
beep();
second = SecondNumber();
lcd.print("=");
beep();
total = first - second;
printTotal();
break;
case '*': if (digits_first == 0) {
lowBeep();
break;
}
lcd.print("*");
beep();
mult = true;
second = SecondNumber();
lcd.print("=");
beep();
total = first * second;
printTotal();
mult = false;
break;
case '/': if (digits_first == 0) {
lowBeep();
break;
}
lcd.print("/");
beep();
second = SecondNumber();
lcd.print("=");
beep();
second == 0 ? lcd.print("Invalid") : total = (float)first / (float)second;
printTotal();
break;
case '.': if (digits_first == 0) {
lowBeep();
break;
}
if (first_decimal) { // already has decimal point
lowBeep();
}
else {
lcd.setCursor(digits_first, 0); // add decimal point
lcd.print(customKey);
digits_first++;
beep();
first_decimal = true;
}
break;
case '=': lowBeep();
resetC();
lcd.clear();
break;
}
}
}
float SecondNumber() {
while ( 1 ) {
customKey = customKeypad.getKey();
if (customKey >= '0' && customKey <= '9') {
if (digits_second < 6) {
if ((mult && (digits_first + digits_second) < 10) || !mult) {
lcd.print(customKey);
beep();
if (second_decimal) {
second_decimal_pos++;
float divider = pow(10, second_decimal_pos);
second = second + (customKey - '0') / divider;
}
else {
second = second * 10 + (customKey - '0'); // if integer (from ascii to numerical value)
}
digits_second++;
Serial.println(second, 6);
}
else {
lowBeep();
}
}
else {
lowBeep();
}
}
if (customKey == '=') break; //return second;
if (customKey == '.') {
if (second_decimal) { // already has decimal point
lowBeep();
}
else {
lcd.print(customKey);
digits_second++;
beep();
second_decimal = true;
}
}
if (customKey == '+' || customKey == '-' || customKey == '*' || customKey == '/' ) lowBeep();
}
return second;
}
void resetC() {
total = 0;
digits_first = 0; digits_second = 0;
first = 0, second = 0; // reset values back to zero for next use
first_decimal = false;
first_decimal_pos = 0;
second_decimal = false;
second_decimal_pos = 0;
}
void printTotal() {
int decimalPlaces;
float temp = total;
for (decimalPlaces = 0; decimalPlaces < 7; decimalPlaces++) {
if (temp == (long)temp) break; temp *= 10.0;
}
Serial.println(total, decimalPlaces);
lcd.setCursor(0, 1);
lcd.print(total, decimalPlaces);
resetC();
}
void beep() {
tone(13, 500);
delay(10);
noTone(13);
}
void lowBeep() {
tone(13, 50); // low beep
delay(10);
noTone(13);
}
void longBeep() {
tone(13, 500); // long beep
delay(1000);
noTone(13);
}
int quizQuestion() {
delay(random(0, 100));
randomSeed(analogRead(A0));
lcd.clear();
answer = 0;
digits_answer = 0;
int upper_limit = score / 2 + 5;
first = random(score / 2 + 1, upper_limit);
delay(random(0, 100));
randomSeed(analogRead(A0));
delay(random(0, 100));
int op = score % 4; // 0 1 2 3
switch (op)
{
case 0: lcd.print(first, 0); // float but show as int
lcd.print("+");
second = random(1, upper_limit - 1);
correct_answer = first + second;
break;
case 1: lcd.print(first, 0); // float but show as int
lcd.print("-");
second = random(1, first + 1);
correct_answer = first - second;
break;
case 2: lcd.print(first, 0); // float but show as int
lcd.print("*");
if (first > 10) {
second = 2;
}
else {
second = random(0, 11);
}
correct_answer = first * second;
break;
case 3: // correct_answer = first >> (first * second) / second = first
second = random(1, first + 1);
correct_answer = first;
lcd.print(first * second, 0); // float but show as int
lcd.print("/");
break;
}
lcd.print(second, 0); // float but show as int
lcd.print("=");
lcd.setCursor(8, 0);
lcd.print("score:");
if (score < 10) lcd.print(" ");
lcd.print(score);
lcd.setCursor(9, 1);
lcd.print("time:");
lcd.setCursor(0, 1);
return correct_answer;
}
///////////////////////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////////////////////////
void beepYes() {
for (int i = 0; i < 3; i++) {
tone(13, 1000);
delay(50);
noTone(13);
delay(50);
}
}
void beepNo() {
for (int i = 0; i < 3; i++) {
tone(13, 100);
delay(50);
noTone(13);
delay(50);
}
}
void showHighscore() {
lcd.clear();
lcd.print("HIGH SCORE= ");
lcd.print(high_score);
lcd.setCursor(0,1);
lcd.print("starting quiz..");
delay(2000);
lcd.clear();
tone(13, 500);
delay(100);
tone(13, 1000);
delay(100);
noTone(13);
}
void showReset() {
lcd.clear();
lcd.print("HIGH SCORE= ");
lcd.print(high_score);
lcd.setCursor(0, 1);
lcd.print("Press 0 to reset...");
}