Arduino.ru
Подает HIGH или LOW значение на цифровой вход/выход (pin).
Если вход/выход (pin) был установлен в режим выход (OUTPUT) функцией pinMode(), то для значение HIGH напряжение на соответствующем вход/выходе (pin) будет 5В (3.3В для 3.3V плат), и 0В(земля) для LOW.
Если вход/выход (pin) был установлен в режим вход (INPUT), то функция digitalWrite со значением HIGH будет активировать внутренний 20K нагрузочный резистор. Подача LOW в свою очередь отключает этот резистор. Нагрузочного резистра достаточно чтобы светодиод, подключенный к входу, светил тускло. Если вдруг светодиод работает, но очень тускло, возможно необходимо установить режим выход (OUTPUT) функцией pinMode().
Замечание. Вход/выход 13 сложнее использовать как цифровой вход, т.к. он имеет встроенный в плату резистор и светодиод. Если вы активируете еще внутренний нагрузочный резистор 20K, то напряжение на этом входе будет около 1.7В, вместо ожидаемых 5В, т.к. светодиод и добавочный резистор снижает напряжение, т.е. Вы всегда будете получать LOW. Если же Вам все же необходимо использовать 13ый вход/выход, то используйте внешний нагрузочный резистор.
Синтаксис
Параметры
- pin: номер вход/выхода(pin)
- value: значение HIGH или LOW
Возвращаемое значение
Пример
int ledPin = 13; // Светодиод подключенный к вход/выходу 13 void setup() < pinMode(ledPin, OUTPUT); // устанавливает режим работы - выход >void loop() < digitalWrite(ledPin, HIGH); // включает светодиод delay(1000); // ждет секунду digitalWrite(ledPin, LOW); // выключает светодиод delay(1000); // ждет секунду >
Примечание
Аналоговые входы (analog pins) могут быть использованы как цифровые вход/выходы (digital pins). Обращение к ним идет по номерам от 14 (для аналогового входа 0) до 19 (для аналогового входа 5).
Смотрите также
- pinMode()
- digitalRead()
- Описание цифровых вход/выходов
Для чего нужна команда digitalwrite
Отправляет на цифровой вывод значение HIGH или LOW.
Если функцией pinMode() вывод сконфигурирован как выход (OUTPUT), то при выполнении функции digitalWrite() его напряжение будет изменено на соответствующее значение: 5 В (либо 3.3 В для плат, работающих от 3.3В) при отправке HIGH, 0 В (земля) — при LOW.
Если вывод сконфигурирован как вход INPUT, то отправка функцией digitalWrite() значения HIGH приведет к подключению внутреннего подтягивающего резистора номиналом 20 КОм (см. инструкцию по цифровым выводам). Запись значения LOW приведет к отключению подтяжки. Внутренний подтягивающий резистор может обеспечить только тусклое свечение светодиода. Поэтому, если светодиод горит, но очень тускло, наиболее вероятная причина этого — подтягивающий резистор. Для решения данной проблемы необходимо перевести соответствующий вывод в режим выхода с помощью функции pinMode().
ПРИМЕЧАНИЕ: Существуют некоторые сложности при использовании вывода 13 в качестве цифрового входа. Причиной этого является светодиод и резистор, которые припаяны к этому выводу на большинстве плат Ардуино. При включении внутреннего подтягивающего резистора 20 КОм, напряжение на этом выводе установится на уровне около 1.7 В, вместо ожидаемых 5 В, поскольку светодиод и последовательно соединенный резистор на плате понижают уровень напряжения. Таким образом, вывод будет всегда находится в состоянии LOW. Поэтому, чтобы использовать вывод 13 в качестве цифрового входа, необходимо использовать внешний резистор на землю.
Синтаксис
digitalWrite(pin, value)
Параметры
pin: номер вывода
value: значение HIGH или LOW
Возвращаемые значения
Пример
int ledPin = 13; // светодиод подключен к выводу 13 void setup() < pinMode(ledPin, OUTPUT); // переключаем цифровой вывод в режим выхода >void loop() < digitalWrite(ledPin, HIGH); // включаем светодиод delay(1000); // ждем 1 секунду digitalWrite(ledPin, LOW); // выключаем светодиод delay(1000); // ждем 1 секунду >
Программа устанавливает на выводе 13 высокий уровень HIGH, выдерживает паузу в 1 секунду, после чего возвращает вывод в низкий уровень LOW.
Примечание
Выводы, являющиеся аналоговыми входами, могут также использоваться как цифровые выводы под именем A0, A1 и т.д.
Смотрите также
- pinMode()
- digitalRead()
- Инструкция: Цифровые выводы
Функции digitalWrite() и delay() в Arduino IDE на примере мигания светодиода.
В статье познакомимся с платой Arduino Uno, пинами платы. Напишем программу мигания светодиода в Arduino IDE.
Сборка схемы
Плата Arduino Uno
Для начала разберемся с платой, с которой будем работать. Для примера используем Arduino Uno — плата с микроконтроллером, то есть микросхемой. Она нужна для управления электронными устройствами.

