Управление светом с помощью ардуины и датчика движения

FDV
Offline
Зарегистрирован: 12.07.2014

Коллеги, помогите с проектом по управлению светодиодной подсветкой с помощью ардуины и датчика движения!
Алгоритм выглядит так:
1. Датчик движения срабатывает и подает 5В на вход ардуины (сигнал держится 1 сек и отключается - так датчик работает)
2. Ардуина видит сигнал и плавно зажигает диод - держит свет 10 сек
3. Спустя 10 сек ардуина смотрит на датчик и если с датчика сигнала нет - начинает гасить плавно диод, если сигнал есть - ждет еще 10 сек

4. Если уже в процессе гашения диода(например уже 50% яркости) датчик срабатывает - то начиная с этих 50% яркость начинает опять расти
(далее ждет 10 сек и опять начинает плавно гаситься)

Друг посоветовал покопаться с прерываниями, но для меня это пока еще слишком сложно...
(прподолжаю копать, но уже дымится мозг и результат нулевой...)
Прошу вашей помощи !

Пока написал такую болванку:

 

int intPin = 4;    // Номер прерывания, которое будет вызыватся.              
int ledPin = 5;    // Контакт с ШИМ для подключения светодиода.
// volatile int x; // Переменная для подсчета времени, 

// Основные параметры
void setup() 
{
  attachInterrupt(intPin,Light,RISING); // Параметры прерывания.
  pinMode(ledPin, OUTPUT);
}

// Функция которая будет выполнятся при нажатии на кнопку.
void Light() 
// Плавно включает светодиод
// Считает минуту до выключения
// Если датчик еще раз подал сигнал - начинает заного отсчитывать минуту
// Если сработал датчик(а диод уже гасится) - принимает уровень яркости при гашении и начинает с этого уровня повышать
// далее доводит до 255 и ждет минуту
{
  analogWrite(ledPin, 255);        

}
// Основная программа.
void loop() 
{
// Плавно гасит светодиод
// Считает уровень яркости
// Если сработал датчик - передает уровень яркости в верхнюю функцию
// Если датчик не сработал - гасит до 0 и ждет срабатывания
analogWrite(ledPin, 0);  
 
// Пример кода по плавному зажиганию светодиода
//  int x = 1;
//  for (int i = 0; i > -1; i = i + x){
//      analogWrite(ledPin, i);
//   }
}

 

leshak
Offline
Зарегистрирован: 29.09.2011

Прерывания, если не умеете их готовить (а судя по всему это так и есть), - вам только создадуть дополнительные проблемы.

Что из этого вы умеете?

1. Ловить нажатие кнопки (не "сейчас нажата", а именно момент "была не нажата, стала нажата")
2. Давить "дребезг кнопки".
3. Мигать светодиодом . 
4. Включать светодиод на какое-то фиксированное время 
5. Плавно менять яркость светодиода 

Пункты 2,3,4,5 в двух вариантах. Блокирую основной скетч (используя delay() и не блокирую (используя millis())

FDV
Offline
Зарегистрирован: 12.07.2014

Да я только учусь, поэтому все понемногу и в основном теория :)

(дребезг кнопки давить не нужно - сигнал цифровой)

с плавным изменением яркости светодиода проблема - циклы работают по кругу.. от 0 до 255...

Вариант без прерываний нашел тут:

http://arduino.ru/forum/programmirovanie/pomogite-novichku-napisat-programmu-dlya-upravleniya-svetodiodami

Но тоже много не понятного для меня - сможете помочь с его пониманием (прокомментировать код)

(в идеале если удалить оттуда все лишнее (датчик света и его обработку))

Просто нужно за что то зацепиться и по ходу изучения кирпичиков наращивать функции

 

leshak
Offline
Зарегистрирован: 29.09.2011

FDV пишет:

Да я только учусь, поэтому все понемногу и в основном теория :)

(дребезг кнопки давить не нужно - сигнал цифровой)

Если возьмете кнопку - будет.

FDV пишет:

Просто нужно за что то зацепиться и по ходу изучения кирпичиков наращивать функции

