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

Вернуться   Форум обсуждения систем "Умный дом", проектов Ардуино, OpenWRT и других DIY устройств > Форум умного дома > Сделай сам

Ответ
 
Опции темы Поиск в этой теме Опции просмотра
Старый 21.02.2013, 19:33   #1
Admin
Administrator
 
Аватар для Admin
 
Регистрация: 12.04.2010
Адрес: Москва
Сообщений: 9,616
Вес репутации: 9821
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 вне форума   Ответить с цитированием
Старый 21.02.2013, 19:45   #2
Bulatovor
Senior Member
 
Регистрация: 20.01.2013
Адрес: Уфа
Сообщений: 444
Вес репутации: 799
Bulatovor has a reputation beyond reputeBulatovor has a reputation beyond reputeBulatovor has a reputation beyond reputeBulatovor has a reputation beyond reputeBulatovor has a reputation beyond reputeBulatovor has a reputation beyond reputeBulatovor has a reputation beyond reputeBulatovor has a reputation beyond reputeBulatovor has a reputation beyond reputeBulatovor has a reputation beyond reputeBulatovor has a reputation beyond repute
По умолчанию

Ну индуктивной нагрузки и в освещении хватает, единственное что радует, так это так это то что у меня дома ко всей индуктивной нагрузке (в отличии от освещения с лампами накаливания) есть полный доступ под фальшпотолками и там уж в габаритах не ограничен
Bulatovor вне форума   Ответить с цитированием
Старый 21.02.2013, 21:01   #3
Admin
Administrator
 
Аватар для Admin
 
Регистрация: 12.04.2010
Адрес: Москва
Сообщений: 9,616
Вес репутации: 9821
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
По умолчанию

Если без delay то можно использовать функцию millis();
Admin вне форума   Ответить с цитированием
Старый 21.02.2013, 21:57   #4
Bulatovor
Senior Member
 
Регистрация: 20.01.2013
Адрес: Уфа
Сообщений: 444
Вес репутации: 799
Bulatovor has a reputation beyond reputeBulatovor has a reputation beyond reputeBulatovor has a reputation beyond reputeBulatovor has a reputation beyond reputeBulatovor has a reputation beyond reputeBulatovor has a reputation beyond reputeBulatovor has a reputation beyond reputeBulatovor has a reputation beyond reputeBulatovor has a reputation beyond reputeBulatovor has a reputation beyond reputeBulatovor has a reputation beyond repute
По умолчанию

Вот быстро набросанный пример с использованием прерывания - он не компилируется -где то в скобках запутался, завтра найду -но основная мыль думаю понятна будет
PHP код:
// Плавное гашение и нарастание

#include <MsTimer2.h> // подключаем библиотеку прерывания по Timer2
int  Dimmer1
int L 0;      //  вводим переменную для обозначения уменьшения яркости, чтоб не использовать два прерывания
int H 0;      //  вводим переменную для обозначения увеличения яркости
void setup() {
  
 
MsTimer2::set(70off_with_time_delay); // установка прерывания по таймеру 1000ms - 1 секунда - определяющая плавность изменения, можно заменить время на переменную
}
 
