Подсветка лестницы. Продолжение 1

Собираем первую версию прототипа автоматической подсветки лестницы на макетной плате. Эта версия почти полностью соответствует схеме из статьи Автоматическая подсветка лестницы с помощью Arduino. Скетч так же подойдёт тот же за исключением своих показаний освещённости (измеряется в "попугаях").

Что может этот прототип

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

Что ещё предстоит добавить

Необходимо доработать прототип, чтобы светодиоды загорались плавно (прикрутить ШИМ управление).
Нужно сделать режим дежурного света, когда первый и последний светодиоды загораются при снижении освещённости до определённого уровня.
Неплохо бы добавить кнопку для переключения режимов работы: всё выключено, полностью включено, автоматический режим, "весёлый" режим мигания (на случай праздника).
Самое главное, что выяснилось в процессе проработки этого проекта, - для светодиодных лент данных компонент (которые перечислены в предыдущей статье) не достаточно. Как описано в статье Автоматическая подсветка лестницы (обновление) для питания светодиодных лент длиной около метра в схему нужно добавить "каскад из hex-инвертора 74hc04 и транзисторной сборки Дарлингтона ULN2803". И хотя, я предполагаю использовать светодиодные ленты длиной 60 см, эти элементы были, на всякий случай, незамедлительно заказаны в Китае и теперь они неторопливо едут ко мне. Два тестовых отрезка светодиодной ленты были куплены там же.
Дополнительная хотелка - фиксирование событий в базе данных. Так, на всякий случай (можно рассматривать как дополнение к охранной системе). Для реализации этой задумки планируется прикрутить к схеме радиопередатчик, который будет посылать сигнал при срабатывании дальномеров, переключении режима, включении дежурного освещения первых ступенек. Ловить сигнал будет... пока не знаю точно что, скорее всего поддержу отечественного производителя и разорюсь на Контроллер домашней автоматизации Wiren Board Smart Home, в котором радиомодуль уже присутствует и возможно развернуть свой мини-сервер.

Пошаговая сборка прототипа

Перед описанием сборки этого проекта покажу, что всё действительно работает.

Подключаем линейный регулятор

Мой регулятор у продавца назывался L7805CV TO-220 Voltage Regulator 5V. Способ подключения представлен в предыдущей статье. На фото ниже видно как за "спиной" линейного регулятора спрятались три провода и конденсатор (который совсем не показался). Первый (красный) провод подводит к регулятору +12 вольт. Второй (оранжевый) провод подвёл к регулятору "минус" с шины двенадцати вольт. Жёлтый провод повёл от регулятора +5 вольт на отдельную шину пяти вольт. Спрятавшийся конденсатор номиналом 0,33 микрофарада (маркировка 334) объединил собой первую и вторую ножку регулятора. Ещё два керамических конденсатора (номиналы 0,33 и 0,1 микрофарада (этот с маркировкой 104)) попали в поле видимости на фото. Не знаю, верно ли всё подключил, но измерения мультиметром показали на выходе действительно 5 вольт.

Подключение драйвера светодиодных лент

Эта штука имеет название ST M5451B7 DIP-40 LED DISPLAY DRIVERS. Подключаем согласно схеме (на рисунке ниже) из описания M5451B7
На фотографии внизу драйвера подключены зелёный (на цифровой пин 7 arduino) и белый (на цифровой пин 6) провода. Это то, что на схеме называется "CLOCK IN" и "DATA IN" соответственно. Сверху драйвера на фото вино, что к первому пину (VDD) подключен красный провод - это +12 вольт. Второй пин драйвера (BRIGHTNESS CONTROL) так же подключен к +12 вольт через резистор номаналом 1 КОм. Последний пин в верхнем ряду драйвера на фото подключен жёлтым проводом к "минусу" двенадцати вольт. Оставшиеся пины (OUTPUT BIT) подключены к катодам (короткие ножки, "минусы") двенадцативольтовых светодиодов. Аноды (длинные ножки, "плюсы") светодиодов подключены к +12 вольт.

Подключаем дальномеры

Мои дальномеры называются Ultrasonic Module HC-SR04. Библиотека для работы с этими дальномерами и принципы подключения приведены в предыдущей статье. Тут я только уточню, к каким входам микроконтроллера подключены конкретно эти дальномеры в проекте. Верхний дальномер: Trig - на 12, Echo - на 13; нижний дальномер: Trig - на 10, Echo - на 11.

Подключаем фоторезистор

Общий принцип подключения представлен в предыдущей статье. Тут я лишь уточню, что подключил фоторезистор к A0 arduino. На фото ниже видно, что белым проводком вход A0 соединён с одной ножкой фоторезистора, к этой же ножке через резистор на 10 КОм подведён "минус". Другая ножка фоторезистора пошла на "плюс".

