работа библиотеки LedControl
- Войдите на сайт для отправки комментариев
Вс, 22/10/2017 - 23:28
Добрый вечер. Собирал летом светодиодный куб в несколько слоёв на мах7219. Скетч управления строил на простой и понятной библиотеке LedControl. Одной из вариаций было вращение-движение плоскости.
#include <LedControl.h>
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//
// Arduino UNO, Pro Mini
//
////////////////////////
//
//программа для LED куба на шести матрицах 6*6, и max7219 //
#include "LedControl.h"//подключаем данную библиотеку
int i=0;int j=0;int k=0;int k1=5;
int n=5;//5 миллисекунд- единица длительности паузы переключений
LedControl LC = LedControl(12, 11, 10, 6);// создаём объект класса для 6 индикаторов
// при этом выводы 12-DIN 11-CLK 10-CS //
void setup()
{
for (i=0;i<=5;i++)
{
LC.shutdown(i, false);//выключаем энергосберегающий режим
LC.setIntensity(i,4 );// устанавливаем интенсивность в 4 единиц между 0 и 15
LC.clearDisplay(i);//очищаем матрицу i
}
}
void loop()
{
///////////////////////////////////// ПРОГРАММА ФАНЕРА ///////////////////////////////////
for (k=0;k<=161;k=k+3)
{
for (i=0;i<=k1;i++) //цикл в цикле для перебора элементов матриц
{
for (j=0;j<=k1;j++)
{
int tabl[162]={0,i,j, i,j,5-i, i,j,5, i,j,i, 5,i,j, i,j,5-i, i,j,0, i,j,i,
0,i,j, i,i,j, i,0,j, i,1,j, i,2,j, i,3,j, i,4,j, i,5,j, i,4,j, i,3,j, i,2,j, i,1,j, i,0,j,
i,5-i,j, 5,i,j, i,i,j, i,5,j, i,5-i,j,
0,i,j, 1,i,j, 2,i,j, 3,i,j, 4,i,j, 5,i,j, 4,i,j, 2,i,j, 1,i,j,
0,i,j, i,j,5-i, i,j,5, i,j,4, i,j,3, i,j,2, i,j,2, i,j,1, i,j,0,
i,j,1, i,j,2, i,j,3, i,j,4, i,j,5, i,j,i, 5,i,j, i,j,5-i, i,j,0, i,j,i};
LC.setLed(tabl[k],tabl[k+1],tabl[k+2],1);
}
}
delay(5*n);
LC.clearDisplay(0);LC.clearDisplay(1);LC.clearDisplay(2);
LC.clearDisplay(3);LC.clearDisplay(4);LC.clearDisplay(5);
}
}
Заметил мерцание плоскости при движении. Связываю это с несовершенством библиотеки. Есть ли возможность улучшения её работы? Простите за наивность.
Что считать "несовершенством", а что "улучшением"?
Видимо я неточен в терминах всвязи с малым опытом. Неодновременное включение светодиодов в одной плоскости, особенно заметное боковым зрением связано с частотой их переключений - она относительно мала, раз заметна. Улучшение, наверное, увеличение частоты - чтобы глаз не замечал. Так мне кажется. Но в рамках скетча поправить мерцание не могу.
Видимо я неточен в терминах всвязи с малым опытом. Неодновременное включение светодиодов в одной плоскости, особенно заметное боковым зрением связано с частотой их переключений - она относительно мала, раз заметна. Улучшение, наверное, увеличение частоты - чтобы глаз не замечал. Так мне кажется. Но в рамках скетча поправить мерцание не могу.
т.е. не хватает скорости?
Сначала попробовать "легким движением руки " - в LedControl в функции spiTransfer (она последняя в файле cpp) заменить вызов стандартной функции shiftOut() на вызов своей, которую написать надо. В ней вместо digitalWrite() прописать прямое управление пинами DIO и CLK (см., например, CyberLib ).
Если нужно еще быстрее - переписать скетч и кое-что перепаять, чтобы обращаться к каждой мс 7219 отдельно, пинов для CS вроде бы хватает.
========
да, и подумать о массиве - не лепо ли будет объявить его глобальным один раз в начале программы ("byte tabl[162]; "), а не 100500 раз во вложенном цикле?
Массив здесь кончно замудрёный. Чтобы зажечь светодиод нужно три числа. А здесь перед каждым зажиганием светодиода рассчитываются 162 элемента массива. Ещё в библиотеке вроде есть функции для зажигания нужных диодов сразу в строке/колонке. Я бы переделал хранение последовательности картинок с учётом использования этих функций, с ними и очистка возможно не потребуется.
Разумеется библиотека не подходит. А раз не подходит библиотека , то ее надо написать. Но если вы не можите, то надо нанимать людей. Опять если вам нужна программа, то одни расценки. А вот научить как и почему это уже другие. Образование уже не бесплатное. Тем более специально для вас надо писать учебник по этой тематике. А это труд и время.
Массив здесь кончно замудрёный. Чтобы зажечь светодиод нужно три числа. А здесь перед каждым зажиганием светодиода рассчитываются 162 элемента массива. Ещё в библиотеке вроде есть функции для зажигания нужных диодов сразу в строке/колонке. Я бы переделал хранение последовательности картинок с учётом использования этих функций, с ними и очистка возможно не потребуется.
Поднять массив в скетче выше не удаётся - переключение светодидов нарушается.
Функция SetRow() это включение светодиодов порядно, единственная в библиотеке при которой мерцание светиков изчезает, тоесть она самая быстрая.
Остаётся попробовать другую библиотеку, Mах72ххPanel, но доходчивой до меня инструкции по её применению пока не нашёл.
Поднять массив в скетче выше не удаётся - переключение светодидов нарушается.
Ну это само собой. Я имел ввиду, создать полностью рассчитанный массив.
Функция SetRow() это включение светодиодов порядно, единственная в библиотеке при которой мерцание светиков изчезает, тоесть она самая быстрая.
Так а почему Вы её не используете?
Остаётся попробовать другую библиотеку, Mах72ххPanel, но доходчивой до меня инструкции по её применению пока не нашёл.
А зачем Вам библиотеки? Работайте с микросхемой напрямую, примеры в сети есть.
Так а почему Вы её не используете?
А зачем Вам библиотеки? Работайте с микросхемой напрямую, примеры в сети есть.
Да с точками как то логичней работать чем со строками. И для куба при рисовании плоскостей, скажем XY, XZ условно - порядное включение пройдёт быстрее, а для плоскости YZ не известно.
Про работу напрямую с мах примеров не видел, но подозреваю, что скетчи будут большими?
Да с точками как то логичней работать чем со строками. И для куба при рисовании плоскостей, скажем XY, XZ условно - порядное включение пройдёт быстрее, а для плоскости YZ не известно.
Про работу напрямую с мах примеров не видел, но подозреваю, что скетчи будут большими?
Я так думаю, тут для себя нужно решить, что Вы хотите получить. Можно оптимизировать скетч под какой-то один визуальный эффект, можно делать что-то более универсальное. Это уж дело хозяйское. В зависимости от этого возможно Вы придумаете какие-то свои функции, которых нет в библиотеках именно под ваши эффекты и под Ваш способ их описания.
А библиотеки, которые Вы сравнить хотите, Вы в код-то их загляните. Может они кроме названия ничем по сути и не отличаются?
#include <SPI.h> // выбор вывода на Ардуино UNO для LOAD/CS (DIN 11,CS 10,CLK 13 ) #define LOAD_PIN 10 void maxTransfer(uint8_t address, uint8_t value) { // функция загрузки данных в регистры digitalWrite(LOAD_PIN, LOW); SPI.transfer(address); SPI.transfer(value); digitalWrite(LOAD_PIN, HIGH); } void setup() { pinMode(LOAD_PIN, OUTPUT); // отправка старшего бита первым SPI.setBitOrder(MSBFIRST); // включение SPI SPI.begin(); //очищаем регистр DisplayTest, для перехода в нормальный режим работы maxTransfer(0x0F, 0x00); // отключаем дешифратор, путем записи 0 в регистр Decode Mode maxTransfer(0x09, 0x00); //записываем значение яркости дисплея, в данном случае — «0», почти минимальное значение Use lowest intensity maxTransfer(0x0A, 0x00); //записываем в ScanLimit максимальное значение «7», что позволяет отображать содержимое всех регистров дисплея от Digit 0 до Digit 7 maxTransfer(0x0B, 0x07); //записываем «1» в регистр MAX7219, тем самым выводя микросхему из режима Shutdown, обычно ей требуется 250 мкс на включение, но это не мешает принимать команды maxTransfer(0x0C, 0x01); } void loop() { for (uint8_t i = 1; i <= 0x08; i=i+2) { maxTransfer(i, 0x55);maxTransfer(i+1, 0xAA); } delay(500); for (uint8_t i = 1; i <= 0x08; i=i+2) { maxTransfer(i, 0xAA);maxTransfer(i+1, B01010101); } delay(500); }Пробую управлять одной матрицей на мах7219 через библиотеку spi. Светодиоды включаются в шахматном порядке, через один - половина горит, половина нет. Через полсекунды половины перемигиваются. Вопрос: как управлять каскадом из шести последовательно включённых модулей ? (должно ли быть отражено это число в скетче) Сколько их может быть в цепочке?
Чтобы засветить N матриц на max7219, необходимо в DOUT кинуть N*8 бит информации. Как только первый контроллер "заполнится" - начнет передавать дальше ненужные ему биты. Когда закончите пушить в DOUT - дергайте LOAD.
Максимальное число теоретически неограничено, но есть нюансы: http://forum.arduino.cc/index.php?topic=259367.0
Чтобы засветить N матриц на max7219, необходимо в DOUT кинуть N*8 бит информации.
Чтобы засветить N матриц на max7219, необходимо в DOUT кинуть N*8 бит информации.
Верно. Всё думал, что написал N*8 байт, а оказалось "бит" почему-то .
Чтобы засветить N матриц на max7219, необходимо в DOUT кинуть N*8 бит информации. Как только первый контроллер "заполнится" - начнет передавать дальше ненужные ему биты. Когда закончите пушить в DOUT - дергайте LOAD.
Максимальное число теоретически неограничено, но есть нюансы: http://forum.arduino.cc/index.php?topic=259367.0
Это получается на переключение одного светодиода надо обновлять значения на всех??
Это так. Но это особенность любых соединенных а цепочку индикаторов. Хоть адресуемых светодиодов, хоть построенных на MAX7219, хоть на сдвиговых регистрах...
Ясно...не придумали пока чтоб в посылке ещё и адрес был для светодиода.
Но это не мешает придумать это самому и оформить библиотекой. SPI работает быстро, так что выплюнуть массив из сотни байт ей нефиг делать.
PS. Хотя, я посмотрел первую попавшуюся библиотеку LedControl - там всё так и делается. Массив выплевывается в SPI и все такое. Единственная неприятная вещь - то, что для изменения состояния каждого "светодиода" через setLed() сразу делается SPITransfer. Несколько экономней, наверное, сначала сформировать массив так, как нужно для смены картинки, а потом уже пушить его целиком. Тогда и фреймрейт можно будет поднять, думаю,
Ясно...не придумали пока чтоб в посылке ещё и адрес был для светодиода.
а при последовательном включении микросхем приходится информацию проталкивать сквозь гирлянду "от москвы до самых до окраин".
Чтобы засветить N матриц на max7219, необходимо в DOUT кинуть N*8 бит информации. Как только первый контроллер "заполнится" - начнет передавать дальше ненужные ему биты. Когда закончите пушить в DOUT - дергайте LOAD.
Максимальное число теоретически неограничено, но есть нюансы: http://forum.arduino.cc/index.php?topic=259367.0
Это получается на переключение одного светодиода надо обновлять значения на всех??
Это получается на переключение одного светодиода надо обновлять значения на всех??
Но если цепочкой - то на всех?
Это получается на переключение одного светодиода надо обновлять значения на всех??
Но если цепочкой - то на всех?
реально изменится один байт в одном из регистров одной из мс. но в каждую микросхему по дороге придется записать что-то в "нулевой" регистр.
для многократного ускорения ТС всего-то надо перепаять схему, чтобы сигналы CS были индивидуальными (я полагаю, свободных пинов хватает), и кое-что переписать (несколько строк).
С CS идея ясна, но проще использовать в другой поделке чем корячить исходную. С нулевым регистром не понятно.
С нулевым регистром не понятно.