Автоматическая подсветка лестницы и MM5450

Brutal
Offline
Зарегистрирован: 14.03.2013

Уважаемый maksim. А подскажите еще плиз неуку ;) У меня в планах есть смена конструкции и соответсвенно колличесва ступенек лестницы. Если я правильно понял то колличество загораемых светиков указываются в строках:

for(char i = 19; i >= 0; i--) // зажигаем светодиоды в одну сторону

for(char i = 0; i <= 20; i++)  // тушим светодиоды

Тоесть, если у меня будет, к примеру, 25 ступеней то надо будет только сменить на:

for(char i = 24; i >= 0; i--) // зажигаем светодиоды в одну сторону

for(char i = 0; i <= 25; i++)  // тушим светодиоды

Верно ? Или еще гдето что то ?

Заранее благодарен !

 

maksim
Offline
Зарегистрирован: 12.02.2012

Нет не только. Еще нужно изменить вывод в MM5450:

void MM5450(uint32_t data)
{  
  digitalWrite(DATA, 1);
  digitalWrite(CLOCK, LOW);
  digitalWrite(CLOCK, HIGH);
  for(byte i = 0; i < 25; i++)
  {
    if(data & (1UL<<i)) digitalWrite(DATA, HIGH);
    else digitalWrite(DATA, LOW);
    digitalWrite(CLOCK, LOW);
    digitalWrite(CLOCK, HIGH);
  }
  digitalWrite(DATA, 0);
  for(byte i = 0; i < 10; i++)
  {    
    digitalWrite(CLOCK, LOW);
    digitalWrite(CLOCK, HIGH);
  }
}

Вот код, в котором можно задать количество светодиодов

//Устанавливаем контакты для первого датчика
#define  T1  12
#define  E1  13
//Устанавливаем контакты для второго датчика
#define  T2  10
#define  E2  11
//Устанавливаем контакты для драйвера
#define  DATA  6
#define  CLOCK 7
//Устанавливаем контакт фоторезистора
#define  FOTO A0

//Задаем количество светодиодов
#define NUM_LEDS 20

const uint32_t mask = 0b11111111111111111111;

void setup() 
{
  pinMode(T1, OUTPUT);
  pinMode(T2, OUTPUT);
  pinMode(E1, INPUT);
  pinMode(DATA, OUTPUT);
  pinMode(CLOCK, OUTPUT);
  digitalWrite(CLOCK, HIGH);
  digitalWrite(FOTO, HIGH);
}

void loop() 
{
  static bool state;
  if(analogRead(FOTO) > 1000) state = 1; // порог освещенности включения
  if(analogRead(FOTO) < 990) state = 0; // порог освещенности выключения
  if(state)
  {
    int D1 = Ultrasonic(T1, E1);    // измеряем расстояние первого датчика
    if(D1 > 0 && D1 < 100)          // если расстояние меньше 100см, то
    {
      for(char i = NUM_LEDS-1; i >= 0; i--) // зажигаем светодиоды в одну сторону
      {
        MM5450(mask<<i);
        delay(100);                 // задержка зажигания
      }
      delay(3000);                  // ждем 3 секунды
      for(char i = 0; i <= NUM_LEDS; i++)  // тушим светодиоды 
      {
        MM5450(mask>>i);
        delay(100);                 // задержка затухания
      }
    }

    int D2 = Ultrasonic(T2, E2);    // измеряем расстояние второго датчика
    if(D2 > 0 && D2 < 100)          // если расстояние меньше 100см, то
    {
      for(char i = NUM_LEDS-1; i >= 0; i--) // зажигаем светодиоды в другую сторону
      {
        MM5450(mask>>i);
        delay(100);                 // задержка зажигания
      }
      delay(3000);                  // ждем 3 секунды
      for(char i = 0; i <= NUM_LEDS; i++)  // тушим светодиоды 
      {
        MM5450(mask<<i);
        delay(100);                 // задержка затухания
      }
    }
  }
  delay(20);
}


int Ultrasonic(byte Trig_pin, byte Echo_pin)
{
  digitalWrite(Trig_pin, HIGH);
  delayMicroseconds(10);
  digitalWrite(Trig_pin, LOW);   
  return pulseIn(Echo_pin, HIGH, 20000)/29.0/2;
}

