Вывод информации на 6 разрядов 7ми сегментного индикатора
- Войдите на сайт для отправки комментариев
Здравствуйте!
Для одного проекта потребовалось выводить 6 цифр подряд, т.е. нужно шесть разрядов. (За основу была взята работа отсуда.) Т.к. под рукой небыло ничего кроме индикаторов KEM-4021BS (сдвоенный семисегментный с ОА) соединил их на макетке и вывел с каждого в один A,B,C,D,E,F,G и на каждый сегмент "+".
Все это должно! работать в динамической индикации с двумя 74НС595.
НО! Вот тут и начинается проблема. Не хатает знаний в программировании.
int latchPin = 8; //Пин "защелки" первого регистра подключен к ST_CP входу первого регистра отвечающего за сегменты int clockPin = 12; //Пин подключен к SH_CP входу 74HC595 int dataPin = 11; //Пин подключен к DS входу 74HC595 int TimeLight = 5; //время для разогрева сегментов int sensorPin=A0; byte SegDisplay; // переменная для вывода символов на индикаторе byte RazrDisplay; // переменная для включения разрядов // Настройка комбинации для отображения каждого номера на дисплее. // Комбинация выбрана на основе таблицы отображаемого знака данным порта // Соответственно { 0 , 1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 , 9 , dp, - } byte g_digits[12]={192,249,164,176,153,146,130,248,128,144,127,255}; //массив цифр, генерирующий из сегментов цифры byte g_registerArray[6]={1,2,4,8,16,32}; //массив цифр, указывающий разряды void setup() { // обозначаем все пины как выходы pinMode(latchPin, OUTPUT); pinMode(clockPin, OUTPUT); pinMode(dataPin, OUTPUT); } void loop() { int disp = 0; //создаем переменную для вывода на экран disp = 8888; // Разбиваем цифру по разрядам индикатора if (disp < 10) // если наша цифра меньше 10, то { Indicate(0, 11); // пишем в первый разряд пусто Indicate(1, 11); // пишем во второй разряд пусто Indicate(2, 11); // пишем в третий разряд пусто Indicate(3, 11); // пишем в третий разряд пусто Indicate(4, 11); // пишем в третий разряд пусто Indicate(5, disp); // пишем в четвертый разряд нашу цифру } else if (disp < 100) // если наша цифра меньше 100, то { Indicate(0, 11); // пишем в первый разряд пусто Indicate(1, 11); // пишем во второй разряд пусто Indicate(2, 11); // пишем во второй разряд пусто Indicate(3, 11); // пишем во второй разряд пусто Indicate(4, disp / 10); // пишем в третий разряд - цифру делёную на 10 Indicate(5, disp % 10); // пишем в четвертый разряд цифру оставшуюся от деления на 10 } else if (disp < 1000) { Indicate(0, 11); Indicate(1, 11); Indicate(2, 11); Indicate(3, disp / 100); Indicate(4, (disp % 100) / 10); Indicate(5, disp % 10); } else if (disp < 10000) { Indicate(0, 11); Indicate(1, 11); Indicate(2, disp / 1000); Indicate(3, (disp % 1000) / 100); Indicate(4, (disp % 100) / 10); Indicate(5, disp % 10); } else if (disp < 100000) { Indicate(0, 11); Indicate(1, disp / 10000); Indicate(2, (disp % 10000) / 1000); Indicate(3, (disp % 1000) / 100); Indicate(4, (disp % 100) / 10); Indicate(5, disp % 10); } else { Indicate(0, disp / 1000000); Indicate(1, (disp % 100000) / 10000); Indicate(2, (disp % 10000) / 1000); Indicate(3, (disp % 1000) / 100); Indicate(4, (disp % 100) / 10); Indicate(5, disp % 10); } } void Indicate(int r,int x) { SegDisplay=g_digits[x]; // получаем цифру и выводим символ, из массива цифр, соответствующий этой цифре. RazrDisplay=g_registerArray[r]; // получаем цифру и выводим номер регистра, из массива цифр, соответствующий этой цифре. digitalWrite(latchPin, LOW); // устанавливаем синхронизацию "защелки" на LOW shiftOut(dataPin, clockPin, MSBFIRST, RazrDisplay); // Записываем информацию для второго регистра (Номер разряда) shiftOut(dataPin, clockPin, MSBFIRST, SegDisplay); // Записываем информацию для первого регистра (Номер символа) digitalWrite(latchPin, HIGH); //"защелкиваем" регистр, тем самым устанавливая значения на выходах delay(TimeLight); // пауза, чтобы сегменты "разгорелись" }
Как видно из кода, за вывод цифр (значений) отвечает переменная disp.
Если число из 4х знаков, то все отображается отлично
disp=7777;
Если знаков больше четырех, то показывает все что угодно.
disp=77777;
По этому прошу помочь. Расскажите где я ошибся и как это исправить. Буду очень благодарен!
А готовый 8-разрядный индикатор чем не устраивает?
http://ru.aliexpress.com/item/J34-Free-Shipping-1PCs-8-Bits-Digital-Tube-LED-Display-Module-Eight-Serial-for-Arduino-595/32402492405.html?spm=2114.30010708.3.2.b0oJpO&ws_ab_test=searchweb201556_2,searchweb201644_5_505_506_503_504_301_502_10001_10002_10016_10005_10006_10012_10003_10004_10007,searchweb201560_8,searchweb1451318400_-1,searchweb1451318411_6448&btsid=95d99567-d907-4294-9819-0955122e9f41
164р
http://ru.aliexpress.com/item/7-Segment-LED-Display-Module-5V-MAX7219-High-Quality-8-Bit-Red-Digital-Tube-For-Arduino/32551946287.html?spm=2114.30010708.3.61.b0oJpO&ws_ab_test=searchweb201556_2,searchweb201644_5_505_506_503_504_301_502_10001_10002_10016_10005_10006_10012_10003_10004_10007,searchweb201560_8,searchweb1451318400_-1,searchweb1451318411_6448&btsid=95d99567-d907-4294-9819-0955122e9f41
на макс7219 - 375р
http://ru.aliexpress.com/item/MAX7219-8-bit-digital-tube-display-module-...
тоже на максе 198р
Я в курсе существования Aliexpress и что на нем есть. Я же сказал, что использовал то что было у меня в наличии.
Когда я задумал 3 месяца назад свой проект и хотел хоть прикинуть варианты реализации - поставил протеуса и нарисовал в минимальном варианте схему. Т.к. модуль 4-секционного индикатора в моделях протеуса не нашел - подкинул 4 индикатора и 595, на нем и опробовал как будет выглядеть. Но перед этим заказал индикаторы с али. После НГ они приехали - и через пару недель на макете все заработало.
Могу кинуть на свой проект в протеусе - но там 4 секции. Но можно добавить еще 2 и разбираться с кодом....
Причина в строке 26
int disp = 0;
максимальное значение 32767. Надо
long disp;
Andy, огромное спасибо. Я бы наверное и не додумался.
Теперь все нормально работает.
disp=123456;
и еще сразу обнаружилась ошибка в строке 81.
ее заменить на
Продолжаю свой проект дальше и сталкнулся с новой проблемой. Проблема заключается в некорректном отображении данных, а конкретно с миганием которое я убрать не могу.
Вот как выглядит проблема:
Думал записывать данные в EEPROM, но не помогло.
Вот в чем вопрос- как убрать мигание значений температуры? И если такое возможно, как добавить после темпетаруты знак "С"?
Продолжаю свой проект дальше и сталкнулся с новой проблемой. Проблема заключается в некорректном отображении данных, а конкретно с миганием которое я убрать не могу.
Некорректное отображение данных - это отображение заведомо неправильных данных.
Мигание индикатора - это неправильная работа системы отображения.
Что есть совсем разные вещи %(
Вот в чем вопрос- как убрать мигание значений температуры? И если такое возможно, как добавить после темпетаруты знак "С"?
Запись в еепром еще более длительная процедура. Кстати о птичках - память еепром имеет таки ограниченное число циклов записи - и использование ее вместо РАМ просто убьет чип. Впрочем 150р не деньги даже в условиях кризиса - можно и поменять... Только ждать с али долго, а покупать у нас дорого.
Убрать мигание очень просто - использовать не проц ардуино для розжига индикатора, а использовать контроллер который сам реализует динамическое управление индикатором. Цена вопроса копеечная, но принципы важнее.....
Знак С в HEX==12
Т.е. нормальный контроллер с библой знает как минимум 16-ю ситему - 0-9,A,b,C,d,E,F
другие символы нужно лепить самому правкой библиотеки. Если понимаешь что и как делать.
PS - мне пока не надо - потому не делал.
Да, орфографию поправь плиз....
С динамической индикацией я вообще не знаком поэтому буду разбираться как эт о вообще работает.
К вопросу о символе "С", не могу правильно записать строчку, что-то неправильно делаю.
disp = dht.readHumidity(), 199; - так не работает
Добавить в массив цифру
byte g_digits[13] = {192, 249, 164, 176, 153, 146, 130, 248, 128, 144, 127, 255, 198}; //массив цифр, генерирующий из сегментов цифры
Попробовать в какй нибудь разряд, например в 0:
Indicate(0, 12);
Код нужно несколько переписать.... завтра набросаю.
Возьми библу от тм1637 например - там 16 шестнадцеритьчных цифр....
static int8_t TubeTab[] = {0x3f,0x06,0x5b,0x4f,
0x66,0x6d,0x7d,0x07,
0x7f,0x6f,0x77,0x7c,
0x39,0x5e,0x79,0x71};//0~9,A,b,C,d,E,F
Вот так для начала