А если в качестве подсветки поставить RGB светодиоды, то по цвету подсветки можно определять уровень сигнала, например, красный - низкий уровень, синий - средний, зеленый - высокий. Всего три цвета - три уровня. Если мало, то смешивать и получать другие цвета и больше уровней.
В любом оборудовании, используемым в работе, самое главное, помимо безопасности, - это удобство им пользования, а уже в последнюю очередь понты. Понты - они такие, только в начале будет казаться, что это круто.
Жорошо пусить будет по вашему , ток можно я этот дабью с цифрами , а то меня испуг охватил я не знаю как это реализовать , я просто взялся за это матрицу а как она работает не допонимаю ,
channel это счетчик почему мы его делим на 8 я так понимаю это две матрицы , и чтобы отображать еще две нам надо увеличить условие до 32х а потом мы результат для столбиков делим (%) опять на 8? и что это (>>) за оператор такой ?
ВЫ правы , панты они действительно такие , но мир катиться в тар тарары , интернет и телевиденье делает свое дело по разложению , но все хотят гавно в красивой упаковке , сейчас офисный планктон мжет мног умничать и пакпать одноразовые автомобили и х не впечатляет матер с конролькой на шее , это их право , хот быть обманутыми это их выбор , ведь еденственное за что человек несет ответственность это только за свой выбор , мой выбор научиться , и я отношусь к вам с благодарностью и уважение то что вы передаете знания , это достойно уважения , я тугодум и сложно обучаем но все же я не гоняюсь за теме вещами что мне ненужны , что нам социум навязывает , мне жаль время тратит в пустую
ELITE мы обезательно их сделаем обещаю ) и к стари ребят у меня есть одна идейка котрая может вам понравиться я задумал нечто глабальное , возможно вы станете еденомышлиниками , https://vk.com/boy_twink можем пообщаться если интересно
:) я вам предлагаю только варианты, в любом случае вам решать какую реализацию вы будете делать :)
В функции LC.setColumn в первом параметре указывается номер матрицы, на котрую выводим данные (от 0 до 3 в нашем случае). Второй параметр - это номер столбца в этой матрице (может принимать значение от 0 до 7, т.к. в каждой матрице всего восемь столбцов). Третий параметр - это непосредственно сами данные для отображения столбца.
Можно конечно и отдельно формировать изображение сначала для нулевой матрицы, потом для первой и т.д. Но ведь есть решение проще. Для понимания можно составить табличку:
Нужно уточнить, что отсчет рядов на LED матрице начинается сверху, то есть самый верхний ряд светодиодов будет нулевым рядом, а самый нижний будет 7-м рядом.Для примера можно создать скетч, который будет выводить на LED матрицу цифру 5. Но прежде всего, нужно понять какие светодиоды будут визуализировать эту цифру. Для этого на сайте есть замечательный "Редактор символов для матриц 8х8", перейдя по ссылке, можно создать свой символ просто кликая по полю 8х8, либо выбрать готовый символ из таблицы ниже. Воспользуемся вторым вариантом, выберем символ "5" из предложенной таблицы.
И вообще, новой информации вы получили много. Думаю, пока достаточно. Лучше было бы, чтобы вы внимательно перечитали еще хотя бы раз нашу переписку. Пропробовали вникнуть в суть. Почитали описание используемых функций. И, когда более менее разберетесь, тогда уж будете приступать к остальному. Сдвиг оставьте на закуску. Если не разберетесь сами со сдвигом, то буду объяснять на пальцах. Но это будет потом. Пока переваривайте ту информацию, что уже получили. А на сегодня хватит.
[code]
#include "LedControl.h"
#define EN 3
#define S0 4
#define S1 5
#define S2 6
#define S3 7
#define SIG A0
LedControl LC = LedControl(12, 11, 10, 4);
byte channel;
void setup()
{
Serial.begin(9600);
for(byte i = 0; i < 4; i++) //цик котрый обращаеться каждой из матриц
{
LC.shutdown(i, false); //отключени энергосберегающего режима
LC.setIntensity(i, 8); // установка яркости
LC.clearDisplay(i); // очистка матрицы
}
pinMode(S0, OUTPUT); //определение пина на выход
pinMode(S1, OUTPUT);
pinMode(S2, OUTPUT);
pinMode(S3, OUTPUT);
digitalWrite(S0, LOW); // запись в пин низкого уровня
digitalWrite(S1, LOW);
digitalWrite(S2, LOW);
digitalWrite(S3, LOW);
pinMode(EN, OUTPUT); // пин которы определяет чтение с мултика
digitalWrite(EN, LOW); // запись низкого уровня
}
void loop()
{
byte controlPin[] = { S0, S1, S2, S3 }; //массив кторый определеться сам с размером , 4 пина адресной шины мультиплексора
for(byte i = 0; i < 4; i ++) // цикл котрый крутит ячейки массива
{
digitalWrite(controlPin[i], bitRead(channel, i));// ?????? поясните как это работает ?? " digitalWrite(controlPin[i]" с этим понято что в массив записуються данные по очереди , а как работает это bitRead(channel, i)????????
}
int val = analogRead(SIG); // считываем данные спорта и записываем в переменную
val = constrain(val, 0, 700); // значение, так чтобы оно была в области допустимых значений, заданной параметрами.
val = map(val, 0, 700, 0, 8); //математическая функция где val переменая получает данные с порта , преобразует в диапозн текуший , и преабразует в диапазан с задаными параметрами
LC.setColumn(channel / 8, channel % 8, 255 >> (8 - val)); вывод на матрицы
channel++; //прибавляем по еденице
if(channel == 16) channel = 0; // оператор сравнения ,если переменная == 16 ,то обнуляем ,channelпеременая - просто счетчик
}
[/code]
channel - не просто счетчик - это номер канала c мультиплексора. Значение изменяется от 0 до 15, в двоичном виде будет так: B0000 (0), B0001(1), B0010(2) .... B1111(15).
bitRead из channel возвращает значение бита под номером i (номер 0 у крайнего правого бита) - то есть когда channel = 0 (B0000) в пинах S0 =0 , S1=0, S2=0, S3=0
когда channel = 10 (B1010) в пинах S0 =0 , S1=1, S2=0, S3=1
byte controlPin[] = { S0, S1, S2, S3 };
for(byte i = 0; i < 4; i ++) // цикл котрый крутит ячейки массива
{
digitalWrite(controlPin[i], bitRead(channel, i)); // ?????? поясните как это работает ??, как работает это bitRead(channel, i)????????
}
S0, S1, S2, S3 - это пины, к которым подключены мультиплексоры. С помощью этих пинов задается адрес входа мультиплексора, данные с которого будут передаваться в ардуино. Т.е. можно в виде таблицы представить для себя, как это происходит - при каких комбинациях какой вход выбран:
S3 S2 S1 S0 вход
0 0 0 0 0
0 0 0 1 1
0 0 1 0 2
0 0 1 1 3
0 1 0 0 4 и т.д.
По сути, комбинация нулей и единиц на пинах Sx - это двоичное представление привычных для нас десятичных цифр:
0 - 0000
1 - 0001
2 - 0010
3 - 0011
4 - 0100
...
14 - 1110
15 - 1111
Выше приведенный код с циклом можно написать и иначе:
Например, какая комбинация должна быть на пинах Sx, если channel будет равно 13?
Для этого представим, как выглядит число 13 в двоичном представлении (для перевода можно воспользоваться виндовским калькулятором, также принимаем, что у нас размерность чисел byte (или 8 бит)). А выглядит оно так: 00001101, но поскольку максимальное число у нас 15, и для его представления достаточно четырех бит, то нас интересуют только четыре последних, т.е. 1101 (для диапазона чисел 0-15 в четырех старших битах (первых четырех слева) всегда будут ноли, нас они не интересуют).
Таким образом, для выбора тринадцатого канала на мультиплексоре необходимо S3 выставить в 1, S2 - 1, S1 - 0 и S0 - 1. Вот для того, чтобы узнать, что же в числе на месте n-нного бита находится и существует функция bitRead(). Например, результатом bitRead(13, 0) будет 1 (1101), а bitRead(13, 1) будет 0 (1101) и т.д. Отсчет битов идет справа (самый правый имеет номер 0).
byte controlPin[] = { S0, S1, S2, S3 }; //массив кторый определеться сам с размером , 4 пина адресной шины мультиплексора
Ну как бы массив не может сам определяться. Номера пинов мы запихнути в массив только для того, чтобы их можно было удобно выбирать по-очереди из цикла.
Jenek_Anapa пишет:
for(byte i = 0; i < 4; i ++) // цикл котрый крутит ячейки массива
{
digitalWrite(controlPin[i], bitRead(channel, i));// digitalWrite(controlPin[i]" с этим понято что в массив записуються данные по очереди
}
Тут да, в цикле мы по-очереди выбираем нужный пин из массива.
Но тут в массив данные не пишутся, а берутся оттуда. Т.е. выбираем очередной пин и на нем выставляем нужный уровень.
И вариант с циклом и этот вариант идентичны по сути и выполняются одинаково. Т.е. это то же самое, как развернуть тот цикл.
Тут первая строка - это то, что происходит при первом проходе цикла, когда i равна 0.
Вторая строка - при втором (i равна 1).
Третья строка - при третьем (i равна 2).
Четвертая строка - при четвертом последнем проходе (i равна 3).
Также разберитесь с двоичной системой счисления, в частности двоичным представлением чисел. Без нее все эти байты, биты, сдвиги - пустые звуки и никогда не будут понятны.
я двоичную систему понимаю мне не понятна последовательнасть действий вырожения , digitalWrite(controlPin[i], bitRead(channel, i)) кто куда кому что записывает и кто куда что выдает , я так понимаю это не арефметическое дествие , а просто алгоритм
все дошло , bitRead(channel, i) крутим данные , потом читаем их из массива controlPin[i], а птом записываем digitalWrite в пин которому пренадлежат данные
Что делает digitalWrite(), я надеюсь, понимаете? Пишет что-то куда-то. Т.е. выставляет на требуемом пине нужное состояние - 1 (оно же HIGH) или 0 (оно же LOW). В первом параметре - номер пина, во втором - какое состояние на нем установить.
Т.е. digitalWrite(S0, bitRead(channel, 0)); установит на пине, указанном в S0, состояние, которое определяется с помощью bitRead(channel, 0). Так вот bitRead "пристально вглядывыется" в число, что находится в переменной channel, а конкретно "смотрит" в данном примере на его нулевой бит. И если он будет равен 1, то digitalWrite на пине S0 (в данном случае) выставит высокий уровень, т.е. 1 (HIGH). Если же бит будет равен 0, то и на пине выставится 0 (LOW).
Правильнее было бы не только изучать и разбирать готовое, но и делать свои "микропрограммы", чтобы посмотреть, что интересующая функция делает в реальности.
[code]
#include "LedControl.h"
#define EN 3
#define S0 4
#define S1 5
#define S2 6
#define S3 7
#define SIG A0
LedControl LC = LedControl(12, 11, 10, 4);
byte channel;
void setup()
{
Serial.begin(9600);
for(byte i = 0; i < 4; i++) //цик котрый обращаеться каждой из матриц
{
LC.shutdown(i, false); //отключени энергосберегающего режима
LC.setIntensity(i, 8); // установка яркости
LC.clearDisplay(i); // очистка матрицы
}
pinMode(S0, OUTPUT); // определение пина на выход
pinMode(S1, OUTPUT);
pinMode(S2, OUTPUT);
pinMode(S3, OUTPUT);
digitalWrite(S0, LOW); // запись в пин низкого уровня
digitalWrite(S1, LOW);
digitalWrite(S2, LOW);
digitalWrite(S3, LOW);
pinMode(EN, OUTPUT); // пин которы определяет чтение с мултика
digitalWrite(EN, LOW); // запись низкого уровня
}
void loop()
{
byte controlPin[] = { S0, S1, S2, S3 }; //массив кторый определеться сам с размером , 4 пина адресной шины мультиплексора
for(byte i = 0; i < 4; i ++) // цикл котрый крутит ячейки массива
{
digitalWrite(controlPin[i], bitRead(channel, i)); // digitalWrite(S0, bitRead(channel, 0)); установит на пине, указанном в S0,
//состояние, которое определяется с помощью bitRead(channel, 0).
// Так вот bitRead "пристально вглядывыется" в число, что находится в переменной channel,
//а конкретно "смотрит" в данном примере на его нулевой бит. И если он будет равен 1,
//то digitalWrite на пине S0 (в данном случае) выставит высокий уровень, т.е. 1 (HIGH).
// Если же бит будет равен 0, то и на пине выставится 0 (LOW).
}
int val = analogRead(SIG); // считываем данные спорта и записываем в переменную
val = constrain(val, 0, 700); // значение, так чтобы оно была в области допустимых значений, заданной параметрами.
val = map(val, 0, 700, 0, 8); //математическая функция где val переменая получает данные с порта , преобразует в диапозн текуший , и преабразует в диапазан с задаными параметрами
LC.setColumn(channel / 8, channel % 8, 255 >> (8 - val)); вывод на матрицы //x x/8 x%8 / - это целочисленное деление, т.е. остается только целая часть
//0 0 0 % - это, наоборот, как раз "хвост" от деления.
//1 0 1 >> - это оператор побитового сдвига
//2 0 2
//3 0 3 В функции LC.setColumn в первом параметре указывается номер матрицы, на котрую выводим данные (от 0 до 3 в нашем случае).
//4 0 4 Второй параметр - это номер столбца в этой матрице (может принимать значение от 0 до 7, т.к. в каждой матрице всего восемь столбцов).
//5 0 5 Третий параметр - это непосредственно сами данные для отображения столбца.
//6 0 6
//7 0 7
//8 1 0
//9 1 1
//10 1 2
//11 1 3
//12 1 4
//13 1 5
//14 1 6
//15 1 7
//16 2 0
//17 2 1
// и тд
channel++; //прибавляем по еденице
if(channel == 16) channel = 0; // оператор сравнения ,если переменная == 16 ,то обнуляем ,channel- номер канала c мультиплексора
}
[/code]
я все законспектировал
я полность с вами согласен , детки сначало основопологаються на ощущения а потом обучаються , писать кирпичем на заборе как бы суть не меняеться но на бумаге ручкой как правильней , читать можно и через микроскоп или подзорную трубу как бы тоже можно но приятней книжку , на машине можно ездить задом но практичней передом , достич результата можно по разному , кто то живет методом тыка а ктото сулшает учиться и преобретает правильные инструменты которыми он будет творить , я же не предложил вам денги за написание программы а попрасил научить меня , хотя правильней нужно отблагодарить и подскажите как я это могу сделать для вас , по тому что это гаразда дороже денег , вы свою жизненую энергию тратите
знаете вот побольше бы таких людей как вы , особено в области медецыны , можно же налюдях тренироваться в плане медикоментов и смотреть на результаты ли бо же учиться у мастеров
Да, так и есть, похоже больше даже не на бегущую строку, а на светомузыкальный бегущий огонь.
В нашем случае, за исходные данные берем полностью "горящий" столбик, т.е. все точки зажжены или все биты установлены в 1 - 11111111 (число 255 в десятичном виде). Если сдвигать этот столбик вправо (>>), то единички будут двигаться в направлении младшего бита (вправо), а в сташем бите будет появляться 0. Например, сдвинули 11111111 вправо на один раз - получили 01111111. Сдинули 11111111 вправо на пять раз - получили 00000111. Т.е., чем больше сдвигаем, тем короче столбик. Но, так как в нашем случае надо, чем больше значение переменной val, тем длиннее столбик (а значит надо меньше его двигать), то мы используем формулу 8 - val. Чем будет больше val, тем меньше сдвинется столбик.
Что касается цифр, то пока отложите этот скетч, и попробуйте в новом скетче выводить разные цифры и в разные места. Когда получится отдельно, тогда уже в этот скетч будем добавлять вывод цифр.
[code]
#include "LedControl.h"
//Синтаксис создания класса LedControl(dataPin,clockPin,csPin,numDevices)
//Где LedControl - объект класса
//dataPin - пин на плате Arduino к которому будет подключен пин DIN
//clockPin - пин на плате Arduino к которому будет подключен пин CLK
//csPin - пин на плате Arduino к которому будет подключен пин CS
//numDevices - количество устройств на шине
//Создать объект класса matrix в нашем случае с одним подключенным устройством
LedControl matrix = LedControl(12, 11, 10, 4);
byte desytki ;
void setup()
{
for(byte i = 0; i < 4; i++){ //цик котрый обращаеться каждой из матриц
matrix.shutdown(i, false); //Устройству с адресом 0 по SPI интерфейсу выйти из спящего режима по умолчанию
matrix.setIntensity(i, 1); //Установить яркость Led матрицы на 8 из 15
matrix.clearDisplay(i); //Очистить дисплей
}
}
//Объявляем массив из 10-ти символов
//Каждый символ включает в себя массив из 8-ти байт
//закодированных числом в шестнадцатиричном коде
byte CountDigits[10][8] =
{
{0xe, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0xe, 0x0}, //0
{0x2, 0x6, 0xe, 0x6, 0x6, 0x6, 0x6, 0x0}, //1
{0xe, 0x1b, 0x3, 0x6, 0xc, 0x18, 0x1f,0x0}, //2
{0xe, 0x1b, 0x3, 0xe, 0x3, 0x1b, 0xe, 0x0}, //3
{0x3, 0x7, 0xf, 0x1b, 0x1f, 0x3, 0x3, 0x0}, //4
{0x1f,0x18, 0x1e, 0x3, 0x3, 0x1b, 0xe, 0x0}, //5
{0xe, 0x1b, 0x18, 0x1e, 0x1b, 0x1b, 0xe, 0x0}, //6
{0x1f,0x3, 0x6, 0xc, 0xc, 0xc, 0xc, 0x0}, //7
{0xe, 0x1b, 0x1b, 0xe, 0x1b, 0x1b, 0xe, 0x0}, //8
{0xe, 0x1b, 0x1b, 0xf, 0x3, 0x1b, 0xe, 0x0}, //9
};
void loop()
{
if(desytki == 10) desytki = 0;
{
for(int i = 0; i < 8; i ++) //листает строки
{
matrix.setRow(3, i, CountDigits[desytki][i]);
}
desytki++;
// delay(10);
}
for(int j = 0; j < 10; j ++) // листает символы
{
for(int i = 0; i < 8; i ++) //листает строки
{
//0 - адрес, либо номер устройства на шине SPI
//j - индекс массива байт с символом
//i - текущий ряд на матрице
//CountDigits[i] - значение(byte) которым заполнится ряд
matrix.setRow(2, i, CountDigits[j][i]);// команда вывода массива
}
delay(300);
}
}
[/code]
В комментарии не вникал. Но если работает, то хорошо.
Небольшие замечания и предложения:
1) в 39 строке последняя запятая лишняя;
2) у вас десятки почему-то отображаются после единиц - единицы на матрице 2, а десятки на матрице 3 - поменяйте;
3) в прошлом коде вы свою матрицу "обозвали" LC, а в этом matrix - желательно сразу использовать одинаковое название (следующим этапом будет объединение скетчей и возникнет путаница и проблемы);
4) цифры размером 5х7, как мне кажется, будут маловаты, тем более, что место на матрице еще остается и по высоте и по ширине, а смотреть на них надо будет издали. Если хотите, то можете воспользоваться шрифтом, что я рисовал для своих часов. Он 6х8 и выглядит вот так:
Домашним заданием на этот раз для вас будет вывод чисел оформить как отдельную функцию, входящим параметром сделать число для отображения. Числа у нас использутся двузначные, поэтому на экране должно выглядеть примерно так, как и сейчас (с учетом замечания). Также сделайте так, чтобы показывалось не 01, 02, 03..., а 1, 2, 3..., т.е. без ноля спереди для однозначных чисел (он там только лишняя визуальная информация). Удачи.
Да. Например, пускай функция называется showNumber() (а вы, как хотите, так и называйте). В переменной, например, channel лежит число 12. Вызываем функцию showNumber(channel); - и на последних двух матрицах показывается это число 12.
Ну, если взялись за шрифт, то с функцией, надо понимать, справились? ;)
Кстати, о шрифте. В вашем скетче цифры закодированы построчно, т.е. 8 строк - 8 байтов. Гораздо эффективней кодировать такой шрифт не строками, а столбцами. Символы обычно выше, чем шире, тем более, что в нашем случае их высота максимум 8 точек. Например, в этом моем шрифте все цифры занимают в ширину 6 точек, а значит, закодировать их можно в 6 байт каждую, а в вашем изначальном так вообще 5. На 10 символах вроде бы выигрыш небольшой, но если нужно будет закодировать всю таблицу, то это уже будет чувствительно по объему. Кроме того, при таком кодировании, как в вашем скетче, можно рисовать символы шириной максимум 8 точек, но если кодировать по столбцам, то ширина символов не ограничена, да еще легко реализуется пропорциональный шрифт (когда разные символы имеют разную ширину).
Но это так, к слову. Для вашей задумки вполне устроит так, как есть. Переделывать не стоит.
[code]
void loop()
{
if(desytki == 10) desytki = 0;
{
for(int i = 0; i < 8; i ++) //листает строки
{
LC.setRow(3, i, CountDigits[desytki][i]);
}
desytki++;
}
for(int j = 0; j < 10; j ++) // листает символы
{
for(int i = 0; i < 8; i ++) //листает строки
{
//0 - адрес, либо номер устройства на шине SPI
//j - индекс массива байт с символом
//i - текущий ряд на матрице
//CountDigits[i] - значение(byte) которым заполнится ряд
LC.setRow(2, i, CountDigits[j][i]);// команда вывода массива
}
delay(1000);
}
}
[/code]
у меня тупик , если бы число с chenel было бы от0 до 9 то просто было бы подставить чтение из буфера , а как десятки вывести до меня не доходит
Ну как-бы мы уже проходили два замечательных оператора / и %. Подумайте, может они сгодятся нам для разделения числа на десятки и единицы. Впрочем, для нашего случая десятки можно даже и не выделять.
Нет, не то. Дайте ответ на простой вопрос. Что должно получиться в результате таких операций?
x = 14 / 10;
и y = 14 % 10;
Чему будут равны x и y? Узнаем насколько хорошо вы поняли, как работают эти операторы. Только сами и быстро, не надо писать скетч и смотреть, что выдаст ардуина.
С целочисленным делением ( / ), думаю, что понятно. Одно число делим на второе, дробную часть игнорируем и, как результат, оставляем только целую часть.
Теперь с оператором %. Тут все с точностью до наоборот. Тут целая часть игнорируется, а результатом операции будет то, что останется от деления.
Например, 11 % 5. Представляем себе как 11 = 5 * 2 + 1. Т.е. число 5 в числе 11 "уместится" дважды и еще плюс единица. Вот эта единица и будет результатом этой операции.
Или другой пример: 25 % 7 записываем как 25 = 7 * 3 + 4. Т.е. результат: 4.
об этом я как то не подумал а с другой стороны ничего страшного , вторй тогда вариан будет будет с двумя марицами и lsd
А если в качестве подсветки поставить RGB светодиоды, то по цвету подсветки можно определять уровень сигнала, например, красный - низкий уровень, синий - средний, зеленый - высокий. Всего три цвета - три уровня. Если мало, то смешивать и получать другие цвета и больше уровней.
В любом оборудовании, используемым в работе, самое главное, помимо безопасности, - это удобство им пользования, а уже в последнюю очередь понты. Понты - они такие, только в начале будет казаться, что это круто.
Жорошо пусить будет по вашему , ток можно я этот дабью с цифрами , а то меня испуг охватил я не знаю как это реализовать , я просто взялся за это матрицу а как она работает не допонимаю ,
LC.setColumn(channel / 8, channel % 8, 255 >> (8 - val));
channel это счетчик почему мы его делим на 8 я так понимаю это две матрицы , и чтобы отображать еще две нам надо увеличить условие до 32х а потом мы результат для столбиков делим (%) опять на 8? и что это (>>) за оператор такой ?
вы видели вот такие часы?
70 см ширина высота чисал около 20см
их видно метров с 50!
-----
так вот такого размера и при этом более яркие символы делаются из простой светодиодной ленты!!
управляется это всё микросхемой МАХ7219 - точно такой же как у вас в ваших матрицах!
так вот - сделать 16 ярких цифр размером 10см в высоту вообще не проблема!!
при этом чтобы это табло подключить к вашей программе достаточно будет также всего 4 провода и изменить ОДНУ строчку кода!!!!
ВЫ правы , панты они действительно такие , но мир катиться в тар тарары , интернет и телевиденье делает свое дело по разложению , но все хотят гавно в красивой упаковке , сейчас офисный планктон мжет мног умничать и пакпать одноразовые автомобили и х не впечатляет матер с конролькой на шее , это их право , хот быть обманутыми это их выбор , ведь еденственное за что человек несет ответственность это только за свой выбор , мой выбор научиться , и я отношусь к вам с благодарностью и уважение то что вы передаете знания , это достойно уважения , я тугодум и сложно обучаем но все же я не гоняюсь за теме вещами что мне ненужны , что нам социум навязывает , мне жаль время тратит в пустую
ELITE мы обезательно их сделаем обещаю ) и к стари ребят у меня есть одна идейка котрая может вам понравиться я задумал нечто глабальное , возможно вы станете еденомышлиниками , https://vk.com/boy_twink можем пообщаться если интересно
:) я вам предлагаю только варианты, в любом случае вам решать какую реализацию вы будете делать :)
В функции LC.setColumn в первом параметре указывается номер матрицы, на котрую выводим данные (от 0 до 3 в нашем случае). Второй параметр - это номер столбца в этой матрице (может принимать значение от 0 до 7, т.к. в каждой матрице всего восемь столбцов). Третий параметр - это непосредственно сами данные для отображения столбца.
Можно конечно и отдельно формировать изображение сначала для нулевой матрицы, потом для первой и т.д. Но ведь есть решение проще. Для понимания можно составить табличку:
x x/8 x%8
0 0 0
1 0 1
2 0 2
3 0 3
4 0 4
5 0 5
6 0 6
7 0 7
8 1 0
9 1 1
10 1 2
11 1 3
12 1 4
13 1 5
14 1 6
15 1 7
16 2 0
17 2 1
и т.д.
/ - это целочисленное деление, т.е. остается только целая часть, а % - это, наоборот, как раз "хвост" от деления.
Таким образом переменная х растет, а номер матрицы и столбца вычисляется "автоматически".
>> - это оператор побитового сдвига. Писать много. Это уже почитайте сами в описании по тем ссылкам, что я приводил.
сылки я скопировал почитаю обезательно а про оператор побитового сдвига я чтото в долеке припоминаю
нам тогда это нужно
Синтаксис вызова функции setRow() имеет вид:
+
matrix.setRow(address, row, value);
Где matrix - объект класса LedControl
Нужно уточнить, что отсчет рядов на LED матрице начинается сверху, то есть самый верхний ряд светодиодов будет нулевым рядом, а самый нижний будет 7-м рядом. Для примера можно создать скетч, который будет выводить на LED матрицу цифру 5. Но прежде всего, нужно понять какие светодиоды будут визуализировать эту цифру. Для этого на сайте есть замечательный "Редактор символов для матриц 8х8", перейдя по ссылке, можно создать свой символ просто кликая по полю 8х8, либо выбрать готовый символ из таблицы ниже. Воспользуемся вторым вариантом, выберем символ "5" из предложенной таблицы.
И вообще, новой информации вы получили много. Думаю, пока достаточно. Лучше было бы, чтобы вы внимательно перечитали еще хотя бы раз нашу переписку. Пропробовали вникнуть в суть. Почитали описание используемых функций. И, когда более менее разберетесь, тогда уж будете приступать к остальному. Сдвиг оставьте на закуску. Если не разберетесь сами со сдвигом, то буду объяснять на пальцах. Но это будет потом. Пока переваривайте ту информацию, что уже получили. А на сегодня хватит.
Спасибо большое , я у с утра все перечитаю и почитаю сылочки котрые вы мне прислали ), доброй ночи
добрый день
вот что получилось после разбора
channel - не просто счетчик - это номер канала c мультиплексора. Значение изменяется от 0 до 15, в двоичном виде будет так: B0000 (0), B0001(1), B0010(2) .... B1111(15).
bitRead из channel возвращает значение бита под номером i (номер 0 у крайнего правого бита) - то есть когда channel = 0 (B0000) в пинах S0 =0 , S1=0, S2=0, S3=0
когда channel = 10 (B1010) в пинах S0 =0 , S1=1, S2=0, S3=1
S0, S1, S2, S3 - это пины, к которым подключены мультиплексоры. С помощью этих пинов задается адрес входа мультиплексора, данные с которого будут передаваться в ардуино. Т.е. можно в виде таблицы представить для себя, как это происходит - при каких комбинациях какой вход выбран:
S3 S2 S1 S0 вход
0 0 0 0 0
0 0 0 1 1
0 0 1 0 2
0 0 1 1 3
0 1 0 0 4 и т.д.
По сути, комбинация нулей и единиц на пинах Sx - это двоичное представление привычных для нас десятичных цифр:
0 - 0000
1 - 0001
2 - 0010
3 - 0011
4 - 0100
...
14 - 1110
15 - 1111
Выше приведенный код с циклом можно написать и иначе:
Например, какая комбинация должна быть на пинах Sx, если channel будет равно 13?
Для этого представим, как выглядит число 13 в двоичном представлении (для перевода можно воспользоваться виндовским калькулятором, также принимаем, что у нас размерность чисел byte (или 8 бит)). А выглядит оно так: 00001101, но поскольку максимальное число у нас 15, и для его представления достаточно четырех бит, то нас интересуют только четыре последних, т.е. 1101 (для диапазона чисел 0-15 в четырех старших битах (первых четырех слева) всегда будут ноли, нас они не интересуют).
Таким образом, для выбора тринадцатого канала на мультиплексоре необходимо S3 выставить в 1, S2 - 1, S1 - 0 и S0 - 1. Вот для того, чтобы узнать, что же в числе на месте n-нного бита находится и существует функция bitRead(). Например, результатом bitRead(13, 0) будет 1 (1101), а bitRead(13, 1) будет 0 (1101) и т.д. Отсчет битов идет справа (самый правый имеет номер 0).
И еще.
Ну как бы массив не может сам определяться. Номера пинов мы запихнути в массив только для того, чтобы их можно было удобно выбирать по-очереди из цикла.
Тут да, в цикле мы по-очереди выбираем нужный пин из массива.
Но тут в массив данные не пишутся, а берутся оттуда. Т.е. выбираем очередной пин и на нем выставляем нужный уровень.
тоесть функция bitRead номер канала (channel) в переменую записывает (i) , а потом В controlPin[i] И ВСЕ ЭТО ВЫКЛАДЫВАЕТЬСЯ В МАССИВ?
Нет. Посмотрите лучше на второй вариант, где я написал, как это можно сделать без цикла и массива. Еще раз его напишу:
И вариант с циклом и этот вариант идентичны по сути и выполняются одинаково. Т.е. это то же самое, как развернуть тот цикл.
Тут первая строка - это то, что происходит при первом проходе цикла, когда i равна 0.
Вторая строка - при втором (i равна 1).
Третья строка - при третьем (i равна 2).
Четвертая строка - при четвертом последнем проходе (i равна 3).
Почитайте еще раз описание bitRead().
Также разберитесь с двоичной системой счисления, в частности двоичным представлением чисел. Без нее все эти байты, биты, сдвиги - пустые звуки и никогда не будут понятны.
я двоичную систему понимаю мне не понятна последовательнасть действий вырожения , digitalWrite(controlPin[i], bitRead(channel, i)) кто куда кому что записывает и кто куда что выдает , я так понимаю это не арефметическое дествие , а просто алгоритм
все дошло , bitRead(channel, i) крутим данные , потом читаем их из массива controlPin[i], а птом записываем digitalWrite в пин которому пренадлежат данные
Что делает digitalWrite(), я надеюсь, понимаете? Пишет что-то куда-то. Т.е. выставляет на требуемом пине нужное состояние - 1 (оно же HIGH) или 0 (оно же LOW). В первом параметре - номер пина, во втором - какое состояние на нем установить.
Т.е. digitalWrite(S0, bitRead(channel, 0)); установит на пине, указанном в S0, состояние, которое определяется с помощью bitRead(channel, 0). Так вот bitRead "пристально вглядывыется" в число, что находится в переменной channel, а конкретно "смотрит" в данном примере на его нулевой бит. И если он будет равен 1, то digitalWrite на пине S0 (в данном случае) выставит высокий уровень, т.е. 1 (HIGH). Если же бит будет равен 0, то и на пине выставится 0 (LOW).
В массив controlPin[] мы записали наш набор пинов и тут этот массив исключительно из-за удобства выбора пина в цикле.
да я усвоил усвоил , огромное спасибо я разобрался , для меня так быстрей доходит и возникают правильные вопросы кода я разбираю что то готовое
Правильнее было бы не только изучать и разбирать готовое, но и делать свои "микропрограммы", чтобы посмотреть, что интересующая функция делает в реальности.
я полность с вами согласен , детки сначало основопологаються на ощущения а потом обучаються , писать кирпичем на заборе как бы суть не меняеться но на бумаге ручкой как правильней , читать можно и через микроскоп или подзорную трубу как бы тоже можно но приятней книжку , на машине можно ездить задом но практичней передом , достич результата можно по разному , кто то живет методом тыка а ктото сулшает учиться и преобретает правильные инструменты которыми он будет творить , я же не предложил вам денги за написание программы а попрасил научить меня , хотя правильней нужно отблагодарить и подскажите как я это могу сделать для вас , по тому что это гаразда дороже денег , вы свою жизненую энергию тратите
Ну я уже не буду вникать в ваши комментарии, это вы сами разберетесь.
Если говорите, что с двоичной системой все понятно, то со сдвигом тоже разобрались?
знаете вот побольше бы таких людей как вы , особено в области медецыны , можно же налюдях тренироваться в плане медикоментов и смотреть на результаты ли бо же учиться у мастеров
да сдвиг я помню если приткнуть число со здвигом то цыфры сместятся , приблизительная анология бегущей строки , про маски тоже помню ,
с циферками мне поможете?
Да, так и есть, похоже больше даже не на бегущую строку, а на светомузыкальный бегущий огонь.
В нашем случае, за исходные данные берем полностью "горящий" столбик, т.е. все точки зажжены или все биты установлены в 1 - 11111111 (число 255 в десятичном виде). Если сдвигать этот столбик вправо (>>), то единички будут двигаться в направлении младшего бита (вправо), а в сташем бите будет появляться 0. Например, сдвинули 11111111 вправо на один раз - получили 01111111. Сдинули 11111111 вправо на пять раз - получили 00000111. Т.е., чем больше сдвигаем, тем короче столбик. Но, так как в нашем случае надо, чем больше значение переменной val, тем длиннее столбик (а значит надо меньше его двигать), то мы используем формулу 8 - val. Чем будет больше val, тем меньше сдвинется столбик.
Что касается цифр, то пока отложите этот скетч, и попробуйте в новом скетче выводить разные цифры и в разные места. Когда получится отдельно, тогда уже в этот скетч будем добавлять вывод цифр.
вот что соорудил
В комментарии не вникал. Но если работает, то хорошо.
Небольшие замечания и предложения:

1) в 39 строке последняя запятая лишняя;
2) у вас десятки почему-то отображаются после единиц - единицы на матрице 2, а десятки на матрице 3 - поменяйте;
3) в прошлом коде вы свою матрицу "обозвали" LC, а в этом matrix - желательно сразу использовать одинаковое название (следующим этапом будет объединение скетчей и возникнет путаница и проблемы);
4) цифры размером 5х7, как мне кажется, будут маловаты, тем более, что место на матрице еще остается и по высоте и по ширине, а смотреть на них надо будет издали. Если хотите, то можете воспользоваться шрифтом, что я рисовал для своих часов. Он 6х8 и выглядит вот так:
Домашним заданием на этот раз для вас будет вывод чисел оформить как отдельную функцию, входящим параметром сделать число для отображения. Числа у нас использутся двузначные, поэтому на экране должно выглядеть примерно так, как и сейчас (с учетом замечания). Также сделайте так, чтобы показывалось не 01, 02, 03..., а 1, 2, 3..., т.е. без ноля спереди для однозначных чисел (он там только лишняя визуальная информация). Удачи.
хорошо, спасибо , попробую , вот не понятно только с функцией , какие параметры вносить нужно будет ?
Параметром должно быть только число, что нужно показать на матрице. Других там никаких и не надо.
тоесть в переменную заносим десячиное число и она выводится на матрице?
Да. Например, пускай функция называется showNumber() (а вы, как хотите, так и называйте). В переменной, например, channel лежит число 12. Вызываем функцию showNumber(channel); - и на последних двух матрицах показывается это число 12.
Вот мой шрифт. Попробуйте, может понравится. Замените строки 28-42 в вашем скетче на эти:
я уже налисточке по битно рисовал , и сделат точно такой же ) по картинке , да мне понравился , циферки покрупенй )
Ну, если взялись за шрифт, то с функцией, надо понимать, справились? ;)
Кстати, о шрифте. В вашем скетче цифры закодированы построчно, т.е. 8 строк - 8 байтов. Гораздо эффективней кодировать такой шрифт не строками, а столбцами. Символы обычно выше, чем шире, тем более, что в нашем случае их высота максимум 8 точек. Например, в этом моем шрифте все цифры занимают в ширину 6 точек, а значит, закодировать их можно в 6 байт каждую, а в вашем изначальном так вообще 5. На 10 символах вроде бы выигрыш небольшой, но если нужно будет закодировать всю таблицу, то это уже будет чувствительно по объему. Кроме того, при таком кодировании, как в вашем скетче, можно рисовать символы шириной максимум 8 точек, но если кодировать по столбцам, то ширина символов не ограничена, да еще легко реализуется пропорциональный шрифт (когда разные символы имеют разную ширину).
Но это так, к слову. Для вашей задумки вполне устроит так, как есть. Переделывать не стоит.
к сожалению еще нет , время было не многдо до компьютера добрался только сейчас ,сейчас попробую слкепить функцию ,
chenel нужно сравнивать как то чтобы получить десятки еденицы раздельно ,
Ну как-бы мы уже проходили два замечательных оператора / и %. Подумайте, может они сгодятся нам для разделения числа на десятки и единицы. Впрочем, для нашего случая десятки можно даже и не выделять.
LC.setColumn(channel / 8, channel % 8, CountDigits[j][i]);
только if(channel == 16) channel = 0; придеться увеличит до 32, правильно ?
Нет, не то. Дайте ответ на простой вопрос. Что должно получиться в результате таких операций?
x = 14 / 10;
и
y = 14 % 10;
Чему будут равны x и y? Узнаем насколько хорошо вы поняли, как работают эти операторы. Только сами и быстро, не надо писать скетч и смотреть, что выдаст ардуина.
x= 1 , y =10
Нет.
ОК. Попытаюсь объяснить, возможно пригодится в будущем.
x= 0,0,0,0,0,0,0,0,0,0,1,1,1,1,
y= 0,1,2,3,4,5,6,7,8,9,0,1,2,3,
С целочисленным делением ( / ), думаю, что понятно. Одно число делим на второе, дробную часть игнорируем и, как результат, оставляем только целую часть.
Теперь с оператором %. Тут все с точностью до наоборот. Тут целая часть игнорируется, а результатом операции будет то, что останется от деления.
Например, 11 % 5. Представляем себе как 11 = 5 * 2 + 1. Т.е. число 5 в числе 11 "уместится" дважды и еще плюс единица. Вот эта единица и будет результатом этой операции.
Или другой пример: 25 % 7 записываем как 25 = 7 * 3 + 4. Т.е. результат: 4.