void MM5450(uint32_t data)
{  
  digitalWrite(DATA, 1);
  digitalWrite(CLOCK, LOW);
  digitalWrite(CLOCK, HIGH);
  for(byte i = 0; i < NUM_LEDS; i++)
  {
    if(data & (1UL<<i)) digitalWrite(DATA, HIGH);
    else digitalWrite(DATA, LOW);
    digitalWrite(CLOCK, LOW);
    digitalWrite(CLOCK, HIGH);
  }
  digitalWrite(DATA, 0);
  for(byte i = 0; i < 35-NUM_LEDS; i++)
  {    
    digitalWrite(CLOCK, LOW);
    digitalWrite(CLOCK, HIGH);
  }
}

 

Brutal
Offline
Зарегистрирован: 14.03.2013

maksim пишет:

Нет не только. Еще нужно изменить вывод в MM5450:

void MM5450(uint32_t data)
{  
  digitalWrite(DATA, 1);
  digitalWrite(CLOCK, LOW);
  digitalWrite(CLOCK, HIGH);
  for(byte i = 0; i < 25; i++)
  {
    if(data & (1UL<<i)) digitalWrite(DATA, HIGH);
    else digitalWrite(DATA, LOW);
    digitalWrite(CLOCK, LOW);
    digitalWrite(CLOCK, HIGH);
  }
  digitalWrite(DATA, 0);
  for(byte i = 0; i < 10; i++)
  {    
    digitalWrite(CLOCK, LOW);
    digitalWrite(CLOCK, HIGH);
  }
}

Вот код, в котором можно задать количество светодиодов

//Устанавливаем контакты для первого датчика
#define  T1  12
#define  E1  13
//Устанавливаем контакты для второго датчика
#define  T2  10
#define  E2  11
//Устанавливаем контакты для драйвера
#define  DATA  6
#define  CLOCK 7
//Устанавливаем контакт фоторезистора
#define  FOTO A0

//Задаем количество светодиодов
#define NUM_LEDS 20

const uint32_t mask = 0b11111111111111111111;

void setup() 
{
  pinMode(T1, OUTPUT);
  pinMode(T2, OUTPUT);
  pinMode(E1, INPUT);
  pinMode(DATA, OUTPUT);
  pinMode(CLOCK, OUTPUT);
  digitalWrite(CLOCK, HIGH);
  digitalWrite(FOTO, HIGH);
}

void loop() 
{
  static bool state;
  if(analogRead(FOTO) > 1000) state = 1; // порог освещенности включения
  if(analogRead(FOTO) < 990) state = 0; // порог освещенности выключения
  if(state)
  {
    int D1 = Ultrasonic(T1, E1);    // измеряем расстояние первого датчика
    if(D1 > 0 && D1 < 100)          // если расстояние меньше 100см, то
    {
      for(char i = NUM_LEDS-1; i >= 0; i--) // зажигаем светодиоды в одну сторону
      {
        MM5450(mask<<i);
        delay(100);                 // задержка зажигания
      }
      delay(3000);                  // ждем 3 секунды
      for(char i = 0; i <= NUM_LEDS; i++)  // тушим светодиоды 
      {
        MM5450(mask>>i);
        delay(100);                 // задержка затухания
      }
    }

    int D2 = Ultrasonic(T2, E2);    // измеряем расстояние второго датчика
    if(D2 > 0 && D2 < 100)          // если расстояние меньше 100см, то
    {
      for(char i = NUM_LEDS-1; i >= 0; i--) // зажигаем светодиоды в другую сторону
      {
        MM5450(mask>>i);
        delay(100);                 // задержка зажигания
      }
      delay(3000);                  // ждем 3 секунды
      for(char i = 0; i <= NUM_LEDS; i++)  // тушим светодиоды 
      {
        MM5450(mask<<i);
        delay(100);                 // задержка затухания
      }
    }
  }
  delay(20);
}


int Ultrasonic(byte Trig_pin, byte Echo_pin)
{
  digitalWrite(Trig_pin, HIGH);
  delayMicroseconds(10);
  digitalWrite(Trig_pin, LOW);   
  return pulseIn(Echo_pin, HIGH, 20000)/29.0/2;
}

void MM5450(uint32_t data)
{  
  digitalWrite(DATA, 1);
  digitalWrite(CLOCK, LOW);
  digitalWrite(CLOCK, HIGH);
  for(byte i = 0; i < NUM_LEDS; i++)
  {
    if(data & (1UL<<i)) digitalWrite(DATA, HIGH);
    else digitalWrite(DATA, LOW);
    digitalWrite(CLOCK, LOW);
    digitalWrite(CLOCK, HIGH);
  }
  digitalWrite(DATA, 0);
  for(byte i = 0; i < 35-NUM_LEDS; i++)
  {    
    digitalWrite(CLOCK, LOW);
    digitalWrite(CLOCK, HIGH);
  }
}

 

Ухты. Клево ! Спасибо !!! Проверю с понедельника (с работы не забрал девайсик).

