Нужна помощь с написанием скетча.

Тема в разделе "Arduino & Shields", создана пользователем Electronic troops, 28 дек 2018.

  1. Доброго времени суток. Возникает проблема при подключении lcd дисплея.
    Код (C++):
    //-------НАСТРОЙКИ---------
    #define coin_amount 5    // число монет, которые нужно распознать
    float coin_value[coin_amount] = {0.5, 1.0, 2.0, 5.0, 10.0};  // стоимость монет
    String currency = "RUB"; // валюта (английские буквы!!!)
    int stb_time = 10000;    // время бездействия, через которое система уйдёт в сон (миллисекунды)

    int coin_signal[coin_amount];    // тут хранится значение сигнала для каждого размера монет
    int coin_quantity[coin_amount];  // количество монет
    byte empty_signal;               // храним уровень пустого сигнала
    unsigned long standby_timer, reset_timer; // таймеры
    float summ_money = 0;            // сумма монет в копилке

    //-------БИБЛИОТЕКИ---------
    #include "LowPower.h"
    #include "EEPROMex.h"
    #include <LiquidCrystal.h>


    boolean recogn_flag, sleep_flag = true;   // флажки
    //-------КНОПКИ---------
    #define button 2         // кнопка проснуться
    #define calibr_button 3  // скрытая кнопка калибровки сброса
    #define disp_power 12    // питание дисплея
    #define LEDpin 11        // питание светодиода
    #define IRpin 4         // питание фототранзистора
    #define IRsens A3        // сигнал фототранзистора


    int sens_signal, last_sens_signal;
    boolean coin_flag = false;

    void setup() {
      // открываем последовательный порт
      Serial.begin(9600);
      delay(500);
     
      // инициализация дисплея
      LiquidCrystal lcd(5, 6, 7, 8, 9, 10);
      lcd.begin(16, 2);

      // кнопки
      pinMode(button, INPUT_PULLUP);
      pinMode(calibr_button, INPUT_PULLUP);

      // пины питания как выходы
      pinMode(disp_power, OUTPUT);
      pinMode(LEDpin, OUTPUT);
      pinMode(IRpin, OUTPUT);

      // подать питание на дисплей и датчик
      digitalWrite(disp_power, 1);
      digitalWrite(LEDpin, 1);
      digitalWrite(IRpin, 1);

      // подключить прерывание
      attachInterrupt(0, wake_up, CHANGE);

      empty_signal = analogRead(IRsens);  // считать пустой (опорный) сигнал


      if (!digitalRead(calibr_button)) {  // если при запуске нажата кнопка калибровки
        lcd.clear();
        lcd.setCursor(3, 0);
        lcd.print("Сервис");
        delay(500);
        reset_timer = millis();
        while (1) {                                   // бесконечный цикл
          if (millis() - reset_timer > 3000) {        // если кнопка всё ещё удерживается и прошло 3 секунды
            // очистить количество монет
            for (byte i = 0; i < coin_amount; i++) {
              coin_quantity[i] = 0;
              EEPROM.writeInt(20 + i * 2, 0);
            }
            lcd.clear();
            lcd.setCursor(0, 0);
            lcd.print("Память очищена");
            delay(100);
          }
          if (digitalRead(calibr_button)) {   // если отпустили кнопку, перейти к калибровке
            lcd.clear();
            lcd.setCursor(0, 0);
            lcd.print("Калибровка");
            break;
          }
        }
        while (1) {
          for (byte i = 0; i < coin_amount; i++) {
            lcd.setCursor(0, 1); lcd.print(coin_value[i]);  // отобразить цену монеты, размер которой калибруется
            lcd.setCursor(13, 1); lcd.print(currency);      // отобразить валюту
            last_sens_signal = empty_signal;
            while (1) {
              sens_signal = analogRead(IRsens);                                    // считать датчик
              if (sens_signal > last_sens_signal) last_sens_signal = sens_signal;  // если текущее значение больше предыдущего
              if (sens_signal - empty_signal > 3) coin_flag = true;                // если значение упало почти до "пустого", считать что монета улетела
              if (coin_flag && (abs(sens_signal - empty_signal)) < 2) {            // если монета точно улетела
                coin_signal[i] = last_sens_signal;                                 // записать максимальное значение в память
                EEPROM.writeInt(i * 2, coin_signal[i]);
                coin_flag = false;
                break;
              }
            }
          }
          break;
        }
      }

      // при старте системы считать из памяти сигналы монет для дальнейшей работы, а также их количество в банке
      for (byte i = 0; i < coin_amount; i++) {
        coin_signal[i] = EEPROM.readInt(i * 2);
        coin_quantity[i] = EEPROM.readInt(20 + i * 2);
        summ_money += coin_quantity[i] * coin_value[i];  // ну и сумму сразу посчитать, как произведение цены монеты на количество
      }

      /*
        // для отладки, вывести сигналы монет в порт
        for (byte i = 0; i < coin_amount; i++) {
          Serial.println(coin_signal[i]);
        }
      */

      standby_timer = millis();  // обнулить таймер ухода в сон
    }

    void loop() {
      if (sleep_flag) {  // если проснулись  после сна, инициализировать дисплей и вывести текст, сумму и валюту
        delay(500);
        lcd.init();
        lcd.clear();
        lcd.setCursor(0, 0); lcd.print("На яхту");
        lcd.setCursor(0, 1); lcd.print(summ_money);
        lcd.setCursor(13, 1); lcd.print(currency);
        empty_signal = analogRead(IRsens);
        sleep_flag = false;
      }

      // далее работаем в бесконечном цикле
      last_sens_signal = empty_signal;
      while (1) {
        sens_signal = analogRead(IRsens);  // далее такой же алгоритм, как при калибровке
        if (sens_signal > last_sens_signal) last_sens_signal = sens_signal;
        if (sens_signal - empty_signal > 3) coin_flag = true;
        if (coin_flag && (abs(sens_signal - empty_signal)) < 2) {
          recogn_flag = false;  // флажок ошибки, пока что не используется
          // в общем нашли максимум для пролетевшей монетки, записали в last_sens_signal
          // далее начинаем сравнивать со значениями для монет, хранящимися в памяти
          for (byte i = 0; i < coin_amount; i++) {
            int delta = abs(last_sens_signal - coin_signal[i]);   // вот самое главное! ищем АБСОЛЮТНОЕ (то бишь по модулю)
            // значение разности полученного сигнала с нашими значениями из памяти
            if (delta < 30) {   // и вот тут если эта разность попадает в диапазон, то считаем монетку распознанной
              summ_money += coin_value[i];  // к сумме тупо прибавляем цену монетки (дада, сумма считается двумя разными способами. При старте системы суммой всех монет, а тут прибавление
              lcd.setCursor(0, 1); lcd.print(summ_money);
              coin_quantity[i]++;  // для распознанного номера монетки прибавляем количество
              recogn_flag = true;
              break;
            }
          }
          coin_flag = false;
          standby_timer = millis();  // сбросить таймер
          break;
        }

        // если ничего не делали, времят аймера вышло, спим
        if (millis() - standby_timer > stb_time) {
          good_night();
          break;
        }

        // если монетка вставлена (замыкает контакты) и удерживается 2 секунды
        while (!digitalRead(button)) {
          if (millis() - standby_timer > 2000) {
            lcd.clear();
            // отобразить на дисплее: сверху цены монет (округлено до целых!!!!), снизу их количество
            for (byte i = 0; i < coin_amount; i++) {
              lcd.setCursor(i * 3, 0); lcd.print((int)coin_value[i]);
              lcd.setCursor(i * 3, 1); lcd.print(coin_quantity[i]);
            }
          }
        }
      }
    }

    // функция сна
    void good_night() {
      // перед тем как пойти спать, записываем в EEPROM новые полученные количества монет по адресам начиная с 20го (пук кек)
      for (byte i = 0; i < coin_amount; i++) {
        EEPROM.updateInt(20 + i * 2, coin_quantity[i]);
      }
      sleep_flag = true;
      // вырубить питание со всех дисплеев и датчиков
      digitalWrite(disp_power, 0);
      digitalWrite(LEDpin, 0);
      digitalWrite(IRpin, 0);
      delay(100);
      // и вот теперь спать
      LowPower.powerDown(SLEEP_FOREVER, ADC_OFF, BOD_OFF);
    }

    // просыпаемся по ПРЕРЫВАНИЮ (эта функция - обработчик прерывания)
    void wake_up() {
      // возвращаем питание на дисплей и датчик
      digitalWrite(disp_power, 1);
      digitalWrite(LEDpin, 1);
      digitalWrite(IRpin, 1);
      standby_timer = millis();  // и обнуляем таймер
    }
    Arduino: 1.8.5 (Windows 7), Плата:"Arduino Nano, ATmega328P"

    E:\Data\money_box_counter\money_box_counter.ino: In function 'void loop()':

    money_box_counter:126: error: 'lcd' was not declared in this scope

    lcd.init();

    ^

    money_box_counter:150: error: 'lcd' was not declared in this scope

    lcd.setCursor(0, 1); lcd.print(summ_money);

    ^

    money_box_counter:170: error: 'lcd' was not declared in this scope

    lcd.clear();

    ^

    Несколько библиотек найдено для "LowPower.h"
    Используется: C:\Program Files\Arduino\libraries\Low-Power-master
    Не используется: C:\Program Files\Arduino\libraries\Low-Power
    Не используется: C:\Program Files\Arduino\libraries\Low-Power
    Не используется: C:\Program Files\Arduino\libraries\Low-Power
    Не используется: C:\Program Files\Arduino\libraries\Low-Power
    exit status 1
    'lcd' was not declared in this scope

    Объясните пожалуйста.
     
  2. b707

    b707 Гуру

    Electronic troops и Daniil нравится это.