Светильник-будильник на Arduino

Ваше мнение об этом проекте будет полезно его автору. Приглашаем Вас присоединиться к его обсуждению на форуме.
 
Светильник-будильник на Arduino

Светильник-будильник на Arduino

Перевод описания проекта светового будильника автора  jeroen:

"

Всем привет,

Я решил сделать светильник Wake-Up, потому что терпеть не мог, когда мой старый будильник будил меня своим раздражающим сигналом. Этот светильник плавно увеличивает яркость, что похоже на восход солнца.

Это поможет мне вставать с кровати в более хорошем настроении

Главные особенности моего светильника


  • Обычный сигнал (как в любом будильнике)
  • Повторяющийся сигнал, который можно поставить на любой день недели для повторения.
  • Плавное затемнение: плавно гасит свет и помогает заснуть
  • Можно использовать в качестве ночной лампы
  • Много разных настроек, таких как максимальная интенсивность света, длительность увеличения яркости, …

Итак, теперь я напишу, как это можно сделать.

Для начала, вам понадобятся эти детали:

  • Arduino (Uno)
  • 12 сверхъярких светодиодов
  • 12 резисторов по 300 Ом
  • NPN транзистор (у меня, например TIP-120)
  • 7 кнопок (push buttons)
  • 8 резисторов по 10 kОм
  • ЖК дисплей (LCD Screen) (Точнее - LCD дисплей с интерфейсом I2C , что сильно экономит порты Arduino - прим. переводчика)
  • Пищалка (buzzer)
  • Несколько штекеров для подключения компонентов к плате  Arduino

Это вся схема в сборе:

schema-1024x629.png
Чтобы облегчить подключение\отключение светодиодов к остальной цепи, я припаял разьем на провода для светодиодов.

Это полезно, когда вы будете помещать все в корпус, в конце работы:

IMG_84331.jpg

На картинке ниже видно, как все части собраны вместе.

IMG_84401.jpg


Исходный код программы проекта можно скачать тут .

#include <Wire.h>
#include <Time.h>
#include <LiquidCrystal_I2C.h>
#include <AlarmController.h>
#include <AlarmSettings.h>
#include <Bounce.h>
#include <Alarm.h>

const uint8_t snoozePin = 2;    //Purple
const uint8_t leftPin = 3;      //Green
const uint8_t rightPin = 4;     //Brown
const uint8_t upPin = 5;        //Blue
const uint8_t downPin = 6;      //Orange
const uint8_t okPin = 8;        //Yellow
const uint8_t cancelPin = 8;    //Grey
const uint8_t ledPin = 9;       //White

const uint8_t buzzerPin = 13;

const uint8_t bounceDelay = 8;

double fadeValue = 0.0;
unsigned long timeStart = 0;
unsigned long timeHigh = 0;
unsigned long timeOn = 0;
unsigned long timeOnPrev = 0;
unsigned long buzzerStart = 0;
//                      x        x        x        x        x      x        x      x        x      x      x        x      x      x        x      x      x      x        x      x      x      x        x      x      x      x      x        x      x      x      x      x
const int buzzerP[] = {150,2000,150,2000,150,2000,150,2000,150,80,150,2000,150,80,150,2000,150,80,150,80,150,2000,150,80,150,80,150,2000,150,80,150,80,150,80,150,2000,150,80,150,80,150,80,150,2000,150,80,150,80,150,80,150,80,150,2000,150,80,150,80,150,80,150,80,150,1000};
const int buzzerPL = 64;
const uint8_t buzzerL = 54;
int buzzerPI = 0;

AlarmSettings set;
LiquidCrystal_I2C lcd(0x27,16,2);

AlarmController ac(&set,&lcd,ledPin);

Bounce btnLeft = Bounce(leftPin,bounceDelay);
Bounce btnRight = Bounce(rightPin,bounceDelay);
Bounce btnUp = Bounce(upPin,bounceDelay);
Bounce btnDown = Bounce(downPin,bounceDelay);
Bounce btnOK = Bounce(okPin,bounceDelay);
Bounce btnCancel = Bounce(cancelPin,bounceDelay);
Bounce btnSnooze = Bounce(snoozePin,bounceDelay);

void setup()  {
  pinMode(ledPin, OUTPUT);
  pinMode(snoozePin, INPUT);
  pinMode(leftPin, INPUT);
  pinMode(rightPin, INPUT);
  pinMode(upPin, INPUT);
  pinMode(downPin, INPUT);
  pinMode(okPin, INPUT);
  pinMode(cancelPin, INPUT);
  pinMode(buzzerPin, OUTPUT);
  timeStart = millis();
  timeOn = millis();
  timeOnPrev = timeOn;
  lcd.init(); 
  lcd.setBacklight(1);
  lcd.home();
 
  lcd.print(F("setup   "));

  uint8_t ledOff[8] =     {0b00000,
                           0b00000,
                           0b00000,
                           0b00000,
                           0b00100,
                           0b01110,
                           0b01110,
                           0b01110 };
  uint8_t ledOn[8] = {0b00100,
                      0b10101,
                  0b10101,
                  0b00000,
                  0b00100,
                  0b01110,
                  0b01110,
                  0b01110 };

  uint8_t checkbox1[8] = {0b00000,
                          0b11111,
                      0b10001,
                      0b10001,
                      0b10001,
                      0b10001,
                      0b11111,
                      0b00000 };

  uint8_t checkbox2[8] = {0b00000,
                          0b11111,
                      0b10001,
                      0b10101,
                      0b10101,
                      0b10001,
                      0b11111,
                      0b00000 };

  lcd.createChar(0b00000, ledOff);
  lcd.createChar(0b00001, ledOn);
 
  lcd.createChar(0b00010, checkbox1);
  lcd.createChar(0b00011, checkbox2);

  digitalWrite(buzzerPin, LOW);
  analogWrite(ledPin, 0);

  ac.setMakeLight(analogWrite);
}

