Урок 5. Ночной светильник


В этом эксперименте светодиод должен включаться при падении уровня освещенности ниже порога, заданного потенциометром.

Список деталей для эксперимента

Для дополнительного задания

  • еще 1 светодиод
  • еще 1 резистор номиналом 220 Ом
  • еще 2 провода

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

Схема на макетке

Обратите внимание

  • В этом эксперименте мы устанавливаем фоторезистор между питанием и аналоговым входом, т.е. в позицию R1 в схеме делителя напряжения. Это нам нужно для того, чтобы при уменьшении освещенности мы получали меньшее напряжение на аналоговом входе.
  • Постарайтесь разместить компоненты так, чтобы светодиод не засвечивал фоторезистор.

Скетч

  1.     #define LED_PIN  13
    
  2.     #define LDR_PIN  A0
    
  3.     #define POT_PIN  A1
    
  4.  
  5.     void setup(
    )
    
  6.     {
    
  7.       pinMode(LED_PIN, OUTPUT)
    ;
    
  8.     }
    
  9.  
  10.     void loop(
    )
    
  11.     {
    
  12.       // считываем уровень освещённости. Кстати, объявлять
    
  13.       // переменную и присваивать ей значение можно разом
    
  14.       int lightness = analogRead(LDR_PIN)
    ;
    
  15.  
  16.       // считываем значение с потенциометра, которым мы регулируем
    
  17.       // пороговое значение между условными темнотой и светом
    
  18.       int threshold = analogRead(POT_PIN)
    ;
    
  19.  
  20.       // объявляем логическую переменную и назначаем ей значение
    
  21.       // «темно ли сейчас». Логические переменные, в отличие от
    
  22.       // целочисленных, могут содержать лишь одно из двух значений:
    
  23.       // истину (англ. true) или ложь (англ. false). Такие значения
    
  24.       // ещё называют булевыми (англ. boolean).
    
  25.       boolean tooDark = (lightness < threshold)
    ;
    
  26.  
  27.       // используем ветвление программы: процессор исполнит один из
    
  28.       // двух блоков кода в зависимости от исполнения условия.
    
  29.       // Если (англ. «if») слишком темно...
    
  30.       if (tooDark) {
    
  31.         // ...включаем освещение
    
  32.         digitalWrite(LED_PIN, HIGH)
    ;
    
  33.       } else {
    
  34.         // ...иначе свет не нужен — выключаем его
    
  35.         digitalWrite(LED_PIN, LOW)
    ;
    
  36.       }
    
  37.     }
    

Пояснения к коду

  • Мы используем новый тип переменных — boolean, которые хранят только значения true (истина, 1) или false (ложь, 0). Эти значения являются результатом вычисления логических выражений. В данном примере логическое выражение — это lightness < threshold. На человеческом языке это звучит как: «освещенность ниже порогового уровня». Такое высказывание будет истинным, когда освещенность ниже порогового уровня. Микроконтроллер может сравнить значения переменных lightness и threshold, которые, в свою очередь, являются результатами измерений, и вычислить истинность логического выражения.
  • Мы взяли это логическое выражение в скобки только для наглядности. Всегда лучше писать читабельный код. В других случаях скобки могут влиять на порядок действий, как в обычной арифметике.
  • В нашем эксперименте логическое выражение будет истинным, когда значение lightness меньше значения threshold, потому что мы использовали оператор <. Мы можем использовать операторы >, <=, >=, ==, !=, которые значат «больше», «меньше или равно», «больше или равно», «равно», «не равно» соответственно.
  • Будьте особенно внимательны с логическим оператором == и не путайте его с оператором присваивания =. В первом случае мы сравниваем значения выражений и получаем логическое значение (истина или ложь), а во втором случае присваиваем левому операнду значение правого. Компилятор не знает наших намерений и ошибку не выдаст, а мы можем нечаянно изменить значение какой-нибудь переменной и затем долго разыскивать ошибку.
  • Условный оператор if («если») — один из ключевых в большинстве языков программирования. С его помощью мы можем выполнять не только жестко заданную последовательность действий, но принимать решения, по какой ветви алгоритма идти, в зависимости от неких условий.
  • У логического выражения lightness < threshold есть значение: true или false. Мы вычислили его и поместили в булеву переменную tooDark («слишком темно»). Таким образом мы как бы говорим «если слишком темно, то включить светодиод»
  • С таким же успехом мы могли бы сказать «если освещенность меньше порогового уровня, то включить светодиод», т.е. передать в if всё логическое выражение:
  1. if (lightness < threshold) {
    
  2.   // ...
    
  3. }
    
  •  За условным оператором if обязательно следует блок кода, который выполняется в случае истинности логического выражения. Не забывайте про обе фигурные скобки {}!
  •  Если в случае истинности выражения нам нужно выполнить только одну инструкцию, ее можно написать сразу после if (…) без фигурных скобок:
  1. if (lightness < threshold)
    
  2.   digitalWrite(LED_PIN, HIGH)
    ;
    
  • Оператор if может быть расширен конструкцией else («иначе»). Блок кода или единственная инструкция, следующий за ней, будет выполнен только если логическое выражение в if имеет значение false, «ложь». Правила, касающиеся фигурных скобок, такие же. В нашем эксперименте мы написали «если слишком темно, включить светодиод, иначе выключить светодиод».

Вопросы для проверки себя

  • Если мы установим фоторезистор между аналоговым входом и землей, наше устройство будет работать наоборот: светодиод будет включаться при увеличении количества света. Почему?
  • Какой результат работы устройства мы получим, если свет от светодиода будет падать на фоторезистор?
  • Если мы все же установили фоторезистор так, как сказано в предыдущем вопросе, как нам нужно изменить программу, чтобы устройство работало верно?
  • Допустим, у нас есть код if (условие) {действие;}. В каких случаях будет выполнено действие?
  • При каких значениях y выражение x + y > 0 будет истинным, если x > 0?
  • Обязательно ли указывать, какие инструкции выполнять, если условие в операторе if ложно?
  • Чем отличается оператор == от оператора =?
  • Если мы используем конструкцию if (условие) действие1; else действие2;, может ли быть ситуация, когда ни одно из действий не выполнится? Почему?

Задания для самостоятельного решения

  • Перепишите программу без использования переменной tooDark с сохранением функционала устройства.
  • Добавьте в схему еще один светодиод. Дополните программу так, чтобы при падении освещенности ниже порогового значения включался один светодиод, а при падении освещенности ниже половины от порогового значения включались оба светодиода.
  • Измените схему и программу так, чтобы светодиоды включались по прежнему принципу, но светились тем сильнее, чем меньше света падает на фоторезистор.
Теги: 
Источник: 

wiki.amperka.ru