Project in progress
Sensal - All Senses Alarm Clock

Sensal - All Senses Alarm Clock © GPL3+

Wake up, get productive or sleepy with the help of all available senses only when you need it.

  • 9,961 views
  • 2 comments
  • 29 respects

Components and supplies

About this project

To begin with, that is my first Arduino project. This is the way i am learning programming and motivate myself to keep learning. So constructive critics is appreciated. And i would not start it without that challenge.

I want to get up easier in the morning. But while doing that project, i understood, that there are so many things, that can be done better. 

We all know about sunrise alarms. Some of you know about smell alarm. I bet they can wake you up every morning with less shock, than classical alarm with often ugly load sound. But that is not enough for me and to make a perfect alarm with best design ever. What is a perfect design for me? It is feeling of pleasure from every sense while dealing with a device.

I want to make a God of dreams and have it near my bed.

By using all our senses, it is possible to make people WANT to get up, to leave your bed with pleasure, if you slept enough. Also it is possible to make you more sleepy in the evening, so we can make something much more than just an alarm. I believe that soon devices and services like that will also remind us to do and not to do some activities to have a good sleep. Watching films late? Sensal will advice not to that, but read smth relaxing instead. Did not move enough during the day? It will also advice you to take a walk.

So, evening, you have to sleep soon. Sensal knows that too, that is why you can smell coniferous relaxing aroma and see, that alarm's light is orange or yellow. Sensal can have many modules. If you have wireless thermostat, it can also make your room cooler, aromatizer, and your bed warmer. It is chilly, and you know, that your bed is nice and warm, because Sensal started to heat your bed, and even lowered temperature with thermostat if you have one. So you will make everything to be there. Once you are, you will warm fast, because your bed has independent heater. You will fall asleep really fast, as soon as you will warm up.

After falling asleep, heater will turn off. When you sleep, body temperature is lower than during the day, so more heat will only harm your dream. And that fact we can use later, during waking up. But heater can be on all night long, if it is extremely cold in your room. It is for you to decide.

Morning, you have to wake up soon. Smell in your room becomes bracing, light starts to shine very slowly. That will wake you up gently, but it will not make you fresh, willing to start your day. But higher temperature will! So your bed heater is working too, to make your body as warm, as your were awake for a while. That will make sleep mission impossible, at least if you are more less healthy and had at least some hours of sleep. You just cannot sleep, it is hot for that, but it is perfect temperature to get up and start moving. But as it must wake you up, Sensal will use sound and vibration, if you are not awake till that time. And to wake up completely, just drink a glass of water, which will wake your stomach and other organs. Probably you will drink it with great pleasure, because as it is hot, you will be thirsty. After that alarm will turn off, and you will be not only awake, but fresh and ready for adventures as much, as it is possible.

As you can see, Sensal can consist of many parts, depending on your needs and wallet. I can see it with integration with smart home, thermostats, activity trackers and smartwatches, tracking temperature in your room and bed, tracking your sleep cycles, changing smells during the day (making you want to sleep, work, wake up, have fun, eat, meditate... ), independent bed heater, RGB powerful LEDs. It is critically important to make Sensal from modules, that can be easily connected with each other. Some people have blanket or bedcover with heating, someone have smart thermostats and air freshener. So all that customer should be able to use integrated with Sensal, multiplying benefits from all his electronics and tools to have a better sleep, mornings and health.

Right now it just a sunrise alarm. I was not able to make windows virtual shield work on my PC, which is sad. It could be much more functional, i love the idea of virtual shields. I will add more functions when i will get more needed hardware. But now you can see how i see the future of that project. To be honest technically it should be something like IFFFT, virtual shields and Blynk all together for the real world. I want you to make your own, very personal and the best devise with a simple algorithm. I want to bring programming in a real world, where arduinos and other electronics will be our "if, while, for...". Smarthome and Iot is nice, but all that geeky hardware removes any limits, give your creativity real freedom, but not in borders of some technology. It is hard, i know. But so sexy!

