Виснет выполнение программы
- Войдите на сайт для отправки комментариев
Сб, 19/10/2019 - 21:18
[code] //******** библиотеки #include <util/atomic.h> #include <Wire.h> #include <LiquidCrystal_I2C.h> LiquidCrystal_I2C lcd(0x38, 16, 2); //******** константы #define TIME1 6 // стоимость 1 пульса - сек // пины подключения #define PIN_RELAY 8 #define PIN_MONEY 7 #define RELAY_ON 1 #define RELAY_OFF 0 #define netVoda 10 int knopka = 9; int knopkaOn; volatile int counter1 = 0;// для подсчета количества пульсов volatile int counter_copy; volatile unsigned int time_run_copy; volatile unsigned int time_run_start; unsigned long timeAllPulse1 = 1200.; // макс. время приема монеты unsigned long timeCount1 = 0; boolean run_cleaner = false;// включение пылесоса volatile unsigned int time_run = 0;// для подсчета времени работы насоса volatile unsigned long millis1 = 0;// для подсчета времени работы насоса void setup() { lcd.init();// инициализируем экран lcd.backlight();// включаем подсветку Serial.begin(9600); pinMode(netVoda, INPUT);// реле уровня воды // настройка пинов pinMode(knopka, INPUT); // кнопка // настройка пинов pinMode(PIN_RELAY, OUTPUT); // реле // настройка пинов digitalWrite(PIN_RELAY, RELAY_OFF); // выключить // настройка пинов attachInterrupt(4, count_pulse1, FALLING); // запуск обработчика прерываний монетоприемника } void loop() { if (counter1 > 0 && (millis() - timeCount1) > timeAllPulse1) { lcd.setCursor(2, 0); lcd.print("BHECEHO="); lcd.print(counter_copy); lcd.print("P"); } atomicTime_run(); // Выполнение атомарного блока присваивания atomicInterrupt(); // Выполняем слежение кнопки knopkaPUSK(); // истекло время приема монеты? if (knopkaOn == HIGH && counter1 > 0 && (millis() - timeCount1) > timeAllPulse1) { counter1 = 0; run_cleaner = true; millis1 = millis(); cleaner_start(); } // отсчет времени работы насоса if (run_cleaner) { if (millis() - millis1 >= 100) { millis1 = millis(); time_run_start = time_run_copy - 1; lcd.setCursor(2, 0); lcd.print("BHECEHO="); lcd.print(time_run_start); lcd.print("P"); if (time_run < 1) // выключить { cleaner_stop(); run_cleaner = false; } } } } // обработка прерывания монетоприемника - получить кол-во импульсов void count_pulse1() { detachInterrupt(4); counter1++; if (counter1 == 1) timeCount1 = millis(); delay(5); attachInterrupt(4, count_pulse1, FALLING); } // включить насос void cleaner_start() { digitalWrite(PIN_RELAY, RELAY_ON); // включить } void knopkaPUSK() // считываем состояние кнопки пуск { knopkaOn = digitalRead(knopka); delay(200); } void atomicInterrupt() // выполнение атомарного блока { ATOMIC_BLOCK(ATOMIC_RESTORESTATE) { // Атомарный доступ к переменной counter1: counter_copy = counter1; } } void atomicTime_run() { ATOMIC_BLOCK(ATOMIC_RESTORESTATE) { time_run_copy = time_run + counter_copy * TIME1; } } // выключить насос void cleaner_stop() { digitalWrite(PIN_RELAY, RELAY_OFF); // выключить delay(1000); counter1 = 0; time_run = 0; } [/code]
Помогите советом знающие принцип прерывания. У меня атомарная переменная time_run_copy при попытке вывести значение
time_run всегда равно 0, стало быть всегда выполняется
if
(time_run < 1)
и выключение насоса (или чего там) происходит на первом же вычете.void
atomicTime_run()
132
{
133
ATOMIC_BLOCK(ATOMIC_RESTORESTATE)
134
{
135
time_run_copy = time_run + counter_copy * TIME1;
136
}
137
}
Убрал вот это
Использовал только
void
atomicInterrupt()
Все заработало как нужно показывает вычет до 0 и отключает реле
time_run всегда равно 0, стало быть всегда выполняется
if
(time_run < 1)
и выключение насоса (или чего там) происходит на первом же вычете.я думал приравнял к 0 что бы при каждой итерации у меня значение в о выходило.Отключилось реле time_run в ноль
Теперь проблема такая.При уменьшении суммы на дисплее на месте ушедших разрядов появляются символы какие то.
Символы инопланетные что ли?
Символы инопланетные что ли?
Каббалистические
Символы старших разрядов.Вместо Руб появляется РРРуб)
ВСЕГДА печатайте строку ОДИНАКОВОЙ длины. Если сумма короткая, добавляйте пробелы слева или справа, как надо. И всего делов. Всё лишнее будет затираться
все логично, строчка двигается вправо, первый символ остается. Выводите на это место пробел
Вот так сказать ищущим страждущим в помощь.Может чем поможет данный скетч)))
У меня вопрос к знатокам.Как мне сделать вывод на дисплей вывод в рублевом эквиваленте вот тут то-есть из переменной
counter_copy к примеру с вычислением дестых долей.Переменную с плавающей точкой создавал туда запихивал counter_copy и полученное пробовал арифметически вычислить с последующим выводом на ЖК ну не получается пишет внесено и 0.00 до тех пор пока реле не отключится
090
lcd.print(time_run);
if
(run_cleaner)
082
{
083
if
(millis() - millis1 >= 100)
084
{
085
millis1 = millis();
086
counter1 = 0;
087
time_run = time_run - 1;
088
lcd.setCursor(0, 0);
089
lcd.print(
"BHECEHO = "
);
090
lcd.print(time_run);
091
lcd.print(
" P\xA9\xA0\x20"
);
092
И как убрать это противное мерцание экрана которое дает команда очистка дисплея вот тут
054
if
(counter_copy > 0 && (millis() - timeCount1) > timeAllPulse1)
// ПЕЧАТАЕМ СКОЛЬКО ВНЕСЕНО
055
{
056
lcd.clear();
057
lcd.setCursor(2, 0);
058
lcd.print(
"BHECEHO="
);
059
lcd.print(counter_copy);
060
lcd.print(
"P"
);
Уберите lcd.clear();
Уберите lcd.clear();
Тогда при следующей итерации накладывается два изображения из menu и это
Уберите lcd.clear();
Можно же затереть пробелами
забавно. Внесено рублей
087
time_run = time_run - 1;
088
lcd.setCursor(0, 0);
089
lcd.print(
"BHECEHO = "
);
090
lcd.print(time_run);
091
lcd.print(
" P\xA9\xA0\x20"
);
и вывод времени работы насоса (time_run).
Эта часть скетча была из чужого кода.Но хочу вывести именно уменьшение рублей.А время работы считалось фоново доля работы насоса.А уменьшение рублей не получается изображение на дисплее зависает
081 if (run_cleaner). Зачем мне в этом условном переходе присваивать к 0 значение получение в обработчике прерывания.Без присваивания counter1 всегда остаётся на с количеством внесённых рублей.Но почему у меня counter1 не хочет сбрасываться в 160 void cleaner_stop()
Уберите lcd.clear();
ну так стирайте только то, что нужно, а не весь экран целиком.
Ну или так #84
Просто внёс строчку с пробелами перед выводом текста)