климат для авто

evgta
Offline
Зарегистрирован: 02.09.2016

Построил автоматическое управление заслонкой печки в пыже 206, привод поставил оригинальный(внутри униполярный шаговик) т.к втает без переделок и шаманства, датчик температуры взял тоже оригинальный, в нем встроен вентилятор и NTN 10K 

принцип работы: при Т ниже чем на +-3 градуса заданной заслока находится в крайнем положении(мах на тепло, или мах на холод), при достижении заданной Т заслонка переходит в среднее 6 положение (из12) и затем раз в 10 секунд если Т выше заданной заслонка перемещается на одну ступень ближе к холоду, еслт Т ниже заданной то соотв наоборот.

Работает достаточно адекватно, за исключением если открыть дверь то печка начинает жарить на полную, при закрытии двери через минуту - полторы наступает стабилизауия по температуре.

 

файлы скетча и протеуса

#include "thermistor.h"
int dathik = 6;
int motorPin1 = 5;          
int motorPin2 = 2;
int motorPin3 =4;
int motorPin4 = 3;
int motor_Speed = 6;   //для реала 6
int motor_Step; 
int shag = 12;       // кол-во шагов от упора до упора(если менять, то надо править дополнительно в лупе)
int stupen=0;
int curr_stupen=12;
int reo=0;
int temp1=0;
int obor = 33;      // задает угол перемещения за 1 шаг(нужно для настройки заслонки)
int vremya = 1000;  //задает время между циклами работы
int stup=0;
#define NTC_PIN               A1

THERMISTOR thermistor(NTC_PIN,        // Analog pin
                      10000,          // Nominal resistance at 25 ºC
                      3435,           // thermistor's beta coefficient
                    10000);         // Value of the series resistor

uint16_t temp;

void setup() {

  pinMode(dathik, OUTPUT);
  pinMode(motorPin1, OUTPUT);
  pinMode(motorPin2, OUTPUT);
  pinMode(motorPin3, OUTPUT);
  pinMode(motorPin4, OUTPUT);
Serial.begin(9600);

nazad();            //выставляю заслонку в нулевое положение
shag=1;
obor=8;
void vpered();
obor=33;
shag=12;

delay (1000);
}



void loop() {
digitalWrite(dathik, HIGH);
delay (150);
temp = thermistor.read();
digitalWrite(dathik, LOW);


reo = analogRead(A0);              // выставление параметров резистора
temp=temp-40;
if (reo>350) {reo=350;}
reo=reo/3.5;
reo=100-reo;
reo=reo+180;   


Serial.println(temp);
Serial.println(reo);   
Serial.println(curr_stupen);
if (reo < 185) {curr_stupen=0; goto bypass;}   // при крайних положениях заслонка постоянно открыта или закрыта
if (reo > 275) {curr_stupen=12; goto bypass;}

if (reo-3<temp){curr_stupen=curr_stupen-1;}                 // +- 5 1 градус на гистерезис
if (reo+3>temp){curr_stupen=curr_stupen+1;}
if (reo-30>temp){curr_stupen=12;}                            // если температура на 3 градуса ниже(выше) нормы заслонка встает в крайнее положение.
if (reo+30<temp){curr_stupen=0;}

if (stup==12 && curr_stupen ==11) {curr_stupen=6;}     // если заслонка была в крайних положениях то при первом изменении положения заслонки, заслонка переходит в среднее 6 положение
if (stup==0 && curr_stupen ==1) {curr_stupen=6;}

if (curr_stupen<0){curr_stupen=0;}
if (curr_stupen>12){curr_stupen=12;}

bypass:
zaslonka();  
delay (vremya);    
    
    
    
    
    
    
    } 

    //--------------------------------------------------------------------------------------------------------------------------------------------------

void nazad()                 
{
  for (int k=0; k< shag; k++)
  {
   for (int i=1; i< obor; i++)
     {
  digitalWrite(motorPin1, HIGH);
  digitalWrite(motorPin2, LOW);
  digitalWrite(motorPin3, LOW);
  digitalWrite(motorPin4, LOW);
  delay(motor_Speed);
  digitalWrite(motorPin1, LOW);
  digitalWrite(motorPin2, HIGH);
  digitalWrite(motorPin3, LOW);
  digitalWrite(motorPin4, LOW);
  delay(motor_Speed);
  digitalWrite(motorPin1, LOW);
  digitalWrite(motorPin2, LOW);
  digitalWrite(motorPin3, HIGH);
  digitalWrite(motorPin4, LOW);
  delay(motor_Speed);
  digitalWrite(motorPin1, LOW);
  digitalWrite(motorPin2, LOW);
  digitalWrite(motorPin3, LOW);
  digitalWrite(motorPin4, HIGH);
  delay(motor_Speed);
     }
}  

delay (500);

}
   //--------------------------------------------------------------------------------------------------------------------------------------------------

