Официальный сайт компании Arduino по адресу arduino.cc
таймер с 2-мя условиями
- Войдите или зарегистрируйтесь, чтобы получить возможность отправлять комментарии
Сб, 26/09/2015 - 22:48
Здраствуйте,я переделываю скеч , и на столе пока всё работает.Хочу добавить 2-е условие в таймер(от 458 строки) turnPeriodMin ,чтоб при выходе outMax и outMin (502-508 строки) отсчитывал разное время.Изначально было одно условие(от 531-закоментировал).Я переписал команды,и всё заработало .Но ........только без histeresis. Если задаю histeresis ,в том интервале (+- от Setpoint) таймер застревает.И уже незнаю где копать.Поделитесь советами пожалуйста.
#include <Wire.h> #include <LiquidCrystal_I2C.h> #include <EEPROM2.h> #include <DallasTemperature.h> #include <OneWire.h> #include <Bounce.h> int del = 50; // переменная ожидания между выборами меню unsigned int interval = 100; // интервал сколько будет длиться цикл while, после чего перейдёт к следующему меню.(кол-во итераций) unsigned long currentMillis = millis (); #define heater_pin 11 // нагреватель10 #define alarm_pin 13 // пин аварии #define beeper_pin 14 //пищалка по аварии #define ledPin 9 // управление поворотом #define button_minus_pin 5 //пин кнопки "минус" #define button_plus_pin 6 //пин кнопки "плюс" #define button_enter_pin 7 //пин кнопки "enter" #define DS18B20_Pin A1 //пин термометра #define BUTTON 8 //limit switch Bounce bouncer = Bounce(BUTTON, 8); // limit switch boolean button_minus; boolean button_plus; boolean button_enter; float temp1Ink; // Температура DS18B20 unsigned long trhMillis = 0; // период опроса датчиков byte measActive = false; const unsigned long TRHSTEP = 3000UL; // Sensor query period long previousMillis = 0; LiquidCrystal_I2C lcd(0x27, 16, 2); // инициализация библиотеки дисплея OneWire oneWire(DS18B20_Pin); DallasTemperature sensors(&oneWire); //Setup PID double outMin , outMax ; double Setpoint, Input; //Output; //I/O for PID /* EEPROM1 - tempInk (float) EEPROM5 - +-alarmTemp (float) EEPROM9 - fanTemp (int) EEPROM11 - turnPeriod (int) EEPROM20 - turnPeriodMin (int) EEPROM12 - hysteresis (float) EEPROM -9 FanMax (int) EEPROM -8 FanMin (int) */ void setup() { Serial.begin(9600); lcd.init(); // Старт дисплея lcd.backlight(); // Включаем подсветку дисплея byte stat; byte error = 0; pinMode(BUTTON, INPUT_PULLUP);// limit switch pinMode(heater_pin, OUTPUT); digitalWrite(heater_pin, LOW); pinMode(alarm_pin, OUTPUT); digitalWrite(alarm_pin, LOW); pinMode(button_minus_pin, INPUT_PULLUP); //подтягиваем входы кнопок к плюсу встроенными резисторами pinMode(button_plus_pin, INPUT_PULLUP); pinMode(button_enter_pin, INPUT_PULLUP); pinMode(ledPin, OUTPUT); sensors.begin(); sensors.setResolution(12); // установить разрешение (точность) sensors.setWaitForConversion(false); // отключить ожидание } void loop() { TCCR2B = TCCR2B & 0b11111000 | 0x01; // 32 kHz PWM button_read(); if (!button_enter) { delay(del); lcd.clear(); menu(); } if (!button_minus) { delay(del); lcd.clear(); //действие по нажатии кнопки "-" } if (!button_plus) { delay(del); lcd.clear(); //действие по нажатии кнопки "+" } getSensors(); thermostat(); // turn(); alarm(); } void button_read() {//функция проверки нажатия кнопки button_minus = digitalRead(button_minus_pin); //запоминаем значение кнопки button_plus = digitalRead(button_plus_pin); //запоминаем значение кнопки button_enter = digitalRead(button_enter_pin); //запоминаем значение кнопки if (!button_minus || !button_plus || !button_enter) beeper(50); } //меню//////////////////////////////////////////////////////////// void menu() { temp_setup(); hysteresis_setup(); turn_setup(); turnMin_setup(); alarm_setup(); ventMax_setup(); ventMin_setup(); } //устанавливаем температуру в меню//////////////////////////////////// void temp_setup() { float tempInk; lcd.clear(); delay(del); button_read(); lcd.setCursor(0, 0); lcd.print("TEMPERATURE "); delay(1000); int x = 0; while (1) { x++; if (x > interval) { break; } button_read(); EEPROM_read(1, tempInk); if (!button_enter) { delay(del); lcd.clear(); //очищаем экран break; } if (!button_minus) { EEPROM_write(1, tempInk + 0.5); if (tempInk > 40) { //проверяем, если выше 40, EEPROM_write(1, 40); //пишем в память 40 } lcd.clear(); } if (!button_plus) { EEPROM_write(1, tempInk - 0.5); if (tempInk < 20.0) { //проверяем, если выше 30, EEPROM_write(1, 20.0); //пишем в память 30 } lcd.clear(); } lcd.setCursor(0, 0); lcd.print("TEMP.K = "); lcd.print(tempInk, 1); lcd.print((char)223); lcd.print("C"); lcd.setCursor(0, 1); lcd.print("minus NEXT plus"); delay(del); } } //устанавливаем Hysteresis//////////////////////////////////////////////////////////////// void hysteresis_setup() { float hysteresisTemp; lcd.clear(); delay(del); button_read(); lcd.setCursor(0, 0); lcd.print("HYSTERESIS SET"); delay(1000); int x = 0; while (1) { x++; if (x > interval) { break; } button_read(); EEPROM_read(12, hysteresisTemp ); if (!button_enter) { delay(del); lcd.clear(); //очищаем экран break; } if (!button_minus) { EEPROM_write(12, hysteresisTemp + 0.5); if (hysteresisTemp > 10.0) { //проверяем, если выше 40, EEPROM_write(12, 10.0); //пишем в память 40 } lcd.clear(); } if (!button_plus) { EEPROM_write(12, hysteresisTemp - 0.5); if (hysteresisTemp < 0.0) { //проверяем, если выше 40, EEPROM_write(12, 0.0); //пишем в память 40 } lcd.clear(); } lcd.setCursor(0, 0); lcd.print("Hysteresis="); lcd.print(hysteresisTemp, 1); //lcd.print((char)223); //lcd.print("C"); lcd.setCursor(0, 1); lcd.print("minus NEXT plus"); delay(del); } } //устанавливаем поворот/////////////////////////////////////////////////// void turn_setup() { int turnPeriod; lcd.clear(); delay(del); button_read(); lcd.setCursor(0, 0); lcd.print("TURN SETUP MAX"); delay(1000); int x = 0; while (1) { x++; if (x > interval) { break; } button_read(); EEPROM_read(11, turnPeriod); if (!button_enter) { delay(del); lcd.clear(); //очищаем экран break; } if (!button_minus) { EEPROM_write(11, turnPeriod + 1); if (turnPeriod > 200) { //проверяем, если выше 40, EEPROM_write(11, 200); //пишем в память 40 } lcd.clear(); } if (!button_plus) { EEPROM_write(11, turnPeriod - 1); if (turnPeriod < 0) { //проверяем, если выше 40, EEPROM_write(11, 0); //пишем в память 40 } lcd.clear(); } EEPROM_read(11, turnPeriod); lcd.setCursor(0, 0); lcd.print("PAUSE MAX = "); lcd.print(turnPeriod); lcd.print(" s"); lcd.setCursor(0, 1); lcd.print("minus NEXT plus"); delay(del); } } //устанавливаем поворот_MIN void turnMin_setup() { int turnPeriodMin; lcd.clear(); delay(del); button_read(); lcd.setCursor(0, 0); lcd.print("TURN SETUP MIN"); delay(1000); int x = 0; while (1) { x++; if (x > interval) { break; } button_read(); EEPROM_read(20, turnPeriodMin); if (!button_enter) { delay(del); lcd.clear(); //очищаем экран break; } if (!button_minus) { EEPROM_write(20, turnPeriodMin + 1); if (turnPeriodMin > 100) { //проверяем, если выше 40, EEPROM_write(20, 100); //пишем в память 40 } lcd.clear(); } if (!button_plus) { EEPROM_write(20, turnPeriodMin - 1); if (turnPeriodMin < 0) { //проверяем, если выше 40, EEPROM_write(20, 0); //пишем в память 40 } lcd.clear(); } EEPROM_read(20, turnPeriodMin); lcd.setCursor(0, 0); lcd.print("PAUSE MIN= "); lcd.print(turnPeriodMin); lcd.print(" s"); lcd.setCursor(0, 1); lcd.print("minus NEXT plus"); delay(del); } } //устанавливаем сигнализацию///////////////////////////////////////////////////////////// void alarm_setup() { int alarmTemp; lcd.clear(); delay(del); button_read(); lcd.setCursor(0, 0); lcd.print("ALARM SETUP"); delay(1000); int x = 0; while (1) { x++; if (x > interval) { break; } button_read(); EEPROM_read(5, alarmTemp); if (!button_enter) { delay(del); lcd.clear(); //очищаем экран break; } if (!button_minus) { EEPROM_write(5, alarmTemp + 1); if (alarmTemp > 40) { //проверяем, если выше 40, EEPROM_write(5, 40); //пишем в память 40 } lcd.clear(); } if (!button_plus) { EEPROM_write(5, alarmTemp - 1); if (alarmTemp < 1) { //проверяем, если выше 40, EEPROM_write(5, 1); //пишем в память 40 } lcd.clear(); } lcd.setCursor(0, 0); lcd.print("T.Alarm + - "); lcd.print(alarmTemp); lcd.print((char)223); lcd.print("C"); lcd.setCursor(0, 1); lcd.print("minus NEXT plus"); delay(del); } } //устанавливаем вентиляцию///////////////////////////////////////////////////////////////// void ventMax_setup() { int fanMax; lcd.clear(); delay(del); button_read(); lcd.setCursor(0, 0); lcd.print("FAN MAX SETUP"); delay(1000); int x = 0; while (1) { x++; if (x > interval) { break; } button_read(); EEPROM_read(9, fanMax); if (!button_enter) { delay(del); lcd.clear(); //очищаем экран break; } if (!button_minus) { x = 0; EEPROM_write(9, fanMax + 1); if (fanMax > 255) { //проверяем, если выше 40, EEPROM_write(9, 255); //пишем в память 40 } lcd.clear(); } if (!button_plus) { x = 0; EEPROM_write(9, fanMax - 1); if (fanMax < 150) { //проверяем, если выше 40, EEPROM_write(9, 150); //пишем в память 40 } lcd.clear(); } lcd.setCursor(0, 0); lcd.print("FAN MAX = "); lcd.print(fanMax); //lcd.print((char)223); lcd.print(""); lcd.setCursor(0, 1); lcd.print("minus NEXT plus"); delay(del); } } void ventMin_setup() { int fanMin; lcd.clear(); delay(del); button_read(); lcd.setCursor(0, 0); lcd.print("FAN MIN SETUP"); delay(1000); int x = 0; while (1) { x++; if (x > interval) { break; } button_read(); EEPROM_read(16, fanMin); if (!button_enter) { delay(del); lcd.clear(); //очищаем экран break; } if (!button_minus) { x = 0; EEPROM_write(16, fanMin + 1); if (fanMin > 50) { //проверяем, если выше 40, EEPROM_write(16, 50); //пишем в память 40 } lcd.clear(); } if (!button_plus) { x = 0; EEPROM_write(16, fanMin - 1); if (fanMin < 5) { //проверяем, если выше 40, EEPROM_write(16, 5); //пишем в память 40 } lcd.clear(); } lcd.setCursor(0, 0); lcd.print("FAN MIN = "); lcd.print(fanMin); //lcd.print((char)223); //lcd.print(""); lcd.setCursor(0, 1); lcd.print("minus NEXT plus"); delay(del); } } void getSensors() ////////////////////////////////////////////////////////////////////// { unsigned long curMillis = millis(); // Получаем текущее время работы sensors.requestTemperatures(); // Demonstrate non-blocking calls if (currentMillis - trhMillis >= TRHSTEP) { // время для нового измерения? measActive = true; trhMillis = curMillis; } temp1Ink = sensors.getTempCByIndex(0); } //используем терморегулятор////////////////////////////////////////// void thermostat() { unsigned long currentMillis = millis (); int fanMax; int fanMin; float tempPoint; float hysteresisTemp ; int turnPeriod; //период поворота лотков в часах int turnPeriodMin; int turnCommand; int ledState = LOW; EEPROM_read_mem(1, &tempPoint, sizeof(tempPoint)); EEPROM_read(1, tempPoint); EEPROM_read(12, hysteresisTemp); EEPROM_read(9, fanMax); EEPROM_read(16, fanMin); EEPROM_read(11, turnPeriod); EEPROM_read(20, turnPeriodMin); outMax = fanMax; outMin = fanMin; Setpoint = tempPoint; Input = temp1Ink; lcd.setCursor(0, 0); // устанавливаем курсор в 0-ом столбце, 0 строка (начинается с 0) lcd.print("T1="); lcd.print(temp1Ink, 1); // печать температуры на дисплей lcd.print((char)223); lcd.print(" ("); lcd.print(Setpoint, 1); lcd.print(")"); lcd.setCursor(9, 1); lcd.print("s"); lcd.print(turnPeriod); lcd.setCursor(13, 1); lcd.print("s"); lcd.print(turnPeriodMin); // if (temp1Ink < (Setpoint - hysteresisTemp)) analogWrite(heater_pin, outMax); // if (temp1Ink > (Setpoint + hysteresisTemp))analogWrite(heater_pin, outMin); if (temp1Ink < (Setpoint - hysteresisTemp)) { analogWrite(heater_pin, outMax); turnCommand = turnPeriod; } else if (temp1Ink > (Setpoint + hysteresisTemp)) { analogWrite(heater_pin, outMin);turnCommand = turnPeriodMin; } if (ledState == LOW) { if (currentMillis - previousMillis > turnCommand * 1000 && ledState == LOW) { ledState = HIGH;//включаем светодиод digitalWrite(ledPin, ledState); } } if ( bouncer.update() ) { if (currentMillis - previousMillis > ( bouncer.read() == LOW ) && ledState == HIGH) { if ( bouncer.read() == LOW ) { previousMillis = currentMillis; // сохраняем время последнего выключения ledState = LOW;//выключаем светодиод digitalWrite(ledPin, ledState); } } } } /* //управляем поворотом//////////////////////////////////////////////////////////////// void turn() { unsigned long currentMillis = millis (); int turnPeriod; //период поворота лотков в часах int turnPeriodMin; int turnCommand; int ledState = LOW; // этой переменной устанавливаем состояние светодиода EEPROM_read(11, turnPeriod); lcd.setCursor(9, 1); lcd.print("s"); lcd.print(turnPeriod); EEPROM_read(20, turnPeriodMin); lcd.setCursor(13, 1); lcd.print("s"); lcd.print(turnPeriodMin); if (turnPeriod == 0) return; //если нулевой период поворота, то не поворачиваем . if (turnPeriod < 13) turnCommand = turnPeriod; if (ledState == LOW) { if (currentMillis - previousMillis > turnCommand * 1000 && ledState == LOW) { ledState = HIGH;//включаем светодиод digitalWrite(ledPin, ledState); } } if ( bouncer.update() ) { if (currentMillis - previousMillis > ( bouncer.read() == LOW ) && ledState == HIGH) { if ( bouncer.read() == LOW ) { previousMillis = currentMillis; // сохраняем время последнего выключения ledState = LOW;//выключаем светодиод digitalWrite(ledPin, ledState); } } } } */ //управляем авариями/////////////////////////////////////////////////////////////////////// void alarm() { float tempInk = sensors.getTempCByIndex(0); int alarmTemp; float setTemp; EEPROM_read(5, alarmTemp); EEPROM_read_mem(1, &setTemp, sizeof(setTemp)); EEPROM_read(1, setTemp); lcd.setCursor(0, 3); lcd.print("A"); lcd.print(setTemp + alarmTemp, 1); if (millis() > 5000) { if (tempInk > (setTemp + alarmTemp) || tempInk < (setTemp - alarmTemp)) { //beeper(10); digitalWrite(alarm_pin, HIGH); //если измеренная температура выше заданной на величину аварии } else digitalWrite(alarm_pin, LOW); //то включаем аварийный сигнал. } } void beeper(int duration) { tone(beeper_pin, 2000, duration); }
Господа гуру, моя первая попытка была весьма неудачная. Написал укороченный скеч.Но рабоает криво: когда температуа нарастает-порядок.А вот при падении таймер переключаетса обратно от верхчей температуры.С ШИМом всё ок.Чего то не хватает,но...?
и как мне до вас достучатся?
А Вы правда расчитывали что кто-то будет вникать и разбираться с Вашими 600(!) строками кода? Это Вам в "ищу исполнителя".
Подсказка - используйте вывод условий/переменных для тестирования, тогда увидите что и где.
спасибо ,JollyBiber,я в serial вывожу val значение и она недаёт повода для размышления.я урезал неважное в #1 посту ,и пока не нахожу инфо ,што надо дописать вот здесь:
штоб таймер переключался вместе с ШИМом
Вот если честно - 3 раза перечитал Ваши сообщения и так и не понял что Вы хотите :)
Подробно:
когда температура <30 - outMax(pwm),turnMin(таймер)
когда температура >30 - outMin,turnMax
когда температура падает до 28 - outMin,turnMin?(переключаетса из turnMax==30)
когда температура ниже 28 - outMax,turnMin.
почему таймер НЕСИНХРОННО работает с analogWrite
(pvm),вот чего я не пойму
Я не знаю. Данные есть только у Вас, что в них знаете только Вы и делиться этим не хотите.
JollyBiber,данные есть в #1 ,но проблема решилась разделив условие.
я дописал лед, как контрольную лампу,и от неё задал таймер
Спасибо всем!
Я продвигаюсь далше.Подключил дачик дыма(temp_c).Он работает как задумал.Хочю сделать ,что пока температура( Temperature) недостигла заданной(TstatTemp),arduino игнорировало заданную температуру дыма(smoke).Может кто помилует.
... это из скеча,што и как
и в чем проблема?
Просто не знаю как написать-"что пока температура( Temperature) недостигла заданной(TstatTemp),arduino игнорировало заданную температуру дыма(smoke).''тоесть,пока ненагрелось,дыма не проверять
тоесть,пока ненагрелось,дыма не проверять
ну у Вас так и написано
если (температура больше заданной)
да,это одна строка для понятия терминов.Мне надо добавить в скеч условие ,чтоб не проверял дыма до нагревания.
То Maverik,если оставить контроль дыма с начало топки,то дом и ненагреть,потому что ардуино будет уводить к снижению температуры.
это и есть условие.
Опять же,спасибо,JollyBiber,я кажется не о том думал!Просто почти повторил главное условие ,и дачик дыма заработал как задумалось.Я прикрепил весь цикл провеки температур,и хочу спросить-правильно эт всё написанно?(он рабочий).