Помогите исправить код
- Войдите на сайт для отправки комментариев
Чт, 18/01/2018 - 12:09
Собрал вот такой скейч, но информацию с датчика не выводиться в кейсах, без них все хорошо. Помогите советом как сделать чтоб и в кецсах выводилась информация с датчиков на дисплей.
UPD: при переключении кейсов показания с датчиков показываются но не обновляются.
//Подключите красный провод к +5V, //Черный провод на массу //Желтый провод датчика к контакту #2 #include <LiquidCrystal_I2C.h> #include "TM1637.h" LiquidCrystal_I2C lcd(0x3F,16,2); // пины под LCD shield #define FLOWSENSORPIN 2 // пин для датчика расхода #define BUTTON_PIN 5 // пин Arduino подключенный к кнопке #define CLK 9 #define DIO 8 TM1637 tm1637(CLK,DIO); int clicks = 0; // текущее кол-во нажатий boolean ready = false; boolean buttonWasUp = true; volatile uint16_t pulses = 0; // считает сколько импульсов volatile uint8_t lastflowpinstate; // отслеживает состояние пина FLOWSENSORPIN volatile uint32_t lastflowratetimer = 0; // отсчитывает время между импульсами volatile float flowrate; // и использует это, чтобы вычислить скорость потока SIGNAL(TIMER0_COMPA_vect) { uint8_t x = digitalRead(FLOWSENSORPIN); if (x == lastflowpinstate) { lastflowratetimer++; return; // nothing changed! } if (x == HIGH) { //low to high transition! pulses++; } lastflowpinstate = x; flowrate = 1000.0; flowrate /= lastflowratetimer; // в герцах lastflowratetimer = 0; } void useInterrupt(boolean v) { if (v) { // Timer0 уже используется для millis() - просто прерываем // в середине и вызываю "Compare A" функция выше OCR0A = 0xAF; TIMSK0 |= _BV(OCIE0A); } else { // не вызывать функцию прерывания больше TIMSK0 &= ~_BV(OCIE0A); } } int flag=0; void setup() { { // инициализация дисплея tm1637.init(); tm1637.set(7); } lcd.init(); lcd.begin(16, 2); pinMode(BUTTON_PIN, INPUT_PULLUP); // начальное сообщение lcd.setCursor(0, 0); lcd.print("TEST CONTROLLERS"); lcd.setCursor(0, 1); lcd.print("-"); delay(100); lcd.setCursor(1, 1); lcd.print("-"); delay(100); lcd.setCursor(2, 1); lcd.print("-"); delay(100); lcd.setCursor(3, 1); lcd.print("-"); delay(100); lcd.setCursor(4, 1); lcd.print("-"); delay(100); lcd.setCursor(5, 1); lcd.print("-"); delay(100); lcd.setCursor(6, 1); lcd.print("-"); delay(100); lcd.setCursor(7, 1); lcd.print("-"); delay(100); lcd.setCursor(8, 1); lcd.print("-"); delay(100); lcd.setCursor(9, 1); lcd.print("-"); delay(100); lcd.setCursor(10, 1); lcd.print("-"); delay(100); lcd.setCursor(11, 1); lcd.print("-"); delay(100); lcd.setCursor(12, 1); lcd.print("-"); delay(100); lcd.setCursor(13, 1); lcd.print("-"); delay(100); lcd.setCursor(14, 1); lcd.print("-"); delay(100); lcd.setCursor(15, 1); lcd.print("-"); delay(1500); lcd.clear(); lcd.setCursor(1, 0); lcd.print("INFORMACIYA"); delay(3000); // Время на прочтение начального сообщения 5сек pinMode(FLOWSENSORPIN, INPUT); digitalWrite(FLOWSENSORPIN, HIGH); lastflowpinstate = digitalRead(FLOWSENSORPIN); useInterrupt(true); } void loop() { if(digitalRead(3)==HIGH&&flag==0)//если кнопка нажата // и перемення flag равна 0 , то ... { flag=1; //это нужно для того что бы с каждым нажатием кнопки //происходило только одно действие // плюс защита от "дребезга" 100% } if(digitalRead(3)==LOW&&flag==1)//если кнопка НЕ нажата //и переменная flag равна - 1 ,то ... { digitalWrite(4,!digitalRead(4)); flag=0;//обнуляем переменную flag } // счетчик нажатий, до 5 раз, потом снова по кругу, каждый раз значение нажатия записывается в переменную boolean buttonRead = digitalRead(BUTTON_PIN); if (buttonWasUp && !buttonRead) { delay(10); if (!digitalRead(BUTTON_PIN)) { clicks = (clicks + 1) % 13; ready = true; // флаг, что надо обновить экран } } if(ready) { lcd.clear(); // очистим экран ready = false; //сбрасываем флаг switch(clicks) { case 1: lcd.backlight(); lcd.setCursor(1, 0); lcd.print("Bettary 100 %"); lcd.setCursor(1, 1); lcd.print("DATA CLOCK"); tone (11, 2200, 1400); // включаем на пьезодинамик 600 Гц delay(2000); // ждем 1 секунду tone(11, 2200, 1400); delay(500); break; case 2: { lcd.backlight(); Serial.begin(9600); lcd.setCursor(4, 0); lcd.print("RASHOD"); lcd.setCursor(0, 1); lcd.print("+"); float liters = pulses; liters /= 7.5; liters /= 60.0; Serial.print(liters); Serial.println(" Liters"); lcd.setCursor(1, 1); lcd.print(liters); lcd.print(" litrov"); tm1637.display(flowrate); delay(3000);} break; case 3: {lcd.backlight(); float liters = pulses; liters /= 7.5; liters /= 60.0; lcd.setCursor(3, 0); lcd.print(pulses, DEC); lcd.setCursor(7, 0); lcd.print(" m1"); tm1637.display(liters); delay(3000);} break; } } buttonWasUp = buttonRead; }
Забавный скетч и комменты, видимо както комменты шифровали. Ну или программу писали 2 разных человека и кто писал комменты не видел кода.
ну на такое вообще можно закрыть глаза
Но вот тут уже перебор
Вы сами то проверяли чему будет равна переменная clicks? Ну и потом защиты от дребезга нет никакой.
Проверьте выполняются ли условие в вышеприведенных if и проверьте чему равна clicks.
Вопрос стоял в помощи о том что не выводит на экран в реальном времени. Если можете подсказать с удовольствием приму Вашу помощь. Скейч составлялся из уже готовых наработок с исправлениями. И то что Вы указали не влияет на данную неисправность которую я хочу найти.
Забавный скетч и комменты, видимо както комменты шифровали. Ну или программу писали 2 разных человека и кто писал комменты не видел кода.
ну на такое вообще можно закрыть глаза
Типичная ситуация когда код и коменты пишутся сразу, а затем в процессе отладки правят только код.
скетч. насколько я вижу - собран из кусков. в которых вы мало что понимаете, верно? Таймеры и прерывания. очевидно, скопированы где-то в инете, а вот код, который касается "Bettery" и "rashod" - видимо ваш ?)
Что касается "кейсов" - разберитесь с параметром clicks. В вашей программе этот параметр меняется от 0 до 12, а кейсов всего три. Вероятно это ошибка.
По поводу расхода - не понял, зачем вы вычисляете его дважды, причем разными способами? Первый раз - в прерывании - получается flowrate. Второй - в кейсах величину liters. Причем на экран выводите первую величину, а в сериал - вторую. Мне кажется, что это не специально так задумано, а просто бардак и путаница, возникшие при склеивании скетча из частей.
И советую прочитать хоть чуть-чуть про циклы - 50 с лишним строкс 76 по 122 можно элементарно ужать до 5 - более чем в 10 раз - если использовать for
Типичная ситуация когда код и коменты пишутся сразу, а затем в процессе отладки правят только код.
нет, это ситуация. когда код пишет один - а потом этот код копирует другой, полный чайник - и начинает что-то менять под себя.
.del
Вопрос стоял в помощи о том что не выводит на экран в реальном времени. Если можете подсказать с удовольствием приму Вашу помощь. Скейч составлялся из уже готовых наработок с исправлениями. И то что Вы указали не влияет на данную неисправность которую я хочу найти.
Э-э-э, да у вас претезии к ответу? :)
Что влияет, а что нет - не вам судить. Судя по всему. в программировании вы - ноль, так что слушайте умных людей или разбирайтесь сами. Код у вас полон самых разнообразных ошибок и нелепиц. Параметр clics работает неверно - а он имеет прямое отношение к вашим "кейсам"
кейсы исправил, на вывод с датчика на экран не помогло, так же не работает. Куда дальше копать.
Куда дальше копать.
написал в сообщении #4 - разберитесь в путанице с вычислением расхода
UPD: при переключении кейсов показания с датчиков показываются но не обновляются.
Что значит "показываются, но не обновляются"? поясните
UPD: при переключении кейсов показания с датчиков показываются но не обновляются.
Что значит "показываются, но не обновляются"? поясните
При подаче питания, идет поток воздуха в датчик расхода, при переключении режима на lcd.print("RASHOD"); показывает сколько прошло до того как этот режим включился и замерает на этой цифре и больше показания не обновляются.
при переключении режима на lcd.print("RASHOD"); показывает сколько прошло до того как этот режим включился и замерает на этой цифре и больше показания не обновляются.
И не должны обновляться. У вас в программе обновление экрана при переключении режимов происходит только один раз, а потом параметр ready устанавливается в false и программа в блок вывода на экран даже не заходит.
При подаче питания, идет поток воздуха в датчик расхода, при переключении режима на lcd.print("RASHOD"); показывает сколько прошло до того как этот режим включился и замерает на этой цифре и больше показания не обновляются.
У вас данные в переменную pulses читаются в прерывании по таймеру, накохер? Если есть attachInterrupt, и этот пин и так уже поддерживает внешние прерывания?
При подаче питания, идет поток воздуха в датчик расхода, при переключении режима на lcd.print("RASHOD"); показывает сколько прошло до того как этот режим включился и замерает на этой цифре и больше показания не обновляются.
У вас данные в переменную pulses читаются в прерывании по таймеру, накохер? Если есть attachInterrupt, и этот пин и так уже поддерживает внешние прерывания?
Как выше уже писали, что я не програмист. Собрал код из того, в чем разобрался. Не могли бы Вы подсказать что нужно убрать или наоборот добавить, чтоб информация корректно выводилась?
По поводу расхода - не понял, зачем вы вычисляете его дважды, причем разными способами? Первый раз - в прерывании - получается flowrate. Второй - в кейсах величину liters. Причем на экран выводите первую величину, а в сериал - вторую.
Там ещё и второй индикатор есть! На LCD литерсы печатаются, а на TM1637 флоурейты. Интересно, индикатор в системе правда есть?
По поводу расхода - не понял, зачем вы вычисляете его дважды, причем разными способами? Первый раз - в прерывании - получается flowrate. Второй - в кейсах величину liters. Причем на экран выводите первую величину, а в сериал - вторую.
Там ещё и второй индикатор есть! На LCD литерсы печатаются, а на TM1637 флоурейты. Интересно, индикатор в системе правда есть?
Да, два экрана один 1602 через I2C, второй 7 сегментный 3642BH
Andrew2018 - "почему не обновляются?" - ответ в сообщении 12
Andrew2018 - "почему не обновляются?" - ответ в сообщении 12
А как сделать чтоб обновлялось?))
можно тупо закомментировать строчку ready = false; (177 строка) Не уверен, что будет устойчиво работать , так как экран будет обновлятся при каждом проходе цикла - но хотя бы проверить, будут ли выводится данные.
можно тупо закомментировать строчку ready = false; (177 строка) Не уверен, что будет устойчиво работать , так как экран будет обновлятся при каждом проходе цикла - но хотя бы проверить, будут ли выводится данные.
Сделал, зацикливает первый кейс. И дальше не пропускает
Сделал, зацикливает первый кейс. И дальше не пропускает
выложите последний вариант кода
Сделал, зацикливает первый кейс. И дальше не пропускает
не вижу, за счет чего может "не проходить дальше". Заклинивает именно в кейсе 1, не нулевом? На кнопку увеличения clics не реагирует?
Закоментировал строку:
177
ready =
false
;
//сбрасываем флаг
И при нажатии на кнопку повторяет один и тот же кейс:
180
case
1:
181
lcd.backlight();
182
lcd.setCursor(1, 0);
183
lcd.print(
"Bettary 100 %"
);
184
lcd.setCursor(1, 1);
185
lcd.print(
"DATA CLOCK"
);
186
tone (11, 2200, 1400);
// включаем на пьезодинамик 600 Гц
187
delay(2000);
// ждем 1 секунду
188
tone(11, 2200, 1400);
189
delay(500);
190
break
;
больше на кнопку не реагирует.
По-моему, тут пытаются получить рабочий скетч методом, которым обезьяны пишут "Война и мир" - т.е. тыка. Вместо того, чтобы начать учиться, прочитать про ту же функцию attachInterrupt, посмотреть кучу _простейших_ примеров по подсчёту RPM компьютерного кулера того же, затем - попробовать вывести это дело в монитор порта, потом уже - прикручивать LCD.
Но мы так делать не будем, это не наш метод! Правда?
DIYMan, погоди, не горячись :) В отличии от большинства халявщиков - этот хоть что-то сам пытается делать.
По-моему, тут дело не в прерывании. Почему у автора не обновляется экран - я указал в #12. Но вот почему код из #22 может зацикливаться в первом кейсе - не вижу....
По-моему, тут пытаются получить рабочий скетч методом, которым обезьяны пишут "Война и мир" - т.е. тыка. Вместо того, чтобы начать учиться, прочитать про ту же функцию attachInterrupt, посмотреть кучу _простейших_ примеров по подсчёту RPM компьютерного кулера того же, затем - попробовать вывести это дело в монитор порта, потом уже - прикручивать LCD.
Но мы так делать не будем, это не наш метод! Правда?
Спасибо большое за совет. Я сюда пришел за помощью, так как не понимаю в програмировании, чтоб меня ткнули носом что вот здесь нужно дописать что то или наоборот удалить. Я понимаю что учиться програмированию для меня уже поздно да и не пригодиться больше это мне. Это разовый проект который хочу доделать, все работает что хотел, только осталось вот это обновление данных. Если кто то сможет помочь мне пусть напишет (я отблагодарю) и пусть озвучит сумму за какую согласиться помочь.
Чтобы посоветовать "что-то дописать или удалить" с гарантированным эффектом при вашем уровне подготовки - кому-то нужно этот скетч переписать и проверить на железке. Иначе вы еще и вставлять будете неизвестно куда.
Только без обид. Это опыт участия в подобных дискуссиях.
DIYMan, погоди, не горячись :) В отличии от большинства халявщиков - этот хоть что-то сам пытается делать.
По-моему, тут дело не в прерывании. Почему у автора не обновляется экран - я указал в #12. Но вот почему код из #22 может зацикливаться в первом кейсе - не вижу....
Спасибо за защиту в мою сторону))
Чтобы посоветовать "что-то дописать или удалить" с гарантированным эффектом при вашем уровне подготовки - кому-то нужно этот скетч переписать и проверить на железке. Иначе вы еще и вставлять будете неизвестно куда.
Только без обид. Это опыт участия в подобных дискуссиях.
Да все собрал, вставить то смогу. Этот код собрал из разных частей, значет, что то еще могу предпринять))
Да люди в лесу тоже грибов насобирают, потому что "дело-то плёвое"... Потом те, кто не помёрли, по полгода лечатся.
Типичная ситуация когда код и коменты пишутся сразу, а затем в процессе отладки правят только код.
Скорее, типичная ситуация безграмотно составленных комментариев. Бессмысленно в комментарии дублировать код, комментарий должен отвечать не на вопрос "Что делаем?" - это видно из самого кода, а объяснять "Зачем мы это делаем?".