Простые схемы на Arduino для начинающих![]() Цикл статей и обучающих схем с радиолюбительскими экспериментами на Arduino для начинающих. Это такая радиолюбительская игрушка-конструктор, из которой без паяльника, травления печатных плат и тому подобного любой чайник в электронике может собрать полноценное работающее устройство, подходящее как для профессионального прототипирования так и для любительских опытов при изучении электроники.
Плата Arduino для предназначена в первую очередь для обучения начинающих радиолюбителей основам программирования микроконтроллеров и созданию микроконтроллерных устройств своими руками без серьезной теоретической подготовки. Среда разработки Arduino позволяет , скомпилировать и загрузить в память платы готовый программный код. Причем загрузка кода предельно проста.
В первую очередь для работы с платой Ардуино начинающему электронщику нужно скачать программу для разработки Arduino, она состоит из встроенного текстового редактора, в котором мы работаем с программным кодом, области сообщений, окна вывода текста(консоли), панели инструментов с кнопками часто применяемых команд и нескольких меню. Для загрузки своих программ и связи это программа через типовой шнур USB подключается к плате Arduino. Самую свежую версию Arduino IDE можно скачать по этой ссылке: ![]() Код, написанный в среде Arduino, называют скетч. Он пишется в текстовом редакторе, имеющем специальные инструменты вставки/вырезки, замены/поиска текста. Во время сохранения и экспорта в области сообщений (смотри рисунок в первом уроке для начинающих, чуть ниже) появляются пояснения, также могут отображаться ошибки. Консоль показывает сообщения Arduino, включающие полные отчеты об ошибках и другую полезную информацию. Кнопки инструментальной панели позволяют проверить и записать скейтч, открыть, создать и сохранить его, открыть мониторинг последовательной шины и многое др. Итак, переходим к первому уроку Arduino схемы начинающих электронщиков.
Контроллер Arduino UNO для удобства начинающих уже имеет сопротивление и LED-светодиод, подсоединенный к 13 выводу разъема, поэтому никаких внешних радиоэлементов в первом опыте нам не нужно. ![]() Загрузив код, Ардуино позволяет нашей программе поучаствовать в инициализации системы. Для этого мы указываем микроконтроллеру команды, которые он выполнит в момент первоначальной загрузки и далее напрочь забудет об них (т.е. эти команды выполнятся Ардуинкой только один раз при старте). И именно с этой целью в нашем коде мы выделяем блок, в котором храняться эти команды. void setup(), а точнее в том пространстве внутри фигурных скобок этой функции, смотри программный скейтч. Не забывайте про фигурные скобки! Потеря хотя бы одной из них сделает весь скейтч полностью нерабочим. Но и лишние скобки тоже не ставьте, т.к также возникнет ошибка.
![]() Функция void loop() это то место, куда мы помещаем команды, которые будут выполняться все то время, пока включена плата Arduino. Начав выполнение с первой команды, Ардуинка дойдет до самого конца и сразу же перейдет в начало, чтобы повторить ту же самую последовательность. И так бесконечное число раз, до тех пор, пока на плату поступает питание. По своей сути, void loop – это главная функция, точка входа в Arduino. Функция delay(1000) задерживает обработку программы на 1000 милисекунд. Все это идет в вечном цикле loop(). Главный вывод после восприятия нашей первой програмки на Ардуино: С помощью функций void loop и void setup мы передаем микроконтроллеру наши инструкции. Все то, что находится внутри блока setup выполнится всего один раз. Содержимое модуля loop будет повторятся в цикле до тех пор, пока останется включенным Arduino. Тайминг
В предыдущей программе между включением и выключением светодиода была секундная задержка. В используемом выше простейшем коде начинающего ардуинщика был один большой минус. Для выдержки паузы между включением и отключением светодиода в одну секунду мы применили функцию delay() и поэтому в этот момент контроллер не способен выполнять другие команды в главной функции loop(). Корректировка кода в функции loop(), представленная ниже решает эту проблему. Вместо установки значения в HIGH, а затем в LOW, мы получим значение ledPin и проинвертируем его. Допустим если оно было HIGH, то станет LOW и т.п. ![]() Второй вариант кода Ардуино для управления светодиодом здесь: Затем можно заменить функцию delay(). Вместо нее, лучше использовать функцию millis(). Она возвращает количество миллисекунд, прошедшее с момента старта программы. Функция переполнится приблизительно через 50 суток работы программного кода. Похожей функцией является micros(), которая возвращает количество микросекунд, прошедшее с момента запуска программного кода. Функция вернется в ноль через 70 минут работы программы. Конечно, это добавит немного строк кода в наш скетч, но это, сделает вас несомненно более опытным программистом и увеличит потенциал вашего Arduino. Для этого нужно всего лишь научиться применять функцию millis. Следует четко понимать, что простейшая функция delay приостанавливает выполнение всей программы Ардуино, делая ее неспособной выполнять какие-либо задачи в этот период времени. Вместо того, чтобы приостанавливать всю нашу программ, можно подсчитывать, сколько времени прошло до завершения действия. Это, прекрасно, реализуется с помощью функции millis(). Чтобы все было легко в понимании, мы рассмотрим следующий вариант мигания светодиодом без временной задержки. Начало этой программы такое же как и у любого другого стандартного скетча Arduino. ![]() Скачать скейтч с 3 вариантом В данном примере начинающего ардуинщика мы изучили две новые переменные currentTime и loopTime. В функции setup() обе переменные имеют одинаковое значение. В функции loop(), переменная currentTime каждый раз обновляется в цикле. Если currentTime выше чем loopTime на 2 секунды (loopTime + 2000), то светодиод переключает свое состояние, а переменной loopTime приравнивается текущее значение currentTime. В данном уроке для начинающих мы не применяли функцию delay() и процессор способен осуществлять в это время другие программные алгоритмы. А можно запрограммировать Ардуино и так, как в коде по ссылке ниже: (Вариант 4 ). ИМХО более граммотный и рациональный вариант. Сначала идет объявление всех нужных переменных и линий ввода/вывода (например, линии 11 для светодиода). Здесь нам также потребуется уже встречаемая переменная типа integer для хранения текущего состояния светодиода. Она будет установлена в LOW, т.к начальное состояние светодиода – выключено. Затем введем новую переменную «previousMillis» типа «unsigned long». В отличие от «int» длинные переменные без знака 32 битные, это требуется для переменных, значение которых может достичь больших значений – как потенциальное время, которое мы можем ожидать, до тех пор, пока не будет предпринято действие. Переменная previousMillis будет применятся в нашем скетче для хранения времени, когда последний раз мигал индикатор. Переменная «const long», также 32-битная, но она не меняет своего значение, то есть она используется для констант (в данном примере Ардуино мы ее применили для константы interval). Мы установим константу на 1000 и применим в качестве паузы. Далее переходим в бесконечный цикл void loop(). Помните, что в данном примере начинающего, вместо задержки мы хотим подсчитать, сколько времени прошло с момента последнего мигания светодиодного индикатора, в нашем случае 1000 мс. Если указанное время вышло, состояние нашего светодиода меняется. Таким образом, мы установим беззнаковый длинный (unsigned long) «currentMillis» равный «millis ()», что задает текущее время в миллисекундах. Это покажет, превысила ли разница между текущим временем и предыдущим - временной интервал в 1000 мс. Затем, если состояние светодиода LOW, делаем его HIGH, иначе - LOW. Затем с помощью уже знакомой команды digitalWrite выводим текущее состояние на светодиодный индикатор.
Этот простой эксперимент не только демонстрирует, как использовать цифровой выход, но и как применять цифровой вход. При нажатии кнопки, подключенной к цифровому входу, включается или выключается светодиод. В программе используются две новые функции digitalWrite() и digitalRead(). Схема подключения к Ардуино показана ниже. ![]() В данном примере используется два цифровых ввода-вывода Arduino. Светодиод подсоединяется к 8 пину, который сконфигурирован как OUTPUT. К 9 через подтягивающий резистор подключена кнопка, которая настроена как INPUT. Когда нажимаем на кнопку пин 9 устанавливается в HIGH, и программа переключает вывод 8 в HIGH, тем самым включая светодиод. Отпускание кнопки сбрасывает девятый вывод в состояние LOW. Затем код переключает вывод 8 в LOW, отключая световой индикатор.
Для управления пятью светодиодами будем применять различные манипуляции с портами Arduino. Для этого напрямую запишем данные в порты Arduino, это позволит задать значения для светодиодов при помощи одной лишь функции. Arduino UNO обладает тремя портами: B (цифровые входа/выхода с 8 по 13); C (аналоговые входа); D (цифровые входа/выхода с 0 по 7) Каждый порт осуществляет управление тремя регистрами. Первый DDR задает чем будет являться pin входом или выходом. При помощи второго регистра PORT можно задать pin в состояние HIGH или LOW. При помощи третьего можно считать информацию о состояние ножек Arduino, в случае если они работает на вход. ![]() Для работы схемы задействуем порт B. Для этого установим все ножки порта как цифровые выхода. У порта B всего 6 ножек. Биты регистра DDRB должны быть заданы в "1", если пин будет использоваться как выход (OUTPUT), и в "0", если пин планируем применять как вход (INPUT). Биты портов нумеруются с 0 по 7, но не всегда имеют все 8 пинов Допустим: DDRB = B00111110; // установить ножки порта В с 1 по 5 как выхода, а 0 как вход. В нашем схеме бегущих огней мы задействуем пять выходов: DDRB = B00011111; // установить пины порта В с 0 по 4 как выходы. Для записи данных в порт В нужно задействовать регистр PORTB. Зажечь первый светодиод можно с помощью управляющей команды: PORTB = B00000001;, первый и четвертый LED: PORTB = B00001001 и т.п Существует два оператора двоичного сдвига: влево и вправо. Оператор сдвига влево заставляет все биты данных переместиться влево, соответственно оператор сдвига вправо, перемещает их вправо. Пример: Теперь вернемся к исходному коду нашей программе. Нам требуется ввести две переменные: upDown будет включать в себя значения куда двигаться - вверх или вниз, а вторая cylon укажет какие Led зажигать.
В функции setup() мы определяем какие ножки должны работать как выхода. В главном цикле loop(), светодиоды загораются по очереди вверх путем увеличения переменной cylon, а когда доходит до самого верхнего, то переменной upDown присваивается ноль и светодиоды начинают светиться вниз по очереди. ![]()
Конструктивно такой светодиод имеет один общий вывод и три вывода для каждого цвета. Ниже показана схема подключения RGB-светодиода к плате Arduino с общим катодом. Все резисторы используемые в схеме для подключения должны быть одного номинала от 220-270 Ом. ![]() Для подключения с общим катодом схема подключения трехцветного led будет почти аналогична, за исключением того, что общий вывод будет подключен не к земле (gnd на устройстве), а к выводу +5 вольт. Выводы Красный, зеленый и синий в обоих случаях подключаются к цифровым выходам контроллера 9, 10 и 11.
К девятому пину Arduino UNO подключим внешний светодиод через сопротивление 220 Ом. Для плавного управления яркостью последнего применим функцию analogWrite(). Она обеспечивает вывод ШИМ-сигнала на ножку контроллера. Причем команду pinMode() вызывать не требуется. Т.к analogWrite(pin,value) включает два параметра: pin - номер ножки для вывода, value - значение от 0 до 255. Код:
/* Учебный пример начинающего ардуинщика, раскрывает возможности команды analogWrite() для реализации Fade-эффекта светодиода */ int brightness = 0; // яркость LED int fadeAmount = 5; // шаг изменения яркости unsigned long currentTime; unsigned long loopTime; void setup() { pinMode(9, OUTPUT); // устанавливаем 9 пин как выход currentTime = millis(); loopTime = currentTime; } void loop() { currentTime = millis(); if(currentTime >= (loopTime + 20)){ analogWrite(9, brightness); // устанавливаем значение на 9 выводе brightness = brightness + fadeAmount; // прибавляем шаг изменения яркости, которая установится в следующем цикле // если достигли мин. или макс. значения, то идем в обратную сторону (реверс): if (brightness == 0 || brightness == 255) { fadeAmount = -fadeAmount ; } loopTime = currentTime; } }
Энкодером предназначен для преобразования угла поворота в электрический сигнал. С него мы получаем два сигнала (А и В), которые противоположны по фазе. В этом учебном примере мы будем применять энкодер SparkFun COM-09117, имеющий двенадцать положений на один оборот (каждое положение ровно 30°). На приведенном ниже рисунке хорошо видно, как зависят выход А и В друг от друга при движении энкодера по часовой или против часовой стрелки. ![]() Если сигнал А переходит от положительного уровня к нулевому, мы считываем значение выхода В. Если выход В в этот момент времени находится в положительном состоянии, значит энкодер двигается по направлению часовой стрелке, если В выдает нулевой уровень, то энкодер двигается в противоположном направлении. Считывая оба выхода, мы при помощи микроконтроллера способны вычислить направление вращения, а при помощи подсчета импульсов с А выхода энкодера - угол поворота. При необходимости можно при помощи расчета частоты, определить насколько быстро происходит вращение энкодера. Применяя энкодер в нашем учебном примере мы будем регулировать яркостью светодиода при помощи ШИМ выхода. Для считывания данных с энкодера мы будем использовать метод, базирующийся на программных таймерах, которые мы уже рассмотрели. Учитывая тот факт, что в самом быстром случае, мы можем повернуть ручку энкодера на 180° за 1/10 секунды, то это будет 6 импульсов за 1/10 секунды или 60 импульсов в одну секунду. В реальности быстрее вращать не возможно. Так как нам необходимо отслеживать все полупериоды, то частота должна быть около 120 Герц. Для полной уверенности, возьмем 200 Гц. Так как, в данном случае, у нас используется механический энкодер, то возможен дребезг контактов, а низкая частота прекрасно отфильтровывает подобный дребезг. ![]() По сигналам программного таймера необходимо постоянно осуществлять сравнение текущего значения выхода А энкодера с предыдущим значением. Если состояние меняется от положительного к нулю, то мы опрашиваем состояние выхода В. В зависимости от результата опроса состояния мы увеличиваем или снижаем счетчик значения яркости LED светодиода. Код программы с временным интервалом около 5 мс (200 Гц), представлен ниже: Код начинающего ардуинщика:
/* ** Энкодер ** Для управлением яркостью светодиода применяется энкодер фирмы Sparkfun */ int brightness = 120; // яркость светодиода, начинаем с половины int fadeAmount = 10; // шаг изменения яркости unsigned long currentTime; unsigned long loopTime; const int pin_A = 12; // pin 12 const int pin_B = 11; // pin 11 unsigned char encoder_A; unsigned char encoder_B; unsigned char encoder_A_prev=0; void setup() { // declare pin 9 to be an output: pinMode(9, OUTPUT); // устанавливаем 9 вывод как выход pinMode(pin_A, INPUT); pinMode(pin_B, INPUT); currentTime = millis(); loopTime = currentTime; } void loop() { currentTime = millis(); if(currentTime >= (loopTime + 5)){ // проверяем состояния каждые 5мс (частота 200 Гц) encoder_A = digitalRead(pin_A); // считываем состояние выхода А энкодера encoder_B = digitalRead(pin_B); // выхода В энкодера if((!encoder_A) && (encoder_A_prev)){ // если состояние меняется с положительного к нулевому if(encoder_B) { // выход В в положительном состояние, значит вращение осуществляется по часовой стрелке // увеличиваем яркость свечения, не более чем до 255 if(brightness + fadeAmount <= 255) brightness += fadeAmount; } else { // выход В в нулевом состояние, значит вращение идет против часовой стрелки // снижаем яркость, но не ниже нуля if(brightness - fadeAmount >= 0) brightness -= fadeAmount; } } encoder_A_prev = encoder_A; // сохраняем значение А для последующего цикла analogWrite(9, brightness); // устанавливаем яркость на девятый пин loopTime = currentTime; } }
В этом примере для начинающих мы рассмотрим работу с пьезоизлучателем для генерирования звуков. Для этого возьмем пьезодатчик позволяющий генерировать звуковые волны в диапазоне частот 20 Гц - 20 кГц.
Это такая радиолюбительская конструкция где по всему объему расположены светодиоды. С помощью этой схемы можно генерировать различные световые и анимационные эффекты. Сложные схемы способны даже отображать различные объемные слова. Другими словами это элементарный объемным монитор
Сервопривод является основным элементом при конструировании различных радиоуправляемых моделей, а управление им с помощью контроллера просто и удобно. ![]() Программа для управления проста и наглядна. Начинается она с подключения файла, содержащего все необходимые команды для управления сервоприводом. Далее, мы создаем объект servo, например servoMain. Следующая функция setup(), в которой мы прописываем, что сервопривод подсоединен к девятому выводу контроллера. Код:
/* Arduino Servo */ #include Servo servoMain; // Обьект Servo void setup() { servoMain.attach(9); // Servo подключен к девятому выводу } void loop() { servoMain.write(45); // Повернуть сервопривод влево на 45 ° delay(2000); // Ожидание 2000 милисекунд (2 секунды) servoMain.write(0); // Повернуть серво влево на 0 ° delay(1000); // Пауза 1 с. servoMain.write(90); // Повернуть серво на 90 °. Центральная позиция delay(1500); // Ожидание 1.5 с. servoMain.write(135); // Повернуть серво вправо на 135 ° delay(3000); // Пауза 3 с. servoMain.write(180); // Повернуть серво вправо на 180 ° delay(1000); // Ожидание 1 с. servoMain.write(90); // Повернуть серво на 90 °. Центральная позиция delay(5000); // Пауза 5 с. } В главной функции loop(), мы задаем команды для серводвигателя, выдерживая паузы между ними.
Этот простой проект на Arduino для начинающих, заключается в создании схемы счетчика на обычном 7-сегментном индикаторе с общим катодом. Программный код, приведенный ниже, позволяет при нажатии на кнопку запускать счет от 0 до 9. Семисегментный индикатор – представляет собой комбинацию 8 светодиодов (последний отвечает за точку) с общим катодом, которые можно включать в нужной последовательности так, чтобы они создавали цифры. Следует обратить внимание, что в данной схеме, смотри рисунок ниже, выводы 3 и 8 отведены под катод. ![]() Справа показана таблица соответствия выводов Arduino и выводов светодиодного индикатора. Код этого проекта: byte numbers[10] = {
B11111100, B01100000, B11011010, B11110010, B01100110, B10110110, B10111110, B11100000, B11111110, B11100110 }; void setup() { for(int i = 2; i <= 8; i++) { pinMode(i, OUTPUT); } pinMode(9, INPUT); } int counter = 0; bool go_by_switch = true; int last_input_value = LOW; void loop() { if(go_by_switch) { int switch_input_value = digitalRead(9); if(last_input_value == LOW && switch_input_value == HIGH) { counter = (counter + 1) % 10; } last_input_value = switch_input_value; } else { delay(500); counter = (counter + 1) % 10; } writeNumber(counter); } void writeNumber(int number) { if(number < 0 || number > 9) { return; } byte mask = numbers[number]; byte currentPinMask = B10000000; for(int i = 2; i <= 8; i++) { if(mask & currentPinMask) digitalWrite(i,HIGH); else digitalWrite(i,LOW); currentPinMask = currentPinMask >> 1; } }
Существенно расширить потенциал плат Ардуино можно и с помощью дополнительных модулей, которые можно подключить к PIN выводам практически любого устройства. Рассмотри наиболее популярные и интересные модули расширения или как их еще называют - шилды. |
![]() |