30 ноября 2017 года

Проекты АРДУИНЩИКА. Калькулятор.

Привет, мои дорогие читатели!
Вот, вчера-сегодня заморочился с давно пришедшей клавиатурой 4х4. Вчера обуздал клаву, а сегодня прикрутил функцию калькулятора. Да заодно, прикрутил LCD дисплей 16x2

Вот что получилось:

Пояснение:

  • Кнопки 1-0 : Вводим цифры от 1 до 0
  • Кнопки ABCD - арифмитические операции, соответственно: + - * /
  • Кнопка # - Вычислить
  • Кнопка * - Ваше решение, что с ней делать :)

    КАК РАБОТАЕТ

    Очень просто!
    После загрузки скетча видим на экране:

    Далее вводим первое число, например, 726:

    Затем, операцию, например, умножить:

    Затем, второе число, например, 536:

    И жмем кнопку #:

    Все очень просто.
    Если сделали ошибку, то можно сбросить первое и второе число двойным нажатием на любую операцию.

    Ну а теперь самое сладкое - скетчи!


    Calculator.ino
    #include "LiquidCrystal_I2C.h"
    
    LiquidCrystal_I2C lcd(0x3F, 16, 2); // Устанавливаем дисплей
    
    
    unsigned int  Wow = 0, Wow1 = 0;
    float         D1 = 0, D2 = 0, D3 = 0;
    unsigned int  Index = 1;
    int Operaciya = 0;
    String Oper = " ";
    
    unsigned int WhatKeyPressed();
    
    // Кнопка А - это +
    // Кнопка B - это -
    // Кнопка C - это *
    // Кнопка D - это /
    // Кнопка # - это =
    // Что делать с кнопкой * - еще не решил
    
    void setup() {
    
      lcd.init();
      lcd.backlight();          // Включаем подсветку дисплея
      lcd.begin(16, 2);
      lcd.clear();
      // Пишем Calculator
      lcd.setCursor(0, 0);       lcd.print(F("Calculator"));
      lcd.setCursor(0, 1);       lcd.print(F("READY!!!"));
    
      pinMode(2, OUTPUT);
      pinMode(3, OUTPUT);
      pinMode(4, OUTPUT);
      pinMode(5, OUTPUT);
      pinMode(13, OUTPUT);
    
      pinMode(6, INPUT);
      pinMode(7, INPUT);
      pinMode(8, INPUT);
      pinMode(9, INPUT);
    
      Serial.begin(9600);
      digitalWrite(2, 0);
      digitalWrite(3, 0);
      digitalWrite(4, 0);
      digitalWrite(5, 0);
      digitalWrite(13, 0);
    
      // Притягиваем к нулю входы, чтобы не использовать внешние резисторы
      // Подсмотрел тут: http://www.robots4life.ru/arduino-keypad - на нано не работает! На уно - не проверял.
      //digitalWrite(6, LOW);
      //digitalWrite(7, LOW);
      //digitalWrite(8, LOW);
      //digitalWrite(9, LOW);
    
      Serial.println("Please, Press any Key!");
    }
    
    void loop() {
      Wow1 = WhatKeyPressed();
      if (Wow1 > 0)
        digitalWrite(13, 1);
      else
        digitalWrite(13, 0);
      if (Wow1 == Wow)
        return;
      Wow = Wow1;
      if (Wow == 0)
        return;
      //  Serial.print(Wow);
      //  Serial.print("  ");
      //  Serial.print(Index);
      //  Serial.print("  ");
      float d = 0;
      switch (Wow) {
        case 1:    d = 1; break;
        case 2:    d = 4; break;
        case 4:    d = 7; break;
        case 8:    d = 115; break;      // Минус?
        case 4096: d = 111; break;      // +
        case 8192: d = 112; break;      // -
        case 16384: d = 113; break;     // *
        case 32768: d = 114; break;     // /
        case 16:   d = 2; break;
        case 32:   d = 5; break;
        case 64:   d = 8; break;
        case 128:  d = 0; break;
        case 256:  d = 3; break;
        case 512:  d = 6; break;
        case 1024: d = 9; break;
        case 2048: d = 110; break;      // =
      }
      if (d >= 111 and d <= 114) {
        Operaciya = d;
        switch (Operaciya) {
          case 111: Serial.println("+"); Oper = "+"; break;
          case 112: Serial.println("-"); Oper = "-"; break;
          case 113: Serial.println("*"); Oper = "*"; break;
          case 114: Serial.println("/"); Oper = "/"; break;
        }
        D2 = D1;
        D1 = 0;
        lcd.setCursor(0, 0);  lcd.print("                ");
        lcd.setCursor(0, 0);  lcd.print(String(D2) + Oper + String(D1));
        return;
      }
      if (d == 110) {
        switch (Operaciya) {
          case 111:    D3 = D2 + D1;  Serial.println(String(D2) + "+" + String(D1) + "=" + String(D3)); break;
          case 112:    D3 = D2 - D1;  Serial.println(String(D2) + "-" + String(D1) + "=" + String(D3)); break;
          case 113:    D3 = D2 * D1;  Serial.println(String(D2) + "*" + String(D1) + "=" + String(D3)); break;
          case 114:    D3 = D2 / D1;  Serial.println(String(D2) + "/" + String(D1) + "=" + String(D3)); break;
        }
        D1 = 0;
        D2 = 0;
        Operaciya = 0;
        Oper = " ";
        lcd.setCursor(0, 1);
        lcd.print(String(D3)+"                 ");
        D3=0;
        return;
      }
      D1 = D1 * 10.0;
      D1 = D1 + d;
      Serial.println(D1);
      lcd.setCursor(0, 0);  lcd.print("                ");
      lcd.setCursor(0, 0);  lcd.print(String(D2) +  Oper  + String(D1));
      lcd.setCursor(0, 1);
      lcd.print(String(D3)+"                  ");
    
      delay(50);
    }
    

    WhatKey.ino
    unsigned int WhatKeyPressed() {
      int Knopka[16] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
      int Index = 0;
      int keyPress = 0;
      unsigned int Wow = 0;
      for (int r = 2; r < 6; r++) {
    // Переводим линии подачи сигнала скана в "неопределенное состояние"
        pinMode(2, INPUT);
        pinMode(3, INPUT);
        pinMode(4, INPUT);
        pinMode(5, INPUT);
    // Переводим одну линию подачи сигнала скана в 1.
        pinMode(r, OUTPUT);
        digitalWrite(r, 1);
    // Последовательно читаем нажатые кнопки на этой линии
        for (int i = 6; i < 10; i++) {
          if (digitalRead(i)) {
            //        Serial.println(String(r) + "." + String(i));
            Knopka[Index] = 1;
            keyPress = 1;
          }
          Index++;
        }
      }
    
      if (keyPress) {
        for (int q = 0; q < 16; q++) {
          Wow = Wow + Knopka[q] * ( 1 << (15 - q) );
          //Serial.print(Knopka[q]);
        }
        //Serial.println("  " + String(Wow));
      }
      return Wow;
    }