Программирую модуль климат-контроля. Есть вопрос.
- Войдите на сайт для отправки комментариев
Здравствуйте.
Затеял первый "серьезный" проект и столкнулся с некоторыми непонятками.
На данный момент код такой:
#include "Servo.h" #include "DHT.h" #include "PID_v1.h" #include "PCD8544.h" #include "EEPROM.h" // Digital pins & PWM #define POWER_RELAY 22 //реле поддержки питания #define POWER_IN 23 //включение зажигания #define INNER_SENSOR 24 //датчик температуры и влажности внутреннего воздуха цифровой (DHT11) #define HEATER_MOTOR 2 //нога по которой управляется скорость вращения вентилятора отопителя #define HEATER_VALVE 3 //сервопривод управления клапаном ОЖ #define OUTER_AIR_SERVO 4 //сервопривод управления заслонкой воздуха #define STATE_LED 13 //встроенный светодиод для индикации работы и имитации бурной деятельности //Analog in pins #define OUTER_TEMP A0 //датчик температуры наружнего воздуха аналоговый #define COOLANT_TEMP A1 //датчик температуры теплоносителя //настройки кнопочной станции #define KEYTEMPUP 30 // | #define KEYTEMPDOWN 31 // | регулировка температуры #define KEYMODEAUTO 32 // режим автоматического регулирования скорости вентилятора #define KEYONOFF 33 // включение\выключение модуля #define KEYFANUP 34 // | #define KEYFANDOWN 35 // | регулировка скорости вращения вентилятора #define OUTER_AIRIN 36 // закрытие забора воздуха с улицы //разметка EEPROM #define FAN_SPEED 1 // #define SETPOINT 2 // Адреса EEPROM для чтения значений при загрузке #define MODE_AUTO 3 // //тип датчика DHT #define DHTTYPE DHT11 // у меня такой, если нужен другой тип - раскоментируй соответствующую строку //#define DHTTYPE DHT21 //#define DHTTYPE DHT22 Servo heaterValve; Servo outerAir; static int heaterSpeed = 0; static double outerTemp; static double innerTemp; static double innerHum; static boolean modeAuto; static double Setpoint, Input, Output; // создаем переменные для ПИД //задаем коэффициенты ПИД static double aggKp = 4, aggKi = 0.2, aggKd = 1; // агрессивные static double consKp = 1, consKi = 0.05, consKd = 0.25; // консервативные static double histeresis = 1; // коэффициент петли гистерезиса. пока не используется. unsigned long beginTime; // переменная начала работы таймера выключения void setup() { //первым делом взведем реле digitalWrite(POWER_RELAY, HIGH); // запуск порта отладки Serial.begin(9600); Serial.println("Climatic module v 0.1"); // Красивости... Serial.print("Initialising"); delay(500); Serial.print("."); delay(500); Serial.print("."); delay(500); Serial.print("."); delay(500); Serial.print("."); delay(500); Serial.print("."); delay(500); //В принципе не мешают, пусть будут. Время работы в данной части не критично // конфигурируем выходы pinMode(POWER_RELAY, OUTPUT); // Выход "Реле "Камикадзе" (Поддерживает питание системы некоторое время после выключения зажигания, затем отключается) pinMode(HEATER_MOTOR, OUTPUT); // Выход "Вентилятор" pinMode(HEATER_VALVE, OUTPUT); // Выход "Клапан" pinMode(STATE_LED, OUTPUT); // Встроенный светодиод Serial.println(); Serial.println("Outputs configured"); // конфигурируем входы pinMode(OUTER_TEMP, INPUT); // Вход "Температура снаружи" pinMode(COOLANT_TEMP, INPUT); // Вход "Температура теплоноситель" pinMode(KEYTEMPUP, INPUT); // | pinMode(KEYTEMPDOWN, INPUT); // | pinMode(KEYFANUP, INPUT); // |Входы кнопок pinMode(KEYFANDOWN, INPUT); // | pinMode(KEYONOFF, INPUT); // | pinMode(KEYMODEAUTO, INPUT); // | pinMode(OUTER_AIRIN, INPUT); // | Serial.println(); Serial.println("Inputs configured"); //добавляем приводы heaterValve.attach(HEATER_VALVE); outerAir.attach(OUTER_AIR_SERVO); Serial.println(); Serial.println("Servos attached"); //создаем вызов внутреннего датчика температуры-влажности DHT inTemp(INNER_SENSOR, DHTTYPE); inTemp.begin(); Serial.println(); Serial.println("Inner temperature sensor is ready"); //запускаем ПИД PID myPID(&Input, &Output, &Setpoint, consKp, consKi, consKd, DIRECT); Serial.println(); Serial.println("PID started"); //считываем значения предыдущего запуска heaterSpeed = EEPROM.read(FAN_SPEED); Setpoint = EEPROM.read(SETPOINT); modeAuto = EEPROM.read(MODE_AUTO); Serial.println(); Serial.println("Previvous start data:"); Serial.print("Fan speed: "); Serial.println(heaterSpeed); Serial.print("Temperature set: "); Serial.println(Setpoint); Serial.print("Fan mode: "); if (modeAuto == 0) { Serial.println("Manual"); } else { Serial.println("Auto"); } Serial.println(modeAuto); //приводим систему в стартовое состояние analogWrite(HEATER_MOTOR, heaterSpeed); //да, 0=0, но пусть пока будет для страховки outerTemp = analogRead(OUTER_TEMP); innerHum = inTemp.readHumidity(); innerTemp = inTemp.readTemperature(); Serial.println(); if (innerTemp >= -50) { if (innerTemp <= 60) { Serial.print("Current temperature: "); Serial.print(innerTemp); Serial.println(" ᵒC"); } else { Serial.println("It's too HOT here! Or temperature sensor fail."); } } else { Serial.println("It's too COLD here! Or temperature sensor fail."); } if (innerHum > 0 && innerHum < 100) { Serial.print("Current humidity: "); Serial.print(innerHum); Serial.println(" %"); } else { Serial.println("Something wrong with humidity sensor!"); } if (outerTemp > -50) { if (outerTemp < 50) { Serial.print("Current temperature: "); Serial.print(outerTemp); Serial.println(" ᵒC"); } else { Serial.println("It's too HOT here! Or temperature sensor fail."); } } else { Serial.println("It's too COLD here! Or overboard temperature sensor fail."); } Serial.println("Thanks for flying our airline!"); } void loop() { Serial.println("Starting!"); //код вызова завершающей функции if (digitalRead(POWER_IN) == LOW) { beginTime = millis(); ending(); } delay(1000); } void ending() { /*эта часть нужна для задержки выключения питания платы при запитке через реле "Камикадзе" но она пока нихрена не работает как задумано.*/ Serial.println("Ignition OFF"); Serial.println(beginTime); Serial.println(millis()); scanIgnition(); Serial.println("Turning system OFF"); digitalWrite(POWER_RELAY, LOW); } void scanIgnition () { do { if (digitalRead(POWER_IN) == HIGH) { Serial.println("Ignition ON"); loop(); } } while (beginTime > (millis() - 100000)); }
Проблема заключается в следующем. в секции loop() пытался реализовать проверку наличия внешнего питания через проверку состояния цифрового входа. Проверка происходит (строки 192-196). При пропадании сигнала вызывается соответствующая (ending()) функция. А дальше начинаются странности.
Как я предполагал выполнение основной функции должно останавливаться и обработка передается в "дочернюю" функцию. Но почему-то loop() продолжает выполняться.
Воторой вопрос, с которым столкнулся - как остановить полностью выполнение программы? По идее после того, как будет отключено реле (строка 208), питание с платы пропадет. Но в случае работы "на столе" программа продолжает выполняться.
Программа расчитана на МЕГУ.
Попробуйте функции в коде "void ending(), scanIgnition ()" перенести выше
void
loop
() или обьявить до
void
loop
()
К сожалению не помогло.
Нет тут никаких станностей, что пишите, то и получаете. Что должно препятствовать продолжению выполнения основного цикла? Что вы пытаетесь сделать в строке 220? Попробуйте посчитать, что у вас получится в этой строке если например beginTime = 100, а millis() возвращает 101.
Я пытался задать интервал времени для того чтобы система ждала появления сигнала на входе POWER_RELAY.
Переписал скетч так, чтобы к переменной beginTime сразу же прибавлялся этот интервал и объеденил обе процедуры в одну. Этот кусок кода заработал как надо. Спасибо!
А что можете посоветовать для остановки выполнения кода программы?
Если ваша система не будет работать месяцами, то такое решение прокатит, если же нет, то примерно через 40 дней ждите глюка. http://arduino.ru/forum/programmirovanie/eshche-raz-migaem-svetodiodom-b...
Спасибо! while(1) - то, что надо. Про переполнение значения я в курсе. Блок проектируется для авто. Аптайм 40 суток не реален.
Канонический таймер (например 3 сек):
А остановить скечь: for (;;){}