Официальный сайт компании Arduino по адресу arduino.cc
Помогите с кодом чайнику (millis)
- Войдите или зарегистрируйтесь, чтобы получить возможность отправлять комментарии
Ср, 08/02/2017 - 15:24
Программа управляет 3х фазным котлом отопления и циркуляционным насосом. Не могу добиться чтобы насос выключался через 5минут после остановки ТЭНов.
// Управление котлом 3фазы // v5.0 // Arduino Mega 2560 #include <EEPROM.h> #include <OneWire.h> #include <DallasTemperature.h> #include <LiquidCrystal.h> // #include <LiquidCrystal_I2C.h> // LiquidCrystal_I2C lcd(0x3F,16,2); // Устанавливаем дисплей OneWire oneWire(24); // 24 вход датчиков 18b20 DallasTemperature ds(&oneWire); LiquidCrystal lcd(8, 9, 4, 5, 6, 7); #define KEY A0 const byte OUT[] = {32, 34, 36}; // номера выходов byte pos; byte tempOUTon[3]; // массив с температурой включения выхода float tempSensor[5]; // массив куда читается температура byte qty; // количество градусников на шине. unsigned long currentTime; unsigned long previousMillis ; // адреса градусников. DeviceAddress sensor1 = {0x28, 0xFF, 0xAB, 0xCA, 0x94, 0x16, 0x04, 0xB8}; DeviceAddress sensor2 = {0x28, 0xFF, 0x40, 0xAA, 0x8C, 0x16, 0x03, 0x6E}; DeviceAddress sensor3 = {0x28, 0xFF, 0x6B, 0x95, 0x94, 0x16, 0x04, 0xD8}; byte gradus[8] = { 0b00110, 0b01001, 0b01001, 0b00110, 0b00000, 0b00000, 0b00000, 0b00000 }; byte on[8] = { 0b01110, 0b11111, 0b11111, 0b11111, 0b11111, 0b11111, 0b01110, 0b00000 }; void readSet() { for (byte i = 0; i < qty; i++) tempOUTon[i] = EEPROM.read(i); } void outOff() { // выключает выходы for (byte i = 0; i < qty; i++) digitalWrite(OUT[i], LOW); } void erorr() { // останавливает работу программы и сигнализирует ошибку outOff(); // выключаем выходы lcd.clear(); lcd.print("sensor error"); while (1) { // крутим бесконечный цикл analogWrite(10, 100); delay(500); analogWrite(10, 255); delay(500); } } //// byte key() { //// для кнопок LCD int val = analogRead(0); if (val < 20) return 5; else if (val < 150) return 3; else if (val < 320) return 4; else if (val < 490) return 2; else if (val < 740) return 1; else return 0; } //// void setMenu(byte pos) { // установка температуры outOff(); lcd.clear(); while (1) { // крутим бесконечный цикл byte KEY = key(); // читаем состояние кнопок lcd.setCursor(2, 0); // выводим на экран lcd.print("Out:"); lcd.print(pos + 1); lcd.setCursor(9, 0); lcd.print("Pin:"); lcd.print(OUT[pos]); lcd.print(" "); lcd.setCursor(0, 1); lcd.print(" PinON: "); lcd.print(tempOUTon[pos]); lcd.write(1); lcd.print("C <>"); if (KEY == 2) { // если нажата кнопка tempOUTon[pos]--; // изменяем значение if (tempOUTon[pos] > 125) tempOUTon[pos] = 0; EEPROM.write(pos, tempOUTon[pos]); // сохраняем в EEPROM } else if (KEY == 5) { tempOUTon[pos]++; if (tempOUTon[pos] > 125) tempOUTon[pos] = 0; EEPROM.write(pos, tempOUTon[pos]); } else if (KEY == 3) { //Выходим из меню lcd.clear(); break; } delay(200); }///// }// void getTemp() { // читаем температуру и заполняем массив ds.requestTemperatures(); tempSensor[0] = ds.getTempC(sensor1); // немного китайского кода tempSensor[1] = ds.getTempC(sensor2); tempSensor[2] = ds.getTempC(sensor3); } void sensorTest() { // ищим датчики на шине, если количество изменилось, останавливаем работу ds.begin(); if (ds.getDeviceCount() != qty) erorr(); } void heat33() { // Мощность 33% digitalWrite(OUT[0], HIGH); digitalWrite(OUT[1], LOW); digitalWrite(OUT[2], LOW); digitalWrite(30, HIGH); } void heat66() { // Мощность 66% digitalWrite(OUT[0], HIGH); digitalWrite(OUT[1], HIGH); digitalWrite(OUT[2], LOW); digitalWrite(30, HIGH); } void heat100() { // Мощность 100% digitalWrite(OUT[0], HIGH); digitalWrite(OUT[1], HIGH); digitalWrite(OUT[2], HIGH); digitalWrite(30, HIGH); } void heatoff() { // Отключаем нагрев digitalWrite(OUT[0], LOW); digitalWrite(OUT[1], LOW); digitalWrite(OUT[2], LOW); pumpoff(); } void pumpoff() { // Отключаем насос через 5 минут // currentTime = millis(); if (currentTime >= (previousMillis + 300000)) // сравниваем текущий таймер с переменной previousMillis + 5 мин. { digitalWrite(30, LOW); previousMillis = currentTime; } } void setup() { // Serial.begin(9600); pinMode(30, OUTPUT); currentTime = millis(); previousMillis = currentTime; ds.begin(); ds.setResolution(sensor1, 10); ds.setResolution(sensor2, 10); ds.setResolution(sensor3, 10); qty = ds.getDeviceCount(); // при включении, сохраняем количество градусников, pinMode(KEY, INPUT); for (int i = 0; i < qty; i++) pinMode(OUT[i], OUTPUT); for (int i = 0; i < qty; i++) digitalWrite(OUT[i], LOW); lcd.createChar(1, gradus); lcd.createChar(2, on); lcd.begin(16, 2); lcd.clear(); readSet(); // читаем настройки из еепром } void loop() { previousMillis = currentTime; if (key() == 1) setMenu(pos); // если нажата селект, уходим в настройки else if (key() == 5 && pos < qty - 1) pos++; // крутим позицию else if (key() == 2 && pos != 0) pos--; else if (key() == 4) analogWrite(10, 10); // если вниз, глушим подсветку else if (key() == 3) digitalWrite(10, HIGH); sensorTest(); // тест наличия градусников на шине getTemp(); // читаем температуру с датчиков //// сверяем температуру и управляем выходами if (tempSensor[1] >= tempOUTon[1]) heatoff(); //Если на подаче 85гр отключаем нагрев полностью else for (int i = 0; i < qty; i++) { if (tempSensor[0] < tempOUTon[0] - 4) heat100(); // В зависимости от температуры на обратке отключаем часть тэнов else if (tempSensor[0] < tempOUTon[0] - 3) heat66(); else if (tempSensor[0] < tempOUTon[0] - 1) heat33(); else if (tempSensor[0] >= tempOUTon[0] + 1); } // Вывод информации на экран lcd.setCursor(0, 0); lcd.print(pos + 1); lcd.print(". "); lcd.print(tempSensor[pos], 1); // показываем температуру с датчика lcd.write(1); lcd.print("C "); lcd.setCursor(2, 1); lcd.print(tempOUTon[pos]); // показываем установленную температуру lcd.write(1); lcd.print("C "); lcd.setCursor(13, 0); // рисуем статус выхода for (int i = 0; i < qty; i++) { if (digitalRead(OUT[i])) lcd.write(2); else lcd.print("O"); } lcd.setCursor(13, 1); // рисуем номера выходов for (int i = 0; i < qty; i++) lcd.print(i + 1); }
строка 175 должно быть
и в логике принятия решения - косяк - строка 209,что делает, УГУ
Так чтоли? Не догоняю чтото..
209 закомментил
пожалуйста, ткните носом как правильно будет
Так чтоли? Не догоняю чтото..
Эта функция из лупа будет вызываться циклически через функцию отключения тэнов, значит при первом вхождение в функцию отключения тэнов (код в loop) надо выставлять флаг, и устанавливать переменной previousMillis текущее значение, но это делать только если не выставлен флаг, если выставлен, то пропускаем этот код
Кривоватенько, конечно, но работать обязано
Вырисовывается еще одна вложенная конструкция if в строке 221
пожалуйста, ткните носом как правильно будет
существует 99 способов, 100, профессор, 100...
первый - лёжа, ...тогда 101 )))
sshmel, тебе щас насоветуют.... Никогда не прибавляй к millis, конечно если не стоит цель написать кривой, не работающий код.
if
(currentTime >= (previousMillis + 300000))
//Не правильноif
(currentTime - previousMillis
300000) //Правильно>=
Никогда не прибавляй к millis...
аха - и, не вычитай.
sshmel, тебе щас насоветуют.... Никогда не прибавляй к millis, конечно если не стоит цель написать кривой, не работающий код.
if
(currentTime >= (previousMillis + 300000))
//Не правильноif
(currentTime - previousMillis
300000) //Правильно>=
Это да! Онож изменит premillis, сам бы так не написал потому видимый косяк пропустил, мне простительно, изучаю недавно
Там много косяков, проще всё переписать, к примеру зачем всё время зубами (релюхами) щёлкать, оно может и не щёлкнет, но ведь совершенно незачем заходить и выполнять код выключения тэнов и насоса на каждом проходе лупа при условии превышения температуры воды свыше 85 градусов
Так правильней?
Никогда не прибавляй к millis...
аха - и, не вычитай.
А я прибавляю, прибавлял и, буду прибавлять!!!
PS Лапауций, а ты откуда так хорошо русский язык знаешь, запятые по знакам пунктуации расставляешь прям
PS Лапауций, а ты откуда так хорошо русский язык знаешь, запятые по знакам пунктуации расставляешь прям
ЗЫ. пленных бурят допрашивал.
Это с какого такого перепугу?
А потом у Вас часы на миллис зделать низзя
PS Лапауций, а ты откуда так хорошо русский язык знаешь, запятые по знакам пунктуации расставляешь прям
ЗЫ. пленных бурят допрашивал.
Я думал ты главный по ардуинам
Это с какого такого перепугу?
А потом у Вас часы на миллис зделать низзя
у кого это у ВАС?
ну, сделай
Я думал ты главный по ардуинам
дуины - это хобби.
Это с какого такого перепугу?
А потом у Вас часы на миллис зделать низзя
у кого это у ВАС?
ну, сделай
по условию задачи после того, как температура на выходе станет 85 градусов надо:
1. выключить тэны
2. через пять минут выключить насос, до этого он качает
То-есть, в переменную previousMillis заносим значение, когда температура стала 85 градусов, так???
по условию задачи после того, как температура на выходе станет 85 градусов надо:
1. выключить тэны
2. через пять минут выключить насос, до этого он качает
То-есть, в переменную previousMillis заносим значение, когда температура стала 85 градусов, так???
фикс:
1. какие тены, бурят?
2. какой насос, бурят?
*я тебе дал пример кода когда что-то после включения выключается через определённый промежуток времени.
Диалог глухого со слепым, я уже выше сказал, код надо переписать, он мне не нравится, просто не нравится, то что ты написал понятно, но ТС это не надо, у меня получается надо вводить два флага и луп переписать, но я не программер, можно же сделать красиво
я не программер, можно же сделать красиво
я не программер - я делаю красиво
*я исправил твой код #9 - насрать на ТС
я не программер, можно же сделать красиво
я не программер - я делаю красиво
*я исправил твой код #9 - насрать на ТС
А! Всё равно работать оно не будет, там логику править надо...
Дождёмся, что ТС скажет
Спасибо за ответы всем. Извините что нет возможности своевременно отвечать. Работаю над проектом в свободное от работы время. Попробую, обязательно отпишусь.
В таком виде работать тоже не захотела
Но я её победил :)
Немного переработал код
Датчик 1 - температура воздуха в помещении. От него зависит греет система или нет.
Датчик 2 стоит на обратке. От его температуры зависит сколько ТЭНов включено (для экономии электроэнергии).
Датчик 3 как аварийный, стоит на подаче. Если t превышает заданную то нагрев выключается.
При отключении нагрева насос отрабатывает заданное в скетче время потом отключается
Проект будет развиваться дальше.
В планах запись данных на SD карту чтобы при желании посмотреть сколько котел проработал на 1/3, 2/3 или на полную мощность, сколько соответственно потребил электроэнергии.
Удаленное управление и мониторинг+охрана:
Отдельно будет стоять ардуино мега, к ней прицепим GSM модуль и датчики пожара, охраны, может ещё чего. По запросу она будет передавать данные на телефон или на сервер, так-же по запросу управлять ардуиной котла отопления (Собрался в гараж, за час-два послал смс чтобы поднял температуру)
Говнокод, будет глючить. Ты так и не понял, почему к millis нельзя прибавлять...
Проект будет развиваться дальше.
В таком случае стоит переделать sensorTest() так чтобы система не отключалась банально изза того что датчик глючит или плохой контакт. В случае ошибки сделайте повторную проверку через пару секунд.
Конечно я не такой сильный гуру как вы или многие другие с этого форума но тем не менее учусь, например с вашей помощью. Месяц назад я не мог понять почему у меня лсдшник не загорался.
По поводу глюков погонял программу с час гдето, повышал и понижал температуру на всех датчиках, пока работает как надо.
ну, сказано же было не делать так:
if
(currentTime >= (previousMillis + 10000)) {
Можете объяснить почему?
Сделал так, работает
И всё же
Я же не прибавляю к millis, я прибавляю к переменной которая равняется millis, разве не так?
Если обозвать её как то по другому суть не изменится
Можете объяснить почему?
потому, что у тебя на руках и ногах по 10-ть пальцев, а не по 10+ещё.
Можете объяснить почему?
потому, что у тебя на руках и ногах по 10-ть пальцев, а не по 10+ещё.
Он еще один посчитал :)
Сделал так, работает
И всё же
Я же не прибавляю к millis, я прибавляю к переменной которая равняется millis, разве не так?
Если обозвать её как то по другому суть не изменится
Именно это вы и делаете - прибавляете к переменной хранящей предыдущее значение времени некую константу, поэтому вам все и говорят. не делайте так
Да, эта переменная должна принимать текущее значение а момент достижения макс.температуры
Второе, алгоритм отключения двигателя через 5 минут после достижения максимальной температуры так и не реализован, а вы говорите, что всё пучком...это мантра такая???
класс титановый велосипед для delay без delay().