*/
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), LED меняет свое состояние, а переменной loopTime присваивается текущее значен е currentTime. Обратите внимание, что при использовании функции millis() и процессор может выполнять другие
операции. |
СибАДИКонтрольные вопросы |
|
1.На базе каких микроконтроллеров выпускаются платы Ардуино?
2.Что такое среда разработки? Какие IDE используются для разработки проектов на базе Ардуино?
3.Какова структура программы (скетча)?
4.Какая команда используется для задания режима работы выводов платы Ардуино?
5.Какие вы знаете назначения выводов платы Ардуино?
6.В чем преимущество функции millis() перед delay()?
11
Для управления светодиодами светофора (красным, желтым и зеленым) воспользуемся выводами портов микроконтроллера, установленного на плате Arduino. Возьмем плату Ардуино-Нано (рис. 8).
|
|
|
|
И |
|
|
|
Д |
|
|
|
А |
|
|
|
б |
|
|
|
|
Рис. 8. Плата рдуино-Нано |
|||
и |
|
|
|
|
Напишем код, работающ й аналогично примеру Blink. |
||||
С |
|
|
|
|
// Глобальные переменные: |
|
|
|
|
int greenLED = 3; int yellowLED = 5; int redLED = 7; void setup() {
pinMode(redLED, OUTPUT); pinMode(yellowLED, OUTPUT); pinMode(greenLED, OUTPUT);
}
void loop() {
digitalWrite(redLED, HIGH); // Включение красного светодиода, delay(500); // задержка.
digitalWrite(redLED, LOW); // Включение красного светодиода delay(100);
digitalWrite(yellowLED, HIGH); delay(500); digitalWrite(yellowLED, LOW);
12
delay(100); digitalWrite(greenLED, HIGH); delay(500); digitalWrite(greenLED, LOW); delay(100);
} // Переход в начало функции loop для повторения.
Теперь продемонстрируем применение команд языка С и запись данных напрямую в порты микроконтроллера, установленного на плате Arduino. Это быстрее, чем работать с конкретными входами/выходами платы, так как позволит переключать светодиоды при помощи одной лишь операции.
У микроконтроллера ATMega328P, установленного на плату Arduino
Nano, имеются 3 порта: |
И |
|
• B (цифровые входы/выходы с 8 по 13); |
||
|
||
• C (аналоговые входы А0 –А7); |
|
|
• D (цифровые входы/выходы с 0 по 7). |
|
|
Д |
||
Каждый порт управляется 3 регистрами. Регистр DDR определяет |
||
направление передачи сигнала: на вывод или ввод. При помощи регистра PORT можно установить вывод в состояние HIGH или LOW. Регистр PIN служит для ввода данных, с его помощью можно считать состояние ножек Arduino, когда они работают на вход.
Для примера будем использовать порт |
D. Сначала мы должны |
установить нужные выводы порта D как цифровые выходы. Биты 3, 5 и 7 |
|
А |
для использования их как |
регистра DDRB должны ыть установлены в 1 |
|
выходы (OUTPUT). Б ты портов нумеруют с 0 по 7, но не всегда содержат |
|||
все 8 выводов. |
|
б |
|
и |
|||
Пример: |
|||
|
|||
DDRD = b10101000; // установить ножки порта D 3, 5 и 7 как выходы, |
|||
а остальные – как входы. |
|
||
Для записи значений в порт D необходимо использовать регистр |
|||
|
С |
|
|
PORTD. Зажечь светодиоды можно командой:
PORTD = B10101000;
Теперь рассмотрим операторы сдвига:
Оператор сдвига влево << заставляет все биты сдвигаться влево, соответственно оператор сдвига вправо >> сдвигает биты вправо.
Пример: |
|
varA = 1; |
// 00000001 |
varA = 1 << 0; // 00000001 varA = 1 << 1; // 00000010 varA = 1 << 2; // 00000100
13
Впрограмме нам нужно ввести 2 переменные: первая upDown будет содержать значение куда двигаться – вверх или вниз, а вторая step − шаг сдвига.
Вфункции setup() мы определяем, какие ножки должны работать как
выходы.
В главном цикле программы loop() светодиоды по очереди загораются вверх путем увеличения переменной step, а когда доходит до самого верхнего, то переменной upDown присваивается 0 и светодиоды загораются вниз по очереди.
Код:
/* Светофор из 3 светодиодов */ |
|
|
|
||||
unsigned char upDown=1; |
// начинаем с движения вверх |
||||||
unsigned char step=0; |
// зажигает светодиоды по очереди |
||||||
void setup() { |
|
|
|
|
|
И |
|
} |
DDRD = B10010100; // устанавливаем биты порта D 3, 5 и 7 как выходы |
||||||
|
|
|
|
|
|
|
|
void loop() { |
|
|
|
|
|
|
|
|
if(upDown==1){ // если идем вверх, то |
|
|
||||
|
step++; |
|
|
|
|
|
|
|
if(step>=7) upDown=0; |
// когда достигнут наибольший номер LED, то в след. |
|||||
цикле идем вниз |
|
|
|
А |
|
||
|
} |
|
|
б |
Д |
||
|
else { |
|
|
||||
} |
step--; |
|
и |
|
|
|
|
|
if(step==0) upDown=1; |
// когда достигнут наименьший номер LED, то в след. |
|||||
цикле идем вверх |
|
|
|
|
|
||
|
} |
|
|
|
|
|
|
|
PORTD = 1 << step; |
//сдв г |
|
|
|
||
|
delay(200); |
|
// пауза 0,2 с |
|
|
||
|
2.2. Плавное управление яркостью светодиода программно |
||||||
|
|
Си с помощью фоторезистора |
|||||
Рассмотрим пример реализации плавного изменения яркости, в котором используется плата Arduino Uno (рис. 9). Вместо функции delay() будем использовать функции таймера millis().
К ножке 9 Arduino Uno подсоединен светодиод через резистор 220 Ом. Для плавного управления яркостью светодиода мы будем
использовать функцию analogWrite().
Данная функция обеспечивает вывод ШИМ-сигнала на ножку контроллера. Причем функцию pinMode() предварительно вызывать не надо. Функция analogWrite(pin,value) содержит 2 параметра: pin – номер ножки для вывода, value – значение от 0 (выкл.) до 255(вкл.).
14
Код: |
|
|
|
|
|
|
|
/* Пример, показывающий возможности |
|
||||||
функции |
analogWrite() |
для |
изменения |
|
|||
яркости свечения светодиода, который |
|
||||||
подключен к ножке D9 Arduino Uno: |
|
||||||
*/ |
|
|
|
|
|
|
|
int brightness = 0; |
// яркость светодиода |
|
|||||
int fadeAmount = 5; // шаг изменения яркости |
|
||||||
unsigned long currentTime |
|
|
|
|
|||
unsigned long loopTime |
|
|
|
|
|||
void setup() { |
|
|
|
|
Рис. 9. Подключение |
||
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; |
|
|
|
||||
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
Для |
управлен я |
светод одом будем |
|
||||
использовать |
фоторез стор |
(р |
с. 10). Эту |
|
|||
схему можно использовать для управления |
|
||||||
источником освещения, который будет |
|
||||||
автоматически включаться, когда темно, и |
|
||||||
выключаться, когдаСибАДИстановится светло. |
|||||||
Сопротивление фоторезистора зависит от |
|
||||||
его освещенности. Используя фоторезистор в |
|
||||||
связке с обычным резистором 4,7 кОм, мы |
|
||||||
получаем делитель напряжения, в котором |
Рис. 10. Фоторезистор и его |
||||||
напряжение |
на |
фоторезисторе |
изменяется в |
подключение |
|||
зависимости от уровня освещенности.
Напряжение с делителя подаем на вход АЦП Arduino (аналоговый вход). Там мы сравниваем полученное значение с заданным нами порогом
ивключаем или выключаем светодиод. Когда освещенность
увеличивается, сопротивление фоторезистора падает и соответственно на
15