LED-матрица + MAX7219 + MaxMatrix.lib

Jenek_Anapa
Offline
Зарегистрирован: 13.02.2018

об этом я как то не подумал а с другой стороны ничего страшного ,  вторй тогда вариан будет будет с двумя марицами и lsd

vk007
Offline
Зарегистрирован: 16.06.2015

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

vk007
Offline
Зарегистрирован: 16.06.2015

В любом оборудовании, используемым в работе, самое главное, помимо безопасности, - это удобство им пользования, а уже в последнюю очередь понты. Понты - они такие, только в начале будет казаться, что это круто.

Jenek_Anapa
Offline
Зарегистрирован: 13.02.2018

Жорошо пусить будет по вашему , ток можно я  этот дабью с цифрами , а то меня испуг охватил я не знаю как  это реализовать , я просто взялся за это матрицу а как она работает не допонимаю ,

 LC.setColumn(channel / 8, channel % 8, 255 >> (8 - val));

channel это счетчик  почему мы его делим на 8 я так понимаю это две матрицы , и чтобы отображать еще две нам надо увеличить условие до 32х  а потом мы результат для столбиков   делим (%) опять на 8? и что это (>>) за оператор такой ?

ELITE
ELITE аватар
Offline
Зарегистрирован: 11.01.2018

вы видели вот такие часы?

70 см ширина высота чисал около 20см

их видно метров с 50!

-----

так вот такого размера и при этом более яркие символы делаются из простой светодиодной ленты!! 

управляется это всё микросхемой МАХ7219 - точно такой же как у вас в ваших матрицах!

так вот - сделать 16 ярких цифр размером 10см в высоту вообще не проблема!!

при этом чтобы это табло подключить к вашей программе достаточно будет также всего 4 провода и изменить ОДНУ строчку кода!!!!

Jenek_Anapa
Offline
Зарегистрирован: 13.02.2018

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

Jenek_Anapa
Offline
Зарегистрирован: 13.02.2018

ELITE мы обезательно их сделаем  обещаю )  и к стари ребят у меня есть одна идейка котрая может вам понравиться я задумал нечто глабальное , возможно вы станете еденомышлиниками , https://vk.com/boy_twink можем пообщаться если интересно 

vk007
Offline
Зарегистрирован: 16.06.2015

:) я вам предлагаю только варианты, в любом случае вам решать какую реализацию вы будете делать :)

В функции 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
и т.д.

/ - это целочисленное деление, т.е. остается только целая часть, а % - это, наоборот, как раз "хвост" от деления.

Таким образом переменная х растет, а номер матрицы и столбца вычисляется "автоматически".

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

Jenek_Anapa
Offline
Зарегистрирован: 13.02.2018

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

нам тогда это нужно

Синтаксис вызова функции setRow() имеет вид:
+

matrix.setRow(address, row, value);

Где matrix - объект класса LedControl

  • address - номер, или адрес устройства(LED матрицы) на шине SPI, в нашем случае будет равен нулю, так как устройство одно.
  • row - ряд на LED матрице.
  • value - значение(тип данных byte) которым заполнится ряд.

Нужно уточнить, что отсчет рядов на LED матрице начинается сверху, то есть самый верхний ряд светодиодов будет нулевым рядом, а самый нижний будет 7-м рядом. Для примера можно создать скетч, который будет выводить на LED матрицу цифру 5. Но прежде всего, нужно понять какие светодиоды будут визуализировать эту цифру. Для этого на сайте есть замечательный "Редактор символов для матриц 8х8", перейдя по ссылке, можно создать свой символ просто кликая по полю 8х8, либо выбрать готовый символ из таблицы ниже. Воспользуемся вторым вариантом, выберем символ "5" из предложенной таблицы. 

vk007
Offline
Зарегистрирован: 16.06.2015

И вообще, новой информации вы получили много. Думаю, пока достаточно. Лучше было бы, чтобы вы внимательно перечитали еще хотя бы раз нашу переписку. Пропробовали вникнуть в суть. Почитали описание используемых функций. И, когда более менее разберетесь, тогда уж будете приступать к остальному. Сдвиг оставьте на закуску. Если не разберетесь сами со сдвигом, то буду объяснять на пальцах. Но это будет потом. Пока переваривайте ту информацию, что уже получили. А на сегодня хватит.

Jenek_Anapa
Offline
Зарегистрирован: 13.02.2018

