Главная chevron_right Уроки chevron_right Встроенные примеры chevron_right Управляющие конструкции chevron_right While Loop — калибровка датчика по нажатию кнопки

While Loop — калибровка датчика по нажатию кнопки

Как использовать цикл while в Arduino, чтобы калибровать аналоговый датчик по нажатию кнопки и управлять яркостью светодиода.

Иногда нужно, чтобы программа «зависла» в одном месте, пока выполняется какое-то условие — и продолжила работу сразу после его снятия. Для этого в Arduino (как и в обычном C++) есть while loop.

В этом уроке цикл while используется для автоматической калибровки calibrate аналогового датчика. Пока пользователь удерживает кнопку, скетч ищет минимальное и максимальное значения фоторезистора. Как только кнопка отпущена — управление возвращается в основной цикл loop(), и светодиод начинает плавно менять яркость в зависимости от освещённости.

Главное преимущество такого подхода: калибровку можно повторить в любой момент — просто снова нажать кнопку. Это удобно, когда условия освещения меняются.

Как это работает

В основном цикле скетч читает значение фоторезистора с аналогового пина A0 и с помощью функции map() преобразует его в диапазон 0–255 для управления яркостью светодиода на пине 9 через analogWrite().

Одновременно программа проверяет состояние кнопки на цифровом пине 2. Пока кнопка нажата (LOW или HIGH — зависит от схемы подключения), выполняется метод calibrate(). Внутри него цикл while удерживает выполнение программы и непрерывно считывает значения датчика, обновляя переменные sensorMin и sensorMax. Когда кнопка отпущена, while завершается и скетч возвращается в loop().

Необходимые компоненты

  • Arduino Board
  • Тактовая кнопка или переключатель
  • Фоторезистор или другой аналоговый датчик
  • 2 резистора по 10 кОм
  • Резистор 220 Ом
  • Макетная плата и провода

Схема подключения

Подключите фоторезистор к аналоговому входу A0 через делитель напряжения: один конец — к 5V, другой — к A0, а между A0 и GND поставьте резистор 10 кОм. Кнопку подключите к цифровому пину 2 аналогично — с подтягивающим резистором 10 кОм к GND. Светодиод подключите к пину 9 через токоограничивающий резистор 220 Ом последовательно.

На схеме: Arduino UNO, макетная плата, светодиод, кнопка, фоторезистор и резисторы. Обозначения пинов — A0, GND, 5V, 9, 2 — соответствуют оригинальной распиновке платы.

Принципиальная схема

На принципиальной схеме показаны: фоторезистор (PHOTORESISTOR) и резистор 10 кОм на входе A0; кнопка (PUSH BUTTON) с резистором 10 кОм на пине 2; светодиод (LED) с резистором 220 Ом на пине 9.

Код

/*

  Условные операторы — while

  Этот пример демонстрирует использование оператора while().

  Пока кнопка нажата, скетч выполняет процедуру калибровки.

  Показания датчика во время цикла while определяют минимальное и максимальное

  ожидаемые значения фоторезистора.

  Это вариант примера calibrate.

  Схема:

  - фоторезистор подключён от +5V к аналоговому входу pin 0

  - резистор 10 кОм подключён от GND к аналоговому входу pin 0

  - LED подключён от цифрового pin 9 к GND через резистор 220 Ом

  - кнопка подключена от pin 2 к +5V

  - резистор 10 кОм подключён от pin 2 к GND

  создан 17 янв. 2009

  изменён 30 авг. 2011

  автор Tom Igoe

  изменён 20 янв. 2017

  автором Arturo Guadalupi

  Этот пример кода находится в общественном достоянии.

  https://www.arduino.cc/en/Tutorial/WhileLoop

*/

// Эти константы не изменяются:

const int sensorPin = A0;       // пин, к которому подключён датчик

const int ledPin = 9;           // пин, к которому подключён LED

const int indicatorLedPin = 13; // пин встроенного LED

const int buttonPin = 2;        // пин, к которому подключена кнопка

// Эти переменные будут изменяться:
int sensorMin = 1023;  // минимальное значение датчика
int sensorMax = 0;     // максимальное значение датчика
int sensorValue = 0;         // значение датчика

void setup() {

  // настроить пины LED как выходы, а пин кнопки — как вход:

  pinMode(indicatorLedPin, OUTPUT);

  pinMode(ledPin, OUTPUT);

  pinMode(buttonPin, INPUT);
}

void loop() {

  // пока кнопка нажата, считывать данные для калибровки:

  while (digitalRead(buttonPin) == HIGH) {

    calibrate();

  }

  // сигнализировать об окончании периода калибровки

  digitalWrite(indicatorLedPin, LOW);

  // считать значение датчика:

  sensorValue = analogRead(sensorPin);

  // применить калибровку к показанию датчика

  sensorValue = map(sensorValue, sensorMin, sensorMax, 0, 255);

  // на случай, если значение датчика выходит за диапазон, зафиксированный при калибровке

  sensorValue = constrain(sensorValue, 0, 255);

  // изменить яркость LED с использованием откалиброванного значения:

  analogWrite(ledPin, sensorValue);
}

void calibrate() {

  // включить индикаторный LED, сигнализируя о выполнении калибровки:

  digitalWrite(indicatorLedPin, HIGH);

  // считать значение датчика:

  sensorValue = analogRead(sensorPin);

  // запомнить максимальное значение датчика

  if (sensorValue > sensorMax) {

    sensorMax = sensorValue;

  }

  // запомнить минимальное значение датчика

  if (sensorValue < sensorMin) {

    sensorMin = sensorValue;

  }
}

Практические замечания

  • Время калибровки — держите кнопку нажатой несколько секунд, медленно перемещая датчик между самым тёмным и самым светлым местом. Чем шире диапазон — тем точнее будет управление яркостью.
  • Начальные значения — переменная sensorMin обычно инициализируется максимально возможным значением (например, 1023), а sensorMax — нулём. Это гарантирует корректное обновление при первом же измерении.
  • Блокировка loop() — пока выполняется while внутри calibrate(), основной цикл не работает. Это нормально для калибровки, но не подходит для задач, требующих постоянной реакции на события.

Типичные ошибки

  • Светодиод не реагирует на освещение — проверьте, что калибровка была выполнена хотя бы один раз. До первого нажатия кнопки sensorMin и sensorMax могут содержать одинаковые значения, и map() вернёт некорректный результат.
  • Кнопка не срабатывает — убедитесь, что резистор подтяжки подключён правильно и пин настроен как INPUT или INPUT_PULLUP в соответствии со схемой.
  • Мерцание светодиода — может быть вызвано слишком узким диапазоном после калибровки. Повторите калибровку в более контрастных условиях освещения.

Дополнительные материалы

Больше базовых примеров можно найти в разделе built-in examples.

Также рекомендуем изучить language reference — подробный справочник по языку программирования Arduino.

Последнее обновление: 2015/08/11, SM