2023-02-24 20:13:21 +03:00
|
|
|
|
---
|
|
|
|
|
title: "📟 Начало работы с Arduino"
|
|
|
|
|
date: 2023-02-24T16:46:09+03:00
|
|
|
|
|
draft: true
|
|
|
|
|
tags: [arduino, tips]
|
|
|
|
|
---
|
|
|
|
|
|
|
|
|
|
⚠️ Статья носит информационный характер и находится в процессе написания.
|
|
|
|
|
Есть вероятность, что через некоторое время, части текста не будет.
|
|
|
|
|
|
|
|
|
|
## Цифровые и аналоговые пины и их назначение
|
|
|
|
|
|
|
|
|
|
Все пины можно разделить на несколько видов,
|
|
|
|
|
различие будет только в **количестве** данных выводов на различных платах.
|
|
|
|
|
|
|
|
|
|
1. **Power Pins** — порты питания, режим их работы нельзя запрограммировать или изменить.
|
|
|
|
|
Они выдают стабилизированное напряжение 5V или 3,3V,
|
2023-03-10 21:15:56 +03:00
|
|
|
|
`Vin` выдает напряжение от источника питания,
|
|
|
|
|
а `GND` — это заземление (общий минус)
|
2023-02-24 20:13:21 +03:00
|
|
|
|
2. **PWM Pins** — порты с ШИМ модуляцией, которые можно запрограммировать,
|
|
|
|
|
как цифровой выход/вход. Данные порты обозначены на плате знаком тильда (˜)
|
|
|
|
|
3. **Analog In** — порты, принимающие аналоговый сигнал от датчиков, работают на вход.
|
|
|
|
|
Данные порты тоже можно запрограммировать, как цифровой вход/выход.
|
|
|
|
|
Данные пины не поддерживают ШИМ модуляцию.
|
|
|
|
|
|
|
|
|
|
Режим пинов назначается в процедуре `void setup` с помощью `pinMode()`, например:
|
|
|
|
|
|
|
|
|
|
```c
|
|
|
|
|
void setup() {
|
|
|
|
|
pinMode(10, OUTPUT); // объявляем пин 10 как выход
|
|
|
|
|
pinMode(A2, OUTPUT); // объявляем пин A2 как выход
|
|
|
|
|
|
|
|
|
|
pinMode(12, INPUT); // объявляем пин 12 как вход
|
|
|
|
|
pinMode(A1, INPUT); // объявляем пин A1 как вход
|
|
|
|
|
}
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
**Пояснения к коду:**
|
|
|
|
|
1. К выходу `10` и `A2` можно подключить светодиод,
|
|
|
|
|
который будет включаться и выключаться при вызове команды в программе.
|
|
|
|
|
2. Пин `10` может использоваться для ШИМ сигнала,
|
|
|
|
|
например, чтобы плавно включить светодиод,
|
|
|
|
|
а пин `A2` может выдавать только цифровой сигнал (`0` или `1`)
|
|
|
|
|
3. К входу `12` и `A1` можно подключить цифровой датчик
|
|
|
|
|
и микроконтроллер будет проверять наличие сигнала на этих пинах
|
|
|
|
|
(логический нуль или единицу)
|
|
|
|
|
4. К входу `A1` можно подключить аналоговый датчик,
|
|
|
|
|
тогда микроконтроллер будет получать не только сигнал,
|
|
|
|
|
но и узнавать характеристику сигнала.
|
|
|
|
|
|
|
|
|
|
ℹ️ **Для справки:**
|
|
|
|
|
|
|
|
|
|
Пины не случайно разделены на пины с ШИМ модуляцией (_PWM Pins_) и аналоговые.
|
|
|
|
|
**PWM** пины создают аналоговый сигнал, к ним подключают сервопривод,
|
|
|
|
|
шаговый двигатель и другие устройства,
|
|
|
|
|
где требуется подавать сигнал с разными характеристиками.
|
|
|
|
|
**Аналоговые пины** (_Analog In_) используются для подключения аналоговых датчиков,
|
|
|
|
|
с них входящий сигнал преобразуется в цифровой с помощью встроенного АЦП.
|
|
|
|
|
|
|
|
|
|
### Использование аналоговых пинов как цифровые
|
|
|
|
|
|
|
|
|
|
При подключении большого количества устройств к плате
|
|
|
|
|
пинов общего назначения может не хватить.
|
|
|
|
|
Тогда в скетче можно указыть, что необходимо использовать аналоговые пины как цифровые.
|
|
|
|
|
Также можно использовать не буквенное, а цифровое обозначение выходов,
|
|
|
|
|
т.е. `A0` — это 14 пин, `A1` — это 15 пин и т.д. (работает только на Uno или Nano).
|
|
|
|
|
|
|
|
|
|
В следующем примере две строчки имеют одинаковое значение.
|
|
|
|
|
|
|
|
|
|
```c
|
|
|
|
|
void setup() {
|
|
|
|
|
pinMode(A2, OUTPUT); // объявляем пин A2, как цифровой выход
|
|
|
|
|
pinMode(16, OUTPUT); // объявляем пин 16, как цифровой выход
|
|
|
|
|
}
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
### Назначение пинов SDA, SCL
|
|
|
|
|
|
|
|
|
|
Данные пины используются для приема/передачи информации по протоколу **I2C**.
|
|
|
|
|
Например, при подключении жк дисплея с модулем I2C или GPS модуля.
|
|
|
|
|
С помощью специальной библиотеки микроконтроллер может обмениваться информацией
|
|
|
|
|
с подключенным периферийным устройством, поддерживающим данный протокол.
|
|
|
|
|
На Ардуино Mega, в отличии от Uno и Nano, имеется целых три пары пинов SDA и SCL.
|
|
|
|
|
|
|
|
|
|
### Назначение пинов TX, RX
|
|
|
|
|
|
|
|
|
|
Пины TX/RX также используются для коммуникации,
|
|
|
|
|
но уже по протоколу **UART**.
|
|
|
|
|
На платах Uni и Nano пины TX/RX подключены параллельно USB разъему для связи с компьютером.
|
|
|
|
|
Поэтому, если подключиться к данным портам устройство, например, Bluetooth модуль,
|
|
|
|
|
то загрузить в Ардуино скетч не получится, так как плата автоматически переключится
|
|
|
|
|
на чтение данных с устройства, а не с компьютера.
|
|
|
|
|
|
|
|
|
|
## Функции `void loop()` и `void setup()`
|
|
|
|
|
|
|
|
|
|
Функции `void loop()` и `void setup()` — это первое с чем сталкивается любой,
|
|
|
|
|
кто начинает знакомство с языком программирования микроконтроллеров Ардуино.
|
|
|
|
|
|
|
|
|
|
Данные циклы должны быть в каждом скетче и вызываться только один раз,
|
|
|
|
|
даже если один из циклов не используется.
|
|
|
|
|
|
|
|
|
|
Дело в том, что при запуске микроконтроллера Arduino,
|
|
|
|
|
начинают работать встроенные микропрограммы,
|
|
|
|
|
которые первым делом проверяют не началась ли загрузка новой программы с компьютера.
|
|
|
|
|
|
|
|
|
|
Если пользователь не начал прошивку,
|
|
|
|
|
то контроллер начинает выполнять ранее загруженный скетч.
|
|
|
|
|
|
|
|
|
|
Оба цикла вызываются встроенной функцией `main()` из файла `main.cpp`.
|
|
|
|
|
При этом функция `void setup()` вызывается один раз,
|
|
|
|
|
а и `void loop()` вызывается в цикле `for` бесконечное количество раз.
|
|
|
|
|
|
|
|
|
|
Если в скетче будут присутствовать более одной функции
|
|
|
|
|
`void setup()` или `void loop()`, то при компиляции Aduino IDE выдаст ошибку:
|
|
|
|
|
`redefinition of ‘void setup()‘` или `redefinition of ‘void loop()’` соответственно.
|
|
|
|
|
|
|
|
|
|
### Функция `void setup()`
|
|
|
|
|
|
|
|
|
|
```c
|
|
|
|
|
void setup() {
|
|
|
|
|
// код должен располагаться между фигурных скобок
|
|
|
|
|
}
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
Фигурные скобки указывают, где начало и конец цикла,
|
|
|
|
|
поэтому все команды должны располагаться между ними.
|
|
|
|
|
|
|
|
|
|
Процедура `void setup()` вызывается один раз
|
|
|
|
|
и её используют для назначения режима работы пинов или команд,
|
|
|
|
|
которые необходимо выполнить только в момент загрузки программы.
|
|
|
|
|
|
|
|
|
|
### `void loop()`
|
|
|
|
|
|
|
|
|
|
После выполнения цикла `setup`, программа переходит в цикл `loop`,
|
|
|
|
|
который будет повторяться до тех пор, пока на плату подано питание.
|
|
|
|
|
|
|
|
|
|
Если цикл содержит одну команду, то она будет выполняться тысячи раз в секунду.
|
|
|
|
|
|
|
|
|
|
Если написать скетч для мигания светодиодом на Arduino,
|
|
|
|
|
то необходимо добавлять в код задержку для выполнения программы,
|
|
|
|
|
иначе мигания светодиода не будет заметно.
|
|
|
|
|
|
|
|
|
|
Функция `loop*()` имеет следующую конструкцию:
|
|
|
|
|
|
|
|
|
|
```c
|
|
|
|
|
void loop() {
|
|
|
|
|
// основной код программы располагается здесь
|
|
|
|
|
}
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
Таким образом, если необходимо при запуске программы
|
|
|
|
|
включить светодиод один раз (для индикации работы устройства)
|
|
|
|
|
на микроконтроллере Arduino Nano,
|
|
|
|
|
то команду лучше написать в цикле `void setup()`.
|
|
|
|
|
|
|
|
|
|
Если в программе необходимо выполнять какое-то действие постоянно, например,
|
|
|
|
|
получать данные с ультразвукового дальномера **HC-SR04**,
|
|
|
|
|
то команду следует располагать в цикле `void loop()`.
|
|
|
|
|
|
|
|
|
|
### Функция `pinMode()`
|
|
|
|
|
|
|
|
|
|
Функция `pinMode()` устанавливает режим работы заданного пина, как входа или выхода.
|
|
|
|
|
|
|
|
|
|
Цифровой пин может находиться в двух состояниях.
|
|
|
|
|
В режиме входа пин считывает напряжение от 0 до 5 Вольт,
|
|
|
|
|
а в режиме выхода – выдавать на пине такое же напряжение.
|
|
|
|
|
|
|
|
|
|
Режим работы пина микроконтроллера выбирается при помощи функции `pinMode(pin, mode)`,
|
|
|
|
|
где `pin` это номер пина, а `mode` это режим.
|
|
|
|
|
|
|
|
|
|
### pinMode OUTPUT
|
|
|
|
|
|
|
|
|
|
**OUTPUT** (порт работает как выход) — пин становится управляемым источником питания
|
|
|
|
|
с максимальным током 40 мА.
|
|
|
|
|
|
|
|
|
|
В зависимости от команды `digitalWrite()` пин принимает значение единицы или нуля.
|
|
|
|
|
Пример: `pinMode(10, OUTPUT)`.
|
|
|
|
|
|
|
|
|
|
### Функция `digitalWrite()` и `analogWrite()`
|
|
|
|
|
|
|
|
|
|
Цифровой пин может генерировать цифровой сигнал с помощью команды `digitalWrite()`,
|
|
|
|
|
т.е. выдавать напряжение 5 Вольт.
|
|
|
|
|
|
|
|
|
|
Цифровой сигнал может иметь два значения — `0` или `1` (0 Вольт или 5 Вольт).
|
|
|
|
|
|
|
|
|
|
Если в программе используется команда `analogWrite()` для ШИМ портов платы,
|
|
|
|
|
то микроконтроллер может генерировать сигнал **PWM** на портах —
|
|
|
|
|
создавать имитацию аналогового сигнала.
|
|
|
|
|
|
|
|
|
|
```c
|
|
|
|
|
void setup() {
|
|
|
|
|
pinMode(10, OUTPUT);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void loop() {
|
|
|
|
|
digitalWrite(10, HIGH);
|
|
|
|
|
delay(250);
|
|
|
|
|
digitalWrite(10, LOW);
|
|
|
|
|
delay(250);
|
|
|
|
|
}
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
К пинам нельзя подключать устройства, потребляющие ток более **40 мА**,
|
|
|
|
|
так как основное назначение микроконтроллера —
|
|
|
|
|
это управления другими устройствами при помощи логических сигналов.
|
|
|
|
|
Если к пину подключить устройство, потребляющее ток больше указанного значения,
|
|
|
|
|
то пин может выгореть. Поэтому к выводам микроконтроллера не следует подключать ничего
|
|
|
|
|
мощнее светодиода.
|
|
|
|
|
|
|
|
|
|
### pinMode INPUT
|
|
|
|
|
|
|
|
|
|
**INPUT** (порт работает как вход) —
|
|
|
|
|
пин в этом режиме считывает данные с аналоговых и цифровых датчиков, состояния кнопок.
|
|
|
|
|
Порт находится в высокоимпедансном состоянии,
|
|
|
|
|
т.е. у пина высокое сопротивление.
|
|
|
|
|
Пример: `pinMode(10, INPUT)`.
|
|
|
|
|
|
|
|
|
|
### Функция `digitalRead()` и `analogRead()`
|
|
|
|
|
|
|
|
|
|
Arduino может определить наличие напряжения на пине через функцию `digitalRead()`,
|
|
|
|
|
которая возвращает `0` (`LOW`) или `1` (`HIGH`).
|
|
|
|
|
|
|
|
|
|
Существует разница между цифровым датчиком (который обнаруживает включение/выключение)
|
|
|
|
|
и аналоговым датчиком, значение которого постоянно изменяется.
|
|
|
|
|
|
|
|
|
|
Используя функцию `analogRead()`, можно прочитать напряжение с аналогового датчика,
|
|
|
|
|
функция возвращает число от `0` до `1023`.
|
|
|
|
|
|
|
|
|
|
```c
|
|
|
|
|
void setup() {
|
|
|
|
|
pinMode(10, INPUT);
|
|
|
|
|
Serial.begin(9600);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void loop() {
|
|
|
|
|
int data = digitalRead(10);
|
|
|
|
|
Serial.println(data);
|
|
|
|
|
delay(250);
|
|
|
|
|
}
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
Нельзя подавать на вход микроконтроллера напряжение выше напряжения питания платы.
|
|
|
|
|
|
|
|
|
|
Кроме того, для аналоговых выводов можно использовать команды
|
|
|
|
|
`digitalRead()` и `digitalWrite()`.
|
|
|
|
|
В этом случае аналоговые порты будут считывать (`digitalRead`)
|
|
|
|
|
или выдавать (`digitalWrite`) цифровой, а не аналоговый сигнал.
|
|
|
|
|
|
|
|
|
|
### pinMode INPUT_PULLUP
|
|
|
|
|
|
|
|
|
|
**INPUT_PULLUP** (порт работает как вход)
|
|
|
|
|
но к пину подключается резистор в 20 кОм.
|
|
|
|
|
|
|
|
|
|
В этом режиме при подключении кнопки к Ардуино можно не использовать
|
|
|
|
|
внешние подтягивающие резисторы.
|
|
|
|
|
Пример: `pinMode(10, INPUT_PULLUP)`.
|
|
|
|
|
|
|
|
|
|
## Директива `#define`
|
|
|
|
|
|
|
|
|
|
Директива `#define` позволяет задавать имена значениям (константам),
|
|
|
|
|
которые делают скетч более понятным.
|
|
|
|
|
|
|
|
|
|
То есть можно в начале программы один раз определить имя константы или фрагмента кода,
|
|
|
|
|
а затем использовать в скетче только это название.
|
|
|
|
|
|
|
|
|
|
Рассмотрим на примерах с описанием правильные варианты использования директивы `#define`.
|
|
|
|
|
|
|
|
|
|
Константы, которые определены через директиву `#define`,
|
|
|
|
|
не занимают места в памяти микроконтроллера,
|
|
|
|
|
так как значение подставляет значения вместо имен при компиляции скетча.
|
|
|
|
|
|
|
|
|
|
Работу директивы можно сравнить с операцией `НАЙТИ` и `ЗАМЕНИТЬ` в текстовом редакторе.
|
|
|
|
|
|
|
|
|
|
При компиляции скетча компилятор находит в программе часть кода `<что меняем>`
|
|
|
|
|
и заменяет ее на кусок кода `<на что меняем>`.
|
|
|
|
|
|
|
|
|
|
**Синтаксис директивы:**
|
|
|
|
|
|
|
|
|
|
```c
|
|
|
|
|
#define <что меняем> <на что меняем>
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
При использовании директивы следует избегать использования имени другой переменной,
|
|
|
|
|
константы или команды ардуино, иначе оно оно будет заменено при компиляции.
|
|
|
|
|
|
|
|
|
|
ℹ️ **Обрати внимание:**
|
|
|
|
|
|
|
|
|
|
В конце строчки не ставится точка с запятой и знак равенства,
|
|
|
|
|
как это делается при объявлении переменной.
|
|
|
|
|
|
|
|
|
|
```c
|
|
|
|
|
#define RED 11 // присваиваем имя RED для пина 11
|
|
|
|
|
#define GRN 12 // присваиваем имя GRN для пина 12
|
|
|
|
|
#define BLU 13 // присваиваем имя BLU для пина 13
|
|
|
|
|
|
|
|
|
|
void setup() {
|
|
|
|
|
pinMode(RED, OUTPUT); // используем PIN 11 для вывода
|
|
|
|
|
pinMode(GRN, OUTPUT); // используем PIN 12 для вывода
|
|
|
|
|
pinMode(BLU, OUTPUT); // используем PIN 13 для вывода
|
|
|
|
|
}
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
При написании кода гораздо удобнее использовать имена вместо номеров,
|
|
|
|
|
чтобы каждый раз не вспоминать какой цвет к какому пину подключен.
|
|
|
|
|
|
|
|
|
|
А программа автоматически будет заменять имена `RED`, `GRN`, `BLU`
|
|
|
|
|
на соответствующие значения при компиляции.
|
|
|
|
|
|
|
|
|
|
### Директивы `#ifdef`, `#ifndef` и `#endif` в скетче
|
|
|
|
|
|
|
|
|
|
Инструкция `#ifdef` проверят, было ли встречено в программе данное определение ранее,
|
|
|
|
|
если было, то ставится блок кода с последующей строки и до `#endif`.
|
|
|
|
|
|
|
|
|
|
В примере проверяется был ли ранее в `#define` определен признак отладки,
|
|
|
|
|
если да, то код (вывод сообщения на монитор порта) будет выполнен,
|
|
|
|
|
если признак не определен, то сообщение на мониторе выводиться не будет.
|
|
|
|
|
|
|
|
|
|
```c
|
|
|
|
|
#ifdef DEBUG
|
|
|
|
|
Serial.println("Debug message: ...");
|
|
|
|
|
#endif
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
Инструкция `#ifndef` проверят, было ли встречено в программе данное определение ранее
|
|
|
|
|
и если не было, то вставится блок кода с последующей строки и до `#endif`.
|
|
|
|
|
|
|
|
|
|
В следующем простом примере объявляется новая константа,
|
|
|
|
|
если только ранее её не объявляли в скетче.
|
|
|
|
|
|
|
|
|
|
Если дефайн с таким именем уже использовался,
|
|
|
|
|
то программа проигнорирует строчки внутри конструкции `#ifndef … #endif`.
|
|
|
|
|
|
|
|
|
|
```c
|
|
|
|
|
#ifndef RED
|
|
|
|
|
#define RED 11
|
|
|
|
|
#endif
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
### Замена функций с помощью `#define`
|
|
|
|
|
|
|
|
|
|
Кроме использования дефайн в программе для объявления констант,
|
|
|
|
|
можно заменять целые фрагменты кода с помощью директивы `#define`.
|
|
|
|
|
|
|
|
|
|
Это более сложный, но интересный вариант использования `#define`,
|
|
|
|
|
который позволяет создать много разных упрощающих инструкций в скетче.
|
|
|
|
|
|
|
|
|
|
Например, можно в первом примере заменить функцию `pinMode()`
|
|
|
|
|
на конструкцию с заданными параметрами.
|
|
|
|
|
|
|
|
|
|
```c
|
|
|
|
|
#define out(pin) pinMode(pin, OUTPUT)
|
|
|
|
|
|
|
|
|
|
void setup() {
|
|
|
|
|
out(11);
|
|
|
|
|
out(12);
|
|
|
|
|
out(13);
|
|
|
|
|
}
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
В примере функция `pinMode()` закодирована одним словом `out`.
|
|
|
|
|
|
|
|
|
|
Теперь, где в скетче встретится слово `out`,
|
|
|
|
|
компилятор подставит строку `pinMode(pin, OUTPUT)` с заданным параметром `pin`.
|
|
|
|
|
|
|
|
|
|
Таким же образом можно заменить команды `digitalWrite()` и `delay()`.
|
|
|
|
|
|
|
|
|
|
Используя RGB светодиод или три обычных светодиода с ардуинкой
|
|
|
|
|
можно проверить работу следующего примера скетча с директивой дефайн.
|
|
|
|
|
|
|
|
|
|
```c
|
|
|
|
|
#define out(pin) pinMode(pin, OUTPUT)
|
|
|
|
|
#define on(pin, del) digitalWrite(pin, HIGH); delay(del)
|
|
|
|
|
#define off(pin, del) digitalWrite(pin, LOW); delay(del)
|
|
|
|
|
|
|
|
|
|
void setup() {
|
|
|
|
|
out(11);
|
|
|
|
|
out(12);
|
|
|
|
|
out(13);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void loop() {
|
|
|
|
|
on(11, 500);
|
|
|
|
|
off(11, 500);
|
|
|
|
|
on(12, 500);
|
|
|
|
|
off(12, 500);
|
|
|
|
|
on(13, 500);
|
|
|
|
|
off(13, 500);
|
|
|
|
|
}
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
## `define` или `const`, что выбрать?
|
|
|
|
|
|
|
|
|
|
Иногда бывает не удобно применять директиву `#define` для создания констант,
|
|
|
|
|
в этом случае используют ключевое слово `const`.
|
|
|
|
|
|
|
|
|
|
В отличие от глобальных переменных, значение `const` должно быть определено сразу
|
|
|
|
|
при объявлении константы.
|
|
|
|
|
|
|
|
|
|
Необходимо помнить, что при использовании `#define` имена следует делать
|
|
|
|
|
максимально уникальными, чтобы не было совпадений с командами из подключаемых библиотек.
|
|
|
|
|
|
|
|
|
|
```c
|
|
|
|
|
const int RED = 11; // присваиваем имя RED для пина 11
|
|
|
|
|
const int GRN = 12; // присваиваем имя GRN для пина 12
|
|
|
|
|
const int BLU = 13; // присваиваем имя BLU для пина 13
|
|
|
|
|
|
|
|
|
|
void setup() {
|
|
|
|
|
pinMode(RED, OUTPUT); // используем PIN 11 для вывода
|
|
|
|
|
pinMode(GRN, OUTPUT); // используем PIN 12 для вывода
|
|
|
|
|
pinMode(BLU, OUTPUT); // используем PIN 13 для вывода
|
|
|
|
|
}
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
ℹ️ **Для справки:**
|
|
|
|
|
|
|
|
|
|
Использование `#define` или `const` не дает никаких преимуществ,
|
|
|
|
|
с точки зрения экономии объема памяти микроконтроллера.
|
|
|
|
|
|
|
|
|
|
## Задержки, `delay()` и `millis()`
|
|
|
|
|
|
|
|
|
|
### `delayMicroseconds()`
|
|
|
|
|
|
|
|
|
|
Функция `delayMicroseconds()` останавливает выполнение программы
|
|
|
|
|
на заданное количество микросекунд (**в 1 секунде 1 000 000 микросекунд**).
|
|
|
|
|
|
|
|
|
|
При необходимости задержки в программе более чем на несколько тысяч микросекунд
|
|
|
|
|
рекомендуется использовать `delay()`.
|
|
|
|
|
|
|
|
|
|
### `delay()`
|
|
|
|
|
|
|
|
|
|
Функция `delay()` останавливает выполнение программы на заданное количество миллисекунд
|
|
|
|
|
(**в 1 секунде 1 000 миллисекунд**).
|
|
|
|
|
|
|
|
|
|
Во время задержки программы с помощью функции `delay()`,
|
|
|
|
|
не могут быть считаны подключенные к плате датчики или произведены другие операции,
|
|
|
|
|
например, запись в `EEPROM` данных.
|
|
|
|
|
|
|
|
|
|
В качестве альтернативы следует использовать функцию `millis()`.
|
|
|
|
|
|
|
|
|
|
### `millis()`
|
|
|
|
|
|
|
|
|
|
Функция `millis()` возвращает количество прошедших миллисекунд
|
|
|
|
|
с момента начала выполнения программы.
|
|
|
|
|
|
|
|
|
|
Счетчик времени сбрасывается на ноль при переполнении значения `unsigned long`
|
|
|
|
|
(**приблизительно через 50 дней**).
|
|
|
|
|
|
|
|
|
|
Функция `millis()` позволяет сделать многозадачность в ардуинке,
|
|
|
|
|
так как выполнение программы не останавливается
|
|
|
|
|
и можно выполнять параллельно другие операции в скетче.
|
|
|
|
|
|
|
|
|
|
```c
|
|
|
|
|
unsigned long timer = 0;
|
|
|
|
|
bool led_state = HIGH;
|
|
|
|
|
|
|
|
|
|
void setup() {
|
|
|
|
|
pinMode(LED_BUILTIN, OUTPUT);
|
|
|
|
|
Serial.begin(9600);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void loop() {
|
|
|
|
|
if (millis() - timer > 200) {
|
|
|
|
|
led_state =! led_state;
|
|
|
|
|
digitalWrite(LED_BUILTIN, led_state);
|
|
|
|
|
|
|
|
|
|
timer = millis();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// выводим количество миллисекунд прошедших с момента начала программы
|
|
|
|
|
Serial.print("Time: ");
|
|
|
|
|
Serial.println(timer);
|
|
|
|
|
}
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
## `tone()`
|
|
|
|
|
|
|
|
|
|
```text
|
|
|
|
|
// FIXIT: https://xn--18-6kcdusowgbt1a4b.xn--p1ai/tone-arduino/
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
## `map()`
|
|
|
|
|
|
|
|
|
|
```text
|
|
|
|
|
// FIXIT: https://xn--18-6kcdusowgbt1a4b.xn--p1ai/map-arduino/
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
## `random()`
|
|
|
|
|
|
|
|
|
|
```text
|
|
|
|
|
// FIXIT: https://xn--18-6kcdusowgbt1a4b.xn--p1ai/random-arduino/
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
## Serial Monitor
|
|
|
|
|
|
|
|
|
|
```text
|
|
|
|
|
// FIXIT: https://xn--18-6kcdusowgbt1a4b.xn--p1ai/%d0%bc%d0%be%d0%bd%d0%b8%d1%82%d0%be%d1%80-%d0%bf%d0%be%d1%80%d1%82%d0%b0-%d0%b0%d1%80%d0%b4%d1%83%d0%b8%d0%bd%d0%be/
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
## Используемые материалы:
|
|
|
|
|
1. [Уроки по Arduino](https://xn--18-6kcdusowgbt1a4b.xn--p1ai/%d0%bf%d0%b8%d0%bd%d1%8b-%d0%b0%d1%80%d0%b4%d1%83%d0%b8%d0%bd%d0%be/) | робототехника18.рф
|