нужен скетч счетчика монет (копилка)

Тема в разделе "Закажу проект", создана пользователем Andy2019, 2 фев 2019.

  1. Andy2019

    Andy2019 Нуб

    Имеется скетч для счетчика монет с LCD 16х02 дисплеем, нужно сменить данный дисплей на OLED 128x64 l2c, уже измучился весь, ну никак. За ранее огромное спасибо! Нужно ребёнку (девочке), копит на бравое дело, а всё время пересчитывать надоедает.
     

    Вложения:

  2. Asper Daffy

    Asper Daffy Иксперд

    Так закажите в платном разделе
     
  3. Andy2019

    Andy2019 Нуб

    уже написал, пока тишина
     
  4. Andy2019

    Andy2019 Нуб

    нужен скетч счетчика монет (копилка) на дисплее OLED 128x64 l2c (скрин на какой именно нужен дисплей)- lcd 16x02 не подходит. цена вопроса какая?
     

    Вложения:

    • 222.jpg
      222.jpg
      Размер файла:
      165 КБ
      Просмотров:
      145
  5. ostrov

    ostrov Гуру

    Какой монетоприемник?
     
  6. Andy2019

    Andy2019 Нуб

    без монета приемника, всё на фоторезисторе, либо поправить вот этот скетч чтобы сменить дисплей, скетч рабочий но на другом дисплее. ссылка на сам проект в котором можно всё увидеть, но ещё раз повторюсь там другой дисплей. https://alexgyver.ru/moneybox_counter-arduino/
     

    Вложения:

  7. ostrov

    ostrov Гуру

    И как отличать монеты?
     
  8. Andy2019

    Andy2019 Нуб

    пробовал переделать, дисплей встает но почему то не хочет очищаться

    по ссылке в проекте всё рассказано

    вот сам скетч так выглядит

    /*
    Электронный распознаватель монет (по размеру) для копилки со счётчиком суммы и статистикой по каждому типу монет.
    Функционал:
    Распознавание размера монет с высокой точностью и его привязка к стоимости каждой монеты
    Вычисление общей суммы монет в копилке
    Статистика по числу монет каждого типа
    Все настройки сохраняются в энергонезависимую память и не сбрасываются при питании
    Накопленная сумма тоже хранится в энергонезависимой памяти и не боится сбоев питания
    Режим глубокого энергосбережения: в спящем режиме потребляется 0.07 мА, в схеме без преобразователя 0.02 мА
    Поддержка любого числа монет разного размера
    Автоматическая калибровка типов монет
    Сброс накопленного количества
    Подробности в видео:


    Created 2017
    by AlexGyver
    AlexGyver Home Labs Inc.
    */

    //-------НАСТРОЙКИ---------
    #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 "LCD_1602_RUS.h"
    //-------БИБЛИОТЕКИ---------

    LCD_1602_RUS lcd(0x27, 16, 2); // создать дисплей
    // если дисплей не работает, замени 0x27 на 0x3f

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

    void setup() {
    Serial.begin(9600); // открыть порт для связи с ПК для отладки
    delay(500);

    // подтягиваем кнопки
    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); // считать пустой (опорный) сигнал

    // инициализация дисплея
    lcd.init();
    lcd.backlight();

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

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

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

    void loop() {
    if (sleep_flag) { // если проснулись после сна, инициализировать дисплей и вывести текст, сумму и валюту
    delay(500);
    lcd.init();
    lcd.clear();
    lcd.setCursor(0, 0); lcd.print(L"На яхту");
    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); // вот самое главное! ищем АБСОЛЮТНОЕ (то бишь по модулю)
    // значение разности полученного сигнала с нашими значениями из памяти
    if (delta < 30) { // и вот тут если эта разность попадает в диапазон, то считаем монетку распознанной
    summ_money += coin_value; // к сумме тупо прибавляем цену монетки (дада, сумма считается двумя разными способами. При старте системы суммой всех монет, а тут прибавление
    lcd.setCursor(0, 1); lcd.print(summ_money);
    coin_quantity++; // для распознанного номера монетки прибавляем количество
    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);
    lcd.setCursor(i * 3, 1); lcd.print(coin_quantity);
    }
    }
    }
    }
    }

    // функция сна
    void good_night() {
    // перед тем как пойти спать, записываем в EEPROM новые полученные количества монет по адресам начиная с 20го (пук кек)
    for (byte i = 0; i < coin_amount; i++) {
    EEPROM.updateInt(20 + i * 2, coin_quantity);
    }
    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(); // и обнуляем таймер
    }
    // Спасибо за внимание, ваш Алекс
     
    Последнее редактирование модератором: 2 фев 2019
  9. parovoZZ

    parovoZZ Гуру

    А что так много? В 10 раз больше, чем в даташите.
     
  10. Airbus

    Airbus Радиохулиган Модератор

    [​IMG]
     
    Nikita228, NikitOS и Tomasina нравится это.
  11. Airbus

    Airbus Радиохулиган Модератор

  12. Andy2019

    Andy2019 Нуб

    Тут без даташит
     
  13. Andy2019

    Andy2019 Нуб

    :rolleyes:
     
  14. Andy2019

    Andy2019 Нуб

    Если бы в данном скетче это было так просто, там дисплей на Библиотеке Crystal а мне oled нужен, Adafruit ssd1306 ставил, либо дисплей ничего не кажет либо просто не делает очистку и получается куча разбросанных светящихся пикселей . Избавиться от этого никак не могу.
     
  15. parovoZZ

    parovoZZ Гуру

    значит, этому говнокоду не стоит уделять ни капли внимания.
     
  16. Andy2019

    Andy2019 Нуб

    Дело в том что он рабочий и работает с lcd 1602 дисплеем, а с oled дисплеем надо менять код, так как в Adafruit не поддерживается lcd, lcd идёт на Crystal
     
  17. ImrDuke

    ImrDuke Гик

    Все уже придумано

     
  18. man9913

    man9913 Гик

    Киргиз, в отличие от оригинала, по ходу не стал "заморачиваться" с режимом сна, что совсем не айс.
     
  19. Andy2019

    Andy2019 Нуб

    Умник, если бы у него был выложен код то это бы меняло дело, но проблема остаётся в том что ты даже не удосужился посмотреть то что этот киргиз давно не отвечает на вопросы и его сайт отключен, и все коды давно улетели, и в видео он ничего не рассказал.
     
  20. Airbus

    Airbus Радиохулиган Модератор

    Ну я о том же.Код поправить не хотите ручками?Я же вам ссылку дал там все разжевано.Заменить одни строчки на другие.Потом уж будем разбираться что не так.Или за Вас это кто то другой должен делать?