Rimidalw
Offline
Зарегистрирован: 04.04.2012

Вот отлично вы переписали код)) Скажите пожалуйста а как вот такой алгоритм можно написать http://www.youtube.com/watch?feature=player_detailpage&v=iBY_xXPOZmg#t=155s ??

Rimidalw
Offline
Зарегистрирован: 04.04.2012

И еще вопрос к Максиму. Чем плоха библиотека Ultrasonic?

Rimidalw
Offline
Зарегистрирован: 04.04.2012

Есть кстати такой вариант http://www.youtube.com/watch?v=udkavy8vv30 Как мы видим реализована одновременная обработка датчиков и анимация идет на встречу.

maksim
Offline
Зарегистрирован: 12.02.2012

Rimidalw пишет:

И еще вопрос к Максиму. Чем плоха библиотека Ultrasonic?

Тем что ее можно заменить четырьмя строками.

maksim
Offline
Зарегистрирован: 12.02.2012

На всех видео применяется диммирование. Чтобы получить диммирование на MM5450 нужно генерить ШИМ на ее выводах, а это уже другая история... 

Brutal
Offline
Зарегистрирован: 14.03.2013

Rimidalw пишет:

Вот отлично вы переписали код)) Скажите пожалуйста а как вот такой алгоритм можно написать http://www.youtube.com/watch?feature=player_detailpage&v=iBY_xXPOZmg#t=155s ??

Плавное затухание и заграние можно реализовать, но в моем варианте яркость задана постоянная (схематически резистором 1К на 19 ногу драйвера светодиодов). Нужно переделать немного схему и само собой скетч. По вопросу скетча - ето у нас Maksim спец ! Когда зажигаеться с двух сторон к средине, по моему не практичен. Мне понравился вариант движения части подсветки, а не всей лестницы под идущим. Красиво, но меня вполне устраивает и уже написанный скетч (спасибо Maksim) Конечно, как вариант на будущее, для смены эффектов можно бы :).

Rimidalw
Offline
Зарегистрирован: 04.04.2012

maksim пишет:

На всех видео применяется диммирование. Чтобы получить диммирование на MM5450 нужно генерить ШИМ на ее выводах, а это уже другая история... 

А если без шим? Огоньки идут навстречу а потом расходятся.

maksim
Offline
Зарегистрирован: 12.02.2012

Есть множество способов как это реализовать ,самый простой это объявить массив состояний светодиодов и выводить их поочередно:

//Устанавливаем контакты для первого датчика
#define  T1  12
#define  E1  13
//Устанавливаем контакты для второго датчика
#define  T2  10
#define  E2  11
//Устанавливаем контакты для драйвера
#define  DATA  6
#define  CLOCK 7
//Устанавливаем контакт фоторезистора
#define  FOTO A0

//Задаем количество светодиодов
#define NUM_LEDS 20

const uint32_t mask[] = {
  0b00000000000000000000,
  0b10000000000000000001,
  0b11000000000000000011,
  0b11100000000000000111,
  0b11110000000000001111,
  0b11111000000000011111,
  0b11111100000000111111,
  0b11111110000001111111,
  0b11111111000011111111,
  0b11111111100111111111,
  0b11111111111111111111,
};

void setup() 
{
  pinMode(T1, OUTPUT);
  pinMode(T2, OUTPUT);
  pinMode(E1, INPUT);
  pinMode(DATA, OUTPUT);
  pinMode(CLOCK, OUTPUT);
  digitalWrite(CLOCK, HIGH);
  digitalWrite(FOTO, HIGH);
}

void loop() 
{
  static bool state;
  if(analogRead(FOTO) > 1000) state = 1; // порог освещенности включения
  if(analogRead(FOTO) < 990) state = 0; // порог освещенности выключения
  if(state)
  {
    int D1 = Ultrasonic(T1, E1);    // измеряем расстояние первого датчика
    int D2 = Ultrasonic(T2, E2);    // измеряем расстояние второго датчика
    if(D1 > 0 && D1 < 100 || D2 > 0 && D2 < 100)          // если расстояние меньше 100см, то
    {
      for(char i = 1; i < 11; i++) // зажигаем светодиоды в другую сторону
      {
        MM5450(mask[i]);
        delay(100);                 // задержка зажигания
      }
      delay(3000);                  // ждем 3 секунды
      for(char i = 9; i >= 0; i--)  // тушим светодиоды 
      {
        MM5450(mask[i]);
        delay(100);                 // задержка затухания
      }
    }
  }
  delay(20);
}