So here are my results:

Code

Arduino sketch for SensalArduino
If you cannot understand my comments, please feel free to write me.
Also for now you have to reflash it every time you want to change your alarm time.
// I assume you know how to connect the DS1302 and LCD.
// DS1302:  RST pin    -> Arduino Digital 5 (red)
//          DAT pin   -> Arduino Digital 6 (orange)
//          SCLK pin  -> Arduino Digital 7 (yellow)
//          VCC pin   -> - (my rtc works only from a built in battery, otherwise it returns an error, so no connection here)
//          GND pin   -> GND
// LCD:     SLC       -> analog  A5(black)
//          SDA       -> analog  A4(white) 
//          VCC       -> VCC
//          GND       -> GND
// A0 -> light control (on GND  photoresistor, on +5v resistor (10k))
// pin 9 -> PWM light control + 1k resistor
// pin 12-> DHT11 (s)
// pin2 -> SW (joystick)
// A2 -> WRy (joystick)
// A1 -> WRx (joystick)
/*
 * 
 Parts:
 - lcd i2c display
 - photoresistor to control LCD backlight
 - joystick
 - RTC module ds1302
 - DHT11 temperature and humidity sensor
 - powerfull LEDs
 - PWM adjustable 
 Soon:
 - speaker
 - relay to control powerful heater
 - fan(s) and small heater to make an aromatizer
 - windows lock
 - much-much more...

Functions:
- shows time, date, temperature, humidity, and alarm time on different screens
- Alarm. Only light alarm for now, sound, heat, smell will be when i get more hardware
- Light. Just click joystick to switch it on and off.
  
*/

//<Wire.h> Needed for LiquidCrystal_I2C.h library
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
#include <DS1302RTC.h>
#include <Time.h>
#include <TimeAlarms.h>
#include <DHT.h>
#define LED_PIN 9
#define DHTPIN 12
#define DHTTYPE DHT11
#define LDR_PIN A0
#define axis_X A1    // horizontal (Х)  Analog 1
#define axis_Y A2    // Vertical (Y)  Analog 2
#define axis_Z 2    //  Z (joystick button)  Digital 2
int value_X, value_Y, value_Z = 0;    // variable to save joystick state
boolean buttonWasUp = true;  // variable to save button state
boolean ledEnabled;  // Are LEDs are turned on?
unsigned long previousMillis = 0;
unsigned long previousMillis1 = 0;
unsigned long previousMillis2 = 0;
boolean ledAlarmIsOn = false;
byte lastBrightnessLevel;
byte ledBrightness = 0;
byte screenNum = 0;
byte lastScreenNum = 0;
byte alarmHour = 19; // set alarm hours
byte alarmMinute = 28; // set alarm minutes
byte cursorNum = 0;
// Initialize DHT sensor for normal 16mhz Arduino
DHT dht(DHTPIN, DHTTYPE);
// Init the DS1302
// Set pins:  CE(rst), IO(dat),CLK
DS1302RTC RTC(5, 6, 7);
// Init the LCD
//   initialize the library with the numbers of the interface pins (sda-a4; scl-a5)
LiquidCrystal_I2C lcd(0x27, 16, 2);

void setup()
{
  pinMode(13, OUTPUT);
 // Serial.begin(9600);
  pinMode(axis_Z, INPUT_PULLUP); // joystick button
 analogWrite(LED_PIN, ledBrightness); // LEDs are turned off by default 
  // Setup LCD to 16x2 characters
  lcd.init();//initialize screen
  dht.begin();//initialize dht11 sensor
  setSyncProvider(RTC.get);          // the function to get the time from the RTC
  // Alarm daily
  Alarm.alarmRepeat(alarmHour, alarmMinute , 0, MorningAlarm); // alarm time
}


