Форум обсуждения оборудования  

Вернуться   Форум обсуждения оборудования "Умный дом" > Форум умного дома > Климатические системы

Ответ
 
Опции темы Поиск в этой теме Опции просмотра
Старый 28.05.2013, 02:46   #1
zsm
Member
 
Регистрация: 28.05.2013
Сообщений: 71
Вес репутации: 0
zsm is an unknown quantity at this point
По умолчанию Плавное изменение оборотов асинхронного вентилятора переменного тока с помощью Arduino.

Здравствуйте уважаемые форумчане.Обращаюсь с такой проблемой:

Недавно решил своими силами сделать устройство позволяющее плавно менять скорость вентилятора( 220 V) в зависимости от температуры.

Для начала решил подключить датчик температуры DS18B20 и прописать логику, для проверки использовал стандартный ШИМ arduino + двигатель постоянного тока через MOSFET. Результат меня более чем устроил, все завелось с пол пинка и олично выполняло свои функции.

Датчик температуры DS18B20 , использовал стандартные библиотеки.
Первый потенциометр VAR_REZ задаёт температуру включения вентиляции (на наименьших оборотах) , второй потенциометр VAR_REZ2 задает температуру на которой вентилятор выйдет на максимальные обороты. Соотношением этих двух резисторов можно довольно тонко настроить соотношение эффективности охлаждения к уровню шума.

вот код: сильно не ругайте он первый у меня

PHP код:
#include <OneWire.h>
#include <DallasTemperature.h>
#define VAR_REZ A0
#define VAR_REZ2 A1
#define ONE_WIRE_BUS 10//назначение термодатчика на пин 10
OneWire oneWire(ONE_WIRE_BUS);
DallasTemperature sensors(&oneWire);
int led 13;
int pwm 9;

void setup(void)
{
pinMode(ledOUTPUT);
pinMode(pwmOUTPUT);
Serial.begin(9600);
Serial.println("Start");
analogWrite(pwm255);
delay(2000);
sensors.begin();
}


void loop(void)

{

int valrez analogRead(VAR_REZ);
int valrez2 analogRead(VAR_REZ2);
int tempmin map(valrez,147,1023,2000,5000) ;
int tempmax map(valrez2,135,1023,2000,5000) ;
Serial.print(" Requesting temperatures...");
sensors.requestTemperatures(); // Send the command to get temperatures
Serial.println("DONE");
Serial.print("min temp-");
Serial.println(tempmin);
Serial.print("max temp-");
Serial.println(tempmax);
Serial.println(valrez);
Serial.println(valrez2);

int pwmval map(sensors.getTempCByIndex(0)*100,tempmin,tempmax,10,255);
Serial.print("pwm-");
Serial.println(pwmval);


if (
sensors.getTempCByIndex(0)*100<tempmin)
{
analogWrite(pwm0);}

else if (
sensors.getTempCByIndex(0)*100>tempmax)
{
analogWrite(pwm255);}

else if (
sensors.getTempCByIndex(0)*100>tempmin)
{
analogWrite(pwmpwmval);}


Serial.print("Temperature: ");
Serial.print(sensors.getTempCByIndex(0));
if (
sensors.getTempCByIndex(0)*100>tempmindigitalWrite(ledHIGH);
if (
sensors.getTempCByIndex(0)*100<tempmindigitalWrite(ledLOW);



Вдохновлённый первым успехом решил начинать с 220v... И тут начались настоящие траблы))Первым ударом было то что придётся отказаться от любимой функции analogWrite,вторым-то что придётся мутить обратную связь и.т.д.

Короче в какой то момент начал понимать что задачу не по зубам взял...Но в какой то момент натолкнулся на статью на Вашем форуме, собрал устройство (пришлось немного изменить номиналы резисторов ) залил скетч из первого поста ,протестировал и понял что данный диммер полностью подходит для моих целей. И с разбегу переписал свой скетч добавив туда код и библиотеки диммера. И всё как будто заработало- логика выполняется , скорость вращения меняется....но вентилятор вращается с прерываниями которое задаёт опрос датчика температуры !!! (видно когда порт мониториш)

В варианте с стандартным ШИМом такого не наблюдалось.Всю голову сломал то ли значение Dimmer1 сбрасывается почему то, при опросе датчика температуры, или конфликт библиотек.( может <DallasTemperature.h> тоже timer 1 использует )

но это всё лиш догадки...

В общем даже не знаю в какую сторону смотреть т.к. это первый проэкт на МК.

Буду рад любым предложениям, советам, критике , примерам)