int Ultrasonic(byte Trig_pin, byte Echo_pin)
{
  digitalWrite(Trig_pin, HIGH);
  delayMicroseconds(10);
  digitalWrite(Trig_pin, LOW);   
  return pulseIn(Echo_pin, HIGH, 20000)/29.0/2;
}

void MM5450(uint32_t data)
{  
  digitalWrite(DATA, 1);
  digitalWrite(CLOCK, LOW);
  digitalWrite(CLOCK, HIGH);
  for(byte i = 0; i < NUM_LEDS; i++)
  {
    if(data & (1UL<<i)) digitalWrite(DATA, HIGH);
    else digitalWrite(DATA, LOW);
    digitalWrite(CLOCK, LOW);
    digitalWrite(CLOCK, HIGH);
  }
  digitalWrite(DATA, 0);
  for(byte i = 0; i < 35-NUM_LEDS; i++)
  {    
    digitalWrite(CLOCK, LOW);
    digitalWrite(CLOCK, HIGH);
  }
}

 

Brutal
Offline
Зарегистрирован: 14.03.2013

maksim пишет:

Есть множество способов как это реализовать ,самый простой это объявить массив состояний светодиодов и выводить их поочередно:

//Устанавливаем контакты для первого датчика
#define  T1  12
#define  E1  13
//Устанавливаем контакты для второго датчика
#define  T2  10
#define  E2  11
//Устанавливаем контакты для драйвера
#define  DATA  6
#define  CLOCK 7
//Устанавливаем контакт фоторезистора
#define  FOTO A0

//Задаем количество светодиодов
#define NUM_LEDS 20

const uint32_t mask[] = {
  0b00000000000000000000,
  0b10000000000000000001,
  0b11000000000000000011,
  0b11100000000000000111,
  0b11110000000000001111,
  0b11111000000000011111,
  0b11111100000000111111,
  0b11111110000001111111,
  0b11111111000011111111,
  0b11111111100111111111,
  0b11111111111111111111,
};

void setup() 
{
  pinMode(T1, OUTPUT);
  pinMode(T2, OUTPUT);
  pinMode(E1, INPUT);
  pinMode(DATA, OUTPUT);
  pinMode(CLOCK, OUTPUT);
  digitalWrite(CLOCK, HIGH);
  digitalWrite(FOTO, HIGH);
}

void loop() 
{
  static bool state;
  if(analogRead(FOTO) > 1000) state = 1; // порог освещенности включения
  if(analogRead(FOTO) < 990) state = 0; // порог освещенности выключения
  if(state)
  {
    int D1 = Ultrasonic(T1, E1);    // измеряем расстояние первого датчика
    int D2 = Ultrasonic(T2, E2);    // измеряем расстояние второго датчика
    if(D1 > 0 && D1 < 100 || D2 > 0 && D2 < 100)          // если расстояние меньше 100см, то
    {
      for(char i = 1; i < 11; i++) // зажигаем светодиоды в другую сторону
      {
        MM5450(mask[i]);
        delay(100);                 // задержка зажигания
      }
      delay(3000);                  // ждем 3 секунды
      for(char i = 9; i >= 0; i--)  // тушим светодиоды 
      {
        MM5450(mask[i]);
        delay(100);                 // задержка затухания
      }
    }
  }
  delay(20);
}


int Ultrasonic(byte Trig_pin, byte Echo_pin)
{
  digitalWrite(Trig_pin, HIGH);
  delayMicroseconds(10);
  digitalWrite(Trig_pin, LOW);   
  return pulseIn(Echo_pin, HIGH, 20000)/29.0/2;
}

void MM5450(uint32_t data)
{  
  digitalWrite(DATA, 1);
  digitalWrite(CLOCK, LOW);
  digitalWrite(CLOCK, HIGH);
  for(byte i = 0; i < NUM_LEDS; i++)
  {
    if(data & (1UL<<i)) digitalWrite(DATA, HIGH);
    else digitalWrite(DATA, LOW);
    digitalWrite(CLOCK, LOW);
    digitalWrite(CLOCK, HIGH);
  }
  digitalWrite(DATA, 0);
  for(byte i = 0; i < 35-NUM_LEDS; i++)
  {    
    digitalWrite(CLOCK, LOW);
    digitalWrite(CLOCK, HIGH);
  }
}

 

Спаисибо! Пробовал скетчик - работает.

Rimidalw
Offline
Зарегистрирован: 04.04.2012

Решение конечно хорошее, но вот если изменить кол-во ступеней нужно будет массив перерисовывать. Я сделал по другому. Один цикл из рассчета кол-во ступеней/2, первую и последнюю зажигаем, вторую и пердпоследнюю зажигаем и тд., а потом наоборот тушим.

