Освой Arduino играючи

Сайт Александра Климова

Шкодим

/* Моя кошка замечательно разбирается в программировании. Стоит мне объяснить проблему ей - и все становится ясно. */
John Robbins, Debugging Applications, Microsoft Press, 2000

Фоторезистор

05.Control: switchCase

На уроке, посвящённому потенциометру, я упомянул, что пример чтения аналоговых выводов (File | Examples | 01.Basics | AnalogReadSerial) является универсальным. Проверим пример на фоторезисторе.

Соберём конструкцию по схеме.

Принципиальная схема с фоторезистором

Схема на макетной плате.

Макетная плата с фоторезистором

Опишем конструкцию словами. Из порта 5V идёт питание на первую ножку фоторезистора. Ко второй ножке присоединяются резистор, который соединяется с GND и отдельный провод, идущий на порт A0. Получается классический делитель напряжения.

Если запустить скетч и открыть окно Serial Monitor, то мы можем наблюдать изменения значений в зависимости от степени освещённости. Показания будут зависеть от второго резистора. Можете попробовать заменить резистор с другой маркировкой и проверить результат. В моём случае использовался резистор на 1 кОм. При этом показания менялись от 4 до 158 зимним днём, когда уже начинало темнеть, а свет в комнате ещё не включал. Если посветить на фоторезистор фонариком, то значение увеличивалось до 918 единиц.

Используем светодиод

Убедившись, что фоторезистор работает и выдаёт результат, можем написать какую-нибудь программу. Допустим, мы хотим, чтобы с наступлением темноты на даче включался фонарик, который осветит дорогу в баню. В качестве фонаря будем использовать встроенный светодиод. Перепишем код.


int ledPin = 13; // используем встроенный светодиод на выводе 13

void setup() {
  pinMode(ledPin, OUTPUT);
}

void loop() {
  // считываем показания с аналогового вывода A0
  int sensorValue = analogRead(A0);
  
  if(sensorValue < 50){
    // Если потемнело, то включаем светодиод
    digitalWrite(ledPin, HIGH);
  }
  else {
    // Если светло, то выключаем светодиод
    digitalWrite(ledPin, LOW);
  }
}

Мы определяем определённую величину, которая будет соответствовать сумеркам и включаем светодиод при достижении этой величины. Теперь фонарь на даче будет включаться без нашего участия.

Плавная регулировка светодиода

Если мы хотим менять яркость светодиода плавно, то встроенный светодиод не подойдёт. Нам понадобится вывод с символом ~. Мы уже проходили подобный урок 01.Basics: Fade (затухание светодиода), поэтому добавим свой светодиод с резистором на макетную плату.

Мы можем явно указать отслеживаемый диапазон, например, от 4 до 200. Но показания могут быть меньше или больше этих значений и нам нужно написать условия, которые учитывали бы эту ситуацию. К счастью, есть готовая функция constrain(), которая делает эту работу за нас. Далее эти значения нужно распределить между диапазоном от 0 до 255 с помощью функции map(), так как светодиод работает только в этом диапазоне. Но если мы оставим как есть, то 4 будет соответствовать 0, а 200 будет соответствовать 255. При таком решении светодиод будет гореть ярче при хорошем освещении и тусклее при плохом освещении. А нам нужна обратная ситуация. Поэтому в функции мы применяем обратный порядок от 255 до 0. Таким образом, код получится следующим.


int ledPin = 10; // используем светодиод с тильдой

void setup() {
  pinMode(ledPin, OUTPUT);
}

void loop() {
  // считываем показания с аналогового вывода A0
  int sensorValue = analogRead(A0);
  
  // только в этом диапазоне
  sensorValue = constrain(sensorValue, 4, 200);
  
  // Отобразим значения от 4 до 200 как от 255 до 0
  int ledLevel = map(sensorValue, 4, 200, 255, 0);
  
  analogWrite(ledPin, ledLevel);
}

Проверяем. У меня работает, а у вас?

05.Control: switchCase

Теперь вы без труда поймёте код из примера File | Examples | 05.Control | switchCase. Опытным путём выясняется, что показания фоторезистора колеблются от 0 до 600 (у вас могут быть другие значения, тогда измените). Делим интервал на четыре части при помощи map(): темно, дымка, средне, ярко. С помощью оператора выбора switch выбираем нужное значение и выводим сообщение. Схема остаётся прежней.


const int sensorMin = 0;      // минимальное значение датчика
const int sensorMax = 600;    // максимальное значение датчика

void setup() {
  Serial.begin(9600);
}

void loop() {
  // получаем данные от датчика
  int sensorReading = analogRead(A0);
  // делим данные на четыре интервала
  int range = map(sensorReading, sensorMin, sensorMax, 0, 3);

  // сравниваем значения и выводим нужное сообщение
  switch (range) {
    case 0:    // рукой закрываем датчик
      Serial.println("dark");
      break;
    case 1:    // подаём немного света
      Serial.println("dim");
      break;
    case 2:    // ещё больше света
      Serial.println("medium");
      break;
    case 3:    // датчик под лампой
      Serial.println("bright");
      break;
  }
  delay(1);        // пауза для стабильности
}
Реклама