Всем заранее спасибо)

Вот код переделаный:

Здесь все библиотеки использованые в проэкте.

PHP код:
#include "nanopins.h" //быстрое управление пинами
#include <TimerOne.h> //использует Timer1
#include <OneWire.h>
#include <DallasTemperature.h>
#define VAR_REZ A0
#define VAR_REZ2 A1
#define ONE_WIRE_BUS 10//назначение термодатчика на пин 10
OneWire oneWire(ONE_WIRE_BUS);
DallasTemperature sensors(&oneWire);
int led 13;
volatile uint8_t ticDimmer1Dimmer2Dimmer3;

void setup() 

  
D4_Out//Настраиваем порт на выход Dimmer1
  
D5_Out//Настраиваем порт на выход Dimmer2
  
D6_Out//Настраиваем порт на выход Dimmer3
  
D4_LowD5_LowD6_Low//установить на выходах низкий уровень сигнала
  
D2_In//настраиваем порт на вход для отслеживания прохождения сигнала через ноль
  
pinMode(ledOUTPUT);
  
Serial.begin(9600);
  
Serial.println("Start");
  
sensors.begin();   
   
  
attachInterrupt(0detect_upFALLING);  // настроить срабатывание прерывания int0 на pin 2 

  
Timer1.initialize(40);              // Интервал срабатывания таймера в мкс 
  
Timer1.attachInterrupt(halfcycle);   //будет вызыватся каждый раз при отсчете заданого времени
  
Timer1.stop();
}
//********************обработчики прерываний*******************************
void halfcycle()  //прерывания таймера

  
tic++;  //счетчик  
  