На изображении видно устройство данной платы. В этой статье нас интересуют цифровые выводы. Они также называются пины или «ножки» платы. Данные пины используются для подключения к плате различных электронных компонентов.
Каждый из пинов имеет своё обозначение. Для работы нам нужны пин 3 и Gnd. Пин 3 мы используем для вывода, а пин Gnd для заземления. Gnd — это сокращение слова ground, в переводе на русский — земля.
Чтобы ток куда-то шел, цепь должна быть замкнута. Для этого есть обозначения + и —. Ток перемещается от + к —

Сборка схемы на макетной плате
Для сборки нам нужны:
- плата Arduino Uno
- макетная плата
- светодиод
- резистор
- провода
Короткую ножку подключаем к пину GND. Длинную ножку светодиода соединяем с резистором. Второй конец резистора соединяем проводом с пином 3.

Программирование светодиода
Для начала разберемся, что такой ввод и вывод. Есть команды, которые мы даем компьютеру. Например, мы вводим какой-то текст, который хотим распечатать. В этом случае клавиатура — это устройство ввода, так как с ее помощью мы передаем команду компьютеру. Принтер — устройство вывода, он «выводит» наш результат на бумагу.

Теперь разберемся с кодом для мигания светодиода. Нам нужно настроить нашу ножку на вывод. Для этого используем команду pinMode. Эта команда говорит плате, как она будет работать: на вход или на вывод. Команда является настройкой программы, поэтому она пишется в первом блоке setup(). Общий вид кода:
void setup() < pinMode(3; OUTPUT); // указываем пину 3 работать на вывод >
В скобках после функции pinMode мы указываем номер пина, с которым мы будем работать. После точки с запятой указываем, на что будет работать наш пин: на ввод INPUT или на вывод OUTPUT. В нашем случае пин 3 работает на вывод, это мы и пишем в коде.
Не забывайте после каждой функции ставить знак «;», например:
pinMode(3; OUTPUT);
Функция digitalWrite()
Функция digitalWrite даёт команду подать напряжение на определённый пин платы. Номер этого пина мы указываем в скобках. У функции есть параметры HIGH и LOW. Параметр HIGH (с английского — высоко) включает напряжение, параметр LOW (с английского — низко) отключает.
Нам нужно включить светодиод. Для этого мы включаем напряжение на 3-ий пин, поэтому код будет выглядеть так:
void setup() < pinMode(3, OUTPUT); // указываем пину 3 работать на вывод >void loop() < digitalWrite(3, HIGH); // подаем напряжение на пин 3 >
Это уже готовый код. На его основе мы можем включить светодиод. Если загрузить этот код на плату, то светодиод загорится.

Для выключения светодиода мы используем ту же функцию. Для этого в скобках после функции задаем параметр LOW. Функция выглядет так: digitalWrite(3; LOW)
Функция delay()
Delay с английского переводится как «задерживать». Эту задачу и выполняет функция: она приостанавливает выполнение программы на указанный промежуток времени. В скобках мы указываем время остановки в миллисекундах. 1 секунда = 1000 миллисекунд, поэтому если нам нужно установить задержку в секунду, пишем: delay(1000).
Теперь допишем наш код с использованием функции delay() и функцией digitalWrite() для выключения светодиода:
void setup() < pinMode(3, OUTPUT); // указываем пину 3 работать на вывод >void loop() < digitalWrite(3, HIGH); // подаем напряжение на пин 3 delay(1000); // ждем 1000 миллисекунд digitalWrite(3, LOW); // выключаем напряжение на пине 3 delay(1000); // ждем 1000 миллисекунд >
После загрузки программы на плату получаем следующее:
Курсы Робикс, в которых изучается этот материал
- Программа занятий по робототехнике Робикс: 2-й уровень. «Робот линии»
- Программа занятий по робототехнике Робикс: 3-й уровень. «Кегельринг».
- Программа занятий по робототехнике Робикс: 4-й уровень «робот-футболист»
Оптимизируем digitalWrite на Arduino

