Здравствуйте уважаемые форумчане.Обращаюсь с такой проблемой:
Недавно решил своими силами сделать устройство позволяющее плавно менять скорость вентилятора( 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(led, OUTPUT);
pinMode(pwm, OUTPUT);
Serial.begin(9600);
Serial.println("Start");
analogWrite(pwm, 255);
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(pwm, 0);}
else if (sensors.getTempCByIndex(0)*100>tempmax)
{analogWrite(pwm, 255);}
else if (sensors.getTempCByIndex(0)*100>tempmin)
{analogWrite(pwm, pwmval);}
Serial.print("Temperature: ");
Serial.print(sensors.getTempCByIndex(0));
if (sensors.getTempCByIndex(0)*100>tempmin) digitalWrite(led, HIGH);
if (sensors.getTempCByIndex(0)*100<tempmin) digitalWrite(led, LOW);
}
Вдохновлённый первым успехом решил начинать с 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 tic, Dimmer1, Dimmer2, Dimmer3;
void setup()
{
D4_Out; //Настраиваем порт на выход Dimmer1
D5_Out; //Настраиваем порт на выход Dimmer2
D6_Out; //Настраиваем порт на выход Dimmer3
D4_Low; D5_Low; D6_Low; //установить на выходах низкий уровень сигнала
D2_In; //настраиваем порт на вход для отслеживания прохождения сигнала через ноль
pinMode(led, OUTPUT);
Serial.begin(9600);
Serial.println("Start");
sensors.begin();
attachInterrupt(0, detect_up, FALLING); // настроить срабатывание прерывания 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(0, detect_down, RISING); //перепрограммировать прерывание на другой обработчик
}
void detect_down() // обработка внешнего прерывания. Сработает по заднему фронту синусоиды
{
Timer1.stop(); //остановить таймер
D4_Low; D5_Low; D6_Low; //логический ноль на выходы
tic=0; //обнулить счетчик
attachInterrupt(0, detect_up, FALLING); //перепрограммировать прерывание на другой обработчик
}
//*************************************************************************
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>tempmin) digitalWrite(led, HIGH);
if (sensors.getTempCByIndex(0)*100<tempmin) digitalWrite(led, LOW);
}