if(Dimmer1 tic D4_High//управляем выходом
  
if(Dimmer2 tic D5_High;  //управляем выходом
  
if(Dimmer3 tic D6_High;  //управляем выходом 
}

void  detect_up()  // обработка внешнего прерывания. Сработает по переднему фронту синусоиды
{  
 
tic=0;             //обнулить счетчик
 
Timer1.resume();   //запустить таймер
 
attachInterrupt(0detect_downRISING);  //перепрограммировать прерывание на другой обработчик
}  

void  detect_down()  // обработка внешнего прерывания. Сработает по заднему фронту синусоиды
{   
 
Timer1.stop(); //остановить таймер
 
D4_LowD5_LowD6_Low//логический ноль на выходы
 
tic=0;       //обнулить счетчик
 
attachInterrupt(0detect_upFALLING); //перепрограммировать прерывание на другой обработчик

//*************************************************************************
void loop() 
{
  
  
int valrez analogRead(VAR_REZ);
  
int valrez2 analogRead(VAR_REZ2);
  
int tempmin map(valrez,147,1023,2000,5000) ;
  
int tempmax map(valrez2,135,1023,2000,5000) ;
  
Serial.print("   Requesting temperatures...");
  
sensors.requestTemperatures(); // Send the command to get temperatures
  
Serial.println("DONE");
  
Serial.print("min temp-");
  
Serial.println(tempmin);
  
Serial.print("max temp-");
  
Serial.println(tempmax);
  
Serial.println(valrez);
  
Serial.println(valrez2); 
  
  
int pwmval map(sensors.getTempCByIndex(0)*100,tempmin,tempmax,150,0);
  
Serial.print("pwm-");
  
Serial.println(pwmval);
  
  
  if (
sensors.getTempCByIndex(0)*100<tempmin
    {
Dimmer1=255;}
  
  else if (
sensors.getTempCByIndex(0)*100>tempmax
    {
Dimmer1=0;}
  
  else if  (
sensors.getTempCByIndex(0)*100>tempmin)
    {
Dimmer1=pwmval;}
 
 
  
Serial.print("Temperature: ");
  
Serial.print(sensors.getTempCByIndex(0));
   if  (
sensors.getTempCByIndex(0)*100>tempmindigitalWrite(ledHIGH);
   if  (
sensors.getTempCByIndex(0)*100<tempmindigitalWrite(ledLOW);
      
  
  } 
zsm вне форума   Ответить с цитированием
Старый 28.05.2013, 12:30   #2
Admin
Administrator
 
Аватар для Admin
 
Регистрация: 12.04.2010
Адрес: Москва
Сообщений: 8,999
Вес репутации: 9197
Admin has a brilliant futureAdmin has a brilliant futureAdmin has a brilliant futureAdmin has a brilliant futureAdmin has a brilliant futureAdmin has a brilliant futureAdmin has a brilliant futureAdmin has a brilliant futureAdmin has a brilliant futureAdmin has a brilliant futureAdmin has a brilliant future
По умолчанию

Для начала нужно понять из за чего глючит.
Для этого потребуется убрать все что связано с вызовом измерения температуры.
Если посте этого даргатся перестанет, то смотреть саму либу на датчик темепературы и пытаться обойти проблему
Admin вне форума   Ответить с цитированием
Старый 28.05.2013, 13:17   #3
zsm
Member
 
Регистрация: 28.05.2013
Сообщений: 71
Вес репутации: 0
zsm is an unknown quantity at this point
По умолчанию

Большое спасибо за совет, Будем ковырять)
zsm вне форума   Ответить с цитированием
Старый 28.05.2013, 13:28   #4
Admin
Administrator
 
Аватар для Admin
 
Регистрация: 12.04.2010
Адрес: Москва
Сообщений: 8,999
Вес репутации: 9197
Admin has a brilliant futureAdmin has a brilliant futureAdmin has a brilliant futureAdmin has a brilliant futureAdmin has a brilliant futureAdmin has a brilliant futureAdmin has a brilliant futureAdmin has a brilliant futureAdmin has a brilliant futureAdmin has a brilliant futureAdmin has a brilliant future
По умолчанию

Я бы для регулировки индуктивной нагрузки, использовал другой вариант регулировки, так как эта схема будет генерировать большое количество помех в сети
Например я бы попробовал вариант который основан на пропуске полупериодов.
Для этого понадобится оптрон с детектором ноля, в цепи симистора.
Алгоритм такой
Например берем за основу 10 полупериодов, это 100%
если включить симмистор на один полупериод, а остальные 9 ПП пропустить, то это будет 10% мощности,
Если 2 ПП то это 20% и т.д.
При таком алгоритме, можно немножко упростить код.
Таймер в коде не понадобится
Admin вне форума   Ответить с цитированием
Старый 28.05.2013, 14:53   #5
zsm
Member
 
Регистрация: 28.05.2013
Сообщений: 71
Вес репутации: 0
zsm is an unknown quantity at this point
По умолчанию

Спасибо , как раз есть moc 3083 . Не могли бы дать ссылку на пример кода?
Как понимаю обратной связи не потребуется?

Последний раз редактировалось zsm; 28.05.2013 в 14:59.
zsm вне форума   Ответить с цитированием
Старый 28.05.2013, 15:30   #6
Admin
Administrator
 
Аватар для Admin
 
Регистрация: 12.04.2010
Адрес: Москва
Сообщений: 8,999
Вес репутации: 9197
Admin has a brilliant futureAdmin has a brilliant futureAdmin has a brilliant futureAdmin has a brilliant futureAdmin has a brilliant futureAdmin has a brilliant futureAdmin has a brilliant futureAdmin has a brilliant futureAdmin has a brilliant futureAdmin has a brilliant futureAdmin has a brilliant future
По умолчанию

Можно попробовать проверить без обратной связи.
Admin вне форума   Ответить с цитированием
Старый 28.05.2013, 15:39   #7
zsm
Member
 
Регистрация: 28.05.2013
Сообщений: 71
Вес репутации: 0
zsm is an unknown quantity at this point
По умолчанию

Схему с пропуском периодов обязательно попробую.
Хочу все же для начала разобраться с первой схемой. удалил по Вашему совету всё что связано с датчиком температуры , всё нормально стало, похоже надо в DallasTemperature.h проблему искать..а там вообще чёрт ногу сломит))
Может датчик другой попробовать? DHT11 например.

Последний раз редактировалось zsm; 28.05.2013 в 15:59.
zsm вне форума   Ответить с цитированием
Старый 28.05.2013, 16:26   #8
Admin
Administrator
 
Аватар для Admin
 
Регистрация: 12.04.2010
Адрес: Москва
Сообщений: 8,999
Вес репутации: 9197
Admin has a brilliant futureAdmin has a brilliant futureAdmin has a brilliant futureAdmin has a brilliant futureAdmin has a brilliant futureAdmin has a brilliant futureAdmin has a brilliant futureAdmin has a brilliant futureAdmin has a brilliant futureAdmin has a brilliant futureAdmin has a brilliant future
По умолчанию

Тогда уж лучше использовать любой из списка аналоговый датчик температуры LM35, LM135, LM235, LM335
Admin вне форума   Ответить с цитированием
Старый 28.05.2013, 16:55   #9
zsm
Member
 
Регистрация: 28.05.2013
Сообщений: 71
Вес репутации: 0
zsm is an unknown quantity at this point
По умолчанию

Спасибо за советы , с аналоговыми проще будет пожалуй, но всё же поковыряюсь с этим ещё.

Последний раз редактировалось zsm; 28.05.2013 в 17:13.
zsm вне форума   Ответить с цитированием
Старый 28.05.2013, 17:11   #10
Admin
Administrator
 
Аватар для Admin
 
Регистрация: 12.04.2010
Адрес: Москва
Сообщений: 8,999
Вес репутации: 9197
Admin has a brilliant futureAdmin has a brilliant futureAdmin has a brilliant futureAdmin has a brilliant futureAdmin has a brilliant futureAdmin has a brilliant futureAdmin has a brilliant futureAdmin has a brilliant futureAdmin has a brilliant futureAdmin has a brilliant futureAdmin has a brilliant future
По умолчанию

Попробуй вот такой вариант регулятора
PHP код:
#include <CyberLib.h>

volatile uint8_t ticDimmer1;

void setup() 

  
D4_Out//Настраиваем порт на выход Dimmer1
  
D4_Low
  
StartTimer1(dimm10000);  


void dimm() 
{  
  
tic++;  //счетчик  
  
D4_Low;
  if(
Dimmer1 >= tic D4_High//управляем выходом



//*************************************************************************
void loop() 
{
   
Dimmer1=5//1=мин. 10=макс 0=выкл 

Admin вне форума   Ответить с цитированием
Ответ


Здесь присутствуют: 1 (пользователей: 0 , гостей: 1)
 
Опции темы Поиск в этой теме
Поиск в этой теме:

Расширенный поиск
Опции просмотра

Ваши права в разделе
Вы не можете создавать новые темы
Вы не можете отвечать в темах
Вы не можете прикреплять вложения
Вы не можете редактировать свои сообщения

BB коды Вкл.
Смайлы Вкл.
[IMG] код Вкл.
HTML код Выкл.

Быстрый переход


Текущее время: 15:59. Часовой пояс GMT +3.


Powered by vBulletin® Version 3.8.5
Copyright ©2000 - 2017, Jelsoft Enterprises Ltd. Перевод: zCarot
Яндекс.Метрика