Приветствую всех. Имею непонятную проблему. использую библиотеку LedControl.h Управляет она тремя последовательно включенными микрухами MAX7219CWG. Т.е имеем 3 строки 7-ми сегментных индикаторов по 8 знаков в каждой. При загрузке значения отображаются на всех трех строках. Спустя 10-15 сек (каждый раз по разному) исчезает вторая строка, топом первая (иногда сразу обе), НО третья продолжает работать как ни в чем не бывало. 3-я строка самая последняя, т.е. сигнал проходит сквозняком через первые две микрухи. Проверил питание - стабильно 5В везде. Масса - отлично. Думал потеря на CLK,LOAD, нифига, сопротивление на дорожках 0,002 Ом (дальше тестер видимо не умеет). В общем полтергей какой-то... Беру тестовый скетч, DemoCascadedDevices - все пашет, сегменты везде загораются. А вот когда LCDDemo7Segment - первый раз показывает на всех строках, потом опять работает только 3-я. Я уже мозг сломал. Помогите!!! )) вот образец кода, без шелухи. Код (C++): // LedControl lc=LedControl(DIN,CLK,LOAD,количество модулей); LedControl lc=LedControl(3,5,4,3); setup lc.shutdown(0,false); // выключаем срящий режим перводо модуля lc.shutdown(1,false); // выключаем срящий режим второго модуля lc.shutdown(2,false); // выключаем срящий режим третьего модуля lc.clearDisplay(0); // Очистка первого дисплея lc.clearDisplay(1); // Очистка второго дисплея lc.clearDisplay(2); // Очистка второго дисплея lc.setIntensity(0,15); // яркость свечения первого модуля lc.setIntensity(1,15); // яркость свечения второго модуля lc.setIntensity(2,15); // яркость свечения второго модуля loop .... получение значений и вывод на экран через функцию .... void printDistance1(long v) { byte ones, tens, hundreds, thousands, tenthousands, fltens, flones; flones=v%10; v=v/10; fltens=v%10; v=v/10; ones=v%10; v=v/10; tens=v%10; v=v/10; hundreds=v%10; v=v/10; thousands=v%10; v=v/10; tenthousands=v%10; //Now print the number digit by digit lc.setDigit(1,7,tenthousands,false); lc.setDigit(1,6,thousands,false); lc.setDigit(1,5,hundreds,false); lc.setDigit(1,4,tens,false); lc.setDigit(1,3,ones,true); lc.setDigit(1,2,fltens,false); lc.setDigit(1,1,flones,false); lc.setDigit(1,0,flones,false); if (tenthousands == 0 & thousands==0 & hundreds==0 & tens==0) { lc.setScanLimit(1, 2); } else if (tenthousands == 0 & thousands==0 & hundreds==0) { lc.setScanLimit(1, 3); } else if (tenthousands == 0 & thousands==0) { lc.setScanLimit(1, 4); } else if (tenthousands == 0) { lc.setScanLimit(1, 5); } }
в этом образце только одна строка, с одной строкой у вас, как я понял,проблемы нет. Выкладывайте реально тот код, на котором возникает проблема
В этом коде возникает проблема, но как я и раньше писал, эта проблема возникает даже в дэмо коде к библиотеке. Код (C++): #include <EEPROM.h> // controller 7-segment LED indicator MAX7219 #include "LedControl.h" // Инициализация дисплеев // LedControl lc=LedControl(DIN,CLK,LOAD,количество модулей); LedControl lc=LedControl(3,5,4,3); // MAX7219 конец //клавиатура #include <Keypad.h> const byte ROWS = 4; //four rows const byte COLS = 4; //four columns //Указываем символы и знаки на клавиатуре char hexaKeys[ROWS][COLS] = { {'1','2','3','A'}, {'4','5','6','B'}, {'7','8','9','C'}, {'*','0','#','D'} }; byte rowPins[ROWS] = {13, 12, 11, 10}; //connect to the row pinouts of the keypad 9, 8, 7, 6 6, 7, 8, 9 byte colPins[COLS] = {9, 8, 7, 6}; //connect to the column pinouts of the keypad 10, 11, 12, 13 13, 12, 11, 10 //initialize an instance of class NewKeypad Keypad customKeypad = Keypad( makeKeymap(hexaKeys), rowPins, colPins, ROWS, COLS); ////// клавиатура конец //////////// // переменные для трипа volatile unsigned long trip_count, tripA_count, tripSpeedcount; // переменные для функции по прерыванию число импульсов датчика, счетчик одометра А,B для трип компьютера unsigned long eepromTime, coef1, coef2, coef3, coef, trip_counteeprom; // рассчитанное время длительности импульса + коэфициент пересчета/калибровка под разные диаметры колес int dist_A, dist_total; byte pedAres = 0; byte pedBres = 1; byte odoAres, odoBres; /// переменные для меню byte MenuPos =1; byte MenuPosMax = 3; byte Submenu = 1; byte SubmenuMax = 5; byte calselect = 1; // значение для меню для выбора конкретной калибровки byte calselectTotal = 3; // общее число возможных калибровок /// конец меню /// переменные для скорости int SPEED, SPEEDmax; /// конец переменных для скорости /// переменные для периода unsigned long period; /// конец переменных для париодов void setup() { Serial.begin(9600); customKeypad.setHoldTime(500); // Default is 1000mS lc.shutdown(0,false); // выключаем срящий режим перводо модуля lc.shutdown(1,false); // выключаем срящий режим второго модуля lc.shutdown(2,false); // выключаем срящий режим третьего модуля lc.clearDisplay(0); // Очистка первого дисплея lc.clearDisplay(1); // Очистка второго дисплея lc.clearDisplay(2); // Очистка второго дисплея lc.setIntensity(0,15); // яркость свечения первого модуля lc.setIntensity(1,15); // яркость свечения второго модуля lc.setIntensity(2,15); // яркость свечения второго модуля coef = 10; //coef = EEPROM_ulong_read(0); coef1 = EEPROM_ulong_read(4); coef2 = EEPROM_ulong_read(8); coef3 = EEPROM_ulong_read(12); trip_count = EEPROM_ulong_read(16); tripA_count = EEPROM_ulong_read(20); SPEEDmax = EEPROM.read(24); attachInterrupt(0, WheelSensor, CHANGE); } void loop() { printDistance0(dist_A); // вызываем функцию отображения на нижнем дисплее и рисуем там промежуточную дистанцию printDistance1(dist_total); // вызываем функцию отображения на вернем дисплее и рисуем там общую дистанцию printDistance2(SPEED); // показываем текущую скорость на выносном дисплее } void WheelSensor() { trip_count++; tripA_count++; //tripB_count++; //tripTime = millis(); tripSpeedcount++; } void printDistance0(long v) { byte ones, tens, hundreds, thousands, tenthousands, fltens, flones; flones=v%10; v=v/10; fltens=v%10; v=v/10; ones=v%10; v=v/10; tens=v%10; v=v/10; hundreds=v%10; v=v/10; thousands=v%10; v=v/10; tenthousands=v%10; //Now print the number digit by digit lc.setDigit(0,7,tenthousands,false); lc.setDigit(0,6,thousands,false); lc.setDigit(0,5,hundreds,false); lc.setDigit(0,4,tens,false); lc.setDigit(0,3,ones,true); lc.setDigit(0,2,fltens,false); lc.setDigit(0,1,flones,false); lc.setDigit(0,0,flones,false); if (tenthousands == 0 & thousands==0 & hundreds==0 & tens==0) { lc.setScanLimit(0, 2); } else if (tenthousands == 0 & thousands==0 & hundreds==0) { lc.setScanLimit(0, 3); } else if (tenthousands == 0 & thousands==0) { lc.setScanLimit(0, 4); } else if (tenthousands == 0) { lc.setScanLimit(0, 5); } } void printDistance1(long v) { byte ones, tens, hundreds, thousands, tenthousands, fltens, flones; flones=v%10; v=v/10; fltens=v%10; v=v/10; ones=v%10; v=v/10; tens=v%10; v=v/10; hundreds=v%10; v=v/10; thousands=v%10; v=v/10; tenthousands=v%10; //Now print the number digit by digit lc.setDigit(1,7,tenthousands,false); lc.setDigit(1,6,thousands,false); lc.setDigit(1,5,hundreds,false); lc.setDigit(1,4,tens,false); lc.setDigit(1,3,ones,true); lc.setDigit(1,2,fltens,false); lc.setDigit(1,1,flones,false); lc.setDigit(1,0,flones,false); if (tenthousands == 0 & thousands==0 & hundreds==0 & tens==0) { lc.setScanLimit(1, 2); } else if (tenthousands == 0 & thousands==0 & hundreds==0) { lc.setScanLimit(1, 3); } else if (tenthousands == 0 & thousands==0) { lc.setScanLimit(1, 4); } else if (tenthousands == 0) { lc.setScanLimit(1, 5); } } void printDistance2(long v) { byte ones, tens, hundreds, thousands, tenthousands, fltens, flones; flones=v%10; v=v/10; fltens=v%10; v=v/10; ones=v%10; v=v/10; tens=v%10; v=v/10; hundreds=v%10; v=v/10; thousands=v%10; v=v/10; tenthousands=v%10; //Now print the number digit by digit lc.setDigit(2,7,0,false); lc.setDigit(2,6,tenthousands,false); lc.setDigit(2,5,thousands,false); lc.setDigit(2,4,hundreds,false); lc.setDigit(2,3,tens,false); lc.setDigit(2,2,ones,true); lc.setDigit(2,1,fltens,false); lc.setDigit(2,0,flones,false); if (tenthousands == 0 & thousands==0 & hundreds==0 & tens==0) { lc.setScanLimit(2, 2); } else if (tenthousands == 0 & thousands==0 & hundreds==0) { lc.setScanLimit(2, 3); } else if (tenthousands == 0 & thousands==0) { lc.setScanLimit(2, 4); } else if (tenthousands == 0) { lc.setScanLimit(2, 5); } } // чтение unsigned long EEPROM_ulong_read(int addr) { byte raw[4]; for(byte i = 0; i < 4; i++) raw = EEPROM.read(addr+i); unsigned long &num = (unsigned long&)raw; return num; } // запись void EEPROM_ulong_write(int addr, unsigned long num) { byte raw[4]; (unsigned long&)raw = num; for(byte i = 0; i < 4; i++) EEPROM.write(addr+i, raw); }
В общем, разобрался. Оказывается нужно добавлять конденсатор 0,1мкф между 19 и 4 ногой MAX7219CWG. Так что в коде все ок.
Небольшая ремарка. Даже в стандартных/покупных модулях имеется недоработка в схемотехнике. Если подключать модуль короткими проводами, то все работает отлично. Но если вы используете провода длинее 5см, начинается пор..фия. Строки пропадают, знаки могут дублироваться, загораются лишние сегменты и пр. В результате нужно: - на КАЖДУЮ микросхему max7219 ставить емкости на питание/земля 0,1 мкФ керамика + 4,7-10мкФ Электролит - так же на ногу Din подтягивающий к земле резистор 10 кОм. В результате сегменты даже горят ярче. (это очень странно, но факт). Плюс библиотека ledcontrol.h поддерживает максимум 8 микросхем. Наверняка есть способ это обойти, но я пока не решил. В моей схеме к плате с МК подключен дисплей проводами 7см. В дисплее 3шт МС МАХ7219. За ними подключается выносной дисплей с 4мя МС МАХ7219 на проводе длиной 1м. На выносном дисплее также пришлось ставить емкости. В результате схема отлично заработала. Всем спасибо, план выполнен.