void vpered()                 
{
for (int k=0; k< shag; k++)
  {
for (int i=1; i < obor; i++)
{
digitalWrite(motorPin4, HIGH);
  digitalWrite(motorPin3, LOW);
  digitalWrite(motorPin2, LOW);
  digitalWrite(motorPin1, LOW);
  delay(motor_Speed);
  digitalWrite(motorPin4, LOW);
  digitalWrite(motorPin3, HIGH);
  digitalWrite(motorPin2, LOW);
  digitalWrite(motorPin1, LOW);
  delay(motor_Speed);
  digitalWrite(motorPin4, LOW);
  digitalWrite(motorPin3, LOW);
  digitalWrite(motorPin2, HIGH);
  digitalWrite(motorPin1, LOW);
  delay(motor_Speed);
  digitalWrite(motorPin4, LOW);
  digitalWrite(motorPin3, LOW);
  digitalWrite(motorPin2, LOW);
  digitalWrite(motorPin1, HIGH);
  delay(motor_Speed);
} 
  }
delay (500);

}
   //--------------------------------------------------------------------------------------------------------------------------------------------------

void zaslonka() {
if (reo!=stupen){   
                 if (curr_stupen< stupen){shag=stupen-curr_stupen;nazad();} 
                  if (curr_stupen> stupen){shag=curr_stupen-stupen;vpered();}  
                  stupen =curr_stupen; stup=curr_stupen;} 

}

 

evgta
Offline
Зарегистрирован: 02.09.2016
evgta
Offline
Зарегистрирован: 02.09.2016

