Помогите исправить код
- Войдите на сайт для отправки комментариев
Чт, 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 разных человека и кто писал комменты не видел кода.
ну на такое вообще можно закрыть глаза
Но вот тут уже перебор
// счетчик нажатий, до 5 раз, потом снова по кругу, каждый раз значение нажатия записывается в переменную boolean buttonRead = digitalRead(BUTTON_PIN); if (buttonWasUp && !buttonRead) { delay(10); if (!digitalRead(BUTTON_PIN)) { clicks = (clicks + 1) % 13; ready = true; // флаг, что надо обновить экран } }Вы сами то проверяли чему будет равна переменная 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 строка) Не уверен, что будет устойчиво работать , так как экран будет обновлятся при каждом проходе цикла - но хотя бы проверить, будут ли выводится данные.
Сделал, зацикливает первый кейс. И дальше не пропускает
Сделал, зацикливает первый кейс. И дальше не пропускает
выложите последний вариант кода
//Подключите красный провод к +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("Bettary 100 %"); 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) % 8; 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(); lcd.setCursor(5, 0); lcd.print("REGIM"); lcd.setCursor(0, 1); lcd.print("Poverka Priborov"); delay(500); break; case 3: lcd.backlight(); lcd.setCursor(1, 0); lcd.print("Nomer protokola"); lcd.setCursor(3, 1); lcd.print("0000044158"); delay(500); break; case 4: lcd.backlight(); lcd.setCursor(2, 0); lcd.print("VIBOR REGIMA"); lcd.setCursor(2, 1); lcd.print("Start - Stop"); delay(500); break; case 5: lcd.backlight(); lcd.setCursor(4, 0); lcd.print("VVEDITE"); lcd.setCursor(0, 1); lcd.print("OB'EM:000 litrov"); delay(500); break; case 6: { 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(" M KUB/CHAS"); tm1637.display(flowrate); delay(3000); break; } case 7: {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;} case 0: lcd.backlight(); lcd.setCursor(4, 0); lcd.print("100 %"); tone (11, 2200, 1400); // включаем на пьезодинамик 600 Гц delay(2000); // ждем 1 секунду tone(11, 2200, 1400); delay(500); break; } } buttonWasUp = buttonRead; }Сделал, зацикливает первый кейс. И дальше не пропускает
не вижу, за счет чего может "не проходить дальше". Заклинивает именно в кейсе 1, не нулевом? На кнопку увеличения clics не реагирует?
Закоментировал строку:
177ready =false;//сбрасываем флагИ при нажатии на кнопку повторяет один и тот же кейс:180case1:181lcd.backlight();182lcd.setCursor(1, 0);183lcd.print("Bettary 100 %");184lcd.setCursor(1, 1);185lcd.print("DATA CLOCK");186tone (11, 2200, 1400);// включаем на пьезодинамик 600 Гц187delay(2000);// ждем 1 секунду188tone(11, 2200, 1400);189delay(500);190break;больше на кнопку не реагирует.
По-моему, тут пытаются получить рабочий скетч методом, которым обезьяны пишут "Война и мир" - т.е. тыка. Вместо того, чтобы начать учиться, прочитать про ту же функцию attachInterrupt, посмотреть кучу _простейших_ примеров по подсчёту RPM компьютерного кулера того же, затем - попробовать вывести это дело в монитор порта, потом уже - прикручивать LCD.
Но мы так делать не будем, это не наш метод! Правда?
DIYMan, погоди, не горячись :) В отличии от большинства халявщиков - этот хоть что-то сам пытается делать.
По-моему, тут дело не в прерывании. Почему у автора не обновляется экран - я указал в #12. Но вот почему код из #22 может зацикливаться в первом кейсе - не вижу....
По-моему, тут пытаются получить рабочий скетч методом, которым обезьяны пишут "Война и мир" - т.е. тыка. Вместо того, чтобы начать учиться, прочитать про ту же функцию attachInterrupt, посмотреть кучу _простейших_ примеров по подсчёту RPM компьютерного кулера того же, затем - попробовать вывести это дело в монитор порта, потом уже - прикручивать LCD.
Но мы так делать не будем, это не наш метод! Правда?
Спасибо большое за совет. Я сюда пришел за помощью, так как не понимаю в програмировании, чтоб меня ткнули носом что вот здесь нужно дописать что то или наоборот удалить. Я понимаю что учиться програмированию для меня уже поздно да и не пригодиться больше это мне. Это разовый проект который хочу доделать, все работает что хотел, только осталось вот это обновление данных. Если кто то сможет помочь мне пусть напишет (я отблагодарю) и пусть озвучит сумму за какую согласиться помочь.
Чтобы посоветовать "что-то дописать или удалить" с гарантированным эффектом при вашем уровне подготовки - кому-то нужно этот скетч переписать и проверить на железке. Иначе вы еще и вставлять будете неизвестно куда.
Только без обид. Это опыт участия в подобных дискуссиях.
DIYMan, погоди, не горячись :) В отличии от большинства халявщиков - этот хоть что-то сам пытается делать.
По-моему, тут дело не в прерывании. Почему у автора не обновляется экран - я указал в #12. Но вот почему код из #22 может зацикливаться в первом кейсе - не вижу....
Спасибо за защиту в мою сторону))
Чтобы посоветовать "что-то дописать или удалить" с гарантированным эффектом при вашем уровне подготовки - кому-то нужно этот скетч переписать и проверить на железке. Иначе вы еще и вставлять будете неизвестно куда.
Только без обид. Это опыт участия в подобных дискуссиях.
Да все собрал, вставить то смогу. Этот код собрал из разных частей, значет, что то еще могу предпринять))
Да люди в лесу тоже грибов насобирают, потому что "дело-то плёвое"... Потом те, кто не помёрли, по полгода лечатся.
Типичная ситуация когда код и коменты пишутся сразу, а затем в процессе отладки правят только код.
Скорее, типичная ситуация безграмотно составленных комментариев. Бессмысленно в комментарии дублировать код, комментарий должен отвечать не на вопрос "Что делаем?" - это видно из самого кода, а объяснять "Зачем мы это делаем?".