Brutal
Offline
Зарегистрирован: 14.03.2013

А как сделать что бы подсветка двигалась под идущим ? Вот как в этом ролике с 3 мин. 12 сек. https://www.youtube.com/watch?v=iBY_xXPOZmg

Serg010
Offline
Зарегистрирован: 19.04.2013

А как все таки реализовать ШИМ на MM5450 ?

Brutal
Offline
Зарегистрирован: 14.03.2013

А вот тут (тот же автор -  Лукьянов с помощью...) реализовал с подсветку с ШИМ ...

Serg010
Offline
Зарегистрирован: 19.04.2013

Не совсем понятно: аппаратно или программно? Конденсатор на 19 ноге драйвера? Но ведь этим задается постоянная общая яркость. 

Если предположить что программно - то обновленный код автор (Лукьянов) не выложил.

stadik
Offline
Зарегистрирован: 09.05.2013

Здраствуйте ! Подскажите пожалуста - как сделать чтоб вместо датчиков растояния можно было поставить физические контакты (кнопки) ?

VitaliyD
Offline
Зарегистрирован: 10.05.2013

Мне кажется автор использовал микруху m5451 с аппаратной поддержкой ШИМ, заказал одну из таких теперь как придут буду колдовать со скетчем

Brutal
Offline
Зарегистрирован: 14.03.2013

stadik пишет:

Здраствуйте ! Подскажите пожалуста - как сделать чтоб вместо датчиков растояния можно было поставить физические контакты (кнопки) ?

Видел где то я в нете с кнопками. А реализовать - даже проще чем с датчиками, так как, для датчика куск скетча больше, а для кнопок нужно будет только "дребезг крнтактов" убрать....

VitaliyD
Offline
Зарегистрирован: 10.05.2013

Brutal пишет:

Видел где то я в нете с кнопками. А реализовать - даже проще чем с датчиками, так как, для датчика куск скетча больше, а для кнопок нужно будет только "дребезг крнтактов" убрать....

Верно про дребезжание подмечено раньше очень часто забывал и из за этого проект неработоспособен. Но сейчас юзаю debounce библиотеку с ней думаю значительно сократиться код.

stadik
Offline
Зарегистрирован: 09.05.2013

Здраствуйте ! Мучаюсь уже месяц и никак не могу сделать рабочий проект с контактами вместо дальномеров  ! Если можно - дайте код для такой схемы ! Буду очень признателен.

VitaliyD
Offline
Зарегистрирован: 10.05.2013

Уже второй день колдую с драйвером m5451b7 все никак не разберусь с управлением яркостью, хочется сделать плавный поджиг, может у кого есть информация как управляться с данным драйвером, заранее спасибо

Brutal
Offline
Зарегистрирован: 14.03.2013

Яркость задаеться резистором на 19 ногу мелкосхемы.

Serg010
Offline
Зарегистрирован: 19.04.2013

Просто резистор на 19 ноге задает общую (и постоянную) яркость для всех каналов. Для плавного (и раздельного) поджига нужен ШИМ сигнал с ардуины, ну и соответственно код.

Serg010
Offline
Зарегистрирован: 19.04.2013

Что, тема закончилась? Никто не смог сделать плавный поджиг. :((

VitaliyD
Offline
Зарегистрирован: 10.05.2013

Кстати тему хотелось бы поднять, так как времени не особо много было почти не занимался, думаю его не составит труда добавить просто когда на драйвере M5451 Clock pin не защелкнут можно добавить плавный поджиг на ноге brightness через оператор FOR, вечером попробую отпишусь

denyang
Offline
Зарегистрирован: 05.08.2013

Похоже тема закрылась.... очень жаль что не удалось реализовать плавный поджиг

VitaliyD
Offline
Зарегистрирован: 10.05.2013

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

denyang
Offline
Зарегистрирован: 05.08.2013

Ну хотя бы сам принцип планого поджига расскажи

maksim
Offline
Зарегистрирован: 12.02.2012

Принцип примерно такой Широтно-импульсная модуляция только реализовать ее надо на M5450. Запускаете SPI на 8 МГц и в прерывании по таймеру формируете программный ШИМ. Примерно как тут Программный ШИМ на сдвиговом регистре

 

denyang
Offline
Зарегистрирован: 05.08.2013

Спасибо :) буду думать :)

 

denyang
Offline
Зарегистрирован: 05.08.2013

Спасибо :) буду думать :)

 

Serg010
Offline
Зарегистрирован: 19.04.2013

