Официальный сайт компании Arduino по адресу arduino.cc
Led matrix 8x8 - зажечь определенные светодиоды.
- Войдите или зарегистрируйтесь, чтобы получить возможность отправлять комментарии
Вс, 16/12/2012 - 04:08
Поскажите, как при такой схеме подключения можно зажечь определенный светодиод?
А чем вас статья откуда вы картинку взяли не устроила?
maksim, эту статью я читала(хотя картинку взяла на английском форуме), но там рассматривается лишь подключение и два примера, а мне нужно немного другое - как программно зажешь определенные светодиоды? Ну к примеру, как зажешь 4 светодиода по углам матрицы, или как зажешь 4 светодиода в центре?
Еще раз перечитйте статью, уберите лишнее из кода, уберите анимацию, добавьте четыре точки по углам:
и вуаля... готово.
И поверьте мне вам нужно именно тоже самое, что и в статье, вам нужно понять принцип работы динамической индикации.
Ну вот убрала я все лишнее. Угловые светодиоды горят, но очень слабо. Что можно еще сделать?
Правильно подключить.
А попробуйте так
Тоже тускло?
А так вообще не работает :(
Так а вы матрицу как на картинке подключаете?
Сейчас пересмотрел код и не пойму зачем вообще вот это:
в cols и rows должны быть номера элентов массива pins, а у вас там номера выводов. Тогда так:
>Так а вы матрицу как на картинке подключаете?
Да, пример с бегущей строкой у меня работает.
>Сейчас пересмотрел код и не пойму зачем вообще вот это
Ну это я по вашему совету все лишнее из кода той статьи пыталась убрать.
>Тогда так:
Так горят, только не те диоды, а вот эти:
0, 0, 0, 0, 0, 0, 0, 0
0, 0, 0, 0, 0, 0, 0, 0
1, 0, 1, 1, 0, 0, 1, X
0, 0, 0, 0, 0, 0, 0, 0
0, 0, 0, 0, 0, 0, 0, 0
0, 0, 0, 0, 0, 0, 0, 0
0, 0, 0, 0, 0, 0, 0, 0
1, 0, 1, 1, 0, 0, 1, X
Х - это тусклые светодиоды.
Может мне все таки лучше на сдвиговых регистрах сделать? Можете подсказать схему подключения для 74HC595? Гугл только на трехцветные матрицы схемы выдает, а там несколько запутано.
А причем тут сдвиговые регистры? С помощью регистров вы освободите выводы дуины и ничего больше, то есть будут заняты не 16, а 4 вывода. Вот транзисторная сборка ULN2803 и токоограничивающие резисторы нужны для нормального свечения светодиодов. Скорее всего простое не совпадение выводов.
Сейчас попробую разобраться...
Если я нигде не ошибся и вы подключили все по схеме, то вот так должно работать:
>А причем тут сдвиговые регистры?
Где-то читала, что при помощи сдвиговых регистров можно избежать не ровномерного свечения.
>Если я нигде не ошибся и вы подключили все по схеме, то вот так должно работать:
Да, так работает, но диоды опять еле светятся :(
Забыла добавить, что я каждую ножку матрицы подключила через резисторы в 250 Ом, а не напрямую, как на картинке. Может быть из за этого? Хотя, если сравнивать с примером бегущей строки, то там светятся достаточно ярко.
Максим, а вы строки зажигаете подтягивающими резисторами случайно или так задумано? Не вникал сильно, но pinMode в строках 30,32 настораживает.
Нет, строка поджигается когда на ней 0(GND), то есть она настроена на выход, когда она настроена на вход на ноге Z-состояние, в общем строки поджигаются как NPN-транзисторами.
Да понятно почему тускло, если на всех ногах матрицы резисторы по 250 Ом, если даже в строке горит только один светодиод, то к нему еще плюсом 500 Ом, а если больше светодиодов то вообще потухнуть могут...
Нет, строка поджигается когда на ней 0(GND),
Ну значит я запутался по какой же схеме подключались. Если из #5 (картинка), что-бы зажечь самый верхний левый диод, нужно на ногу R1 дать HIGH, и на первый пин ULN-ки тоже HIGH!!
ULN-ка же, в отличает от ULS инвертирует сигнал. Что-бы она свой выход подключила к земле, ей же, если не ошибась, HIGH на вход дать нужно?
Но при любых раскладах, зачем тут Z-состояние примешивать? Чем обычный OUTPUT режим не подходит и на нем HIGH/LOW менять?
Не, не, схема из самого первого сообщения топик-стартера - прямое подключение матрицы к дуине, поэтому и Z-состояние нужно.
Все резисторы убрать? А не сгорят диоды-то? Ведь даже в оригинальной статье сказанно "Note: DON'T FORGET CURRENT-LIMITING RESISTORS."
Не сгорят, так как каждый вывод дуины имеет сопротивление 20 Ом, так диод оказывается между двух выводов получается 40 Ом. Вот когда через ULN будете подключать, вот тогда обязательно нужно ставить резисторы, НО только на аноды.
Можете еще уменьшить время подсветки строки с 10 до 1 мкс delayMicroseconds(1);, но тогда это может повлиять на снижение яркости.
>Да, так работает, но диоды опять еле светятся :(
Попробуйте увеличить, в строке 31, delayMicroseconds(10); на что-то побольше.
Подорать компромис между "яркость" и "уже заметно перемигивание".
>Да, так работает, но диоды опять еле светятся :(
Попробуйте увеличить, в строке 31, delayMicroseconds(10); на что-то побольше.
Подорать компромис между "яркость" и "уже заметно перемигивание".
с 500 Омами не поможет.
Можете еще уменьшить время подсветки строки с 10 до 1 мкс delayMicroseconds(1);, но тогда это может повлиять на снижение яркости.
А зачем же уменьшать время подсветки, если проблема в "тускло"? IMHO наоборот - увеличить попытатся.
Чем больше соотношение времени "подстветка"/остальной скетч - тем визуально ярче будет.
Крайний случай - светить кажду строчку минуту :) Будет максимальная яркость :) (и перемигивание).
Можете еще уменьшить время подсветки строки с 10 до 1 мкс delayMicroseconds(1);, но тогда это может повлиять на снижение яркости.
А зачем же уменьшать время подсветки, если проблема в "тускло"? IMHO наоборот - увеличить попытатся.
Чем больше соотношение времени "подстветка"/остальной скетч - тем визуально ярче будет.
Крайний случай - светить кажду строчку минуту :) Будет максимальная яркость :) (и перемигивание).
Короче, хотите, что бы хоть как-то светила матрица без транзисторов - убираете все резисторы, потому как когда у вас будут в одной строке гореть 3 светодиода и выше, яркость строки будет уменьшаться при увеличении количества светящихся светодиодов. При таком подключении максимум на что повлияеет завышенный ток - это на срок службы светодиодов, быть может в 2 раза при условии, что светодиод может служить лет 15 при постоянном использовании.
И на будующее, когда у вас спрашивают: "точно как на схеме подключаете" и вы говорите "да", то оно так и должно быть иначе вы будете создовать себе лишние сложности.
Спасибо за помощь. Убрала резисторы:)
Но теперь слишком ярко светит:) Можно ли как-то понизить яркость для всех светодиодов, ну например как тут http://arduino.ru/Tutorial/Fade ?
Можете еще уменьшить время подсветки строки с 10 до 1 мкс delayMicroseconds(1);, но тогда это может повлиять на снижение яркости.
Если все равно ярко то тогда так
и чем больше вторая задержка тем ниже яркость.
Можно даже при желании сделать компенсацию яркости в зависимости от количества светящихся светодиодов в стоке.
Можете еще уменьшить время подсветки строки с 10 до 1 мкс delayMicroseconds(1);, но тогда это может повлиять на снижение яркости.
Точно. Спасибо еще раз.
Можно даже при желании сделать компенсацию яркости в зависимости от количества светящихся светодиодов в стоке.
А вот это интересно. Попробую сделать.
Вот, вроде получилось
Если зависимость задержка/яркость получилась линейной как у вас в коде, то можно чуть-чуть оптимизировать код:
delayMicroseconds(SV*10);
Я тоже хотела так упростить код, но так почему-то тускло маргает.
И еще вопрос. Если мне придется отказаться от delay, то чем его можно заменить? Смотрела тему и пример, где без delay можно мигать светодиодом, но там задержка в милисекундах, а тут в микро.
Так же как и в примере только в микросекундах, есть такая функция micros().
И еще вопрос. Если мне придется отказаться от delay, то чем его можно заменить?
Логикой. Если вам нужно выполнить какое-то "долгоирающие действие", например "светить 3 sec", но нельзя останавливать скетч, то общий подход такой:
Небольшая вариация. Принципиальных отличий нет, дело вкуса (если только не предполагается беспрерывная работа больше 49-дней, тогда лучше первый вариант).
В коде это выглядить примерно так:
delayMicroseconds(SV*10);
Я тоже хотела так упростить код, но так почему-то тускло маргает.
Можно, что-бы не выполнять относительно ресурсоемкое вычисление, загнать значения заранее в массив (плюс это позволит задавать нелинейную зависимосить). Очень похоже на ваши if, только чуть-чуть компактней.
И еще, советую почитать, в разделе программирование, подраздел "типы данных". И обращать внимание, в документации на функции, какие типы параметров она принимает и какие возвращает.
В вашем случае, для переменной SV достаточным будет тип byte, а для переменной RR желателен unsigned int, а не int (так как delayMicroseconds ждет именно unsigned int). С конкретными вашими цифрами задержками "будет работать и так". Просто повезло, но лучше заранее привыкать "делать правильно". Это, убережет и от неоправданного расхода ресурсов проца и ваших нервов при поиски трудноуловимых ошибок из-за небрежности с типами.
если только не предполагается беспрерывная работа больше 49-дней
А почему так? Переполнение?
Хм, все равно почему-то тускло мигает, а не светит, как при if. Но все равно спасибо за пример и советы.
Покажите весь код.
если только не предполагается беспрерывная работа больше 49-дней
А почему так? Переполнение?
Хм, все равно почему-то тускло мигает, а не светит, как при if. Но все равно спасибо за пример и советы.
Ну значит причина не в этом. Если вы сейчас сюда вставите IF-вы - будет точно также. Хотя.... возможно просто время чуть увеличить нужно. С IF-вами у вас еще есть задержка в неявном виде. Постоянная проверка IF-вов тоже время занимает. То есть у вас, к этим цифрам, в лучае if еще какие-то микросекунды добавляются (что плохо, так как оно будет изменятся в случае увеличение количества проверок, плохо предсказуемо и т.п.).
Или причина в другом (тогда и с if-вами будет тускло), и тогда нужен код целиком.
если только не предполагается беспрерывная работа больше 49-дней
А почему так? Переполнение?
Совершенно верно. Сколько микросекунд может влезть в unsigned long (это примерно 49.1 дней). В случае когда мы плюсуем, при переполнении у нас получится маленький offTime, явно меньше текущего времени в "выключится сразу", а вот разница (millis()-КОГДА_ВКЛЮЧИЛИ) посчитается правильно даже при переполнении (если только само время "сколько светить" не будет больше 49-ти дней).
При переполнении она получится отрицательной, но так как тип беззнаковый, то произойдет "переполнение в обратную сторону" и все будет хорошо.
Что-бы понять, можете завести переменную типа байт (она переполняется на 255), и попытася повычитать из нее, что-то типа (5-253) . И посмотреть какая разница выходит :)
Вот весь код
Подробнее опишите что и как мигает.
Ну значит причина не в этом. Если вы сейчас сюда вставите IF-вы - будет точно также. Хотя.... возможно просто время чуть увеличить нужно. С IF-вами у вас еще есть задержка в неявном виде. Постоянная проверка IF-вов тоже время занимает. То есть у вас, к этим цифрам, в лучае if еще какие-то микросекунды добавляются (что плохо, так как оно будет изменятся в случае увеличение количества проверок, плохо предсказуемо и т.п.).
Или причина в другом (тогда и с if-вами будет тускло), и тогда нужен код целиком.
Ну вот я увеличила задержку
Стало по ярче светить, но все равно моргает.
С IF-вами у вас еще есть задержка в неявном виде.
Непойму, ведь тут задержка не должна приводить к миганию, а только к увеличению или уменьшению яркости?
maksim, ну светодиоды по углам сначала загараются, а потом гаснут. Как будто задержка стоит после Display(); в функции loop.
Непойму, ведь тут задержка не должна приводить к миганию, а только к увеличению или уменьшению яркости?
Неверно. Оно приводить и к тому и к другому. И тут "искать баланс". Чем дольше вы держите строку включенной тем он светит ярче, но при этом тем дольше выключенными являеются другие строки (и это в том числе "когда мы светим другими").
Если у вас задержка, для каждой строки XXX микросекунд, то выходит что мы XXX времени светим и 7*XXX не светим (занимаемся другими строками). Когда 7*XXX становится слишком большим, то инерция зрения не справляется и картинка распадается на "мигания".
Варианты:
1. Все таки брать ULN/транзисторы и увеличивать проходящий ток (c тем что-бы можно было уменьшить задержку до "не моргает").
2. Пытаться "ускорить" скетч путем отказа от digitalWrite и перехода на прямую запись в регистр (не факт что поможет).
3. Попытатся ускорить, заранее высчитав sv для каждой строки брать готовые задержки (зачем нам каждый раз вычислять? их можно пересчитывать только если поменялся массив mem).
4. Может Максиму что-то еще в голову прийдет :)
Здесь в чем то другом дело, потому как если даже взять максимальную задржку 180 микросекунд и умножить на 8, то получится 1,5 миллисекунды, ну предположим остальной код выполняется еще 1 миллисекунду получаетя 2,5. 1000/2,5 получаем 400 кадров в секунду. Ну или какаято операция занимает несколько миллисекунд, я таких не знаю.
3. Попытатся ускорить, заранее высчитав sv для каждой строки брать готовые задержки (зачем нам каждый раз вычислять? их можно пересчитывать только если поменялся массив mem).
Как-то так:
Так я понять не могу, вот так
тускло горит или мигает???
Можно еще попобовать вот так дополнить Display(), что-бы не дуплить на пустных строках вообще:
2Максим: и все-таки муляет мне это pinMode в display. Там реально нужно Z-состояние или можно, все-таки на digitalWrite заменить?
Кстати, а что вы думаете про такой "финт ушами"?:
что-бы не разбиратся к какому порту какая нога принадлежит, выводим один раз все с помощью digitalWrite-тов, запоминаем состояния PORTB,PORTD и т.п.
и потом вызываем displayFast(), который использует прямую запись в порт из подготовленных значений?
Поможет такое или "выжатых тактов" за счет отказа от digitalWrite все равно не хватит?