void loop()
{

  // turn LEDs on if alarm is on.  (pause in milliseconds between brightness levels, 
  //starting level of brightness , final level of brightness,
  //should it blink in a given range)
  AlarmLed(3000, 0, 40, false);
  AlarmLed(1500, 40, 70, false);
  AlarmLed(100, 60, 220, false);
  AlarmLed(50, 60, 220, true);
  readJoystick(); //read joystick movements
  click (); // read joystick button state
  joystick(); // //control LED brightness with joystick
  screenBacklight(); // screen autobrightness
  screens(screenNumX()); // showing different screens
  Alarm.delay (1);   // Wait small time before repeating, needed for aralm
}


void print2digits(int number) {
  if (number >= 0 && number < 10) {
    lcd.write('_');
  }
  lcd.print(number);
}

// this method is needed for alarm to work
void MorningAlarm() {
  ledAlarmIsOn = true;
}

// control LED. (on-off-blinking in given range of brightness) (pause in milliseconds between brightness levels, 
//starting level of brightness , final level of brightness,
  //should it blink in a given range)
void AlarmLed(unsigned int interval, int startLed, int endLed, boolean blink) {
  // was brightness decreasing?
  if ( ledBrightness == endLed  || ledBrightness < lastBrightnessLevel) {
    if(ledBrightness != startLed && blink == true && (unsigned int)(millis() - previousMillis) >= interval )
    {
      previousMillis = millis();
      lastBrightnessLevel = ledBrightness;
      ledBrightness--;
      analogWrite(LED_PIN, ledBrightness);
    }
  }
  // was brightness increasing?
  else if (ledBrightness == startLed || ledBrightness >= lastBrightnessLevel) {
    if (ledAlarmIsOn == true  && ledBrightness < endLed  && ((unsigned int)(millis() - previousMillis) >= interval) ){
      previousMillis = millis();
      lastBrightnessLevel = ledBrightness;
      ledBrightness++;
      analogWrite(LED_PIN, ledBrightness);
    }
  }
}


void  click () {
  value_Z = digitalRead(axis_Z);   // read joystick butoon state
    // is button pressed now?
  boolean buttonIsUp = digitalRead(axis_Z);
  // if was up (&&) and not up now»...
  if (buttonWasUp && !buttonIsUp) {
    // ...it may be click or fault signal, so we wait a little
    delay(5);
    // ... and read signal again
    buttonIsUp = digitalRead(axis_Z);
    if (!buttonIsUp) {  // if it is still presed
      // ...it is a click. Revert LED state
      ledEnabled = !ledEnabled;
      if (ledEnabled  ) {
        ledBrightness = 110;
        analogWrite(LED_PIN, ledBrightness);
     
      }
      else if (ledAlarmIsOn) {
        ledAlarmIsOn = false;
        ledBrightness = 0;
        analogWrite(LED_PIN, ledBrightness);
         }
      else {
        ledBrightness = 0;
        analogWrite(LED_PIN, ledBrightness);
         }
    }
  }
  buttonWasUp = buttonIsUp;   // remember last state of the button
}


void screenBacklight() {
  // screen autobrightness
  if ( analogRead(LDR_PIN) >= 890 && ledAlarmIsOn == false) {

    lcd.noBacklight();
  }
  else {
    lcd.backlight();
  }
}

//control LED brightness with joystick
void joystick() {

  if (ledEnabled)

  {
    
    if (millis() >= (previousMillis + 200)) {            // comparing current time with previous time plus 0.2 seconds

      previousMillis = millis();

      if (value_Y >= 0 && value_Y < 50 && ledBrightness > 1)        ledBrightness -= 2;
      else if (value_Y >= 0 && value_Y < 50 && screenNum == 1 )       cursorNum--;
      if (value_Y > 50 && value_Y < 485 && ledBrightness > 0)        ledBrightness--;
      else if (value_Y > 50 && value_Y < 485 && screenNum == 1 )        cursorNum--;
      if (value_Y > 495 && value_Y < 900 && ledBrightness < 160)     ledBrightness++;
      else if (value_Y > 495 && value_Y < 900 && screenNum == 1 )        cursorNum++;
      if (value_Y > 980 && ledBrightness < 159)       ledBrightness += 2;
      else if (value_Y > 980  && screenNum == 1 )       cursorNum ++;
      analogWrite(LED_PIN, ledBrightness);
    }
  }
}