А вот есть такая штука - PCA9685 (16-канальный контроллер светодиодов с 12-разрядными ШИМ, управляемый посредством шины I²C) http://catalog.gaw.ru/index.php?page=component_detail&id=64764

denyang
Offline
Зарегистрирован: 05.08.2013

у PCA9685 каналов маловато.. мне нужно на 18 ступеней  

maksim
Offline
Зарегистрирован: 12.02.2012

analogWrite() на любом выводе + 2 шт. SHARP2Y0A02 и будет вам плавной разгорание, затухание 18 каналов без доп.микросхем, если на канал не более двух светодиодов подключите. Если больше двух или светодиодную ленту, то нужны ключи или сборки например 3 шт. ULN2003.

 

denyang
Offline
Зарегистрирован: 05.08.2013

Да блин уже приобрел М5451.... 

maksim
Offline
Зарегистрирован: 12.02.2012

Так у М5451 ток на канал тоже всего 15 мА и если подключать ленту, то все равно нужны ключи.

Serg010
Offline
Зарегистрирован: 19.04.2013

Библиотека от Maksima тоже вариант. Теперь другой вопрос - как с помощью кнопок сделать оперативные регулировки скорости перетекания.

pkv
Offline
Зарегистрирован: 20.08.2013

maksim пишет:

Так у М5451 ток на канал тоже всего 15 мА и если подключать ленту, то все равно нужны ключи.

Максим, подскажи, а принцип работы сборок ULN2003, точнее неправильно.. как эти  сборки подключать?

я правильно понимаю:

ноги 8 - это земля для БП лент, 10-16 - сигнальные от ардуины, 1-7 - минус от св. лент?

еще в описании на ULN2003 нашел цифру VCE = 50V, VI = 30A, т.е. максимальная нагрузка может быть 50*30 = 1500W ? 
PS: Или эти обозначения что-то другое указывают?..

pkv
Offline
Зарегистрирован: 20.08.2013

В тему никто не заглядывает что ль?

С ULNками разобрался.. 500мА на канал оказывается.

Сегодня хотел проверить работу драйвера, собрал на макетной плате следующее:

и залил скейч:



//Устанавливаем контакты для драйвера
#define  DATA  6
#define  CLOCK 7
//Устанавливаем контакт фоторезистора
//#define  FOTO A0

//Задаем количество светодиодов
#define NUM_LEDS 20

const uint32_t mask = 0b11111111111111111111;

void setup() 
{
  //pinMode(T1, OUTPUT);
  //pinMode(T2, OUTPUT);
  //pinMode(E1, INPUT);
  pinMode(DATA, OUTPUT);
  pinMode(CLOCK, OUTPUT);
  digitalWrite(CLOCK, HIGH);
  //digitalWrite(FOTO, HIGH);
}

void loop() 
{
  //static bool state;
  //if(analogRead(FOTO) > 1000) state = 1; // порог освещенности включения
  //if(analogRead(FOTO) < 990) state = 0; // порог освещенности выключения

      for(char i = NUM_LEDS-1; i >= 0; i--) // зажигаем светодиоды в одну сторону
      {
        MM5450(mask<<i);
        delay(100);                 // задержка зажигания
      }
      delay(300);                  // ждем 3 секунды
      for(char i = 0; i <= NUM_LEDS; i++)  // тушим светодиоды 
      {
        MM5450(mask>>i);
        delay(100);                 // задержка затухания
      }
}


void MM5450(uint32_t data)
{  
  digitalWrite(DATA, 1);
  digitalWrite(CLOCK, LOW);
  digitalWrite(CLOCK, HIGH);
  for(byte i = 0; i < NUM_LEDS; i++)
  {
    if(data & (1UL<<i)) digitalWrite(DATA, HIGH);
    else digitalWrite(DATA, LOW);
    digitalWrite(CLOCK, LOW);
    digitalWrite(CLOCK, HIGH);
  }
  digitalWrite(DATA, 0);
  for(byte i = 0; i < 35-NUM_LEDS; i++)
  {    
    digitalWrite(CLOCK, LOW);
    digitalWrite(CLOCK, HIGH);
  }
}

в итоге светодиоды не загораются. В чем может быть проблема?

pkv
Offline
Зарегистрирован: 20.08.2013

UPD: 

Подключил светодиод напрямую к 6 ноге ардуины - моргает, к 7 ноге - горит. Т.е. код выполняется.. как проверить исправен ли сам драйвер или он у меня некорректно подключен?..

 

UPD2: Разобрался :) 

Светодиоды подключал неправильно, надо: от ног драйвера подключать "-", а от второго вывода светодиода на "+" от ардуины.

Zirex
Offline
Зарегистрирован: 07.11.2013

