Введение

Проект “Öölamp” представляет собой умную ночную лампу на базе Arduino, которая:

  • Позволяет вручную выбирать цвет свечения с помощью потенциометра.
  • Автоматически регулирует яркость в зависимости от уровня освещённости в помещении (используется фоторезистор).
  • Поддерживает пять режимов работы, включая полное выключение.

Этот конспект детально разбирает схему подключения, работу кода и возможные модификации проекта.

Аппаратная часть (Схема подключения)

Основные компоненты

На схеме изображены следующие элементы:

1. RGB-светодиод

  • Подключён к цифровым пинам Arduino с ШИМ (PWM):
    • Красный (RED) — пин 11
    • Зелёный (GREEN) — пин 10
    • Синий (BLUE) — пин 9
  • Принцип работы:
    • Каждый цвет регулируется отдельно с помощью analogWrite(), что позволяет смешивать цвета и получать разные оттенки.

2. Потенциометр (переменный резистор)

  • Подключён к аналоговому входу A0.
  • Функция:
    • Позволяет выбирать режим работы лампы (1–5) в зависимости от положения ручки.

3. Фоторезистор (датчик освещённости)

  • Подключён к аналоговому входу A1.
  • Функция:
    • Измеряет уровень света в помещении.
    • Чем темнее в комнате, тем ярче будет светить лампа (автоматическая регулировка).

4. Питание

  • Используются стандартные контакты Arduino:
    • 3.3V и 5V — для питания датчиков.
    • GND — общий провод (земля).

Программная часть (Код Arduino)

int RED = 11;
int GREEN = 10;
int BLUE = 9;

int potentsiomeeterPIN = A0;
int photoresistorPIN = A1;

int lightLevel, high = 0, low = 1023;

void setup() {
  pinMode(RED, OUTPUT);
  pinMode(GREEN, OUTPUT);
  pinMode(BLUE, OUTPUT);

  Serial.begin(9600);
}

void loop() {
  int photoresistorVALUE = analogRead(photoresistorPIN);  
  int potentsiomeeterVALUE = analogRead(potentsiomeeterPIN);  

  // Выбираем режим по значению с потенциометра
  int mode = map(potentsiomeeterVALUE, 0, 1023, 1, 5);  
 
  lightLevel = photoresistorVALUE;  
  autoTune();  // Настроим яркость по данным с фоторезистора

  // Отправляем данные в серийный монитор
  Serial.print("photoresistorVALUE: ");
  Serial.print(photoresistorVALUE);
  Serial.print(", lightLevel: ");
  Serial.println(lightLevel);

  // В зависимости от режима, задаем цвет
  if (mode == 1) {
    // Режим 1 — все выключено
    setColor(0, 0, 0);
  } else if (mode == 2) {
    // Режим 2 — голубой (смешиваем синий и зелёный)
    setColor(0, lightLevel, lightLevel);
  } else if (mode == 3) {
    // Режим 3 — красный
    setColor(lightLevel, 0, 0);
  } else if (mode == 4) {
    // Режим 4 — зелёный
    setColor(0, lightLevel, 0);
  } else if (mode == 5) {
    // Режим 5 — синий
    setColor(0, 0, lightLevel);
  }

  delay(100);  // Пауза для стабильности
}

void setColor(int r, int g, int b) {
  analogWrite(RED, r);
  analogWrite(GREEN, g);
  analogWrite(BLUE, b);
}

void autoTune() {
  // Настроим диапазон значений для фоторезистора
  if (lightLevel < low) low = lightLevel;
  if (lightLevel > high) high = lightLevel;

  lightLevel = map(lightLevel, low + 10, high - 30, 0, 255);
  lightLevel = constrain(lightLevel, 0, 255);
}

1. Основные переменные

int RED = 11;        // Пин для красного канала RGB-светодиода  
int GREEN = 10;      // Пин для зелёного канала  
int BLUE = 9;        // Пин для синего канала  

int potentsiomeeterPIN = A0;   // Потенциометр подключён к A0  
int photoresistorPIN = A1;     // Фоторезистор подключён к A1  

int lightLevel;       // Текущая яркость (0–255)  
int high = 0;        // Максимальное значение с фоторезистора  
int low = 1023;      // Минимальное значение с фоторезистора  
  • lightLevel — итоговое значение яркости после обработки данных с фоторезистора.
  • high и low — динамически обновляемые границы для автоматической калибровки.

2. Функция setup()

void setup() {
  pinMode(RED, OUTPUT);      // Настройка пинов светодиода на выход  
  pinMode(GREEN, OUTPUT);  
  pinMode(BLUE, OUTPUT);  

  Serial.begin(9600);        // Инициализация Serial-порта для отладки  
}
  • Зачем нужен Serial.begin(9600)?
    • Для вывода значений с датчиков в Монитор порта (Ctrl+Shift+M в Arduino IDE).
    • Полезно при отладке, чтобы убедиться, что фоторезистор и потенциометр работают корректно.