void loop()  {
  //update time
  timeOn = millis();
  if(timeOn<timeOnPrev) { //overflow!!
    set.getTime()->addMillis((4294967295ul - timeOnPrev) + timeOn);
  }
  else{
    set.getTime()->addMillis(timeOn - timeOnPrev);
  }
  timeOnPrev = timeOn;
 
  //update AlarmState
  ac.checkAlarmState();
 
  //make noise?
  if(ac.mustMakeNoise()) {
    if(buzzerPI % 2 == 0) {
      digitalWrite(buzzerPin, HIGH);
    }
    else {
      digitalWrite(buzzerPin, LOW);
    }
    if(abs(millis() - buzzerStart) > buzzerP[buzzerPI]) {
      buzzerPI++;
      if(buzzerPI == buzzerPL)
        buzzerPI = buzzerL;
      buzzerStart = millis();
    }
  }
  else {
    buzzerPI = 0;
    digitalWrite(buzzerPin, LOW);
  }
 
  //update LCD
  ac.printLCD();

  //check snooze-button
  btnSnooze.update();
  if(btnSnooze.risingEdge()) {
    ac.doSnooze();
    if(ac.getAlarmState() == 0) {
      timeStart = millis();
      btnSnooze.update();
      ac.printLCD();
      fadeValue = 0.0;
      analogWrite(ledPin,round(fadeValue));
      while(btnSnooze.read() == HIGH) {
        if(abs(millis() - timeStart) > 600) {
          //fadeValue += 15;
          fadeValue += (fadeValue / 600) + 1;
          if(fadeValue > 255) {
            fadeValue = 255.0;
          }
          analogWrite(ledPin,round(fadeValue));
          delay(10);
        }
        btnSnooze.update();
      }
    }
  }

  //Check other buttons
  btnLeft.update();
  btnRight.update();
  btnUp.update();
  btnDown.update();
  btnOK.update();
  btnCancel.update();

  if(btnOK.risingEdge()) {
    ac.doOK();
  }
  else if(btnCancel.risingEdge()) {
    ac.doCancel();
  }
  else if(btnLeft.risingEdge()) {
    ac.doLeft();
  }
  else if(btnLeft.fallingEdge()) {
    ac.endLeft();
  }
  else if(btnRight.risingEdge()) {
    ac.doRight();
  }
  else if(btnRight.fallingEdge()) {
    ac.endRight();
  }
  else if(btnUp.risingEdge()) {
    ac.doUp();
    btnUp.update();
    timeStart = millis();
    ac.printLCD();
    while(btnUp.read() == HIGH) {
      if(abs(millis() - timeStart) > 800) {
        ac.doUp();
        ac.printLCD();
        delay(140);
      }
      btnUp.update();
    }
  }
  else if(btnDown.risingEdge()) {
    ac.doDown();
    btnUp.update();
    timeStart = millis();
    ac.printLCD();
    while(btnDown.read() == HIGH) {
      if(abs(millis() - timeStart) > 800) {
        ac.doDown();
        ac.printLCD();
        delay(140);
      }
      btnDown.update();
    }
  }
 
}


Там вы найдете скетч для Arduino и все необходимые библиотеки. Я не создавал библиотеки “Bounce”, “LiquidCristal_I2C” и “Wire”, но если они вам нужны, они так же есть в свободном доступе (все остальное домашнего приготовления )

Для лучшего понимания исходного кода, я создал схему алгоритма lifecycle. На этой схеме можно видеть все состояния, в которых светильник Wake-Up может находиться.

Также я создал диаграмму, отображающую последовательность вывода информации на дисплей screenflow.

Оригинальные файлы также добавлены в мою public Dropbox folder. (Эти схемы созданы при помощи программы Dia)

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

(Я нарисовал чертеж в SketchUp, вы можете скачать его тут )

IMG_8446.jpg


И вот конечный результат:

IMG_8451.jpg


IMG_8453.jpg

Заметка: На экране написано “Maandag”, что знает “Понедельник” на моем языке, но в прикрепленном коде, все строки переведены на английский.

...
"

В результате у автора получился приятный и полезный проект, который похож на Будильник РАССВЕТ MT5090 компании Мастер Кит, собранный своими руками