Максим, здравствуйте! 

Подскажите пожалуйста, как правильно сделать вариант, когда человек (или несколько) остановился на лестнице?

Я понимаю так, что надо считать сведения с нижнего датчика несколько раз (приближается человек или отдаляется), записать в какой нибудь регистр 1, и зажигать светодиоды. Если за ним поднялся второй то добавить к этому регистру 1. Если с верхнего датчика тоже пошли два человека, то записать ещё 2 в этот регистр. И если человек спустился и отдаляется, то вычитать из этого регистра 1. В логике, конечно я это придумал, но как это правильно написать?

Zirex
Offline
Зарегистрирован: 07.11.2013

Вы в этом(20) посте выдвигаете эту идею, но если одновременно пойдет два человека, то лестница погаснет.

Aleksandr2013
Offline
Зарегистрирован: 29.11.2013

maksim пишет:

Принцип примерно такой Широтно-импульсная модуляция только реализовать ее надо на M5450. Запускаете SPI на 8 МГц и в прерывании по таймеру формируете программный ШИМ. Примерно как тут Программный ШИМ на сдвиговом регистре

 

Максим. Добрый день. Вот нашол код который реализуе почти плавное загорание светодиодов

то что под заголовком (Linear per-LED brightness method) в loop реализует плавное загорание и затухание через один светодиод

то что (Turn on a couple to make a "comet" with dimming tail) змейка с плавным затуханием 

Теперь вопрос: можно ли обединить ваш код и эти что бы получить плавное загорание и затухание всех светодиодов по очереди?

Тут много лишнего просто были и другие команды я убрал.

Заранее благодарен

int myClockPin = 2;             // Arduino pin that goes to M5451 clock
int mySerDataPin = 3;           // Arduino pin that goes to M5451 data

void setup()                    // run once, when the sketch starts
{
}


#define M5451_NUMOUTS 35
#define M5451_CLK 0
class M5451
{
  public:
  byte clockPin;
  byte brightPin;
  byte serDataPin;
  M5451(byte clockPin,byte serDataPin,byte brightPin);
     
  void set(unsigned long int a, byte b=0);
  void setBrightness(byte b);
 
  private:
  void mydelay(int clk);
};

void M5451::setBrightness(byte b)
{
  if (brightPin < 0xff)
    analogWrite(brightPin,b);
}

#define MaxBrightness 4096  //256
class FlickerBrightness:public M5451
{
  public:
  FlickerBrightness(byte clkPin, byte dataPin, byte brightnessPin);
 
  void shift(int amt=1)
    {
    offset+=amt;
    if (offset>=M5451_NUMOUTS) offset -=M5451_NUMOUTS;
    else if (offset< 0) offset +=M5451_NUMOUTS;
    }
  void loop(void);
 
  int brightness[M5451_NUMOUTS];
  int bresenham[M5451_NUMOUTS];
  int iteration;
  int offset;
};

FlickerBrightness::FlickerBrightness(byte clkPin, byte dataPin,byte brightnessPin):M5451(clkPin,dataPin,brightnessPin)
{
  for (int i=0;i < M5451_NUMOUTS;i++)
  {
    brightness[i] = 0;
    bresenham[i]  = 0;
  }
 
  iteration = 0;
  offset = 0;
}

void FlickerBrightness::loop(void)
{
  int i;
  byte pos;
  unsigned long int a=0;
  byte b=0;
  boolean lvl=false;
 
  for (i=0,pos=offset;i < M5451_NUMOUTS;i++,pos++)
    {
      if (pos>=M5451_NUMOUTS) pos=0;
      bresenham[i] += brightness[pos];
      if (bresenham[i]>=MaxBrightness)
        {
          bresenham[i] -= MaxBrightness;
          lvl = true;
        }
      else lvl = false;
     
      if (i<32) a = (a<<1)|lvl;
      else b = (b<<1)|lvl;
    }
  iteration++;
  if (iteration > MaxBrightness) iteration = 0; 
 
  set(a,b);
}


M5451::M5451(byte clkPin, byte dataPin, byte brightnessPin)
{
  int i;
 
  clockPin = clkPin;
  serDataPin = dataPin;
  brightPin = brightnessPin;
 
  pinMode(clkPin, OUTPUT);      // sets the digital pin as output
  pinMode(serDataPin, OUTPUT);      // sets the digital pin as output
  pinMode(brightPin,OUTPUT);

  // Clear out the device so we can clock in items
  digitalWrite(serDataPin,LOW); 
  for (i=0;i< M5451_NUMOUTS+2;i++)
    {
    mydelay(M5451_CLK);
    digitalWrite(clockPin,HIGH);
    mydelay(M5451_CLK);
    digitalWrite(clockPin,LOW);   
    }
}