// change screen number
byte screenNumX() {

  lastScreenNum = screenNum;
  if (millis() >= (previousMillis1 + 500)) {            //  comparing current time with previous time plus 0.5 seconds
    previousMillis1 = millis();
    if (value_X >= 0 && value_X < 490  ) screenNum++;
    if (value_X > 510 && value_X > 980 ) screenNum++;
  }
  if (screenNum > 1) screenNum = 0;
  return screenNum;
}

// change screen depending on screen number
void screens(byte x) {
  if (lastScreenNum != screenNum)   lcd.clear(); // if screen is changing, clear it before change
  if (screenNum == 0   ) {

    // print current ledbrightness
    lcd.setCursor(13, 1);
    lcd.print(ledBrightness);
    lcd.print(F("   "));

    int h = dht.readHumidity(); // Read Humidity
    int t = dht.readTemperature(); // Read temperature as Celsius
    // print humidity
    lcd.setCursor(9, 0);
    lcd.print('h');
    lcd.setCursor(10, 0);
    lcd.print(h);
    // print temp
    lcd.setCursor(13, 0);
    lcd.print('t');
    lcd.setCursor(14, 0);
    lcd.print(t);

    static int sday = 0;// Saved day number for change check

    // Display time centered on the upper line
    lcd.setCursor(0, 0);
    print2digits(hour());
    lcd.print(' ');
    print2digits(minute());
    lcd.print(' ');
    print2digits(second());

    // Update in 00:00:00 hour only
    if (sday != day() || lastScreenNum != 0 ) {
      // Display abbreviated Day-of-Week in the lower left corner
      lcd.setCursor(0, 1);
      lcd.print(dayShortStr(weekday()));
      // Display date in the lower right corner
      lcd.setCursor(4, 1);
      lcd.print(' ');
      print2digits(day());
      lcd.print('/');
      print2digits(month());
      //   lcd.print("/");
      //   lcd.print(year());
    }
    // Warning!
    if (timeStatus() != timeSet) {
      lcd.setCursor(0, 1);
      lcd.print(F("RTC ERROR: SYNC!"));
    }
    // Save day number
    sday = day();
  }

  else if (screenNum == 1 && lastScreenNum != screenNum) {

    if (cursorNum == 0 || cursorNum == 1) {

      if (millis() >= (previousMillis2 + 100)) {   // comparing current time with previous time plus 0.1 seconds
        previousMillis2 = millis();

        lcd.setCursor(0, 0);
      }
      lcd.print(alarmHour);
      lcd.print(' ');
      lcd.print(alarmMinute);
    }
  }
}

void readJoystick() {
  value_X = analogRead(axis_X);    // read horizontal (Х)  joystick
  value_Y = analogRead(axis_Y);    // read vertical (y) joystick
}

Schematics

Sensal
arduino%20clock.fzz
Sensal
Arduino%20clock bb

Comments

Similar projects you might like

Complete Digital Clock Including Alarm and Motion Sensor

Project tutorial by LAGSILVA

  • 12,677 views
  • 11 comments
  • 50 respects

Weather Clock

Project showcase by Tittiamo

  • 7,666 views
  • 7 comments
  • 22 respects

Alarm Clock

by Tittiamo

  • 46,996 views
  • 61 comments
  • 48 respects

Alarm Clock and Timer Working Standalone

Project showcase by ozyRonald

  • 5,617 views
  • 6 comments
  • 10 respects

Adjusting Dual Clock using DS3231 on 1.8" ST7735 Display

Project showcase by FLORICA Tudor-Nicusor

  • 4,453 views
  • 2 comments
  • 12 respects

Buzzer Alarm System With Help Of Arduino

by Team ONYX

  • 37,904 views
  • 5 comments
  • 21 respects
Add projectSign up / Login