Arduino + 4-хразрядный семисегментник + сдвиговые регистры
- Войдите на сайт для отправки комментариев
Чт, 11/09/2014 - 17:55
Имеется Arduino UNO R3 + 4-хразрядный семисегментник (китайский 5461as с четырьмя точками и без двоеточия) + сдвиговые регистры.
Подскажите как на таком дисплее выводить обратный отсчет от 59.59 до 0 и задействовать минимум выходов?
Как всё это правильно подключить и потом этим управлять? Напрямую разобрался с подключением, но задействовать сразу 12 портов - это перебор.
Буду благодарен за любую помощь.
уже все куплено или на стадии выбора?
Уже всё куплено... если вопрос в мелочевке, то можно пересмотреть варианты исполнения
Уже всё куплено... если вопрос в мелочевке, то можно пересмотреть варианты исполнения
Вопрос, а вы поиском умеете пользоваться?
Да умею, и очень не плохо... но может вы лучше умеете?
Да умею, и очень не плохо... но может вы лучше умеете?
Пользуйтесь. Тут целые тома про сдвиговые регистры и семисигментные индикаторы. Не плодите темы.
Целые тома обсуждения - да, но ни одного конкретного примера... да и как еще обратный отсчет (а не просто собрать схему и вывести одинаковые циферки) заставить при этом работать - вот ведь в чем вопрос.
Целые тома обсуждения - да, но ни одного конкретного примера... да и как еще обратный отсчет (а не просто собрать схему и вывести одинаковые циферки) заставить при этом работать - вот ведь в чем вопрос.
Вы уверены что взялись за то что вам по плечу? Если все настолько запущено, может тогда в ищю исполнителя?
Ну как вариант, может кто согласиться баксов за 25 в час заниматься с вами основами.
какой уровень владения программированием? почитай про динамическую индикацию, там и пример кода чтобы пока без сдвиговых регистров сделать
какой уровень владения программированием? почитай про динамическую индикацию, там и пример кода чтобы пока без сдвиговых регистров сделать
Ну ты спросил. Какой уровень, угадай сам, если вопрос стоит как время наоборот отсчитывать.
ну да. но ничего. разберется. только все объяснять не буду. пусть сам разбирается, только буду говорить в какую сторону копать
а если снова лентяй нафиг забью. посмотрим что за человек
А он уже убежал.
Убежал... конечно.... круглосуточно не сижу за компом...
Обратный отсчет при прямом подключении удалось сделать по вот такой инструкции: http://www.hobbytronics.co.uk/arduino-countdown-timer
Уже более-менее представляю себе как подключить через сдвиговые регистры, но вот во-первых с первого раза не получилось, а во-вторых не понимаю как на них засылать сигналы для двух регистров и 4х разрядов 7-мисегментника...
А тут, я смотрю, больше любители носом потыкать, чем куда-то по конкретному адресу послать. Да, я не профи, это всего лишь хоби в свободное время.
upd. в субботу попробую еще раз с нуля собрать
ну смотри сам. а вообще ты хочешь научится или чтобы тебе готовый код дали?
а выше уже писал. не собираюсь за тебя все делать. мозг включи, а куда копать подскажу
Хочет что бы послали по конкретному адресу. :)
Учитывая, что конечное устройство - это "игра аля разминируй" - запускается таймер и введя цифровой код с клавиатуры она "разряжается" - то все-таки сам хочу научиться. С клавиатурой и с вводом и проверкой пароля разобрался... тут как бы знаний хватило... а во со связкой сдвиговый + семисегментник пока не очень въезжаю.
А что касается готового варианта - то я бы заказал готовое устройство - в смысле уже распаянную плату. Если есть в Одессе кому - скидывайте контакты. Наличие ардуины в схеме совсем не обязательно.
Но второй вариант не отменяет первого :)
Целые тома обсуждения - да, но ни одного конкретного примера... да и как еще обратный отсчет (а не просто собрать схему и вывести одинаковые циферки) заставить при этом работать - вот ведь в чем вопрос.
Мне какжется, кто-то себя сильно переоценил... раз так в 10, как минимум :)
Вам кажется. Я за 50 в час еще размышляю надо оно мне с дома выходить. А за 25 и кого то обучать, однозначно НЕТ.
а не легче было сразу такой дисплей купить))) там и динамическая инидкация. и регулировка яркости и пины экономит
http://ru.aliexpress.com/item/MAX7219-Red-Module-8-Digit-7-Segment-Digit...
Я бы рекомендовал использовать драйвер дисплея MAX7219 - он как раз для дисплеев с общим катодом(к одной MAX7219 можно подключить 2 таких дисплея).
а не легче было сразу такой дисплей купить))) там и динамическая инидкация. и регулировка яркости и пины экономит
http://ru.aliexpress.com/item/MAX7219-Red-Module-8-Digit-7-Segment-Digit...
Я тут твое учительство по 25 баксов в час продаю.:)
Целые тома обсуждения - да, но ни одного конкретного примера... да и как еще обратный отсчет (а не просто собрать схему и вывести одинаковые циферки) заставить при этом работать - вот ведь в чем вопрос.
Мне какжется, кто-то себя сильно переоценил... раз так в 10, как минимум :)
...самокритика - тоже иногда нужна :)-
хорошо пухлявый. деньги пополам))
хорошо пухлявый. деньги пополам))
Мне не нужно. Все 100% тебе. Ибо работа нервная. А у тебя еще девушка и все такое.
да тут хоть помогай, хоть флуди, хоть хвали все равно мудаком останешься))
хорошо пухлявый. деньги пополам))
распилили бабло ? а Лешак ?
да тут хоть помогай, хоть флуди, хоть хвали все равно мудаком останешься))
правильно тут Пухлявый подметил - изменились вы, а вот ваш кот ( аватарный ) - нет ! :)
а лешак ничего не писал
))) я похоже теперь больше стал походит на аватарку
моя просто думал , что он с любой темы про коды имеет по умолчанию 20% , а вы - за железо - 15% :)-
Я бы рекомендовал использовать драйвер дисплея MAX7219 - он как раз для дисплеев с общим катодом(к одной MAX7219 можно подключить 2 таких дисплея).
Спасибо, почитаю за драйвер MAX7219
http://arduino.ru/forum/apparatnye-voprosy/arduino-4-khrazryadnyi-semise...
http://arduino.ru/forum/apparatnye-voprosy/arduino-4-khrazryadnyi-semise...
Завтра начну с радиобазара.. в зависимости от того, что найду и что сколько стоит будет понятно с чем продолжать...
Для начала я бы (хотя стоп, почему "бы", именно в таком порядке я и делал в первый раз) разобрался как работает сдвиговый регистр. Понавтыкал светодиодов и смотрел как по нему "сдвигаются регистры". Потом подключил второй сдвиговый регистр, и посмотрел как "огоньки" перескакивают с одного регистра на второй (вот вам уже и каскад сдвиговых регистров), ну а дальше все просто, для каждой цифры определяете какой сегмент должен гореть, а какой нет, делите оставшееся время на 4 цифры и пропихиваете полученные данные в каскад сдвиговых регистров.
Для начала я бы (хотя стоп, почему "бы", именно в таком порядке я и делал в первый раз) разобрался как работает сдвиговый регистр. Понавтыкал светодиодов и смотрел как по нему "сдвигаются регистры". Потом подключил второй сдвиговый регистр, и посмотрел как "огоньки" перескакивают с одного регистра на второй (вот вам уже и каскад сдвиговых регистров), ну а дальше все просто, для каждой цифры определяете какой сегмент должен гореть, а какой нет, делите оставшееся время на 4 цифры и пропихиваете полученные данные в каскад сдвиговых регистров.
Точно! Спасибо за верное направление!
Добрался я до подключения 4хразрядного семисегментника через два сдвиговых регистра. Делал по этому примеру: http://greenoakst.blogspot.com/2012/01/arduino-7-spi.html
Только там в статье используется дисплей с общим анодом, а у меня (5461as) с общим катодом, на сколько я понял.
Какие изменения надо вносить в подключение и потом в программу учитывая разницу в дисплеях?
Проинвертировать массив static uint8_t digit[11], то есть там где по факту в байтах были нули, должны быть единицы, и наоборот.
Как это делается:
Первый байт 0xC0
Берём калькулятор Windows (Win+R -> calc -> Enter), переводим в Programmer mode (Alt+3). Переключаем в режим HEX (F5), убедимся что размер числа переключен в Byte (переключается в левом нижнем углу). Вбиваем наш байт С0, жмём кнопку Not (в том же углу, слева). Под индикатором видны нули и единицы, показывающие биты нашего байта. Видно, что при нажатии Not они становятся наоборот. Из C0 по Not станет 3F, это и будет первый байт нового массива. Вписываем туда.
Берём следующий байт 0xF9, таким же образом получаем из него 0x06. И так далее погнали до конца массива. В остальном программа изменений не требует.
DO NOT OVERQUOTE!!!
Не цитируйте сообщения полностью!
避免全报价!!!!!!!11111111
Спасибо... байты перевел...но, почему-то, не заработало... На ардуине при запуске скетча почти сразу гаснет светодиод L и ниччего не происходит....
П.С. Порадовал байт "99" который превратился в "66"... мелочь - а настроение поднял :)
Убедитесь в соответствии вашей схемы примеру из статьи. Вообще желательно посмотреть на схему.
То что гаснет светодиод и Arduino вообще как "типа отключенная" может указывать на срабатывание защиты USB-порта по току. То есть кз. Проверьте, не подключены ли какие-либо аноды к тем выходам на которых должны быть катоды.
И снова здравствуйте.
Те кто думает что я забил - таки сильно не правы... за это время я выяснил что один из китайских регистров есть бракованный, да и кучка китайских проводочков для макетки тоже нервы потрепала... Так что дисплеф удачно подключить и запустить таймер удалось
1 вопрос отвалился...
Подскажите как сделать обратный отсчет на 4х секционном семисегментнике от 59:59 до 0? - немогу нагуглить готовый скетч
Вам бы RTC... но да ладно, хер с ним. Заводите переменную min, sec - byte будет достаточно (он до 255).
Далее делается цикл, двигателем которого будет условие if(milllis()-lastCount>=1000), где lastCount - метка времени (сохраненное значение миллис) когда в последний раз сработало это условие. Прошло 1000 мс или больше - значит надо уменьшить секунду. millis() имеет размер DWORD (4 байта), иначе называется unsigned long. Соответственно, переменная lastCount должна иметь тип unsigned long. В примере "Blink wothout delay()" написано, тащемта.
Внутри этого условия должно быть:
во-первых, сохранение новой метки: lastCount=millis();
во-вторых, уменьшение секунды. Надо проверять, чтобы секунда была больше чем 0. Если 0, значит надо секунду снова сделать 59 а уменьшить минуту. Если последняя больше 0. Если равна 0 то бабах.
Разбор числа на разряды делается так же как в примере, min/10 - десятки, min%10 - единицы. Процент в C это то же что mod в паскале, остаток от деления.
Если последняя больше 0. Если равна 0 то бабах.
мммм. про бабах как то опасно получается.
А что ещё надо делать когда на таймере 00:00?
:)
А что ещё надо делать когда на таймере 00:00?
:)
ну не знаю. в рельсу звонить? типа АБЕД АБЕД
Далее делается цикл, двигателем которого будет условие if(milllis()-lastCount>=1000), где lastCount - метка времени (сохраненное значение миллис) когда в последний раз сработало это условие. ...
Эх... думал где готовым разжиться... щас будем ваять....
Оффтоп: Кстати, на счет ба-бах - что можно прикольного замутить на ардуинке кроме пищалки и мигания светодиодами?
ну не знаю. в рельсу звонить? типа АБЕД АБЕД
Я уже рефлекторно Ваш АБЕД (ABED) перевожу в двоичный код для семисегментника :)
Оффтоп: Кстати, на счет ба-бах - что можно прикольного замутить на ардуинке кроме пищалки и мигания светодиодами?
сервой колокольчик трясти (ну, или ей же по рельсе дубасить)
Таймер получился офигенно.... всем спасибо за помощь. За основу взял вот отсюда набросок: http://arduino.ru/forum/programmirovanie/pomogite-s-sozdaniem-taimera-obratnogo-otscheta.
Теперь еще надо прикрутить кейпад для "разминирования"... Если позволите, я не буду создавать новую тему, а продолжу писать вопросы здесь. Пока эксперементирую....
Нужна помощь.... "прикрутил" я кейпад.... да видать не туда... зависает на 3 ряду (если нажимать 7,8 или 9) контакт этот подключен на 10й выход Ардуины. Можно ли его на 0й или1й перебросить? Остальные уже заняты.
При этом остальные кнопки обрабатываются нормально... контакты проверил...
Полный скетч:
#include <SPI.h> #include <Password.h> #include <Keypad.h> enum { reg = 8 }; const int buttonPin = 2; // назначаем пин D26 для кнопки const int ledGreenPin = 12; // назначаем пин D13 для сигнального светодиода const int ledRedPin = 12; // назначаем пин D13 для сигнального светодиода const int highLevelPin = 30; // назначаем пин D30 для дублирущего светодиода // const int displayPin = 6; // назначаем пины для семисегментого индикатора boolean buttonState = false; // логическая переменная для состояния кнопки Password password = Password( "123" ); //password to unlock box, can be changed const byte ROWS = 4; // Four rows const byte COLS = 3; // columns // Define the Keymap char keys[ROWS][COLS] = { { '1','2','3' } , { '4','5','6' } , { '7','8','9' } , { '*','0','#' } }; // Connect keypad ROW0, ROW1, ROW2 and ROW3 to these Arduino pins. byte rowPins[ROWS] = { 5, 4, 10, 3 }; // Connect keypad COL0, COL1 and COL2 to these Arduino pins. byte colPins[COLS] = { 9, 7, 6 }; // Create the Keypad Keypad keypad = Keypad( makeKeymap(keys), rowPins, colPins, ROWS, COLS ); void setup() { SPI.begin(); pinMode(reg, OUTPUT); // инициализация пинов pinMode(buttonPin, INPUT); digitalWrite(buttonPin, HIGH); //включаем внутренний подтягивающий резистор на 20К, чтобы не закоротить пины при нажатии кнопки без обвязки pinMode(ledRedPin, OUTPUT); digitalWrite(ledRedPin, LOW); // гасим светодиод pinMode(ledGreenPin, OUTPUT); digitalWrite(ledGreenPin, HIGH); // зажигаем светодиод pinMode(buzzerPin, OUTPUT); // digitalWrite(buzzerPin, LOW); // затыкаем пищалку pinMode(highLevelPin, OUTPUT); digitalWrite(highLevelPin, LOW); // обнуляем выход на устройство keypad.addEventListener(keypadEvent); //add an event listener for this keypad Serial.begin(9600); // вывод отладочной информации Serial.println("Ready..."); } int secondsOnes=0, secondsTens=0, minutesOnes=0, minutesTens=0, curCount=0; byte minStart=10, secStart=9, minCur=0, secCur=0; static uint8_t digit[11] = { 0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F,0x00}; static uint8_t pos[4]= { 0x1C,0x1A,0x16,0x0E}; unsigned long timer=0, timerPrev=0; void loop() { buttonState = digitalRead(buttonPin); // читаем состояние кнопки и инвертируем его, т.к. у нас включен подтягивающий резистор // Serial.println(buttonState); if (buttonState == true) { // дeйствия при нажатии кнопки Serial.println("Button pressed!"); preStart(); // выполняем условия предстарта sendSignal(); // подаем сигнал на устройство mainStart(); // выполняем условия старта sendSignal(); // подаем сигнал на устройство finish(); // выполняем условия финиша Serial.println("THE END"); } else { // действия, если кнопка не нажата // digitalWrite(ledPin, LOW); } } void output(){ digitalWrite(reg, LOW); SPI.transfer(digit[minutesTens]); SPI.transfer(pos[0]); digitalWrite(reg, HIGH); delay(3); digitalWrite(reg, LOW); SPI.transfer(digit[minutesOnes]); SPI.transfer(pos[1]); digitalWrite(reg, HIGH); delay(3); digitalWrite(reg, LOW); SPI.transfer(digit[secondsTens]); SPI.transfer(pos[2]); digitalWrite(reg, HIGH); delay(3); digitalWrite(reg, LOW); SPI.transfer(digit[secondsOnes]); SPI.transfer(pos[3]); digitalWrite(reg, HIGH); delay(3); digitalWrite(reg, LOW); SPI.transfer(0x80); SPI.transfer(pos[1]); digitalWrite(reg, HIGH); delay(3); } void preStart() { Serial.println("Prestart..."); // display.show(" "); // очищаем дисплей for (int i = 5; i > 0; i--) { Serial.println(i); // выводим в порт показания отсчета // выводим на дисплей показания отсчета digitalWrite(reg, LOW); SPI.transfer(digit[i]); SPI.transfer(pos[3]); digitalWrite(reg, HIGH); digitalWrite(ledGreenPin, HIGH); // мигаем светодиодом // tone(buzzerPin, 2000, 200); // пищим 200 мс с частотой 2000 Гц delay(800); // ждем еще 0,8 сек digitalWrite(ledGreenPin, LOW); } noTone(buzzerPin); // затыкаем пищалку Serial.println("Done."); } void mainStart() { Serial.println("Main Start!"); digitalWrite(ledRedPin, HIGH); // включаем светодиод minCur = minStart; secCur = secStart; curCount = minCur * 60 + secCur; minutesTens = minCur/10; minutesOnes = minCur - minutesTens * 10; secondsTens = secCur/10; secondsOnes = secCur - secondsTens * 10; Serial.println(curCount); while (curCount>0) { keypad.getKey(); timer=millis(); if (timer-timerPrev>999){ curCount-=1; secondsOnes-=1; if (secondsOnes==-1){ secondsOnes=9; secondsTens-=1; } if (secondsTens==-1){ secondsTens=5; minutesOnes-=1; } if (minutesOnes==-1){ minutesOnes=9; minutesTens-=1; } if(minutesTens==-1){ minutesTens=0; } timerPrev=timer; } output(); } digitalWrite(reg, LOW); SPI.transfer(0x40); SPI.transfer(0x00); digitalWrite(reg, HIGH); digitalWrite(ledRedPin, LOW);// гасим светодиод Serial.println("Done."); } void finish() { Serial.println("Finish..."); tone(buzzerPin, 2000, 1000); // пищим сигнал об окончании noTone(buzzerPin); // затыкаем пищалку Serial.println("Wait 15 seconds..."); delay(15000); // ничего не делаем 15 сек for (int i = 0; i <= 4; i++) // пищим финальный аккорд { tone(buzzerPin, 3000, 100); delay(200); } noTone(buzzerPin); // затыкаем пищалку // display.show("--"); // закончили задачу, выводим режим готовности к следующему этапу buttonState = false; // устанавливаем исходное состояние кнопки Serial.println("Done."); } void sendSignal() { Serial.println("Send HI to device"); digitalWrite(highLevelPin, HIGH); // подаем высокий уровень на устройство delay(250); // ждем 250 мсек digitalWrite(highLevelPin, LOW); Serial.println("Send LOW to device"); } void keypadEvent(KeypadEvent eKey){ switch (keypad.getState()){ case PRESSED: Serial.print("Enter: "); Serial.println(eKey); delay(10); switch (eKey){ case '#': checkPassword(); delay(1); break; case '*': password.reset(); delay(1); break; default: password.append(eKey); delay(1); } } } void checkPassword(){ if (password.evaluate()){ //if password is right open box Serial.println("Accepted"); delay(10); //Add code to run if it works digitalWrite(12, HIGH);//turn on delay(700); //wait 5 seconds digitalWrite(12, LOW);// turn off } else{ Serial.println("Denied"); //if passwords wrong keep box locked delay(10); //add code to run if it did not work digitalWrite(12, HIGH); //turn on delay(200); //wait 5 seconds digitalWrite(12, LOW);//turn off } }Уберите сериал, тогда будет можно.
И снова здравствуйте. Спасибо всем за советы! Всё получилось. Но совершенству нет пределу, а для совершенства нужны дополнительные пины :) В связи с этим вопрос:
Как клавиатуру подключить через меньшее количество разъемов и потом обрабатывать нажатия?
Сейчас с клавиатурой работаю как в листинге выше - т.е. надо ввести пароль и он проверяется на валидность.
П.С. Для тех кто будет использовать мой скетч - цикл с таймером надо переделывать - он дает офигенную погрешность.
теже сдвиговые регистры - только с параллельной записью и последовательной передачей
здесь были темы про светодиоды через регистр и про клавиатуру через регистр....