void M5451::mydelay(int clk)
{
  int i;
  for (i=0;i< clk;i++);
  //delay(clk);
}

void M5451::set(unsigned long int a, byte b)
{
  int i;

  // Write the initial "start" signal
  digitalWrite(clockPin,LOW);
  digitalWrite(serDataPin,LOW);
  mydelay(M5451_CLK);
  digitalWrite(clockPin,HIGH);
  mydelay(M5451_CLK);
  digitalWrite(clockPin,LOW);
  mydelay(M5451_CLK/2);
  digitalWrite(serDataPin,HIGH);
  mydelay(M5451_CLK/2);
  digitalWrite(clockPin,HIGH);
  mydelay(M5451_CLK);
  digitalWrite(clockPin,LOW);
   
  // Write the bits
  for (i=0;i< M5451_NUMOUTS;i++)
  {
    int serDataVal;
    if (i<32) { serDataVal = (a&1); a >>=1;}
    else { serDataVal = (b&1); b>>=1;}
    mydelay(M5451_CLK/2);
    digitalWrite(serDataPin,serDataVal);
    mydelay(M5451_CLK/2);
    digitalWrite(clockPin,HIGH);
    mydelay(M5451_CLK);
    digitalWrite(clockPin,LOW);
  }
}

void loop()                     // run over and over again
{
  unsigned long int j;
  int i;
  FlickerBrightness leds(myClockPin,mySerDataPin,9);
 
 

 // Linear per-LED brightness method
  if (1) for (j=0;j<4096;j++)
    {
      for (i=0;i< M5451_NUMOUTS;i++)
        {
          int k = j*10;
          if (i&1)
          {       
            leds.brightness[i] = abs((k&(MaxBrightness*2-1))-MaxBrightness);
          }
          else
            leds.brightness[i] = MaxBrightness - abs((k&(MaxBrightness*2-1))-MaxBrightness);
        }
      for (i=0;i<10;i++) leds.loop();
    }

// Turn on a couple to make a "comet" with dimming tail 
  leds.brightness[0] =  MaxBrightness-1;
  leds.brightness[1] =  MaxBrightness/2;
  leds.brightness[2] =  MaxBrightness/4;
  leds.brightness[3] =  MaxBrightness/8;
  leds.brightness[4] =  MaxBrightness/16;
  leds.brightness[5] =  MaxBrightness/64;
  leds.brightness[6] =  MaxBrightness/100;

  for (j=0;j<100;j++)
    {
      leds.shift(1);
      for (i=0;i<150;i++) leds.loop();
    }
   
  for (j=0;j<100;j++)
    {
      leds.shift(-1);
      for (i=0;i<100;i++) leds.loop();
    }
 

  if (1)
{ 
  leds.set(0xffffffff,0x7);
  delay(1000);
  //leds.set(0xf0f0f0f0,0x7);
  //delay(10000);
  //leds.set(0x11111111,0x1);
  //delay(10000);
}

}

 

 

denyang
Offline
Зарегистрирован: 05.08.2013

Начал эксперементы с яркостью светодиодов, подключив к 9 ноге ардуины 19 ногу от ММ5451. Пока добился изменение яркости в статике (если ориентироваться на реализацию Лукьянова) повторил постоянное свечение яркости верхней и нижней ступеней порядка 30% от макимальной, при срабатывании датчиков свечение 100%. Плавный поджиг пока не получается.

Вопрос Максиму. Повторил Ваш код с изменяемым количеством ступеней и почему то после срабатывания  датчика гасятся не все диоды, последние три остаются гореть. Опытным путем установил что при строке :

  for(char i = 0; i <= NUM_LEDS+3; i++) // тушим светодиоды 

гаснут все. Почему так происходит?

maksim
Offline
Зарегистрирован: 12.02.2012

denyang пишет:

Почему так происходит?

Задайте еще маску соответствующуюю количеству светодиодов:

const uint32_t mask = 0b11111111111111111111;

то есть количество единичек должно соответствовать количеству светодиодов.

denyang
Offline
Зарегистрирован: 05.08.2013

Понял. Спасибо большое. А вот как можно реализовать, как у Лукьянова, изменение количества ступеней с помощью кнопочек? Я так понамию что это меняется маска и заносится в EPROM?

Naddd
Offline
Зарегистрирован: 07.12.2013

Здравствуйте Максим. А можно с вами как-нибудь связаться ? Напишите пожалуйста почту.

maksim
Offline
Зарегистрирован: 12.02.2012