Простые схемы на Arduino для начинающих

Arduino для начинающих
Цикл статей и обучающих схем с радиолюбительскими экспериментами на Arduino. Это такая радиолюбительская игрушка-конструктор, из которой без паяльника, травления печатных плат и тому подобного любой чайник в электронике может собрать полноценное работающее устройство, подходящее как для профессионального прототипирования так и для любительских опытов при изучении электроники.
Все для  Arduino

Как управлять установленным в Arduino UNO светодиодом

Контроллер Arduino UNO уже имеет сопротивление и LED-светодиод, подсоединенный к 13 выводу разъема, поэтому никаких внешних радиоэлементов в первом опыте нам не нужно.

управлять установленным в Arduino светодиодом
Код:
/* Мигание LED
* ------------
*
* Включает и выключает светодиод (LED) подсоединенный
* к выходу 13, с интервалом в 2 секунды
*
*/
int ledPin = 13; // Светодиод подсоединен к выводу 13
void setup()
{
pinMode(ledPin, OUTPUT); // устанавливаем вывод 13 как выход
}

void loop()
{
digitalWrite(ledPin, HIGH); // включаем светодиод
delay(1000); // пауза 1 секунда (1000 мс)
digitalWrite(ledPin, LOW); // выключаем LED
delay(1000); // пауза 1 секунда (1000 мс)
}

Функция delay(1000) задерживает обработку программы на 1000 милисекунд. Все это идет в вечном цикле loop().

Тайминг

В предыдущей программе между включением и выключением светодиода была секундная задержка. В используемом выше коде был один большой минус. Для выдержки паузы между включением и отключением светодиода в одну секунду мы применили функцию delay() и поэтому в этот момент контроллер не способен выполнять другие команды в главной функции loop(). Корректировка кода в функции loop(), представленная ниже решает эту проблему.

Вместо установки значения в HIGH, а затем в LOW, мы получим значение ledPin и проинвертируем его. Допустим если оно было HIGH, то станет LOW и т.п.

Код:
void loop()
{
digitalWrite(ledPin, !digitalRead(ledPin)); // включаем/выключаем LED
delay(1000); // задержка 1 сек.

Затем можно заменить функцию delay(). Вместо нее, лучше использовать функцию millis(). Она возвращает количество миллисекунд, прошедшее с момента старта программы. Функция переполнится приблизительно через 50 суток работы программного кода.

Похожей функцией является micros(), которая возвращает количество микросекунд, прошедшее с момента запуска программного кода. Функция вернется в ноль через 70 минут работы программы.

/* Мигание светодиода вариант 2
* ------------------------
* Включает и выключает подсоединенный светодиод (LED)
* к выходу 13, с интервалом в 2 секунды используя функцию millis()
*
*/
int ledPin = 13; // LED подсоединен к выводу 13
unsigned long currentTime;
unsigned long loopTime;

void setup()
{
pinMode(ledPin, OUTPUT); // устанавливаем вывод 13 как выход
currentTime = millis(); // считываем время, прошедшее с момента запуска программы
loopTime = currentTime;
}

void loop()
{
currentTime = millis(); // считываем время, прошедшее с момента запуска программы
if(currentTime >= (loopTime + 1000)){ // сравниваем текущий таймер с переменной loopTime + 1
секунда
digitalWrite(ledPin, !digitalRead(ledPin)); // включаем/выключаем LED
loopTime = currentTime; // в loopTime записываем новое значение
}
// Здесь могут быть другие команды }

В данном примере мы изучили две новые переменные currentTime и loopTime. В функции setup() обе переменные имеют одинаковое значение. В функции loop(), переменная currentTime каждый раз обновляется в цикле. Если currentTime выше чем loopTime на 1 секунду (loopTime + 1000), то светодиод переключает свое состояние, а переменной loopTime приравнивается текущее значение currentTime. В данном уроке для начинающих мы не применяли функцию delay() и процессор способен осуществлять в это время другие программные алгоритмы.

Пример реализации схемы бегущего огня на Arduino UNO

Для управления пятью светодиодами будем применять различные манипуляции с портами Arduino. Для этого напрямую запишем данные в порты Arduino, это позволит задать значения для светодиодов при помощи одной лишь функции.

Arduino UNO обладает тремя портами: B (цифровые входа/выхода с 8 по 13); C (аналоговые входа); D (цифровые входа/выхода с 0 по 7)

Каждый порт осуществляет управление тремя регистрами. Первый DDR задает чем будет являться pin входом или выходом. При помощи второго регистра PORT можно задать pin в состояние HIGH или LOW. При помощи третьего можно считать информацию о состояние ножек Arduino, в случае если они работает на вход.

Схема бегущего огня на Arduino UNO

Для работы задействуем порт 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 и т.п

Существует два оператора двоичного сдвига: влево и вправо. Оператор сдвига влево заставляет все биты данных переместиться влево, соответственно оператор сдвига вправо, перемещает их вправо.

Пример:
varA = 1; // 00000001
varA = 1 << 0; // 00000001
varA = 1 << 1; // 00000010
varA = 1 << 2; // 00000100

Теперь вернемся к исходному коду нашей программе. Нам требуется ввести две переменные: upDown будет включать в себя значения куда двигаться - вверх или вниз, а вторая cylon укажет какие Led зажигать.

В функции setup() мы определяем какие ножки должны работать как выхода.

В главном цикле loop(), светодиоды загораются по очереди вверх путем увеличения переменной cylon, а когда доходит до самого верхнего, то переменной upDown присваивается ноль и светодиоды начинают светиться вниз по очереди.

Код:
/*
Бегущий огонь на пяти светодиодах
*/
unsigned char upDown=1; // начинаем с движения вверх
unsigned char cylon=0; // определяет очередность LED

void setup() {
DDRB = B00011111; // устанавливаем порт B с 0 по 4 как выхода
}

void loop() {
if(upDown==1){ // если идем вверх, то
cylon++;
if(cylon>=4) upDown=0; // когда достигнут наибольший номер LED, то в след. цикле идем вниз
}
else {
cylon--;
if(cylon==0) upDown=1; // когда достигнут наименьший номер LED, то в след. цикле идем вверх
}
PORTB = 1 << cylon; //сдвиг
delay(200); // пауза 200 мс
}
эффект плавного затухания светодиода с помощью Arduino UNO

К девятому пину 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;
}
}
Работа Arduino с энкодером

