Дайте совет по управлению светодиодами
- Войдите на сайт для отправки комментариев
Пт, 29/03/2013 - 17:50
В нижеприведённом скетче я указал место где нужно остановить выполнение кода в данном соостоядии полупроводниковыхсветоизлучающих элементах.
1. подскажите как это сделать.
2. При выполнении плавного разгорания и затухания светодиодов то "0" до "255" и обратно если выполняется до нуля, при следующей команде с нуля и начинается, а если выполняется до "255", то начинается от "255".Как сделать чтоб всегда начинался розжиг с "0"?
int brightness = 0; int fadeAmount = 5; void setup() { pinMode(10, OUTPUT); //левый ходовой огонь pinMode(11, OUTPUT); //правый ходовой огонь pinMode(2, INPUT); // ACC (зажигание) pinMode(3, INPUT); // габаритные огни pinMode(4, INPUT); // постановка на охрану pinMode(5, INPUT); //звуковой сигнал pinMode(6, INPUT); //снятие с охраны } void loop() { if(digitalRead(2) == HIGH) AccOn(); if(digitalRead(2) == LOW) AccOff(); if(digitalRead(3) == HIGH) LiteOn(); if(digitalRead(3) == LOW) LiteOff(); if(digitalRead(4) == HIGH) LockOn(); if(digitalRead(5) == HIGH) AlarmOn(); if(digitalRead(6) == HIGH) LockOn(); } void AccOff() { digitalWrite(10, LOW); digitalWrite(11, LOW); } void AccOn() { for(byte i=0;i<6;i++) { digitalWrite(11, HIGH); delay(40); digitalWrite(11, LOW); delay(40); } for(byte i=0;i<6;i++) { digitalWrite(10, HIGH); delay(40); digitalWrite(10, LOW); delay(40); } for(byte i=0;i<153;i++) { analogWrite(10, brightness); analogWrite(11, brightness); brightness = brightness + fadeAmount; if (brightness == 0 || brightness == 255) { fadeAmount = -fadeAmount ; } delay(10); } digitalWrite(10, HIGH); digitalWrite(10, HIGH); //тут надо остановить до включения других кнопок (pin3,4,5,6) или выключения этой (pin 2) } void LiteOff() { } void LiteOn() { } void AlarmOn() { for(byte i=0;i<6;i++) { digitalWrite(11, HIGH); delay(40); digitalWrite(11, LOW); delay(40); } for(byte i=0;i<6;i++) { digitalWrite(10, HIGH); delay(40); digitalWrite(10, LOW); delay(40); } delay(50); for(byte i=0;i<4;i++) { digitalWrite(10, HIGH); digitalWrite(11, HIGH); delay(40); digitalWrite(10, LOW); digitalWrite(11, LOW); delay(40); } } void LockOn() { for(byte i=0;i<6;i++) { digitalWrite(11, HIGH); delay(40); digitalWrite(11, LOW); delay(40); } for(byte i=0;i<6;i++) { digitalWrite(10, HIGH); delay(40); digitalWrite(10, LOW); delay(40); } delay(50); for(byte i=0;i<204;i++) { analogWrite(10, brightness); analogWrite(11, brightness); brightness = brightness + fadeAmount; if (brightness == 0 || brightness == 255) { fadeAmount = -fadeAmount ; } delay(10); } }
1)
2)Если я правильно понял, о чем идет речь, то надо в самом начале функций AccOn и LockOn написать
Кроме того, из соображений защиты от ошибок лучше поменять строчки
на
Ну и последнее - если на пине 2 (ACC) у вас HIGH всегда, пока включено зажигание, то функция AccOn будет вызываться каждый раз в loop.
Судя по всему, она должна вызываться ровно один раз при включении зажигания.
Для этого в начало надо добавить переменную
В теле loop изменить соответствующие строки кода:
на
А в функциях AccOn и AccOff написать, соответственно
Куски Вашего реального кода я заменил многоточиями, не забудьте вернуть его обратно :-)
PS: По сравнению с тем, что было в поршлых топиках успехи ОЧЕНЬ радуют!
Стараюсь! Спасибо, плюс ещё и ответили на вопрос который я только готовил. Буду пробовать.
Да, всё получилось как надо за исключением того что если при включённом зажигании "посигналить" (digitalRead(5) == HIGH), после "перемигиваний" диоды тухли. Я сделал так: (по колхозному наверно но получилось)
в конце void AlarmOn() добавил -
Теперь буду пытаться плавно выключить их при включении габаритов.
Нормально, только между accState и 1 должно быть ДВА знака равно.
Да, уже допетрил. Спасибо.
Всё, дописал, работает как надо, можно к монтажу переходить. Осталась пара вопросиков.
1. Я так понял что нижеприведённое выражение в моём скетче не нужно, это просто пример того как остановить выполнение кода до каких либо действий?
2. для габаритных огней вводил ещё одну переменную int lightState = 0; Для чего я понял, но мне немного не понятно при каких условиях меняется её значение.
Вот что получилось:
1)да, этот код прост стоит на месте, пока значение в условии не станет ложным. Если необходимость в нем отпала, можно его и убрать.
2)Я не очень понял вопрос. В таком варианте, как сейчас в коде суть этой переменной "не вызывать второй раз функцию lightOn, если огни уже включены". Насколько я понимаю, это именно то, что надо. Соответственно в функии lightOn ее значение устанавливается в 1(габариты включены), в функции lightOff ее значение устанавливается в ноль (габариты выключены).
Да, Вы правельно всё поняли, это так и надо. Я как раз хотел задать вопрос как написать чтоб МК отличал включено только что или уже было включено. Вы мне показали как это сделать для АссOn. Для LightOn я добавил ещё одну переменную по Вашему примеру и оперировал ей, понимая её значение, но не совсем понимая от чего она зависит, а именно в каком месте прописывается что она меняет состояние и от чего. Наверное тоже непонятно обьяснил. Попробую ещё порассматривать сам.
В общем я понял это так:
Вводим переменную int accState = 0; задавая начальное значения путём приравнивания к нулю.
Далее в функции при появлении единици на пине 2 сравниваем её с начальным значением if((digitalRead(2) == HIGH) && (accState == 0) ) AccOn(); (т.е. именно тут определяется была ли уже "1" на пине или только появилась.) Если ЛОЖЬ, функция не выполняется. А привязывается переменная accState k функции AccOn своим названием acc.
Ну хоть примерно правельно я понял?
Вводим переменную int accState = 0; задавая начальное значения путём приравнивания к нулю.
Это правильно.
Далее в функции при появлении единици на пине 2 сравниваем её с начальным значением if((digitalRead(2) == HIGH) && (accState == 0) ) AccOn(); (т.е. именно тут определяется была ли уже "1" на пине или только появилась.) Если ЛОЖЬ, функция не выполняется.
Опять же, почти правильно. Только сравниваем не с НАЧАЛЬНЫМ значением, а с ПОСЛЕДНИМ известным значением (состоянием зажигания)
А привязывается переменная accState k функции AccOn своим названием acc.
А вот тут - нет. По имени ничего привязываться в С не умеет.
Просто внутри функции AccOn первой командой пишется "accState = 1", что обозначает "зажигание включено" и это состояние остается до тех пор, пока мы не войдем в функцию AccOff, где первой интсрукцией пишем "accState=0" - "зажигание выключено".
Хорошо, теперь посоветуйте какие порты выбрать на меге8 и как?
Нужно наqти схему той ардуины, которую вы будете использовать для компиляции в ArduinoIDE (это должна быть плата на ATMega8), в нем найти какие ноги МК висят на тех пинах, которые используются (в данном случае 2, 3, 4, 5, 6, 10 и 11)
Потом найти даташит на соответствующую мегу и посмотреть, какие пины висят на этих ногах.
Решил остановится на портах "D". Переписал пины в коде выходы 2 и 3, входы 4, 5, 6, 11, 12. выбрал плату мега8 и при компеляции вылазеет хренова туча ошибок. Что то я вобще не в ту степь залез. Что подскажите?
Это может быть связано с тем что на мегу8 я не качал hardware (не нашёл), а создал текстовый документ boards и вставил туда данные по этой меге?
Это может быть связано с тем что на мегу8 я не качал hardware (не нашёл), а создал текстовый документ boards и вставил туда данные по этой меге?
Не просто может, а скорее всего так и есть.
Выберите board "Arduino NG or older w/ATmega8"
И соответстувующие номера пинов смотрите не на МК а на разводке платы NG (вот например http://robocraft.ru/files/craftduino/CraftDuino-wb.png)
Ой, выбрал Arduino NG or older w/ATmega8, всё получилось. Ещё раз плагодарен. Осталось подкорректировать в коде пини для меги.
Я опять стучусь к Вам. Залил скетч в мегу8, странно себя ведёт, интервалы времени отсчитывает как будто заморожена во времени: Delay (50); это для меги8 - 0,5 секунды, не вкурсе почему так?
Потому что ArduinoIDE считает, что мега работает на одной скорости (прописанной в boards.txt), а в жизни мега работает на другой скорости
(определенной схемой подключения внешнего генератора и фьюзами в МК).
Нужно привести эти скорости в соответствие друг другу.
То есть в первую очередь определиться с правильным значением фьюз-битов для меги (например "от внутреннего 8МГц осциллятора", "предделитель 1"), прошить их в МК, после
чего постаить реальную частоту работы меги в boards.txt (для указанных выше значение это будет 8000000).
Без внешнего генератора работать не будет?
Будет, но это надо указать в конфигурации фьюзов.
Как именно - ответ в даташите к конкретной модели МК
Хоть примерно скажите что делать и как это обычно выглядит? От изучения даташита легче не стало
Как раз в текстовом документе к восьмой меге прописано 8 МГц.
Дисклеймер: Все ниженаписанное появилось исключительно, как результат чтения даташита на ATmega8
Личного опыта у меня нет. На других МК фьюзы могут быть другими.
В даташите написанно, что по дефолту МК поставляется, сконфигурированный на работу от 1МГц внутреннего осцилятора.
Если частота 1МГц устраивает, но надо просто прописать ее в boards.txt для Arduino NG
Если нужно получить 8МГц от внутреннего осциллятора,то биты CKSEL3:0 нужно установить в 0100
CKSEL - это младшие 4 бита в Fuse Low Byte
Биты SUT1:0 (4 и 5 биты Fuse Low Byte) можно оставить в том виде какими они есть по дефолту.
Биты 6 и 7 Fuse Low Byte лучше не трогать.
Я наверное немножко застрелюсь :) Выставил в boards для Arduino NG 1 МГЦ, с фьюзами не получилось. Пошло как надо НО....... теперь brightness не выполняется, или "0" или "1". Нет плавного разгорания или затухания.
Я кажется понял почему
Очень нужно уместить созданый ранее скетч на Attiney2313А, и тут интересная штука (уже обговаривали её) При компилировании для Attiney45, выходит вот это:"Размер скетча в двоичном коде: 2 020 байт (из 4 096 байт максимум)"
а для Attiney2313,: "Размер скетча в двоичном коде: 2 090 байт (из 2 048 байт максимум)".
Совсем чуток. Что знаю , перепробовал. Что посоветуете?
имхо, почитать вот это: http://arduino.ru/Tutorial/Upravlenie_portami_cherez_registry
Смысл понял, но на практике не получается, пишу простейший код на два диода и две кнопки, не работает, меняю или подставляю знаки, диоды живут своей жизнью. К тому же у меня два выхода порты "В" на ШИМ. На сколько я понял если задам еденици, ШИМа не получится.
Ещё варианты есть?
Пля ну куда деть грёбаные 42 байта ((((((((((
У вас достаточно много блоков типа
либо
Это четыре (два) вызова функций со всеми прилагающимися прелестями - запоминание параметров в стеке, загрузка в стек адреса возврата, загрузка в стек содержимого некоторых регистров. Команды, команды, команды - слова, слова, слова (слово=2 байта).
Если написать функцию вроде
то есть надежда сэкономить несколько слов программной памяти, ведь вместо примерно n*N*4+m*N*2=N*(n*4+m*2) слов будет затрачено примерно (n+m)*N+N*(4+2)=N*(n+m+6) слов.
здесь
n - число блоков по 4 инструкции, которые мы собираемся заменять одним вызовом универсальной мигательной функции
m - число блоков по 2 инструкции
N - число слов программной памяти, занимаемое вызовом одной отдельно стоящей функции (будь то digitalWrite, delay или digiW).
В общем - попробуйте. Результат не гарантируется, но, как любил говаривать Лаврентий Павлович, "попытка - не пытка".
Замени delay( на delayMicroseconds(
и еще разок
Перепишите хотя бы этот кусок, внимательно прочитав: http://arduino.ru/Tutorial/Upravlenie_portami_cherez_registry
Кстати2, по умолчанию все пины и так включены на вход, так что делать pinMode(...,INPUT) - не обазательно.
Из другой темы, но тоже в тему
Чтоб не "заблудится" сделал Так:
было 2090 , стало 2060 из 2048. Полегчало.
По ссылке переходил, вчера до двух ночи колдовал.Там описания скудны, примеры выщепнуты из выщепнутого, пишется для знающих и понимающих которые это и так уже знают. Как по мне, рас уж начали пояснять, так и разжувать уже можно чтоб и моя бабушка поняла. Вобщем с DDRD = и с PORTD = , неполучается так же как и в моей теме "LCD 128x64 и MEGA2560. Зажгём?", Дают дельные советы а как применить....((((
delay( на delayMicroseconds( - пробовал?
2004 из 2048 П О Б Е Д А!!! Благодарю.
Буду знать что это не одно и то же. Остановлюсь на этом, но позже, для себя надо рассмотреть пример "DDRD = B11111110;" и с "
" тоже. Сам вижу что в скетче много мусора, но в мегу8 влезло, работает и ладно, а в тиньку вот пришлось потрудиться, и по большей части вам. Ещё раз спасибо.
P.S. Подправил все delay, получилось 1810, ещё и жене на сапоги осталось))))))
Вот опять проблема. delayMicroseconds игнарируется если значение больше 16383. Наша песня хороша, начинай с начала (((
P.S. где значения больше, поменял на delay , вместилось
Что то я непойму, в процессе работы у МК может меняться тактовая частота? Сначала розжиг и затухание нормально, как надо, спустя время как притормаживать начинает раза в два.
Подключено питание через кренку, =5,02В. это что с ним?