Пробовал прикрутить ПИД ничего хорошего невышло ((( шарохает заслонкой туда сюда кидая температуру в салоне ,

уже как ни крутил коэф ничего путевого невыходит

#include "thermistor.h"
#include <PID_v1.h>//библиотека ПИД-ругулятора
double Setpoint, Input, Output;
PID myPID(&Input, &Output, &Setpoint,0.5,0.2,0.2, DIRECT);//создаем ПИД-регулятор

boolean revers;

int dathik = 6;
int motorPin1 = 5;          
int motorPin2 = 2;
int motorPin3 =4;
int motorPin4 = 3;
int motor_Speed = 6;   //для реала 6
int motor_Step; 
int shag = 12;       // кол-во шагов от упора до упора(если менять, то надо править дополнительно в лупе)
int stupen=0;
int curr_stupen=12;
int reo=0;
int temp1=0;
int obor = 33;      // задает угол перемещения за 1 шаг(нужно для настройки заслонки)
int vremya = 1000;  //задает время между циклами работы
int stup=0;
#define NTC_PIN               A1

THERMISTOR thermistor(NTC_PIN,        // Analog pin
                      10000,          // Nominal resistance at 25 ºC
                      3435,           // thermistor's beta coefficient
                    10000);         // Value of the series resistor

uint16_t temp;

void setup() {
Setpoint = 200;//заданная температура в салоне автомобиля
Input = temp;
myPID.SetOutputLimits(0, 12);
if (Setpoint<Input){//если начальная температура больше заданной
revers=true;
myPID.SetControllerDirection(REVERSE);//ПИД-регулятор используем обратный
}
myPID.SetMode(AUTOMATIC);//включаем ПИД-регулятор
//myPID.SetSampleTime(2000);

  pinMode(dathik, OUTPUT);
  pinMode(motorPin1, OUTPUT);
  pinMode(motorPin2, OUTPUT);
  pinMode(motorPin3, OUTPUT);
  pinMode(motorPin4, OUTPUT);
Serial.begin(9600);

nazad();            //выставляю заслонку в нулевое положение
shag=1;
obor=8;
void vpered();
obor=33;
shag=12;

delay (1000);
}



void loop() {
digitalWrite(dathik, HIGH);
delay (150);
temp = thermistor.read();
digitalWrite(dathik, LOW);


reo = analogRead(A0);              // выставление параметров реостата
temp=temp-40;
if (reo>350) {reo=350;}
reo=reo/3.5;
reo=100-reo;
reo=reo+180;   

                                                      // +- 3 0.6 градус на гистерезис

//if (temp <= reo+2 && temp >= reo-2){goto bypass;}

Setpoint=reo;
Input = temp;
myPID.Compute();
curr_stupen=Output;


Serial.println(Input);
Serial.println(reo);   
Serial.println(curr_stupen);
if (reo < 185) {curr_stupen=0;}   // при крайних положениях заслонка постоянно открыта или закрыта
if (reo > 275) {curr_stupen=12;}
Serial.println(curr_stupen);





bypass:
delay (vremya);    
    
    
  zaslonka();  
    
    
    
    } 

    //--------------------------------------------------------------------------------------------------------------------------------------------------

void nazad()                 
{
  for (int k=0; k< shag; k++)
  {
   for (int i=1; i< obor; i++)
     {
  digitalWrite(motorPin1, HIGH);
  digitalWrite(motorPin2, LOW);
  digitalWrite(motorPin3, LOW);
  digitalWrite(motorPin4, LOW);
  delay(motor_Speed);
  digitalWrite(motorPin1, LOW);
  digitalWrite(motorPin2, HIGH);
  digitalWrite(motorPin3, LOW);
  digitalWrite(motorPin4, LOW);
  delay(motor_Speed);
  digitalWrite(motorPin1, LOW);
  digitalWrite(motorPin2, LOW);
  digitalWrite(motorPin3, HIGH);
  digitalWrite(motorPin4, LOW);
  delay(motor_Speed);
  digitalWrite(motorPin1, LOW);
  digitalWrite(motorPin2, LOW);
  digitalWrite(motorPin3, LOW);
  digitalWrite(motorPin4, HIGH);
  delay(motor_Speed);
     }
}  

delay (500);

}
   //--------------------------------------------------------------------------------------------------------------------------------------------------

void vpered()                 
{
for (int k=0; k< shag; k++)
  {
for (int i=1; i < obor; i++)
{
digitalWrite(motorPin4, HIGH);
  digitalWrite(motorPin3, LOW);
  digitalWrite(motorPin2, LOW);
  digitalWrite(motorPin1, LOW);
  delay(motor_Speed);
  digitalWrite(motorPin4, LOW);
  digitalWrite(motorPin3, HIGH);
  digitalWrite(motorPin2, LOW);
  digitalWrite(motorPin1, LOW);
  delay(motor_Speed);
  digitalWrite(motorPin4, LOW);
  digitalWrite(motorPin3, LOW);
  digitalWrite(motorPin2, HIGH);
  digitalWrite(motorPin1, LOW);
  delay(motor_Speed);
  digitalWrite(motorPin4, LOW);
  digitalWrite(motorPin3, LOW);
  digitalWrite(motorPin2, LOW);
  digitalWrite(motorPin1, HIGH);
  delay(motor_Speed);
} 
  }
delay (500);

}
   //--------------------------------------------------------------------------------------------------------------------------------------------------

void zaslonka() {

                 if (curr_stupen< stupen){shag=stupen-curr_stupen;nazad();} 
                  if (curr_stupen> stupen){shag=curr_stupen-stupen;vpered();}  
                  stupen =curr_stupen; stup=curr_stupen;

}

 

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

evgta пишет:

за исключением если открыть дверь то печка начинает жарить 

Так у Вас же есть сигнал, что дверь открыта (светодиод на панели же как-то загорается), заведите его на свой контроллер и поступайте как сочтёте нужным.

evgta
Offline
Зарегистрирован: 02.09.2016

как вариант на время открытия двери и последующую минуту-30 сек) после закрытия зафиксировать положение заслонки, 

omi4
Offline
Зарегистрирован: 01.01.2017

Лампу в шитке заюзать вряд ли выйдет, это не ваз. Смотри в сторону CAN. Модуль для CAN у китайцев 150р, рабоотает через SPI.

evgta
Offline
Зарегистрирован: 02.09.2016

omi4 пишет:

Лампу в шитке заюзать вряд ли выйдет, это не ваз. Смотри в сторону CAN. Модуль для CAN у китайцев 150р, рабоотает через SPI.


У меня нет can шины , k-line только, да и лампы в щитке тоже нет, плафон в салоне загорается так что проблем с подключением нет.

omi4
Offline
Зарегистрирован: 01.01.2017

CAN в 206 есть, ее нет на OBD разъеме.

В добавок в системах где неизвестны все данные применяют мягкую логику

https://habrahabr.ru/post/125614/

 

evgta
Offline
Зарегистрирован: 02.09.2016

Кан шина идет с 2003 года на авто с мультиплексом, у меня 2001 с k-line

omi4
Offline
Зарегистрирован: 01.01.2017

Vehicle Area Network (VAN) это кан шина в которой еще не оформлен протокол в виде жестких стандартов SAE и ISO. И был он в пыжах с хз каких годов. 

Почитай тут http://graham.auld.me.uk/projects/vanbus/protocol.html

С шиной работать не сложно, нужно ее просто слушать. Ничего запрашивать не нужно.