• Witaj na Forum Arduino Polska! Zapraszamy do rejestracji!
  • Znajdziesz tutaj wiele informacji na temat hardware / software.
Witaj! Logowanie Rejestracja


Ocena wątku:
  • 0 głosów - średnia: 0
  • 1
  • 2
  • 3
  • 4
  • 5
Kalkulator - prośba o pomoc w znalezieniu błędu
#7
Dziękuję za pomoc. Po formatowaniu zadziałało.

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...");
}
 
Odpowiedź
  


Wiadomości w tym wątku
RE: Kalkulator - prośba o pomoc w znalezieniu błędu - przez indego - 13-01-2019, 21:10

Skocz do:


Przeglądający: 1 gości