Ну вот я вам и перечислил пункты-кирпичики которые нужно освоить (понимать каждую строчку, а не просто "где-то найти), уметь написать код для этотих задач "если разбудили". А потом, вот из этих кирпичиков и сложится решение вашей задачи.

Идите в шапку сайта, раздел "программирование". Смотрите какие есть функции вообще (хотя-бы бегло, что-бы знать какие кирпичики вообще существуют). Смотрите примеры (там есть примеры и для пунктов из моего списка). Смотрите прикрепленную ветку для новичков про кнопки. Смотрите примеры которые идут с ардуино IDE. Хотя-бы те которые базовые (Base).

 

f69346df80
Offline
Зарегистрирован: 09.12.2014

Господи, зачем же так отчаянно заниматься самолюбованием? Это же форум, люди могут увидеть.
Человек откровенно и четко попросил конкретной помощи в конкретном проекте.
А ему в ответ какой-то неудавшийся «сэнсэй» пытается предостеречь от «дополнительных проблем», давать «оценку умений зелёного несмышлёныша», учить освоению взаправдашней техники «написать если разбудили» (и отвергать примитивную технику «где-то найти»), «раскрыть ему глаза на кирпичики» и «направить на путь истинный (в шапку)»…
Знаете, как помочь — помогите.
Не знаете, как помочь — ответ ясен.
Знаете, как помочь, но не хотите помогать  — тоже понятно.
Зачем же устраивать дешевый спектакль, указывая на отсутствие навыков у человека, просящего помощи?
Ответ типа: «Чтобы решить эту задачу, нужно сесть…    и крепко подумать».
Вот, вы, например, с ошибками пишите. Вас же не отправляют в школу грамматику осваивать, а уже потом, когда вы поднимитесь на уровень третьего класса, освоите технику письма, только потом, постепенно начинать что-то писать на форумах необъятной всемирной паутины…
Вас, наверное, неквалифицированные учителя в школе обижали. Или, может, не учителя.., и не в школе…
И, поэтому, теперь, при случае, надо стебануться над неопытным в конкретном вопросе человеком, поправив тем самым больное самолюбие.
Жалкое зрелище, от которого хочется блевать.

dimax
dimax аватар
Offline
Зарегистрирован: 25.12.2013

f69346df80, вот это вы зря так. Лешак тут много лет, и оказал неоценимую помощь начинающим. Я сам учился на его примерах и объяснениях, и очень ему благодарен. Не стоило тут регистрироваться, что бы написать эту гадость про хорошего человека.

An25
Offline
Зарегистрирован: 19.09.2014
//#include <avr/wdt.h> 

byte pins[5] = {
  10,9,6,5,3}; // массив выводов  ШИМ-сигнала на лампочки
int states[5] = {
  255,255,255,255,255}; // массив состояний датчиков лампочек здесь 255 - лампа выключена

void setup() 
{    
  // 
  // wdt_enable(WDTO_4S);
  PORTC = 0b11111;  // подтяжка входных выводов на 1 
  PORTD = 0b100;    // подтяжка входных выводов на 1
  // настройка на выход выводов
  for(byte i = 0; i < 5; i++)
    pinMode(pins[i], OUTPUT);     
}

void loop() 
{
 
    // цикл изменения состояния по каждой лампе
    for(byte i = 0; i < 5; i++)
    {
      // когда датчик очередной лампы в 1 - декримент (увеличение светимости) шим сишнала на 3 единицы 
      if((PINC&(1<<i))) states[i] -= 3;
        else 
          {
     // даже если датчик лампы неактивен, но включились другие галогенки - декримент (увеличение светимости) очередной лампы         
            if((PIND&0b100)) states[i] -= 3;
            else states[i]++;
          }        
      states[i] = constrain(states[i], 0, 255);
      analogWrite(pins[i], states[i]);
      delay(3);
    }

  
  
  //wdt_reset();
}

Работает это уже с год, как надо. Ссылка ниже. Прерывания тут конечно есть (ШИМ). Но они прозрачны для программиста Лампы - галогенки на 20Вт, их соответственно 5 штук. ШИМ усиливается 2-я RGB усилителями. За все время сгорел один канал в одном усилителе, но он изначально грелся, видимо канал был дефектным.

Там еще есть одна ножка - она следит за основным светом и если основной свет включен то и эти 5 ламп тоже загораются.

http://www.youtube.com/watch?v=66kS64uEOTU&list=UUlv_twA53DK0TKn5YMpzERA