Сегодня я протестирую фактическую скорость работы функции digitalWrite на своей Arduino Mega2560 и расскажу как ускорить работу программы в 50 раз! В основе отладочной платы Arduino Mega2560 лежит микроконтроллер AT2560, работающий с тактовой частотой 16 Мгц. Если перевести эти 16 миллионов колебаний во временной интервал, то получим достаточно небольшой период, равный 62.5 нс. Это быстро, но действительно ли Arduino выполняет операции с такой же скоростью? Давайте посмотрим.
Команды, которые мы пишем на языке Wiring, в процессе компиляции преобразуются в более простые команды, так называемый, машинный код, которые микроконтроллер уже непосредственно выполняет. Некоторые команды микроконтроллера выполняются за один такт работы микроконтроллера, на некоторые требуются больше тактов, соответственно и времени выполнения. Поэтому одна, на наш взгляд, простая команда или функция будет выполняться микроконтроллером за несколько, может даже несколько десятков или сотен тактов. К тому же, помимо вычислений, нам требуются операции чтения/записи в память, поэтому, средняя частота обработки команд будет значительно отличаться от тактовой частоты микроконтроллера. Вопрос только на сколько.
Попробуем выяснить сколько же выполняется простая команда изменения значения на цифровом выходе Arduino — digitalWrite. Проведем несколько экспериментов. В ходе первого эксперимента выполним следующий код.
void setup() < pinMode(13, OUTPUT); >void loop()
Этот код мигает светодиодом, расположенном на плате и подключенным к 13 выводу. Мы просто поочередно меняем состояние этого выхода. Если запустить этот код, то мы увидим, что светодиод будет светится непрерывно, но, на самом деле это не так. Светодиод включается и выключается, просто наш глаз не может воспринимать колебания частотой свыше 25 Гц и такие колебания мы видим как постоянно горящий светодиод с яркостью, определяемой скважностью подаваемого сигнала.
Для того, чтобы посмотреть, что же на самом деле происходит на 13 выводе, я воспользуюсь осциллографом. Осциллограмма сигнала на 13 пине выглядит так:

Похоже, что команда digitalWrite (13, HIGH) выполняется за 6.6 мкс, а digitalWrite (13, LOW) за 7.2 мкс. Итого 13.8 мкс. Это намного дольше, чем 62.5 нс, в действительности, в 220 раз дольше. Также, можно заметить, что нахождение с состоянии LOW (7.2 мкс) занимает больше времени, чем нахождение в состоянии HIGH (6.6 мкс).
Проведем следующий эксперимент.
void setup() < pinMode(13, OUTPUT); >void loop()
Теперь мы переводим дважды 13 пин в состояние HIGH, а затем один раз в LOW и цикл повторятся заново. Я ожидал увидеть значение времени для состояния HIGH равное 6.6 × 2 = 13.2 мкс и для LOW равное по прежнему 7.2 мкс. Посмотрим на фактическую осциллограмму сигнала, полученного в результате выполнения второго скетча.

По факту, две инструкции, переводящие вывод в состояние HIGH дважды занимают 19.4 мкс, или, в среднем, по 9.7 мкс на одну команду, на нахождение в состоянии LOW, по прежнему, уходит 7.2 мкс.
Попробуем реализовать теперь еще одну последовательность состояний: HIGH→LOW→LOW.
void setup() < pinMode(13, OUTPUT); >void loop()
В результате выполнения этого кода, осциллограмма сигнала на 13 пине выглядит так:

Единственная инструкция HIGH занимает 6.8 мкс — примерно так же как и ожидалось (6.6 мкс). Две подряд команды, переводящие вывод в состояние LOW занимают 13.8 мкс — это чуть меньше, чем ожидаемые 14.4 мкс (7.2 × 2 ).
Что получатеся? В цикле loop (), используя функцию digitalWrite, мы можем менять состояние пина с частотой максимум 72 кГц, а в отдельных случаях, эта частота может быть и ниже, например, как во втором случае — около 37 кГц. Такая частота значительно меньше тактовых 16 Мгц, но если использовать прерывания по таймеру, то мы можем значительно увеличить этот показатель.
Реализация функции digitalWrite в языке Wiring является, мягко говоря, не оптимальной. Если посмотреть на ее реализацию на Ассемблере, то можно обнаружить несколько проверок, в частности, проверятся не нужно ли выключить таймер ШИМ после предыдущей функции analogWrite (). Наиболее быстрая реализация, но, в то же время и наиболее затратная по времени ее написания, могла бы быть на языке Ассемблер. Но написание кода на Ассемлере — то еще насилие над собой. Я уже не говорю про отладку ассемблерного кода. Одним из компромиссных решений может быть использование оптимизированных библиотек, реализующих различные функции ввода/вывода. В дальнейших своих публикациях я рассмотрю некоторые из таких библиотек.
Еще одной причиной задержки является сама функция loop (). Когда все команды внутри loop () выполнены, то неявно для нас выполняется еще код, который производит возврат к повторному выполнению команд внутри этого цикла. Именно поэтому время последовательности из двух одинаковых состояний в конце loop () не равно сумме длительностей одиночного переключения состояния — здесь микроконтроллером еще выполняются инструкции, производящие возврат к началу цикла.
Для того, чтобы сократить время изменения состояния какого-либо вывода можно использовать команды прямой записи в регистр порта. Для изменения значений пинов с 8 по 13 используется регистр PORTB в который необходимо записать слово данных (два младших бита этого слова данных, то есть 1 и 2 биты не используются, а оставшиеся шесть — как раз и устанавливают состояния цифровых портов с 8 по 13). Для изменения состояний цифровых пинов с 0 по 7 используется PORTD.
void setup() < DDRB = B10000000; // устанавливаем 13 пин как OUTPUT >void loop() < // создаем свой бесконечный цикл while (1) < PORTB = B10000000; // устанавливаем состояние pin13 как HIGH PORTB = B00000000; // устанавливаем состояние pin13 как LOW >>
И вновь смотрим на осциллограму получившигося сигнала на 13 выводе:

Мы получили заветные 62 нс! Наша программа выполняется за 4 рабочих такта микроконтроллера. Фантастика! Режим работы 13 пина в качестве цифрового выхода мы устанавливаем всего один раз и сколько уходит на это времени — нас мало интересует. Один рабочий такт микроконтроллера уходит на перевод состояния 13 вывода в HIGH, еще один — для установки состояния этого пина в LOW и за два такта, с помощью бесконечного цикла while (1) <. >мы циклически возвращаемся вновь к установке состояния в HIGH. Зачем же здесь while (1), когда loop () делает фактически то же самое — циклически выполняет код, можете спросить вы? Изменим скетч, просто убрав из loop вложенный бесконечный цикл:
void setup() < DDRB = B10000000; // устанавливаем 13 пин как OUTPUT >void loop() < PORTB = B10000000; // устанавливаем состояние pin13 как HIGH PORTB = B00000000; // устанавливаем состояние pin13 как LOW >
И вновь обратимся к помощи осциллографа:

Как можно видеть, частота снизилась с 4 МГц до 1 Мгц. Время нахождения в состоянии HIGH не изменилось и по-прежнему равно 62.5 нс (на осцилограмме просто показано, Wid (1)). Следовательно, остальное время уходит на возврат к началу, и на это уходит в восемь раз больше времени, то есть 8 тактов. Вывод: функция loop не столь уж и эффективна.
В этом примере мы получили четырехкратное увеличение скорости, но это предельный случай. На самом деле, мы экономим несколько тактов работы и при увеличении времени выполнения программного кода внутри loop эффект сокращения времени работы программы значительно снизится.
Итак, подведу итог:
- Использование регистров портов вместо функции digitalWrite позволяет значительно увеличить скорость выполнения программы.
- Использованием вложенного в loop () бесконечного цикла while (1)мы можем сэкономить несколько тактов работы процессора на каждом витке работы цикла.