Спасибо большое , я у с утра все перечитаю и почитаю сылочки котрые вы мне прислали ), доброй ночи 

Jenek_Anapa
Offline
Зарегистрирован: 13.02.2018

добрый день 

[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]

вот что получилось после разбора 

ven-til
Offline
Зарегистрирован: 13.02.2018

Jenek_Anapa пишет:
channel переменая - просто счетчик

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

vk007
Offline
Зарегистрирован: 16.06.2015

Jenek_Anapa пишет:

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

Выше приведенный код с циклом можно написать и иначе:

digitalWrite(S0, bitRead(channel, 0));
digitalWrite(S1, bitRead(channel, 1));
digitalWrite(S2, bitRead(channel, 2));
digitalWrite(S3, bitRead(channel, 3));

Например, какая комбинация должна быть на пинах 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).

 

vk007
Offline
Зарегистрирован: 16.06.2015

И еще.

Jenek_Anapa пишет:

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]" с этим понято что в массив записуються данные по очереди
} 

Тут да, в цикле мы по-очереди выбираем нужный пин из массива.
Но тут в массив данные не пишутся, а берутся оттуда. Т.е. выбираем очередной пин и на нем выставляем нужный уровень.

Jenek_Anapa
Offline
Зарегистрирован: 13.02.2018

тоесть функция bitRead  номер канала (channel) в переменую записывает  (i) , а  потом В controlPin[i] И ВСЕ  ЭТО ВЫКЛАДЫВАЕТЬСЯ В МАССИВ?

vk007
Offline
Зарегистрирован: 16.06.2015

Нет. Посмотрите лучше на второй вариант, где я написал, как это можно сделать без цикла и массива. Еще раз его напишу:

digitalWrite(S0, bitRead(channel, 0));
digitalWrite(S1, bitRead(channel, 1));
digitalWrite(S2, bitRead(channel, 2));
digitalWrite(S3, bitRead(channel, 3));

И вариант с циклом и этот вариант идентичны по сути и выполняются одинаково. Т.е. это то же самое, как развернуть тот цикл.

Тут первая строка - это то, что происходит при первом проходе цикла, когда i равна 0.
Вторая строка - при втором (i равна 1).
Третья строка - при третьем (i равна 2).
Четвертая строка - при четвертом последнем проходе (i равна 3).

Почитайте еще раз описание bitRead().

vk007
Offline
Зарегистрирован: 16.06.2015

Также разберитесь с двоичной системой счисления, в частности двоичным представлением чисел. Без нее все эти байты, биты, сдвиги - пустые звуки и никогда не будут понятны.

Jenek_Anapa
Offline
Зарегистрирован: 13.02.2018

я двоичную систему понимаю  мне не понятна последовательнасть действий вырожения , digitalWrite(controlPin[i], bitRead(channel, i)) кто куда кому что записывает и кто куда что выдает , я так понимаю  это не арефметическое  дествие , а просто алгоритм 

Jenek_Anapa
Offline
Зарегистрирован: 13.02.2018

все дошло , bitRead(channel, i) крутим данные , потом читаем  их из массива controlPin[i], а птом записываем  digitalWrite в пин которому пренадлежат данные 

vk007
Offline
Зарегистрирован: 16.06.2015

Что делает digitalWrite(), я надеюсь, понимаете? Пишет что-то куда-то. Т.е. выставляет на требуемом пине нужное состояние - 1 (оно же HIGH) или 0 (оно же LOW). В первом параметре - номер пина, во втором - какое состояние на нем установить.

Т.е. digitalWrite(S0, bitRead(channel, 0)); установит на пине, указанном в S0, состояние, которое определяется с помощью bitRead(channel, 0). Так вот bitRead "пристально вглядывыется" в число, что находится в переменной channel, а конкретно "смотрит" в данном примере на его нулевой бит. И если он будет равен 1, то digitalWrite на пине S0 (в данном случае) выставит высокий уровень, т.е. 1 (HIGH). Если же бит будет равен 0, то и на пине выставится 0 (LOW).

vk007
Offline
Зарегистрирован: 16.06.2015

В массив controlPin[] мы записали наш набор пинов и тут этот массив исключительно из-за удобства выбора пина в цикле.

Jenek_Anapa
Offline
Зарегистрирован: 13.02.2018

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

vk007
Offline
Зарегистрирован: 16.06.2015

Правильнее было бы не только изучать и разбирать готовое, но и делать свои "микропрограммы", чтобы посмотреть, что интересующая функция делает в реальности.

