Откуда: Балашиха
Благодарил (а): 129 раз. Поблагодарили: 33 раз.
Авто: 310221 406 05, Патриот 2012
|
Хоть и опять не в планируемом объёме, но этот день (точнее дни блеать) настал. Долгими зимними вечерами писал программу. Собрал на столе макет. СНял с машины, притащил блок. Выпаял крутилку задающую температуру, снял с неё значения АЦП: Вложение:
IMG_20190501_153819.jpg [ 188.67 КБ | Просмотров: 10364 ]
Долгими весенними вечерами переписывал программу. Внезапно выяснилось, что как я ни старался максимально раздробить функции, как раз для этого - нихера не получилось. Слишком много было завязано на этой грёбанной кнопке стеклоподъёмника. Это мой стратегический просчёт, который стоил мне нескольких томных вечеров и добавил эстетической кривизны в код в виде конструкций которые ничего не делают, но убирать я их боюсь, потому что уже не помню для чего точно они нужны)) В итоге, каменный цветок вышел и на макетной плате заработал. Далее нашёл китайский стабилизатор напряжения, настроил его на 10В, припаял его на китайскую PCB 5х7, туда же Андурину, драйвер двигателя и чуток резисторов. Разработал 3Д модель коробочки и напечатал её. ПРосверлил в коробке дырки, вывел провода, обжал разъёмы. Вложение:
IMG_20190427_184204.jpg [ 1.19 МБ | Просмотров: 10364 ]
Вложение:
IMG_20190427_184217.jpg [ 833.78 КБ | Просмотров: 10364 ]
Вложение:
IMG_20190501_152133.jpg [ 623.25 КБ | Просмотров: 10364 ]
Ещё раз всё соединил, проверил - работает. Светодиоды в блок решил впаять другие . Фото делал, но почему части фоток в итоге нет)) Диоды у китайца назывались 5630/5730 3.2-3.4В. Приклеил их не на плату, а на сам корпус, точнее на стенку ближе к основанию. Оказались шибко маленькие. Пока 6шт спаял, да приклеил, столько же сломал)) Сначала спаял все в гирлянду, но гореть при 12В они отказались. Пришлось разбить на 2 группы и ставить резистор. Отдельный стабилизатор городить под них не стал. Датчик температуры я для удовлетворения своей лени решил поставить на старое место. Выпаял старый, впаял на его место новый. Массу к массе, на остальных контактах выпаял резисторы и подпаял на их места свои провода. Установка вентилятора в блок вроде уже освещалась, останавливаться на этом этапе не стану. СОбрал блок, ещё раз всё соединил, проверил - не работает. Упор заслонки, электроникой не фиксируется. Выяснилось, что неправильно был подключен делитель на вход Андурины, потому что на схеме у меня было не правильно нарисовано. Как оно у меня раньше работало - непонятно. Перепаял, проверил, работает. ПОтащил все эти сопли в машину... Пусконаладочные работы: Вложение:
IMG_20190501_175643.jpg [ 839.87 КБ | Просмотров: 10364 ]
В результате 2х часов торчания в машине и не продолжительной поездки в магазин выяснилось: Внетилятор продувки датчика у меня изначально отключался при крайних положениях заслонки. Это привело к проблемам регулирования. В итоге сделал его работу постоянной. ВОт щас пытался вспомнить к каким именно проблемам это привело и не смог Помню лишь, что температура на датчике быстро росла стоило отключить продув. Но почему это стало проблемой??? Вентилятор лопастями цеплялся за мой "воздуховод" который я сделал из найденного на стройке материала, который стремится вернуть свою форму, и как его не прогибай, через время он опять цепляет лопасти и останавливает вентилятор. В итоге подключил его к бортовой сети. На 10В он не мог побороть препятствия, а на 14В воет, но работает. Вопрос с этим открыт, надо переделывать. Подсветка блока слабовата. Резистор при случае надо заменить на меньший номинал, раза в 2. Нынешнее время реакции в 10 секунд маловато. Надо поставить наверное секунд 30. С одной стороны при коротком интервале реакция быстрее, но с другой - заслонка постоянно мечется из одного крайнего положения в другое. В целом ощущения положительные. Автомат работает и не смотря на выявленные недостатки - это намного лучше чем кнопка стеклоподъёмника. Следующим этапом я навреное добавлю управление краном отопителя. А ещё следующим приколхожу экран и датчик наружной температуры. К своему первоначальному плану с несколькими датчиками и контролем температуры двигателя и т.п. врятли в ближайшее время вернусь. Прошивка Андурины: Код: #include <EEPROM.h> #include <DallasTemperature.h> #define ONE_WIRE_BUS 11 // Данные датчика теипературы на пине 11 OneWire oneWire(ONE_WIRE_BUS); DallasTemperature ds(&oneWire); DeviceAddress insideThermometer;
float tempC; // переменная для температуры int IN1 = 2; // Вывод на драйвер, нога 2 int IN2 = 4; // Вывод на драйвер, нога 7 int HotLED = 7; // Вывод для индикатора "тепло" int ColdLED = 8; // Вывод для индикатора "холод" int ButtonHot = 10; // Вывод для кнопки "тепло" int ButtonCold = 11; // Вывод для кнопки "холод" int Vent = 10; // Вывод для вентилятора продувки датчика температуры int Current = 0; // Вывод для чтения тока мотора int i1; // переменная для чтения тока int i2; // переменная для чтения тока int i3; // переменная для чтения тока int ButtonHotState = 0; // переменная для чтения состояния кнопки int ButtonColdState = 0; // переменная для чтения состояния кнопки int over = 998; // значение при котором и менее появляется факт упора мотора, было 998 unsigned long ActMotor; // Время старта мотора unsigned long BtnPress; // Время нажатия кнопки boolean OverloadHot = false; // Флаг перегрузки по току - упор заслонки в горячем положении boolean OverloadCold = false; // Флаг перегрузги в холодном положении boolean Overload = false; boolean f1 = false; char Dir; // Направление мотора заслонки unsigned long Tp; // Время периода. Отметка unsigned long Tut = 0; // Время воздействия. Отметка int i; // Вывод в порт количество перидов
//------------------------- Измерение пложения ручки температуры ---------------------------------- int Temp = 1; // Вывод для уставки температуры int TempS; // Переменная для хранения выбранной уставки температуры int TCold[7] = {208,209,210,211,212,213,214}; // АЦП для максимально холодного положения ручки int T16[7] = {230,231,232,233,234,235,236}; // АЦП для уставки 16 градусов int T18[7] = {256,257,258,259,260,261,262}; // АЦП для уставки 18 градусов int T20[7] = {288,289,290,291,292,293,294}; // АЦП для уставки 20 градусов int T22[7] = {329,330,331,332,333,334,335}; // АЦП для уставки 22 градуса int T24[7] = {383,384,385,386,387,388,389}; // АЦП для уставки 24 градуса int T26[7] = {455,456,457,458,459,460,461}; // АЦП для уставки 26 градусов int T28[7] = {560,561,562,563,564,565,566}; // АЦП для уставки 28 градусов int THot[7] = {726,727,728,729,730,731,732}; // АЦП для макимального горячего положения ручки
//------------------------------------ П И Д ----------------------------------- float Kp = 0.3; // Коэффициент пропорциональной составляющей float Ki = 0.2; // Коэффициент интегральной составляющей float Kd = 0.5; // Коэффициент дифферинциальной составляющей float Pt; // Пропорциональная составляющая текущего момента float It; // Интегральная составляющая текущего момента float It1; // Интегральная составляющая предыдущего момента float Dt; // Дифферинциальная составляющая float et; // Ошибка текущего момента float et1; // Ошибка предыдущего момента float ut; // Время воздействия (включения мотора заслонки) //------------------------------------------------------------------------------
void setup() { analogReference(DEFAULT); pinMode (IN1, OUTPUT); pinMode (IN2, OUTPUT); pinMode (HotLED, OUTPUT); pinMode (ColdLED, OUTPUT); pinMode (ButtonHot, INPUT); pinMode (ButtonCold, INPUT); pinMode (Vent, OUTPUT);
digitalWrite (Vent, HIGH);
Serial.begin(9600);
// EEPROM.write(1, 0); // EEPROM.write(2, 0);
if (EEPROM.read(1) != 255) { OverloadHot = EEPROM.read(1); } if (EEPROM.read(2) != 255) { OverloadCold = EEPROM.read(2); } if (OverloadCold == true || OverloadHot == true ) { /*digitalWrite (Vent, LOW);*/ Overload = true; } else { digitalWrite (Vent, HIGH); Overload = false; } temp(); TempSet(); Serial.print("Ustavka: "); Serial.print(TempS); Serial.print("; Temperatura: "); Serial.println(tempC);
Serial.print("Hot: "); Serial.print(OverloadHot); Serial.print("; EEPROM: "); Serial.println(EEPROM.read(1));
Serial.print("Cold: "); Serial.print(OverloadCold); Serial.print("; EEPROM: "); Serial.println(EEPROM.read(2));
if (OverloadHot == true) { digitalWrite (HotLED, HIGH); } if (OverloadCold == true) { digitalWrite (ColdLED, HIGH); }
}
void MotorHot() { digitalWrite (IN1, HIGH); digitalWrite (IN2, LOW); digitalWrite (HotLED, HIGH); digitalWrite (ColdLED, LOW); // ActMotor = millis(); ControlM("Hot"); Dir = "Hot"; if (Overload == false) { digitalWrite (IN1, LOW); digitalWrite (HotLED, LOW); } }
void MotorCold() { digitalWrite (IN2, HIGH); digitalWrite (IN1, LOW); digitalWrite (ColdLED, HIGH); digitalWrite (HotLED, LOW); // ActMotor = millis(); ControlM("Cold"); Dir = "Cold"; if (Overload == false) { digitalWrite (IN2, LOW); digitalWrite (ColdLED, LOW); } }
void Blinc(char* Dir) { int i; for (i = 1; i < 6; i++) { digitalWrite (ColdLED, HIGH); digitalWrite (HotLED, LOW); delay(100); digitalWrite (HotLED, HIGH); digitalWrite (ColdLED, LOW); delay(100); digitalWrite (HotLED, LOW); digitalWrite (ColdLED, LOW); } Serial.println(Dir); if (Dir == "Hot") { digitalWrite (HotLED, HIGH); } if (Dir == "Cold") { digitalWrite (ColdLED, HIGH); } }
/* void ControlMotor(char* Dir) // Контроль тока при управлении кнопками. Осталось ради обратной совместимости. По хорошему надо переписать. { int i; while (millis() - ActMotor < 500) // Не контролируем ток первые 0.5с во избежание ложного срабатывания от пускового тока. { OverloadHot = false; OverloadCold = false; } Overload = false; Serial.println(Dir); while (ButtonHotState == HIGH || ButtonColdState == HIGH || f1 == true) { i1 = analogRead(Current); i2 = analogRead(Current); i3 = analogRead(Current); Serial.print(i1); Serial.print(", "); Serial.print(i2); Serial.print(", "); Serial.println(i3); if (i1 < over && i2 < over && i3 < over) { digitalWrite (IN1, LOW); digitalWrite (IN2, LOW); if (Dir == "Hot") { delay(100); digitalWrite (IN2, HIGH); digitalWrite (IN1, LOW); delay(50); digitalWrite (IN1, LOW); digitalWrite (IN2, LOW); } if (Dir == "Cold") { delay(100); digitalWrite (IN1, HIGH); digitalWrite (IN2, LOW); delay(50); digitalWrite (IN1, LOW); digitalWrite (IN2, LOW); } Overload = true; Blinc(Dir); if (Dir == "Hot") { // digitalWrite (HotLED, HIGH); // Overload = true; OverloadHot = true; EEPROM.write(1, 1); Serial.println("Hot overload"); } if (Dir == "Cold") { // digitalWrite (ColdLED, HIGH);
OverloadCold = true; EEPROM.write(2, 1); Serial.println("Cold overload"); } f1 = false; break; } ButtonHotState = digitalRead(ButtonHot); ButtonColdState = digitalRead(ButtonCold); } } */
void ControlM(char* Dir) //--------------------------------Контроль тока. Дорабатывается ----------------------------- { int i; delay(500); // Залипаем, чтобы не контроллить пусковой ток мотора // Overload = false; Serial.println(Dir);
while (millis() - Tut < abs(ut)) { // Контроль времени воздействия i1 = analogRead(Current); i2 = analogRead(Current); i3 = analogRead(Current); Serial.print(i1); Serial.print(", "); Serial.print(i2); Serial.print(", "); Serial.println(i3); if (i1 < over && i2 < over && i3 < over) { digitalWrite (IN1, LOW); digitalWrite (IN2, LOW); if (Dir == "Hot") { delay(100); digitalWrite (IN2, HIGH); digitalWrite (IN1, LOW); delay(50); digitalWrite (IN1, LOW); digitalWrite (IN2, LOW); } if (Dir == "Cold") { delay(100); digitalWrite (IN1, HIGH); digitalWrite (IN2, LOW); delay(50); digitalWrite (IN1, LOW); digitalWrite (IN2, LOW); } Overload = true; digitalWrite (Vent, LOW); Blinc(Dir); if (Dir == "Hot") { OverloadHot = true; EEPROM.write(1, 1); Serial.println("Hot overload"); } if (Dir == "Cold") { OverloadCold = true; EEPROM.write(2, 1); Serial.println("Cold overload"); } return; // Выход из функции, если заслонка упёрлась } } digitalWrite (IN1, LOW); digitalWrite (IN2, LOW); // digitalWrite (ColdLED, LOW); // digitalWrite (HotLED, LOW); digitalWrite (Vent, HIGH); Overload = false; } //--------------------------------------------------------------------------------------------------------
void temp() // Определение температуры в салоне { // int t; ds.requestTemperatures(); delay(1000); tempC = ds.getTempCByIndex(0); // t = round(tempC * 1); // Serial.print("t="); // Serial.println(tempC); }
void TempSet() // Определение положения ручки температуры { int t; t = analogRead(Temp);
if (t < 230) { TempS = 1; } if (t > 230 && t < 250) { TempS = 16; } if (t > 250 && t < 280) { TempS = 18; } if (t > 280 && t < 300) { TempS = 20; } if (t > 300 && t < 350) { TempS = 22; } if (t > 350 && t < 400) { TempS = 24; } if (t > 400 && t < 500) { TempS = 26; } if (t > 500 && t < 650) { TempS = 28; } if (t > 650) { TempS = 100; } }
void PID() // Определение времени включениия мотора заслонки посредством ПИД регулирования { // TempSet(); // temp(); et = TempS - tempC; Pt = Kp*et; It = It1+(Ki*et); Dt = Kd*(et-et1); ut = (Pt+It+Dt)*1000; // Вычисление ПИД и перевод в миллисекунды if (ut > -1000 && ut < 0) { ut = -1000; } // Фиксируем минимальное время воздействия if (ut < 1000 && ut > 0) { ut = 1000; } if (TempS == 1 || TempS == 100) { ut = 0; } et1 = et; It1 = It; // Serial.print("ut = "); // Serial.print(Pt); Serial.print(" + "); Serial.print(It); Serial.print(" + "); Serial.print(Dt); // Serial.print(ut); }
void loop() { int period = 5000; // Время периода boolean b1 = false; boolean b2 = false;
delay (period); TempSet(); temp(); // Serial.print("Tp: "); // Serial.print(Tp); // Serial.print(", millis = : "); // Serial.println(millis()); // if ((millis() - Tp) > period) // { Serial.print("Period: "); Serial.println(i); i++; // PID(); Serial.print("Ustavka: "); Serial.print(TempS); Serial.print("; Temperatura: "); Serial.print(tempC); Serial.print("; ut: "); Serial.println(ut);
// while (millis() - Tut < abs(ut)) // Цикл - пока не кончится время воздействия // { if (TempS == 1 && OverloadCold != true){ // Мaксимально холодное положение OverloadHot = false; EEPROM.write(1, 0); Serial.println("Hot overload down"); ut = 30000; // Заслонка движется до упора Tut = millis(); MotorCold(); return; } if (TempS == 100 && OverloadHot != true) { // Максимально горячее положение OverloadCold = false; EEPROM.write(2, 0); Serial.println("Cold overload down"); ut = 30000; // Заслонка движется до упора Tut = millis(); MotorHot(); return; } if (TempS - tempC > 0 && OverloadHot != true){ OverloadCold = false; EEPROM.write(2, 0); Serial.println("Cold overload down"); PID(); Tut = millis(); MotorHot(); } if (TempS - tempC < 0 && OverloadCold != true){ OverloadHot = false; EEPROM.write(1, 0); Serial.println("Hot overload down"); PID(); Tut = millis(); MotorCold();} // if (Overload == true) { break; } // Если есть упор в положении куда надо двигать - не ждём окончания времени воздействия // }
// } }
Вложения: |
Комментарий к файлу: Пока так. Когда нарисую нормальную - ХЗ))
IMG_20190501_153811.jpg [ 1.2 МБ | Просмотров: 10364 ]
|
|
|