| В наборе GyverKIT | Aliexpress | |
|---|---|---|
![]() |
START |
Купить |
![]() |
START IOT |
Купить |
![]() |
START IOT |
Купить |
![]() |
START IOT |
Купить |
Режим INPUT #
Обязательно изучите вводный цикл уроков про электричество
В данном режиме пин находится в высокоимпедансном состоянии - можно считать, что он подключен к GND последовательно через резистор с сопротивлением в десятки и сотни мегаом - это очень большое сопротивление, практически "обрыв провода", т.е. пин как будто "висит в воздухе". Собственно МК будет измерять напряжение на данном резисторе:

Таким образом, если подключить к нему GND - вольтметр покажет 0, а если подключить VCC - всё это напряжение упадёт на резисторе и МК его измерит. При подключении VCC в цепи пойдёт ничтожно маленький ток (при питании от 5V получится 5 / 100000000 А). Это - измерительная цепь, она практически не потребляет энергию.
Нельзя подавать на пин в режиме входа напряжение выше напряжения питания МК или отрицательное напряжение!
Чтение пина #
Для измерения цифрового сигнала на пине используется функция digitalRead(пин) (цифровое чтение), где пин - номер пина по распиновке. Давайте соберём простую схему и измерим сигнал на пине:
void setup() {
Serial.begin(115200);
//pinMode(2, INPUT); // пин по умолчанию как вход, можно не указывать
}
void loop() {
bool signal = digitalRead(2);
Serial.println(signal);
delay(100);
}
В первом случае в порт будет печататься 1 - высокий сигнал, а во втором - 0 - низкий. Аккуратно подключайте провод поочерёдно к 5V и GND, не отключая плату от компьютера - значение в мониторе порта будет меняться.
Оставьте провод подключенным к D2 и просто держите его в руках или подключите куда-нибудь в свободное место на макетке (справа от платы). С большой вероятностью в порт пойдут случайные значения 001001100111010100101010 - дело в том, что провод как антенна "ловит" различные наводки из воздуха: окружающего оборудования и сетевых проводов.
Какое напряжение на GPIO МК считает за 0, а какое за 1? Это указано в документации на МК, например для Arduino Nano (ATMega328p) за 0 считается напряжение от -0.5 V до 0.3 VCC, а за 1 - от 0.7 VCC до VCC + 0.5, где VCC это напряжение питания. При питании от 5V получится логический ноль при (-0.5.. 1.5)V и единица при (3.5.. 5.5)V
Чтение с OUTPUT #
Чтение сигнала с пина работает в любом режиме, т.е. пин может измерить и напряжение, которое сам на себя подал. Наглядный пример - перепишем мигающий светодиод из прошлого урока, заменив конструкцию включить и выключить на переключить. Для этого нужно просто подать на пин сигнал, противоположный текущему измеренному - !digitalRead(пин), где восклицательный знак - инверсия:
void setup() {
pinMode(LED_BUILTIN, OUTPUT); // сделать пин выходом
}
void loop() {
digitalWrite(LED_BUILTIN, !digitalRead(LED_BUILTIN)); // переключить (подать обратное)
delay(500); // ждать 500 мс
}
Push-pull и open-drain #
Есть две большие группы источников (выходов) цифрового сигнала:
- Push-pull (толкать-тянуть) или активный выход - источник выдаёт активный высокий и низкий сигналы. Это как мы в примере выше переключали провод между VCC и GND
- Open-drain (открытый коллектор) - источник выдаёт только низкий сигнал, вместо высокого он переходит в высокоимпедансное состояние (отключается от пина). Это как если в примере выше мы будем вставлять и вынимать провод из GND, держа его "в воздухе" вместо подключения к VCC
На практике встречаются оба варианта: GPIO микроконтроллера обычно умеет работать в обоих режимах (есть как активный выход, так и высокоимпедансный вход). У простых микросхем часто встречается open-drain, потому что аппаратно это проще и дешевле (один транзистор). Также open-drain позволяет избегать короткого замыкания при реализации передачи данных по одному проводу в обе стороны, например так работает шина I2C и интерфейс One Wire, по которому общаются например термометры DS18b20.
Для чтения push-pull сигнала достаточно подключить его к пину и всё - на пине всегда будет активный стабильный сигнал для чтения. А вот с open-drain всё немного сложнее.
Чтение open-drain #
Высокоимпедансное состояние удобно тем, что не потребляет энергию. Но у него есть и серьёзный минус - если пин никуда не подключен, то он имеет неопределённое состояние со случайным сигналом. Если в реальном устройстве от такого пина "отвалится" провод - МК начнёт получать с него случайные значения. Страшно представить что случится, если это кнопка - она может "натыкать" в устройстве всё что угодно! Более того, обычно кнопка имеет всего два контакта, то есть может только замыкать и размыкать цепь. Если мы подключим кнопку вот так:

То при нажатии она будет подавать на пин стабильные 5V, их можно будет точно измерить. А вот если отпустить кнопку - пин начнёт получать случайные значения.
У типичной тактовой кнопки контакты соединены следующим образом:

Подключите её и посмотрите что получится. Программа та же, что выше:
При нажатии будет стабильная единица 1, а при отпускании могут пойти случайные значения.
Подтяжка #
Для решения неопределённого поведения используется подтяжка - в схему добавляется резистор с сопротивлением порядка нескольких десятков кОм, который устанавливает на пине стабильное напряжение, пока кнопка не нажата. Подтяжка делается к противоположному от кнопки полюсу - если резистор подтягивает к VCC - подтяжка называется pull-up, если к GND - pull-down:

Кнопка может быть подключена по разному, а вот в случае с open-drain выходом всегда нужна подтяжка к питанию. Например - датчик температуры DS18b20:
Если сопротивление подтяжки слишком маленькое (сотни Ом) - через неё будет идти большой ток (трата энергии, нагрев), а если слишком большое (сотни кОм) - могут "пробиться" помехи. Типичное сопротивление подтяжки - единицы и десятки кОм, на практике чаще всего встречается 10 кОм
Добавьте внешнюю подтяжку в схему двумя способами и понажимайте кнопку, программа та же:
В первом случае нажатая кнопка - это сигнал 1, а во втором - 0.
Режим INPUT_PULLUP #
Для удобства подключения кнопок и прочих open-drain устройств МК часто имеют внутреннюю подтяжку в несколько десятков кОм (см. доку на конкретный МК), она активируется через pinMode(). В этом режиме никуда не подключенный пин будет выдавать стабильный высокий сигнал. Давайте добавим этот режим на тот же пин и подключим кнопку без внешних резисторов:
void setup() {
Serial.begin(115200);
pinMode(2, INPUT_PULLUP);
}
void loop() {
bool signal = digitalRead(2);
Serial.println(signal);
delay(100);
}
Теперь кнопка может стабильно опрашиваться без внешних резисторов, выдавая 0 при нажатии и 1 при отпускании. Об алгоритмах опроса кнопки читайте в соответствующем уроке.
Пин, к которому подключен светодиод на плате (13 на Arduino Nano/UNO) некорректно работает в режиме INPUT_PULLUP - имеет сигнал LOW, так как подключенный светодиод тянет его к GND через свой резистор!
Дополнительно #
Дополнительный контент доступен владельцам набора GyverKIT и по подписке, подробнее читай здесь. Блок содержит:
- Тезисы
Полезные страницы #
- Набор GyverKIT – наш большой стартовый набор Arduino, продаётся в России
- Каталог ссылок на дешёвые Ардуины, датчики, модули и прочие железки с AliExpress
- Обратная связь – сообщить об ошибке в уроке или предложить дополнение по тексту ([email protected])
- Поддержать автора за работу над уроками