// Обработчик прерываний Таймера2
void off_with_time_delay() {
 if(
L==1// если стоит указатель на плавное гашение
    
{if(Dimmer1<255)// и свет еще горит, вместо максимального значения в 255 можно использовать переменную - определяющую до какого уровня гасить
       
{Dimmer1++;} // увеличиваем значение переменной Dimmer1 на единицу
       
else
       {
MsTimer2::stop();L=0;};} // иначе (если свет уже потух) останавливаем прерывание и обнуляем указатель направления гашения
 
if(H==1// а тут все наоборот
    
{if(Dimmer1>0)
       {
Dimmer1--;}
       else
       {
MsTimer2::stop();H=0;};   
  }
void loop() 
   { 
// В теле программы или в каком нибудь другом месте - например по прерываниям кнопки запускаем прерывание и присваиваем переменным L или H( в зависимости от того гасим или зажигаем)единицу
           
MsTimer2::start(); // запускаем таймер             
           
L=1;
       }; 
Bulatovor вне форума   Ответить с цитированием
Старый 21.02.2013, 22:31   #5
vadymkyr
Junior Member
 
Регистрация: 21.02.2013
Адрес: Севастополь
Возраст: 32
Сообщений: 7
Вес репутации: 0
vadymkyr is an unknown quantity at this point
По умолчанию

спасибо, только не совсем понял, как это все скрестить
vadymkyr вне форума   Ответить с цитированием
Старый 22.02.2013, 20:46   #6
Bulatovor
Senior Member
 
Регистрация: 20.01.2013
Адрес: Уфа
Сообщений: 444
Вес репутации: 799
Bulatovor has a reputation beyond reputeBulatovor has a reputation beyond reputeBulatovor has a reputation beyond reputeBulatovor has a reputation beyond reputeBulatovor has a reputation beyond reputeBulatovor has a reputation beyond reputeBulatovor has a reputation beyond reputeBulatovor has a reputation beyond reputeBulatovor has a reputation beyond reputeBulatovor has a reputation beyond reputeBulatovor has a reputation beyond repute
По умолчанию

Вот дополняю скетч управлением диммером через кнопку с реализацией функций плавного гашения а так же зажигания. Возник вот какой вопрос - как отслеживать состояние кнопки, что быстрее - читать напрямую с порта о состоянии кнопки или ввести переменную - флаг состояния кнопки, переключаемый при каждом прерывании по PCINT?
Bulatovor вне форума   Ответить с цитированием
Старый 22.02.2013, 22:50   #7
dmitry123
Member
 
Регистрация: 03.12.2012
Адрес: Ярославль
Сообщений: 53
Вес репутации: 0
dmitry123 has a brilliant futuredmitry123 has a brilliant futuredmitry123 has a brilliant futuredmitry123 has a brilliant futuredmitry123 has a brilliant futuredmitry123 has a brilliant futuredmitry123 has a brilliant futuredmitry123 has a brilliant futuredmitry123 has a brilliant futuredmitry123 has a brilliant futuredmitry123 has a brilliant future
По умолчанию

Alex74, у вас command_in имеет значение уровня диммирования ? (полученого через serial)
Если да, то что непонятного ?
Если типы данных разные, то приводим к int
http://arduino.ru/Reference/IntCast
Dimmer1=int(command_in);
.....

Последний раз редактировалось dmitry123; 22.02.2013 в 22:56.
dmitry123 вне форума   Ответить с цитированием
Старый 22.02.2013, 23:31   #8
Bulatovor
Senior Member
 
Регистрация: 20.01.2013
Адрес: Уфа
Сообщений: 444
Вес репутации: 799
Bulatovor has a reputation beyond reputeBulatovor has a reputation beyond reputeBulatovor has a reputation beyond reputeBulatovor has a reputation beyond reputeBulatovor has a reputation beyond reputeBulatovor has a reputation beyond reputeBulatovor has a reputation beyond reputeBulatovor has a reputation beyond reputeBulatovor has a reputation beyond reputeBulatovor has a reputation beyond reputeBulatovor has a reputation beyond repute
По умолчанию

вот попробовал написать свой вариант программы на основе выложенной в первом посте плюс управление кнопками. Китайский новый год меня подвел, так что на железе не испытывал -все жду посылки, реализовано плавное гашение на основе millis(), от использования прерывания я отказался - слишком мало их, хотя с ними программка выглядит интересней.
PHP код:
// Данный скетч на основе программы Admina реализует управление диммером при помощи кнопки, с функцией планого гашения и включения, отключения с задержкой
#include "nanopins2.h" //подключаем библиотеку быстрого управления пинами 
#include <TimerOne.h> //библиотека использует Timer1 


int tic ;
int Dimmer1 // переменная определяющая яркость свечения
int Dimmer1M // переменная для хранения значения Dimmer1 при операциях
int qbutton1 ;        //  начальное значение счетчика нажатий на кнопку 1 
int b1millis;           // время последнего прерывания по кнопке 1 
int tcl 1000// время, после которого считается что серия нажатий на кнопки окончена -временно для отладки -потом можно заменить на твердую цифру 
int tc0 2000// время, после которого считается что серия нажатий на кнопки окончена и никакими переменными 

int L 0;      //  вводим переменную для обозначения уменьшения яркости
int H 0;      //  вводим переменную для обозначения увеличения яркости
int B 0// флаг состояния кнопки
int dmillis=0// переменная для фиксации времени команды на отложеное отключение
int lhmillis=;// переменная для фиксации времени команды на плавное гашение-зажигания
int tg=2//  интервал в миллисикундах между степенями гашения

void setup()  
{  
  
D4_Out//Настраиваем порт на выход Dimmer1 
  
D4_Low;  //установить на выходах низкий уровень сигнала 
  
D2_In//настраиваем порт на вход для отслеживания прохождения сигнала через ноль   
  
D9_In//настраиваем порт на вход для кнопки 1  
  
D9_High;  //установить на входах высокий уровень и подключить резистор  

  
attachInterrupt(0detect_upFALLING);  // настроить срабатывание прерывания int0 на pin 2  

  
Timer1.initialize(40);              // Интервал срабатывания таймера в мкс  
  
Timer1.attachInterrupt(halfcycle);   //будет вызыватся каждый раз при отсчете заданого времени 
  
Timer1.stop(); 
  
PCICR  |= (0<<PCIE2) | (0<<PCIE1) | (1<<PCIE0); 
  
// разрешение прерываний с портов B (PCINT[7:0]) и запрет  D (PCINT[23:16]) и   C (PCINT[14:8]) 
  
PCMSK0 |= (0<<PCINT7)  | (0<<PCINT6)  | (0<<PCINT5)  | (0<<PCINT4)  | (0<<PCINT3)  | (0<<PCINT2)  | (1<<PCINT1)  | (0<<PCINT0); 
  
// маскирование ноги 9 на порту B -разрешение на прерывание, остальные запрет 


//********************обработчики прерываний******************************* 
void halfcycle()  //прерывания таймера 
{  
  
tic++;  //счетчик   
  
if(Dimmer1 tic D4_High//управляем выходом 


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

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

  if(
D9_RL// условие для обработки прерывания только по нажатию кнопки, изменение фронта при отпускании отфильтровывается 
  
{
    
b1millis=millis(); // фиксация времени прерывания 
    
qbutton1++; // счетчик нажатий на кнопку 1 
    
B=1// флаг о том что кнопка нажата
  
};
  if(
D9_RH// условие для обработки прерывания только по отпусканию кнопки  
  
{
    
b1millis=millis(); // фиксация времени прерывания 
    
B=0// флаг о том что кнопка отжата
  
};


//************************************************************************* 
void loop()  
{  
// Обработка количества нажатий кнопки 1 
  // если переменная количества нажатий кнопки не равна 0 - можно и без этого, но это существенно ускорит программу, так как не будут обрабатываться последующие "если", если кнопка не нажималась 
  
if(qbutton1!=0
  {  
    
//если было одно нажатие и с момента последнего нажатия прошло время заданное переменной tc1, а так же кнопка все еще нажата 
    
if(qbutton1==&& millis()-b1millis>tcl && B==1
      
// значит это длинное нажатие и принимаем соответствующие действия для него 
    
{
      
Serial.println("long press"); 
      while(
Dimmer1>0&& B==1){
        
Dimmer1-- ;
      }; 
//пока кнопка нажата и диммер не достиг максимального значения уменьшаем значение переменной
      
Dimmer1M=Dimmer1;// например здесь печатаем в терминал "длинное нажатие", 
      
qbutton1=0
    }
// и обнуляем переменную количества нажатий 


    //если было одно нажатие и с момента последнего нажатия прошло время заданное переменной tc1, а так же кнопка уже опущена
    
if(qbutton1==&& millis()-b1millis>tcl&& B==0
      
// значит это кроткое нажатие и принимаем соответствующие действия для него 
    

      
Serial.println("1 click"); // например здесь печатаем в терминал "1 клик" 
      
qbutton1=0;                  // и обнуляем переменную количества нажатий 
      
if(Dimmer1<=200){
        
H=0;
        
L=1
        
lhmillis=millis();
        
Dimmer1M=Dimmer1;
      };
// если свет включен присваеваем значение переменной что надо выключить свет, 
      //и обнуляем переменную о выключении что избежать конфликта, если кто-то ранее её уже включил, фиксируем время команды? и запоминаем состояния димеера перед выклчением
      
if(Dimmer1>200){
        
H=1;
        
L=0;
        
lhmillis=millis();
      };
// есоответсвенно наоборт
    
}                                               

    
//если было два  нажатие и с момента последнего нажатия прошло время заданное переменной tc1, а так же кнопка все еще нажата 
    
if(qbutton1==&& millis()-b1millis>tcl&& B==0)  
      
// значит это одно короткое нажатие и кнопка едерживается и принимаем соответствующие действия для него 
    
{
      
Serial.println("1 click + long press"); // например здесь печатаем в терминал "1 клик + длинное нажатие", 
      
while(Dimmer1<=200&& B==1){
        
Dimmer1++            ;}; //пока кнопка нажата и диммер не достиг минимального  значения уменьшаем значение переменной
      
Dimmer1M=Dimmer1;// запоминаем опказания диммера, 
      
qbutton1=0;
    }
// и обнуляем переменную количества нажатий 


    //если было два  нажатия и с момента последнего нажатия прошло время заданное переменной tc1, а так же кнопка уже опущена( если кнопка нажата -переменную количества нажатий обнулена в предыдущем шаге) 
    
if(qbutton1==&& millis()-b1millis>tcl
      
// значит 2 коротких нажатия нажатия и принимаем соответствующие действия для него 
    

      
Serial.println("2 click");  // например здесь печатаем в терминал "1 клик" 
      
Dimmer1=0
      
// говорим что значение переменной минимальное и свет надо на полную сразу или можно присвоить значение переменной Dimmer1M ноль и переменной H единицу и тогда плавно загорится на полную
      
qbutton1=0;                  // и обнуляем переменную количества нажатий 
    
}              

    
//если было три   нажатия и с момента последнего нажатия прошло время заданное переменной tc1, а так же кнопка уже опущена( если кнопка нажата -переменную количества нажатий обнулена в предыдущем шаге) 
    
if(qbutton1==&& millis()-b1millis>tcl
      
// значит 3 коротких нажатия нажатия и принимаем соответствующие действия для него 
    

      
Serial.println("3 click");  // например здесь печатаем в терминал "3 клик" 
      
Dimmer1=0
      
// говорим что значение переменной минимальное и свет надо на полную сразу или можно присвоить значение переменной Dimmer1M ноль и переменной H единицу и тогда плано загорится на полную
      
qbutton1=0;                  // и обнуляем переменную количества нажатий 
    
}          

    
// обнуление счетчика нажатий, если количество нажатий не указано в предыдущих выборках и прошло больше переменной tc0                                               
    
if(qbutton1!=&& millis()-b1millis>2000
    {
      
Serial.println("counter clicks reset"); // в рабочей версии здесь наверное ничего не будет, 
      
qbutton1=0;
    } 
// и обнуляем переменную количества нажатий 
  
}; 


  
//  Обработка гашения и зажигания света
  
if (L==1)//  если есть команда на плавное гашение
  
{
    if (
Dimmer1<200)// если состояние диммера не на минимальном значении
    
{
      if( 
millis()-lhmillis>tg// и прошло время плавности гашения
      
{
        
Dimmer1++; // увеличиваем значение переменной на единицу
        
lhmillis=millis(); // обновляем значение переменной
      
}
      if (
Dimmer1>=200// если диммер уже на миниммуме
      
{
        
Dimmer1=255// выключаем его полностью
        
L=0// и снимаем флаг на плавное гашение
      
}
    }
  };
  if (
L==1)//  если есть команда на плавное включение
  
{
    if (
Dimmer1>Dimmer1M// если значение диммера больше сохраненной переменной
    
{
      if( 
millis()-lhmillis>tg// дальше по аналогии с гашением
      
{
        
Dimmer1--;
        
lhmillis=millis();
      }

      if (
Dimmer1<=Dimmer1M)
      {
        
H=0;
      }
    }
  };





Последний раз редактировалось Bulatovor; 24.02.2013 в 11:22.
Bulatovor вне форума   Ответить с цитированием
Старый 22.02.2013, 23:50   #9
vadymkyr
Junior Member
 
Регистрация: 21.02.2013
Адрес: Севастополь
Возраст: 32
Сообщений: 7
Вес репутации: 0
vadymkyr is an unknown quantity at this point
По умолчанию

ругается на не объявленные В9_RL и D9_RH.
vadymkyr вне форума   Ответить с цитированием
Старый 23.02.2013, 08:16   #10
Bulatovor
Senior Member
 
Регистрация: 20.01.2013
Адрес: Уфа
Сообщений: 444
Вес репутации: 799
Bulatovor has a reputation beyond reputeBulatovor has a reputation beyond reputeBulatovor has a reputation beyond reputeBulatovor has a reputation beyond reputeBulatovor has a reputation beyond reputeBulatovor has a reputation beyond reputeBulatovor has a reputation beyond reputeBulatovor has a reputation beyond reputeBulatovor has a reputation beyond reputeBulatovor has a reputation beyond reputeBulatovor has a reputation beyond repute
По умолчанию

Скачай модернизированной мной библиотеку nanopins.h - nanopins2.h http://cyber-place.ru/attachment.php...9&d=1360420141 или переделай под модернизированною Adminom nanopins.h http://cyber-place.ru/attachment.php...9&d=1360420141
Bulatovor вне форума   Ответить с цитированием
Ответ


Здесь присутствуют: 24 (пользователей: 0 , гостей: 24)
 

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

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

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


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


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