Энкодером предназначен для преобразования угла поворота в электрический сигнал. С него мы получаем два сигнала (А и В), которые противоположны по фазе. В этом учебном примере мы будем применять энкодер SparkFun COM-09117, имеющий двенадцать положений на один оборот (каждое положение ровно 30°). На приведенном ниже рисунке хорошо видно, как зависят выход А и В друг от друга при движении энкодера по часовой или против часовой стрелки.

Диаграмма зависимости выходов энкодера друг от друга

Если сигнал А переходит от положительного уровня к нулевому, мы считываем значение выхода В. Если выход В в этот момент времени находится в положительном состоянии, значит энкодер двигается по направлению часовой стрелке, если В выдает нулевой уровень, то энкодер двигается в противоположном направлении. Считывая оба выхода, мы при помощи микроконтроллера способны вычислить направление вращения, а при помощи подсчета импульсов с А выхода энкодера - угол поворота.

При необходимости можно при помощи расчета частоты, определить насколько быстро происходит вращение энкодера.

Применяя энкодер в нашем учебном примере мы будем регулировать яркостью светодиода при помощи ШИМ выхода. Для считывания данных с энкодера мы будем использовать метод, базирующийся на программных таймерах, которые мы уже рассмотрели.

Учитывая тот факт, что в самом быстром случае, мы можем повернуть ручку энкодера на 180° за 1/10 секунды, то это будет 6 импульсов за 1/10 секунды или 60 импульсов в одну секунду.

В реальности быстрее вращать не возможно. Так как нам необходимо отслеживать все полупериоды, то частота должна быть около 120 Герц. Для полной уверенности, возьмем 200 Гц.

Так как, в данном случае, у нас используется механический энкодер, то возможен дребезг контактов, а низкая частота прекрасно отфильтровывает подобный дребезг.

Схема контроллера Arduino с энкодером

По сигналам программного таймера необходимо постоянно осуществлять сравнение текущего значения выхода А энкодера с предыдущим значением. Если состояние меняется от положительного к нулю, то мы опрашиваем состояние выхода В. В зависимости от результата опроса состояния мы увеличиваем или снижаем счетчик значения яркости 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;
}
}
Пьезоизлучатель arduino, подключение мощной нагрузки

В этом примере для начинающих мы рассмотрим работу с пьезоизлучателем для генерирования звуков. Для этого возьмем пьезодатчик позволяющий генерировать звуковые волны в диапазоне частот 20 Гц - 20 кГц.

Светодиодный куб 3х3х3 на контроллере Arduino

Это такая радиолюбительская конструкция где по всему объему расположены светодиоды. С помощью этой конструкции можно генерировать различные световые и анимационные эффекты. Сложные схемы способны даже отображать различные объемные слова. Другими словами это элементарный объемным монитор

Как при помощи Arduino UNO управлять сервоприводом

Сервопривод является основным элементом при конструировании различных радиоуправляемых моделей, а управление им с помощью контроллера просто и удобно.

Arduino UNO управление сервоприводом

Программа для управления проста и наглядна. Начинается она с подключения файла, содержащего все необходимые команды для управления сервоприводом. Далее, мы создаем объект 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(), мы задаем команды для серводвигателя, выдерживая паузы между ними.