/*
* Набор для экспериментов ArduinoKit
* Код программы для опыта №6: sketch 06
*
* ФОТОРЕЗИСТОР
*
* Написано для сайта http://arduinokit.ru
*
*
* Помощь сообщества Arduino.
* Посетите сайт http://www.arduino.cc
*
*
* ФОТОРЕЗИСТОР
*
* Использование фоторезистора (датчика освещенности) для управления
* светодиодом.
*
* Подключение оборудования:
*
* Фоторезистор:
*
* Подсоедините один вывод фоторезистора к питанию +5 Вольт (5V).
* Другой вывод фотрезистора к Аналоговому порту 0 (ANALOG pin 0).
* Подсоедините резистор 10 КОм между Аналоговом портом 0 и землей (GND).
*
* Такая конструкция называется делителем напряжения, она состоит из
* двух резисторов, в данном случае один из которых — фоторезистор.
* Выходной сигнал делителя будет поступать на аналоговый вход Arduino (pin 0),
* и будет изменяться в зависимости от меняющегося освещенности фоторезистора.
*
* Светодиод:
*
* Подсоедините положительный вывод (длинная ножка) светодиода
* к цифровому порту 9 (digital pin 9) платы Arduino. Для того чтобы Arduino
* могла плавно изменять его яркость, он должен быть подключен к ШИМ,
* напомним ШИМ это Широтно Импульсная Модуляция, эти порты помечены
* на плате «~».
*
* Подсоедините отрицательный вывод (короткая ножка) светодиода к
* резистору 330 Ом.
*
* Подсоедините другой вывод резистора к Земле (GND).
*
* Комментарий к программе переведен
* 28 сентября 2014 * специально для http://arduinokit.ru
*
*/
// Как обычно, мы создадим константы с именами для используемых портов.
// Это позволит сделать код более понятным.
const int sensorPin = 0; const int ledPin = 9;
// А также создадим глобальные переменные для уровней яркости
// high (высокий), low (низкий):
int lightLevel, high = 0, low = 1023;
void setup() {
// Укажем Arduino, что порт управления светодиодом, — исходящий (Нам не
// нужно делать ничего особенного, чтобы использовать аналоговый вход).
pinMode(ledPin, OUTPUT);
// Serial.begin(9600);
// для отладки, чтобы увидеть показания датчиков
// через «монитор порта»
}
void loop() {
// Для того чтобы измерить напряжение, идущее с делителя напряжения
// (фоторезистор — резистор), как и в прошлых опытах, мы будем
// использовать функцию analogRead(). Диапазон чисел с которыми работает
// функция находится в пределах от 0 (0 вольт) и 1023 (5 вольт).
// Но! Управлением яркостью светодиода занимается функция analogWrite(),
// у нас возникают не большие сложности, так как она использует
// диапазон от от 0 до 255..
lightLevel = analogRead(sensorPin);
// Эту проблему можно решить с помощью двух полезных функций под названием
// map() и constrain():
// Функция map() может преобразовывать один диапазон значений
// в другой. К примеру — мы указываем map() в параметрах, диапазон «из» 0-1023
// «в» 0-255, она преобразует первый больший диапазон во второй, более мелкий.
// Так 0 останется 0, а 1023 станет 255, средние значения — 500 станет ~ 125.
// lightLevel = map(lightLevel, 0, 1023, 0, 255);
// Поскольку map() может столкнуться с числами за пределами диапазона,
// скажем или больше, или меньше, или даже с отрицательными, — она просто
// сделает свою работу «не моргнув глазом» и будет права.
// Поэтому нужно за ранее подготовиться к такому повороту событий, для этого
// можно, и даже нужно использовать еще одну функцию — constrain().
// Функция constrain() проверит содержится ли число в заданном диапазоне.
// Если число выше диапазона, он будет уменьшено до самого большого,
// а если число ниже диапазона, он будет увеличенно до самого низкого
// Пример: если constrain() столкнулось с числами 1024, 1025, 1026.., она
// их преобразует в 1023, 1023, 1023..). С отрицательными числами она сделает
// тоже самое, т.е все отрицательные станут 0. Если числа находится в пределах
// диапазона, они останутся теми же самым.
// lightLevel = constrain(lightLevel, 0, 255);
// Еще одна вещь, о которой стоит задуматься. Схема, которую мы
// сделали не будет работать в полную силу, потому что изменение освещенности
// не так сильно меняет сопротивление фоторезистора, как нам хотелось бы, а
// следовательно и ток на sensorPin() (делителя напряжения).
// Это будет меньший диапазон чем 0-1023, он будет приблизительно от 300 (темно)
// до 800 (светло). Если мы просто отдадим эти значения map(), светодиод конечно
// изменит яркость, но это никогда не будут максимальные значения.
// Изменить это можно двумя способами, каждый из которых представляет из
// себя функцию расположенную ниже: manualTune() и autoTune().
// Для того чтобы задействовать оду из них — раскомментируйте одну и
// закомментируйте другую. Выбор за вами!
manualTune(); // ручное изменение диапазона от светлого к темному
//autoTune(); // автоматическое — пусть Arduino все сделает за нас!
// Вышеупомянутые функции будут изменять «lightLevel», до максимальных
// значений от «Полностью Вкл» к «Полному Выкл». И это значит, что теперь
// мы сможем регулировать яркость светодиода в широких пределах:
analogWrite(ledPin, lightLevel);
// Выражение выше, будет изменять яркость светодиода вместе с уровнем
// освещенности. Чтобы сделать наоборот, заменить в analogWrite(ledPin, lightLevel)
// «lightLevel» на «255-lightLevel». Теперь у нас получился ночник!
// для отладки, чтобы увидеть показания датчиков через «монитор порта»,
//раскомментируйте следующие 3 строчки
// Serial.print(lightLevel); // вывод данных с фоторезистора (0-1023)
// Serial.println(«»); // возврат каретки
// delay(500); // пауза
}
void manualTune() {
// Как мы упоминали выше, фоторезистор не в состоянии менять сопротивление, в
// зависимости от освещения, в широких пределах, а значит схемка, которую мы
// создали, не будет перекрывать весь диапазон от 0 до 1023. Скорее всего весь
// он будет от 300 темно, до 800 (светло). Поэтому если выполнить этот скетч
// как есть, то видимые изменения яркости светодиода конечно видны будут, но
// это не будут максимальные значения.
// В качестве эксперимента мы изменим параметры, и скормим их функции map().
// Сначала попробуем полный спектр от 0 до 1023, а потом изменим его на 300 и 800.
// Если светодиод все же не загорается в полную силу, увеличте большее число.
// Если светодиод полностью не выключается, уменьшайте меньшее число.
// Не забудьте, изменения не должны выходить за пределы диапазона от 0 до 1023!
lightLevel = map(lightLevel, 300, 800, 0, 255);
lightLevel = constrain(lightLevel, 0, 255);
// Теперь возвратимся к main loop(), и пошлем lightLevel светодиоду.
}
void autoTune() {
// Как мы, уже не однократно упоминали, фоторезистор не в состоянии менять
// сопротивление, в зависимости от освещения, в широких пределах — весь
// диапазон будет иметь границы, примерно от 300 темно, до 800 (светло).
// В функции manualTune() вам придется неоднократно изменять цифры в ручную и
// запускать программу снова, и снова пока она не заработает так как должна.
// Но почему мы должны делать эту работу в ручную? У Вас же есть компьютер,
// который просто обязан выполнить такую работу за нас!
// В этой функции, Arduino будет отслеживать самые высокие и самые низкие
// значения, которые мы читаем из analogRead().
// Если Вы посмотрите в начало программы, то увидите, что мы специально
// выбрали LOW(НИЗКИЙ)=1023, т.е показания датчика гарантированно уместятся
// в заданные пределы. Таким образом мы надеемся что ничего не упустим.
if (lightLevel < low) // если уровень «lightLevel» меньше 1023, то присвоим
{ // константе «low» новое значение, которое и будет
low = lightLevel; // теперь самым «низким» ~ 800
}
// Тоже самое мы сделаем и с «HIGH» ~ 200:
if (lightLevel > high)
{
high = lightLevel;
}
// Теперь, когда мы определили самые высокие и самые низкие значения, мы
// можем «отдать» их непосредственно функции map(). И никакое ручное
// изменение не потребуется!
// Здесь есть один маленький баг — мерцание светодиода, чтобы этого
// не происходило добавим небольшие смещения, чтобы уменьшить границы:
lightLevel = map(lightLevel, low+0, high-30, 0, 255);
lightLevel = constrain(lightLevel, 0, 255);
// Теперь возвратимся к main loop(), и пошлем lightLevel светодиоду.
}
в строчке — // delay(500); // пауза }
} — надо б на новую строку перенести, а-то она в комент попадает и компилятор ошибку выдаст..
Спасибо за поправки. Исправил