3. Функция loop()

3.1. Чтение данных с датчиков

int photoresistorVALUE = analogRead(photoresistorPIN);  
int potentsiomeeterVALUE = analogRead(potentsiomeeterPIN);  
  • photoresistorVALUE — значение с фоторезистора (0–1023).
  • potentsiomeeterVALUE — значение с потенциометра (0–1023).

3.2. Выбор режима работы

int mode = map(potentsiomeeterVALUE, 0, 1023, 1, 5);  
  • Преобразует значение потенциометра в один из пяти режимов:
    • 1 — лампа выключена.
    • 2 — голубой свет (зелёный + синий).
    • 3 — красный свет.
    • 4 — зелёный свет.
    • 5 — синий свет.

3.3. Автоматическая регулировка яркости

lightLevel = photoresistorVALUE;  
autoTune();  // Корректирует lightLevel в диапазоне 0–255  

Функция autoTune() адаптирует яркость под текущий уровень освещённости.

3.4. Вывод данных в Serial Monitor

Serial.print("photoresistorVALUE: ");  
Serial.print(photoresistorVALUE);  
Serial.print(", lightLevel: ");  
Serial.println(lightLevel);  
  • Пример вывода:
photoresistorVALUE: 450, lightLevel: 120  
  • (Чем выше photoresistorVALUE, тем темнее в комнате → lightLevel увеличивается).

3.5. Управление RGB-светодиодом

if (mode == 1) {  
    setColor(0, 0, 0);  // Выключено  
} else if (mode == 2) {  
    setColor(0, lightLevel, lightLevel);  // Голубой  
} else if (mode == 3) {  
    setColor(lightLevel, 0, 0);  // Красный  
} else if (mode == 4) {  
    setColor(0, lightLevel, 0);  // Зелёный  
} else if (mode == 5) {  
    setColor(0, 0, lightLevel);  // Синий  
}  
  • setColor(R, G, B) — устанавливает яркость каждого канала светодиода.

3.6. Задержка для стабильности

delay(100);  // Пауза 100 мс  
  • Нужна, чтобы избежать мерцания и слишком частого обновления значений.

4. Функция setColor()

void setColor(int r, int g, int b) {  
    analogWrite(RED, r);  
    analogWrite(GREEN, g);  
    analogWrite(BLUE, b);  
}  
  • Использует ШИМ (PWM) для плавного управления яркостью.
  • Примеры цветов:
    • setColor(255, 0, 0) — максимальный красный.
    • setColor(0, 150, 150) — голубой.

5. Функция autoTune()

void autoTune() {  
    if (lightLevel < low) low = lightLevel;  // Обновление минимума  
    if (lightLevel > high) high = lightLevel;  // Обновление максимума  

    lightLevel = map(lightLevel, low + 10, high - 30, 0, 255);  
    lightLevel = constrain(lightLevel, 0, 255);  
}  
  • Как это работает?
    1. low и high — это минимальное и максимальное значения, которые когда-либо считывал фоторезистор.
    2. map() пересчитывает lightLevel в диапазон 0–255.
    3. constrain() ограничивает значение, чтобы не выйти за границы.
  • Почему low + 10 и high - 30?
    • Это “буферные зоны”, чтобы избежать крайних значений (например, полной темноты или яркого света).

6. Возможные улучшения и модификации

6.1. Добавление новых режимов

Можно расширить выбор цветов:

else if (mode == 6) {  
    setColor(lightLevel, lightLevel, 0);  // Жёлтый  
} else if (mode == 7) {  
    setColor(lightLevel, 0, lightLevel);  // Фиолетовый  
}  

6.2. Плавное переключение цветов

Использовать for-цикл для градиента:

for (int i = 0; i < 255; i++) {  
    setColor(i, 0, 0);  // Плавное увеличение красного  
    delay(10);  
}  

6.3 Энергосберегающий режим

Автоматическое выключение при долгом бездействии:

if (millis() - lastActivity > 60000) {  
    setColor(0, 0, 0);  // Выключить через 1 минуту  
}  

7. Заключение

Этот проект демонстрирует:

  • Работу с аналоговыми датчиками (потенциометр, фоторезистор).
  • Использование ШИМ (PWM) для управления RGB-светодиодом.
  • Динамическую адаптацию к условиям освещения.

Код хорошо структурирован и легко модифицируется под свои нужды. Можно добавить больше цветов, кнопки управления или даже подключить лампу к Wi-Fi (через ESP8266).