Мой скетч

В скетче используется библиотека для работы со светодиодным драйвером  lightuino3, взятая из пакета по ссылке. Только пришлось внести небольшую правку в эту библиотеку (иначе не компилировалось). Строку 81 дополнил словом "const". Было:
prog_uchar bitRevTable[] PROGMEM = {0,16,8,24,4,20,12,28,2,18,10,26,6,22,14,30,1,17,9,25,5,21,13,29,3,19,11,27,7,23,15,31};
Стало:
const prog_uchar bitRevTable[] PROGMEM = {0,16,8,24,4,20,12,28,2,18,10,26,6,22,14,30,1,17,9,25,5,21,13,29,3,19,11,27,7,23,15,31};

#include "lightuino3.h"
#include "Ultrasonic.h"

//Устанавливаем контакты для первого датчика
#define  TRIG_PIN  12
#define  ECHO_PIN  13
//Устанавливаем контакты для второго датчика
#define  TRIG2_PIN  10
#define  ECHO2_PIN  11
//Определяем первый датчик
Ultrasonic OurModuleUp(TRIG_PIN, ECHO_PIN);
//Определяем второй датчик
Ultrasonic OurModuleDown(TRIG2_PIN, ECHO2_PIN);
// pins 0, 1 used by Serial
const unsigned char DataPin = 6;
const unsigned char clockPin = 7;

// задержка между ступеньками
const long lightSpacing = 280;
//задержка свечения всей лестницы
const long lightHold = 10000;
//задержка выстрела сенсоров
const long pingReadDelay = 50;

// Диапазон при котором сработает сенсор
const float minBottomIn = 33.0f;
const float minTopIn = minBottomIn;

LightuinoSink sinks(clockPin, DataPin, 100, 4);

boolean bClimbStarted = false;
boolean bDescentStarted = false;

int val;
void setup() {
  Serial.begin(9600);        
  pinMode(DataPin, OUTPUT);
  pinMode(clockPin, OUTPUT);      
  delay(1000);   
  sinks.set(0,0,0);
}

void loop() {
   val = analogRead(0);
   Serial.println(val);
   //Проверяем освещенность в помещении
   if (val<=500){
   
 UltrasonicDownFire();//Выстрел нижнего датчика  
  if(bClimbStarted) {
    bClimbStarted = false;
    bDescentStarted = false;
    climbLightSequence(); 
  } 
  else {
    // Выстрел верхнего датчика
    UltrasonicUpFire();    
    if(bDescentStarted) {
      bClimbStarted = false;
      bDescentStarted = false;
      descentLightSequence(); 
    } 
  }
  delay(pingReadDelay);  
  }
}

//Обработка верхнего датчика
void UltrasonicUpFire() {

  if((OurModuleUp.Ranging(INC) < minTopIn) && (OurModuleUp.Ranging(INC) > 0)) {
    Serial.println("Top sensor tripped.");
    bDescentStarted = true;
  } 
} 

//Обработка нижнего датчика]
void UltrasonicDownFire() {
  
    if((OurModuleDown.Ranging(INC) < minTopIn) && (OurModuleDown.Ranging(INC) > 0)) {
      Serial.println("Bottom sensor tripped.");
      bClimbStarted = true;
    }
}

void climbLightSequence(){
LedsOnDown();
}
void LedsOnDown(){
  //Обнуляем
   byte ledState[9];
  for (int j=0;j<9;j++) {
    ledState[j] = B00000000;
  }
  //Зажигаем
  for (int k=1;k>=0;k--)
  {
  for (int j=8;j>=1;j--)    
  {
   ledState[k] = (ledState[k] >> 1) + 128;
    sinks.set(ledState); 
    delay(lightSpacing);
  }
     }
//Задержка
  delay(lightHold);
//Гасим   
  for (int k=1;k>=0;k--)
  {
  for (int j=8;j>=1;j--)    
    {
    ledState[k] = (ledState[k] >> 1);
    sinks.set(ledState); 
    delay(lightSpacing);
    }
  }
 delay(pingReadDelay);  
}

void descentLightSequence(){
  LedsOnUp();
} 

void LedsOnUp(){
 //Обнуляем
  byte ledState[9];
  for (int j=0;j<9;j++) {
    ledState[j] = B00000000;
  }
 //Зажигаем
  for (int k=0;k<=1;k++)
  {
  for (int j=0;j<9;j++)    
  {
    ledState[k]=(ledState[k] << 1) + 1;
    sinks.set(ledState);          
     delay(lightSpacing);
  }    }
  delay(lightHold);
  for (int k=0;k<=1;k++)
  {
  for (int j=0;j<9;j++)    
  {
    ledState[k]=(ledState[k] << 1);
    sinks.set(ledState);          
     delay(lightSpacing);
  }    
}
 delay(pingReadDelay);  
}


