Официальный сайт компании Arduino по адресу arduino.cc
Помогите новичку с программой
- Войдите или зарегистрируйтесь, чтобы получить возможность отправлять комментарии
Чт, 23/05/2013 - 11:06
Здравствуйте. Взялся за изучение Arduino. Но немного застрял. Подключил к плате сдвиговый регистр 595.
Получается следуюющая картина. Светодиодики, подключенные к выходу 595-го зажигаються в одну сторону и гаснут. А я хочу, чтобы они начала зажглись по одному, а потом по одному погасли ( туда и обратно). И так в цикле.
Но у меня прога встала..
int latchPin = 5; int clockPin = 6; int dataPin = 4; byte leds = 0; void setup() { pinMode(latchPin, OUTPUT); pinMode(dataPin, OUTPUT); pinMode(clockPin, OUTPUT); } void loop() { leds = 0; updateShiftRegister(); delay(500); for (int i = 8; i >= 0; i--) { bitSet(leds, i); updateShiftRegister(); delay(500); } for (int i=0; i < 8; i++) { bitClear(leds, i); updateShiftRegister(); delay(500); } } void updateShiftRegister() { digitalWrite(latchPin, LOW); shiftOut(dataPin, clockPin, LSBFIRST, leds); digitalWrite(latchPin, HIGH); }
Подскажите - где засела ошибка???
Если убрать второй for - то все работает - понимаю что где-то конфликт, а где ???
убрал знак "=" из равенства (больше или равно - заработало). Только теперь не функционирует одни светодиод - с выхода Q7. Почему так?
Скорее всего не это причина ваших проблем, но тоже косяк:
строка 19-ть. Вы начинаете с i=8, заканчиваете на i=0. Всего - пытаетесь установить 9-ть битов :) А их 8-мь. Биты у нас нумеруются с 0-левого, по 7-дьмой (во втором цикле - вы верно по ним проходите).
Начинать нужно с i=7
И еще. Везде вместо int, правильней было-бы использовать byte
UPD. Убирать знак равенства не нужно было. В таком варианте вы нулевой бит не выставляете. Возможно поэтому и не горит что-то.
Проблему этим не решить - поскольку не светиться "0" светодиод, а с 7-м то все впрорядке.
Почему byte корректнее?
Проблему этим не решить - поскольку не светиться "0" светодиод, а с 7-м то все впрорядке.
Угу. А с 8-мым как дело обстоит?
Читайте апдейт. Пока на набирал, вы внесли поправку - убрали знак равно. ВОт вам нулевой и не светится. Так как цикл выполняется только когда i>0, а ноль не больше нуля.
Почему byte корректнее?
Потому, что i - у вас не бывает больше 256, не бывает отрицательным.
То же самое - номера пинов. Ни большими, ни отрицательными - не бывают. Следовательно - лишний расход памяти.
То же самое и Led-дом. Если у вас всего 8-мь светиков, то byte будет самым "минимально достаточным" типом.
Вообщем лучше сразу привыкать осознанно выбирать наиболее подходящий тип. А в некоторых случаях - ошибка с типами будет истичником трудно-уловимых проблем.
UPD. Убирать знак равенства не нужно было. В таком варианте вы нулевой бит не выставляете. Возможно поэтому и не горит что-то.
Да НО со знаком равенства получаем затык после первого for и цикл останавливается. Программа не идет дольше.
Спосибо - соориентировался. Сделал так
Процесс пошел. Спасибо за терпение. Вопрос пока снят ( до дальнейшей модернизации ).
UPD. Убирать знак равенства не нужно было. В таком варианте вы нулевой бит не выставляете. Возможно поэтому и не горит что-то.
Да НО со знаком равенства получаем затык после первого for и цикл останавливается. Программа не идет дольше.
[/quote]
Ну, ok. Не хотите равенства - не нужно ;)
Делайте свой for(byte i=8;i>0...
Но тогда, вам нужно будет делать bitSet(leds, i-1);
Тогда i у вас будет пробегать 8..1, а в bitSet уходить 7..0
И да, кажись прогнал я (хотя вы, похоже заметили эту мою ошибку). В первом цикле, i таки бывает отрицательным. Значит нужен знаковый тип. byte - не подходит. Нужен либо char (может принимать -128..127), либо int (один байт памяти будем расходовть зря).
И да :)
это тоже самое что
:) Это вы верно заметили. Но, imho, i>=0 - все таки луче читается.
На самом деле про byte/int - я только благодаря вам заметил. А то что читаемость i>=0 лучше - это бесспорно. Хотя именно в таком ключе программа и не запускалась...
А вот теперь назрел вопрос - а как прикрутить 2-й сдвиговый регистр с теми-же функциями. Но теперь там количество выводов 16 получается.
Ну взять да и погуглить статьи по работе с этим сдвиговым (или поиском по форуму, не раз же...) . Или даже не гуглить, а пойти в раздел "Программирование" (в шапке сайта), и во втором же абзаце ("Базовые и полезные знания, необходимые для успешного программирования.....") найти статью описывающую работу со сдвиговым. В ней есть описание и как два подключать. И кода примеры даны.
спасибо. Пошел искать.
Опять у меня какой-то непонятный момент...
Код из примера работы со сдвиговым регисторм. НО есть нюанс. У меня задача та-же что в прошлый раз - постепенное поднимание лесенки (без гашения) и постепенное погасание светодиода. В тексте есть функция (строка 21) которая определяет кокой светодиод горит, и гасит предыдущий. Если её убрать - то ничего не меняется, почему?? Более того, программа запускается , а с опросником for - нет.
сделал я симбиоз 2-х программ - вот что получилось - работает как и первая
получается, что для данного светодиода записывается единица в данный разряд, а как теперь сделать, чтобы предыдущие светодиоды не гасли при наборе, а гасли при обратном проходе?
> Если её убрать - то ничего не меняется, почему
Тут зависит от того что вы вы ожидали. Внутри функции registerWrite у вас все равно выключаются все, кроме того которому вы ставите HIGH.
А когда вы вызвыете registerWrite(ПОФИГ, LOW); - вы все равно гасите ВСЕ диоды.
Что вы, в конечном итоге отправляете на сдвиговый? bitsToSend . А какое у него значение? Вначале - ноль. Потом, возможно, выставим ему какой-то бит, и тогда отправим.
Если вы хотите что-бы у вас "сохранялось свечение" - вам нужно что-бы и значение bitsToSend сохранялось между вызовыми функций.
Самое простое - добивать слово static перед unsigned int
Либо вынести объявление unsigned int bitsToSend = 0; из функции (объявить его в начале скетча) - сделать глобальной переменной.
>Более того, программа запускается , а с опросником for - нет.
А тут я вообще не понял про что вы.
Вообщем попробуйте
Спасибо. Опять выручили - действительно помогло. Теперь буду гасить в том-же порядке - поскольку они набрались - и остались светиться.
Всё!!! получилось!!!!
Теперь понятно - почему не оставалось всечение. Код на всякий случай - может кому пригодиться.
Теперь буду крутить кнопки - аж 2 штуки!!!
Теперь буду крутить кнопки - аж 2 штуки!!!
Ага. Только в следующий раз постарайтесь темы называть более информативно/уникально.
"помогите", "новичок", "проблема с программой" - такое название можно дать 95% темам. Но это же не повод называть все одинаково. Ориентировать не возможно. Вот код вы выложили - но никто же его не найдет :(
Что-то типа "бегущая волна на сдвиговом регистре" - было бы более "говоряще" :)
А то что "проблемы", "новичок" и "нужна помощь" - так это и так самоочевидно :)
Тут отпираться не буду, но в своё оправдание скажу - что когда тему создавал - то я же не знал - куда меня кривая выведет... А вдрух не получилось - бы ничего. И тогда бы еще больше всех запутал. Я думаю администраторы могут смело поменять тему - как вариант на "Сдвиговые регистры 74СН959 или куда бежит светодиод?" ну или как то так - я не знаю. Еще раз спасибо за советы...
Новый день - новые свешения, новый код.
Прикрутил я кнопку - прописал, поставил условие if ( вход низкий, тогда true)? НО условие игнорируется, и программа работат без нажатия. А у меня задача - чтобы отработала 1 цикл - и дальше ждала нажатия кнопки. Где промахнулся??? Вроде по структуре ошибок не допускал?
Разобрался! Ошибочка со знаком припинания после if точка с запятой не нужна.
хочу добавить регулировку я ркости - делаю вот так:
а регулировка не происходит - такое ощущение, что она опросник кнопки просто проходит. Что не правильно сделал?
Если на 32 строке вставить код
светодиод включается и выключается - значит кнопку видит, НО почему-то не между циклами ( при полном включенном состоянии) , а после полного прохождения. В чем тут подвох - ведь по тексту стоит так, что-б ыотрегулировать яркость - когда все светодиоды ключены?
Блин, классный форум! Сам српосил - сам ответил. Успеваю решить вопрос ДО того как кто-то вмешается... А прога выше работает...