Jenek_Anapa
Offline
Зарегистрирован: 13.02.2018
[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]


я все законспектировал

 

Jenek_Anapa
Offline
Зарегистрирован: 13.02.2018

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

vk007
Offline
Зарегистрирован: 16.06.2015

Ну я уже не буду вникать в ваши комментарии, это вы сами разберетесь.

Если говорите, что с двоичной системой все понятно, то со сдвигом тоже разобрались?

Jenek_Anapa
Offline
Зарегистрирован: 13.02.2018

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

Jenek_Anapa
Offline
Зарегистрирован: 13.02.2018

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

Jenek_Anapa
Offline
Зарегистрирован: 13.02.2018

с циферками мне поможете?

 

vk007
Offline
Зарегистрирован: 16.06.2015

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

В нашем случае, за исходные данные берем полностью "горящий" столбик, т.е. все точки зажжены или все биты установлены в 1 - 11111111 (число 255 в десятичном виде). Если сдвигать этот столбик вправо (>>), то единички будут двигаться в направлении младшего бита (вправо), а в сташем бите будет появляться 0. Например, сдвинули 11111111 вправо на один раз - получили 01111111. Сдинули 11111111 вправо на пять раз - получили 00000111. Т.е., чем больше сдвигаем, тем короче столбик. Но, так как в нашем случае надо, чем больше значение переменной val, тем длиннее столбик (а значит надо меньше его двигать), то мы используем формулу 8 - val. Чем будет больше val, тем меньше сдвинется столбик.

Что касается цифр, то пока отложите этот скетч, и попробуйте в новом скетче выводить разные цифры и в разные места. Когда получится отдельно, тогда уже в этот скетч будем добавлять вывод цифр.

Jenek_Anapa
Offline
Зарегистрирован: 13.02.2018
[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]

вот что соорудил 

vk007
Offline
Зарегистрирован: 16.06.2015

В комментарии не вникал. Но если работает, то хорошо.

Небольшие замечания и предложения:
  1) в 39 строке последняя запятая лишняя;
  2) у вас десятки почему-то отображаются после единиц - единицы на матрице 2, а десятки на матрице 3 - поменяйте;
  3) в прошлом коде вы свою матрицу "обозвали" LC, а в этом matrix -  желательно сразу использовать одинаковое название (следующим этапом будет объединение скетчей и возникнет путаница и проблемы);
  4) цифры размером 5х7, как мне кажется, будут маловаты, тем более, что место на матрице еще остается и по высоте и по ширине, а смотреть на них надо будет издали. Если хотите, то можете воспользоваться шрифтом, что я рисовал для своих часов. Он 6х8 и выглядит вот так:

Домашним заданием на этот раз для вас будет вывод чисел оформить как отдельную функцию, входящим параметром сделать число для отображения. Числа у нас использутся двузначные, поэтому на экране должно выглядеть примерно так, как и сейчас (с учетом замечания). Также сделайте так, чтобы показывалось не 01, 02, 03..., а 1, 2, 3..., т.е. без ноля спереди для однозначных чисел (он там только лишняя визуальная информация). Удачи.

Jenek_Anapa
Offline
Зарегистрирован: 13.02.2018

хорошо, спасибо , попробую , вот не понятно только с функцией , какие параметры вносить нужно будет ?

vk007
Offline
Зарегистрирован: 16.06.2015

Параметром должно быть только число, что нужно показать на матрице. Других там никаких и не надо.

Jenek_Anapa
Offline
Зарегистрирован: 13.02.2018

тоесть в переменную заносим десячиное  число и она выводится на матрице?

vk007
Offline
Зарегистрирован: 16.06.2015

Да. Например, пускай функция называется showNumber() (а вы, как хотите, так и называйте). В переменной, например, channel лежит число 12. Вызываем функцию showNumber(channel); - и на последних двух матрицах показывается это число 12.

vk007
Offline
Зарегистрирован: 16.06.2015

Вот мой шрифт. Попробуйте, может понравится. Замените строки 28-42 в вашем скетче на эти:

const byte CountDigits[10][8] =
{
  { 0x3C, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x3C },  // 0
  { 0x18, 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x7E },  // 1
  { 0x7C, 0x06, 0x06, 0x06, 0x0C, 0x18, 0x30, 0x7E },  // 2
  { 0x7C, 0x06, 0x06, 0x3C, 0x06, 0x06, 0x06, 0x7C },  // 3
  { 0x0E, 0x1E, 0x36, 0x66, 0x66, 0x7E, 0x06, 0x06 },  // 4
  { 0x7E, 0x60, 0x60, 0x7C, 0x06, 0x06, 0x06, 0x7C },  // 5
  { 0x1C, 0x30, 0x60, 0x7C, 0x66, 0x66, 0x66, 0x3C },  // 6
  { 0x7E, 0x06, 0x06, 0x0C, 0x0C, 0x18, 0x18, 0x18 },  // 7
  { 0x3C, 0x66, 0x66, 0x3C, 0x66, 0x66, 0x66, 0x3C },  // 8
  { 0x3C, 0x66, 0x66, 0x66, 0x3E, 0x06, 0x0C, 0x38 }   // 9
};

 

Jenek_Anapa
Offline
Зарегистрирован: 13.02.2018

 я уже налисточке по битно рисовал , и сделат точно такой же ) по картинке , да мне понравился , циферки покрупенй )

 

vk007
Offline
Зарегистрирован: 16.06.2015

Ну, если взялись за шрифт, то с функцией, надо понимать, справились? ;)

Кстати, о шрифте. В вашем скетче цифры закодированы построчно, т.е. 8 строк - 8 байтов. Гораздо эффективней кодировать такой шрифт не строками, а столбцами. Символы обычно выше, чем шире, тем более, что в нашем случае их высота максимум 8 точек. Например, в этом моем шрифте все цифры занимают в ширину 6 точек, а значит, закодировать их можно в 6 байт каждую, а в вашем изначальном так вообще 5. На 10 символах вроде бы выигрыш небольшой, но если нужно будет закодировать всю таблицу, то это уже будет чувствительно по объему. Кроме того, при таком кодировании, как в вашем скетче, можно рисовать символы шириной максимум 8 точек, но если кодировать по столбцам, то ширина символов не ограничена, да еще легко реализуется пропорциональный шрифт (когда разные символы имеют разную ширину).

Но это так, к слову. Для вашей задумки вполне устроит так, как есть. Переделывать не стоит.

Jenek_Anapa
Offline
Зарегистрирован: 13.02.2018

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

Jenek_Anapa
Offline
Зарегистрирован: 13.02.2018
[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 то просто было бы подставить чтение из буфера , а как десятки вывести до меня не доходит 

 

Jenek_Anapa
Offline
Зарегистрирован: 13.02.2018

chenel нужно сравнивать  как то чтобы получить десятки еденицы раздельно , 

vk007
Offline
Зарегистрирован: 16.06.2015

Ну как-бы мы уже проходили два замечательных оператора / и %. Подумайте, может они сгодятся нам для разделения числа на десятки и единицы. Впрочем, для нашего случая десятки можно даже и не выделять.

Jenek_Anapa
Offline
Зарегистрирован: 13.02.2018

LC.setColumn(channel / 8, channel % 8, CountDigits[j][i]); 

только if(channel == 16) channel = 0;   придеться увеличит до 32, правильно ?

 

vk007
Offline
Зарегистрирован: 16.06.2015

Нет, не то. Дайте ответ на простой вопрос. Что должно получиться в результате таких операций?

x = 14 / 10;
и
y = 14 % 10;

Чему будут равны x и y? Узнаем насколько хорошо вы поняли, как работают эти операторы. Только сами и быстро, не надо писать скетч и смотреть, что выдаст ардуина.

Jenek_Anapa
Offline
Зарегистрирован: 13.02.2018

x= 1 , y =10

vk007
Offline
Зарегистрирован: 16.06.2015

Нет.

ОК. Попытаюсь объяснить, возможно пригодится в будущем.

Jenek_Anapa
Offline
Зарегистрирован: 13.02.2018

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,

     

vk007
Offline
Зарегистрирован: 16.06.2015

С целочисленным делением ( / ), думаю, что понятно. Одно число делим на второе, дробную часть игнорируем и, как результат, оставляем только целую часть.

Теперь с оператором %. Тут все с точностью до наоборот. Тут целая часть игнорируется, а результатом операции будет то, что останется от деления.

Например, 11 % 5. Представляем себе как 11 = 5 * 2 + 1. Т.е. число 5 в числе 11 "уместится" дважды и еще плюс единица. Вот эта единица и будет результатом этой операции.
Или другой пример: 25 % 7 записываем как 25 = 7 * 3 + 4. Т.е. результат: 4.