Комментарии

  1. Хорошая статья! А как насчёт ШИМ?

    ОтветитьУдалить
    Ответы
    1. Светодиодный драйвер M5451 умеет плавно зажигать/тушить своих подопечных. Как это реализуется на практике опишу в "Продолжении 2". Пока (как находится время) делаю платку со всей обвязкой для светодиодных лент.

      Удалить
  2. У меня имеется М5450. Она тоже умеет плавно зажигать? Жду с нетерпением продолжения проекта)

    ОтветитьУдалить
    Ответы
    1. Различия между этими драйверами минимальные. Так что почти все возможности и трудности совпадают. На макетке я собрал схемку, где плавное зажигание/гашение работали (программа чужая из тырнета), но уже успел всё разобрать. Но зарисовал всё в Fritzing и пытаюсь найти время всё это спаять. А вот с программой мне ещё предстоит разбираться, т.к. мои хотелки несколько больше, чем те примеры, которые нашлись.

      Удалить
  3. Нескромный вопрос: когда можно ожидать готовую третью часть? заранее спасибо. P.S. наглость второе счастье

    ОтветитьУдалить
    Ответы
    1. Ох, медленно дело продвигается :-( До готового установленного изделия ещё далеко. Но в ближайшие пару недель выложу "Продолжение 2" по "железу" - плата с транзисторами uln2803 и инверторами логики 74hc04. За окончательную программу ещё не брался.

      Удалить
  4. И снова здравствуйте. Подскажите пожалуйста, как регулировать количество ступенек на даном этапе?

    ОтветитьУдалить
    Ответы
    1. В данной программе из статьи отдельной переменной для количества ступенек нет. За количество "ступенек" отвечают наибольшие числа в циклах за комментариями "//Обнуляем", "//Зажигаем", "//Гасим". Там стоит "9" (в некоторых местах 9-1="8") - вместо девяти поставьте ваше количество ступенек.

      Удалить
  5. здравствуйте, помогите разобраться в ошибке Arduino: 1.6.5 (Windows XP), Плата"Arduino Uno"

    In file included from C:\Documents and Settings\Loner\Мои документы\Arduino\libraries\lightuino5/lightuino3.h:28:0,
    from sketch_jul21c.ino:1:
    C:\Documents and Settings\Loner\Мои документы\Arduino\libraries\lightuino5/lightuinoSink.h:158:31: error: 'prog_uchar' has not been declared
    AniPattern(Lightuino& shld, prog_uchar* anim,prog_uint16_t* delayLst, int total_frames): shield(shld) {flags=0; delays=delayLst; ani=anim; numFrames=total_frames; curFrame=0; curDelay=0; anidir=1;}
    ^
    C:\Documents and Settings\Loner\Мои документы\Arduino\libraries\lightuino5/lightuinoSink.h:158:48: error: 'prog_uint16_t' has not been declared
    AniPattern(Lightuino& shld, prog_uchar* anim,prog_uint16_t* delayLst, int total_frames): shield(shld) {flags=0; delays=delayLst; ani=anim; numFrames=total_frames; curFrame=0; curDelay=0; anidir=1;}
    ^
    C:\Documents and Settings\Loner\Мои документы\Arduino\libraries\lightuino5/lightuinoSink.h:166:3: error: 'prog_uchar' does not name a type
    prog_uchar* ani;
    ^
    C:\Documents and Settings\Loner\Мои документы\Arduino\libraries\lightuino5/lightuinoSink.h:167:3: error: 'prog_uint16_t' does not name a type
    prog_uint16_t* delays;
    ^
    C:\Documents and Settings\Loner\Мои документы\Arduino\libraries\lightuino5/lightuinoSink.h: In constructor 'AniPattern::AniPattern(Lightuino&, int*, int*, int)':
    C:\Documents and Settings\Loner\Мои документы\Arduino\libraries\lightuino5/lightuinoSink.h:158:115: error: 'delays' was not declared in this scope
    AniPattern(Lightuino& shld, prog_uchar* anim,prog_uint16_t* delayLst, int total_frames): shield(shld) {flags=0; delays=delayLst; ani=anim; numFrames=total_frames; curFrame=0; curDelay=0; anidir=1;}
    ^
    C:\Documents and Settings\Loner\Мои документы\Arduino\libraries\lightuino5/lightuinoSink.h:158:132: error: 'ani' was not declared in this scope
    AniPattern(Lightuino& shld, prog_uchar* anim,prog_uint16_t* delayLst, int total_frames): shield(shld) {flags=0; delays=delayLst; ani=anim; numFrames=total_frames; curFrame=0; curDelay=0; anidir=1;}
    ^
    Ошибка компиляции.

    Это сообщение будет содержать больше информации чем
    "Отображать вывод во время компиляции"
    включено в Файл > Настройки

    ОтветитьУдалить
    Ответы
    1. Я пока проверить не могу. Видимо, в какой-то момент изменились доступные типы переменных в языке программирования для Arduino. Возможно, поможет, изменить "prog_uchar" на "const unsigned char", а "prog_uint16_t" на "const uint16_t". Я постараюсь выяснить и добавить в статью это.

      Удалить
  6. Олег,
    здравствуйте!
    Планировал установку контроллера у себя в доме. Прошу Вас написать мне на эл.почту ovchinnikovr собака mail.ru . Надеюсь, что получится посотрудничать.

    ОтветитьУдалить
  7. Hello
    I'm trying to build this project but stummble on some problems. when importing sketch i get errors related to lightuino library.

    n file included from C:\Users\User\Documents\Arduino\libraries\lightuino5/lightuino3.h:28:0,
    from rujo_novo.ino:1:
    C:\Users\User\Documents\Arduino\libraries\lightuino5/lightuinoSink.h:158:31: error: 'prog_uchar' has not been declared
    AniPattern(Lightuino& shld, prog_uchar* anim,prog_uint16_t* delayLst, int total_frames): shield(shld) {flags=0; delays=delayLst; ani=anim; numFrames=total_frames; curFrame=0; curDelay=0; anidir=1;}
    ^
    C:\Users\User\Documents\Arduino\libraries\lightuino5/lightuinoSink.h:158:48: error: 'prog_uint16_t' has not been declared
    AniPattern(Lightuino& shld, prog_uchar* anim,prog_uint16_t* delayLst, int total_frames): shield(shld) {flags=0; delays=delayLst; ani=anim; numFrames=total_frames; curFrame=0; curDelay=0; anidir=1;}
    ^
    C:\Users\User\Documents\Arduino\libraries\lightuino5/lightuinoSink.h:166:3: error: 'prog_uchar' does not name a type
    prog_uchar* ani;
    ^
    C:\Users\User\Documents\Arduino\libraries\lightuino5/lightuinoSink.h:167:3: error: 'prog_uint16_t' does not name a type
    prog_uint16_t* delays;
    ^
    C:\Users\User\Documents\Arduino\libraries\lightuino5/lightuinoSink.h: In constructor 'AniPattern::AniPattern(Lightuino&, int*, int*, int)':
    C:\Users\User\Documents\Arduino\libraries\lightuino5/lightuinoSink.h:158:115: error: 'delays' was not declared in this scope
    AniPattern(Lightuino& shld, prog_uchar* anim,prog_uint16_t* delayLst, int total_frames): shield(shld) {flags=0; delays=delayLst; ani=anim; numFrames=total_frames; curFrame=0; curDelay=0; anidir=1;}
    ^
    C:\Users\User\Documents\Arduino\libraries\lightuino5/lightuinoSink.h:158:132: error: 'ani' was not declared in this scope
    AniPattern(Lightuino& shld, prog_uchar* anim,prog_uint16_t* delayLst, int total_frames): shield(shld) {flags=0; delays=delayLst; ani=anim; numFrames=total_frames; curFrame=0; curDelay=0; anidir=1;}
    ^
    rujo_novo.ino: In function 'void UltrasonicUpFire()':
    rujo_novo:70: error: 'class Ultrasonic' has no member named 'Ranging'
    rujo_novo:70: error: 'INC' was not declared in this scope
    rujo_novo:70: error: 'class Ultrasonic' has no member named 'Ranging'
    rujo_novo.ino: In function 'void UltrasonicDownFire()':
    rujo_novo:80: error: 'class Ultrasonic' has no member named 'Ranging'
    rujo_novo:80: error: 'INC' was not declared in this scope
    rujo_novo:80: error: 'class Ultrasonic' has no member named 'Ranging'


    Any pointers??

    ОтветитьУдалить
    Ответы
    1. Old var types work fine in Arduino IDE 1.0.5. If you are using a newer version of the program, you will need to replace all older types of variables to supported from the list: https://www.arduino.cc/en/Reference/HomePage (Data Types). For example: prog_uchar -> unsigned char; prog_uint16_t -> unsigned int.

      Удалить

Отправить комментарий

Популярные сообщения из этого блога

Пропорциональное распределение суммы

Битрикс: своя геолокация

Bitrix24 API - разбор демо приложения третьего типа