Прошу помощи с Blink через PID
- Войдите на сайт для отправки комментариев
Заранее еще раз напомню, что начинающий "ардуинщик". Поэтому прошу строго не судить. Что-то почитать никогда не против по данной теме.
Итак, ситуация такая. Злободневный PID-регулятор температуры ТЭНов (на данном этапе лампочка)
DHТ11, SSR, Лампа накаливания.
В зависимоти от показания температуры расчитываются показания PID регулятора, в зависимости от показания PID, происходи вкл/выкл SSR по типу Blink.
Первая задача - регулировать промежуток между Blink и время самого горения светодиода.
Нарисовал скетч
int ledPin = 3; int ledState = LOW; unsigned long previousMillis = 0; long OnTime = 50; long OffTime = 1000; void setup() { pinMode(ledPin, OUTPUT); } void loop() { unsigned long currentMillis = millis(); if((ledState == HIGH) && (currentMillis - previousMillis >= OnTime)) { ledState = LOW; previousMillis = currentMillis; digitalWrite(ledPin, ledState); } else if ((ledState == LOW) && (currentMillis - previousMillis >= OffTime)) { ledState = HIGH; previousMillis = currentMillis; digitalWrite(ledPin, ledState); } }
здесь путем изменения
long OnTime = 50; и long OffTime = 1000;
получается все это регулировать.
Сама суть проблемы -
Когда вставляю этот скетч в скетч самого регулятора, параметры Blink работают по другому. Сам PID работает корректо, по крайней мере для моих задач. Но не регулируется, точнее неккоректно регуляируется длительность мерцания, а промежуток между Блинками не получается опустить менее чем 500 мс.
Первая мысль, которая приходит в голову, это то, что на это происходит в силу времени расчета PID.
В общем все, что мог просмотрел и прочитал, как местное так и буржуйское, но с проблеммой не спарвился. Возможно я вообще не правильно использую millis. Хочется не только доработать аппарат, но понять суть всей работы.
Сам код PID - регулятора.
#include <PID_v1.h> #include <Wire.h> #include <DHT.h> #define DHTPIN 5 #define DHTTYPE DHT11 DHT dht(DHTPIN, DHTTYPE); double Setpoint, Input, Output; PID myPID(&Input, &Output, &Setpoint ,8, 0, 1, DIRECT); int ledPin = 3; int ledState = LOW; unsigned long previousMillis = 0; void setup() { Serial.begin(9600); pinMode(ledPin, OUTPUT); Setpoint = 40; myPID.SetMode(AUTOMATIC); myPID.SetOutputLimits(0, 255); } void loop() { int t = dht.readTemperature(); // Send the command to get temperatures Input = t; myPID.Compute(); int val = Output; val = map(val, 0, 255, 0, 100); if ( val > 30) {PIDon();} if ( val <= 30 && val >= 21) {PIDx();} if ( val <= 20 && val >= 10 ) {PIDx1();} if ( val <= 9) {PIDx2();} if ( val < 3) {PIDoff();} Serial.print("OUTPUT "); Serial.print(val); Serial.print(" %"); Serial.print("Temperature: "); Serial.print(t); Serial.println(" *C"); } void PIDx() { long OnTime = 1; long OffTime = 50; unsigned long currentMillis = millis(); if((ledState == HIGH) && (currentMillis - previousMillis >= OnTime)) { ledState = LOW; // Turn it off previousMillis = currentMillis; // Remember the time digitalWrite(ledPin, ledState); // Update the actual LED } else if ((ledState == LOW) && (currentMillis - previousMillis >= OffTime)) { ledState = HIGH; // turn it on previousMillis = currentMillis; // Remember the time digitalWrite(ledPin, ledState); // Update the actual LED } } void PIDx1() { long OnTime = 50; long OffTime = 250; unsigned long currentMillis = millis(); if((ledState == HIGH) && (currentMillis - previousMillis >= OnTime)) { ledState = LOW; // Turn it off previousMillis = currentMillis; // Remember the time digitalWrite(ledPin, ledState); // Update the actual LED } else if ((ledState == LOW) && (currentMillis - previousMillis >= OffTime)) { ledState = HIGH; // turn it on previousMillis = currentMillis; // Remember the time digitalWrite(ledPin, ledState); // Update the actual LED } } void PIDx2() { long OnTime = 50; long OffTime = 500; unsigned long currentMillis = millis(); if((ledState == HIGH) && (currentMillis - previousMillis >= OnTime)) { ledState = LOW; // Turn it off previousMillis = currentMillis; // Remember the time digitalWrite(ledPin, ledState); // Update the actual LED } else if ((ledState == LOW) && (currentMillis - previousMillis >= OffTime)) { ledState = HIGH; // turn it on previousMillis = currentMillis; // Remember the time digitalWrite(ledPin, ledState); // Update the actual LED } } void PIDon() { digitalWrite(ledPin, HIGH); } void PIDoff() { digitalWrite(ledPin, LOW); }
За ранее благодарен и прошу прощения за почерк.
класс титановый велосипед для delay без delay().
класс титановый велосипед для delay без delay().
Извините, я не нашел где в этом классе можно задать время горения LED? Мне необходимо, чтобы светодиод "сверкал", т.е. говоря аппаратным языком - горел 50 млс, а негорел 1000 млс.
класс титановый велосипед для delay без delay().
И кстати, попробовал поставить этот класс в свой скетч, таже история, ставлю 100, а все равно быстрее 500 не моргает.
И кстати, попробовал поставить этот класс в свой скетч, таже история, ставлю 100, а все равно быстрее 500 не моргает.
поробуй этот "класс" воткнуть в свой скетч
тоже быстрее 500 не моргает? :D
Извините, я не нашел где в этом классе можно задать время горения LED? Мне необходимо, чтобы светодиод "сверкал", т.е. говоря аппаратным языком - горел 50 млс, а негорел 1000 млс.
казалось бы, вкуда здесь nD_01.read(100); #28 воткнуть 100, что бы тикало каждые 100 миллисекунд?
что нужно сделать, что бы тикало то 50, то 1000 - угадай с первого раза?
всё.
Извините, я не нашел где в этом классе можно задать время горения LED? Мне необходимо, чтобы светодиод "сверкал", т.е. говоря аппаратным языком - горел 50 млс, а негорел 1000 млс.
казалось бы, вкуда здесь nD_01.read(100); #28 воткнуть 100, что бы тикало каждые 100 миллисекунд?
что нужно сделать, что бы тикало то 50, то 1000 - угадай с первого раза?
Ругается
всё.
Спасибо большое.
Я так понимаю это таймер, еще не изучал работу по таймеру.
Но всё заработало как положено, только возникает большая проблемма - виснет монитор порта через несколько секунд((((
Ругается
#7 #5
странно. переделал вот так
не зависает сериал. не хочет, наерн. :)
странно. переделал вот так
не зависает сериал. не хочет, наерн. :)
Отдельным скетчем не зависает, когда в скетч пида вставляю зависает.
#7 #5
Таже самая история, отдельным скетчем работает все как положено, в скетче пида минимум 500, даже когда задано 100.(((
Таже самая история, отдельным скетчем работает все как положено, в скетче пида минимум 500, даже когда задано 100.(((
я же тебя просил проверить digitalWrite(13, !digitalRead(13));
мошт, надо нам пидаскетч показать?
мошт, надо нам пидаскетч показать?
в самом начале нарисован
мошт, надо нам пидаскетч показать?
Если уже с таймером, то
Вариант 1
Вариан 2
Во втором варианте строчка
вообще не срабатывает.
А всё, въехал. Прочитал 1 пост внимательно. Мой TTimerList Вам не подойдет.
Хотя, могу его чуть переделать.
скачайте новый uTimerList и пропробовайте так.
скачайте новый uTimerList и пропробовайте так.
Там же на GitHube? Скачал. В общем ситуация такая, все работает, не виснет но когда val опускается ниже 21, ledPin выключается совсем, т.е. уже на PIDx1() срабатывает LOW, в скетче причины не нашел. Ну а так начало отличное.
ОК, приеду с дачи, буду разбираца
ОК, приеду с дачи, буду разбираца
Хорошо, будем подождать))
А меня пока работой завалили. :(
А меня пока работой завалили. :(
Ясненько :( , ну ладно, как будет времячко по свободнее, тогда поглядите что там, да как...Если все заработает я закину вам немножко спасибо ))
попробуй в loop вотак написать, чо будет?
попробуй в loop вотак написать, чо будет?
Тоже самое, там кстати надо < а не >, val обратно температуре.
Дошло до уставки с такими условиями
Но частота блинка не менялась.
А если поменять значения в PIDx1 например на 500 , то вообще не моргает (LOW)
А кинь мне весь скетч на почту, я ночером поразбира
А кинь мне весь скетч на почту, я ночером поразбира
кинуто)
а я понял в чем дело. loop выполняется быстро и таймеры каждый раз при выполнении условия перезапускаюца. Во первых исправь if-ы вот так
скопируй как есть, не исправляй ничего.
опрос датчиков, надо изменить, если с последнего измерения ничего не изменилось, не надо дальше и идти.
примерно так
у меня моргает как заводная. :)
Смекаешь?
правильней бы было вообще опрос датчика из loop убрать а в нем проверять только изменения.
Домашка: сделай опрос датчика тоже по таймеру, раз допустим в 3 - 5 секунд.
только переменную, где хранишь val обьяви как volatile int
правильней бы было вообще опрос датчика из loop убрать а в нем проверять только изменения.
Домашка: сделай опрос датчика тоже по таймеру, раз допустим в 3 - 5 секунд.
только переменную, где хранишь val обьяви как volatile int
Хорошо, будем попробывать). Мне кстати в ближайшие пару дней далласы придут, я поменяю DHT на даллас)
правильней бы было вообще опрос датчика из loop убрать а в нем проверять только изменения.
Домашка: сделай опрос датчика тоже по таймеру, раз допустим в 3 - 5 секунд.
только переменную, где хранишь val обьяви как volatile int
Что-то не получается, даже DHT не заводится, пицот вариантов испробывал и две библиотеки, не то что время опроса датчика не изменяется, сам датчик с таймером запустить не могу.
На сегодня силы исчерпаны. Может завтра еще попробую.
А PID заработал, спасибо огромное, как обещал с з.п. закину немного спасибо)
не пытайся в функции таймера читать DHT, она работает в контексте прерывания, DHT врет безбожно, потому что micros() не работает.
Как я сделал: В функции таймера которая вызывается раз в 5 секунд взвожу флаг, что надо прочитать DHT, a в loop, если этот флаг взведен, вызываю уже функцию чтения DHT, которая флаг этот сбрасывает, то есть следующее чтение будет опять через 5 сек.