I often have the problem, that I have trouble getting up in the morning, while at the same time, I have trouble falling asleep in the night.
I've checked out several possibilities to make both easier.
Getting up in the morning
Sunrise alarm / light alarm clocks (amazon): instead of ringing the hell out of you, those alarm clocks dimm up light until it gets quite bright in your room, simulating a sunrise. Those often come in combination with some ambient sound, to make your wake up experience even more natural.
Unfortunately those alarm clocks can be hardly configured (color light gradient, mixture of ambient sound,...) and they are quite expensive (~100 bucks).
Sleep cycle / sleep phase alarm clocks (play store, amazon): Those are alarm clocks that track your movement during night and track when you are in a phase of light sleep and wake you up at this time. This makes getting up easier as your body is already in a nearly wake state. Those alarm clocks come in hardware and as apps in software (using the sensors in your phone).
Both types have drawbacks: physical alarm clocks are damn expensive (>300 bucks) and you usually have to wear a wrist- or headband that tracks your movement (=>uncomfortable). The app is a lot cheaper, however, you have to sleep very closely to your cell phone, so it can track your movements (I have a very soft mattress, which filters out basically all movement + the sensors in my smartphone are not that great).
There're dozens of possibilities to fall asleep, but I personally fall asleep very quickly when listening to an audiobook (or if my girlfriend reads a book to me).
Another alternative is to listen to ambient sounds.
The problem with listening to anything in order to fall asleep is, that the player doesn't turn off automatically when you are asleep (ok, there're some apps that can detect motion, or force you to keep a finger on the display to keep running, but that's not really comfortable).
Everything above not being an ideal option I decided to build my own device.
Despite the title I won't call it an alarm clock, but a sleep supporter. It should not be there to wake you up, but give you a better sleeping experience (i.e. fall asleep faster, and get up easier).
- I wanted to have a sleeping cycle alarm combined with a sunrise alarm: by detecting your movements during night, your next light sleeping phases will be detected, and the light alarm will be scheduled accordingly (it must start prior to your upcoming light sleeping phase, so some estimation must be done here). The movement detection should be unnoticable (no wristbands or whatsoever).
- The same concept of movement detection can also be applied in an ebook reader / ambient sound player: volume is turned down after a few minutes, when no motion is detected within a certain time frame the audiobook stops playing. The position when you moved the last time to continue playing is stored, so the book can be played from this position.
- As my night stand is not that big and the sleep supporter emits light anyway, It can be used as a lamp or moodlight.
- It should not display time or anything. In my oppinion displaying time would lead to pressure and pressure leads to bad sleep.
I used a raspberry Pi with a wi-fi stick to host a node.js/express.js/mongoDb/angular js based web-application to configure and start alarms, audiobook and an additional moodlight mode.
I used an active speaker for sound output
I used 3 1W RGB LEDs to produce a bright enough light which are connected to the Pi (+a fan to dissipate heat).
I added 2 temperature sensors (1 inside to monitor heat development and prevent the RGB-LEDs from taking damage), 1 light sensor (basically for statistics, to help you find the best brightness to wake up) and 2 accelerometers which are put into the matress to track your motion.
I added a pushbutton as really simple interface. It stops anything that's currently running (audiobook, moodlight, alarm, light,....). If nothing has been running it turns on light.
Any more complex interaction is done via the web interface.
The form of the sleep supporter tries to resemble an egg (symbol for beginning of something new, like a new day:-))
In the next few steps I will guide you through how I
- made the enclosure
- designed and built the circuitry
- implemented the software
- solved a lot of unexpected problems that occurred during implementation.
At the end I will outline some ideas I want to implement at a later time
The following video shows a sunrise with ambient sound. Unfortunately the camera had trouble to capture the brightness. The end of the sunrise is much more white/yellowish not as read as seen in the video.
The next video shows a short demonstration of the mood light mode (at high speed)
Step 1: Enclosure - Materials
The enclosure consists of two parts. the lower part is made from glued up wood which is then turned on a lathe.
The upper, semi transparent part is made from a vacuum formed sheet of hdpe. The mold for the vacuum forming is made from some cheap mdf
- Sheet of HDPE (~1mm thickness), at least 30cm x 30cm
- Block of hardwood or hardwood board to glue up a block (volume: ~ 20x25x25cm)
- Some scrap multiplex (~0.2 x 25 x 25cm)
- Small metal rod
Step 2: Housing - Design
To get an impression of what the finished project might look like I took a photo of an egg, made it black/white in gimp, vectorized it in inkscape imported it in openscad, rotated it there, and voila I had an egg:-)
I've attached the openscad file.
After I had a rough impression on how it may look, I took the inkscape file to get the side view for more exact measurement.
I've also attached the inkscape file.
Step 3: Housing - Turning the Bottom Part and the Mold
At first I wanted to create the bottom part from mdf and laquer it in white to match the color of the top part.
Unfortunately mdf cannot be turned so well. When it get's narrower it tends to break off, because it's so soft.
So in a first step I glued up the complete egg shape roughly from mdf.
To do this I measured the diameter of the layers from the inkscape schematics (I printed it to it's final size), cut out the circles, and drilled a whole in the middle (in the diameter of a threaded rod I had lying around).
I used the threaded rod to align the circles while gluing it up.
After the glue had dried I put it on my lathe to turn out the complete egg (after I had removed the threaded rod, of course).
To get as close as possible to my schematics I glued the schematics to a thin sheet of multiplex and cut it out, so that I had a template, which I could hold against the egg in the lathe.
When the outer form was completed, I parted off the top part which would act as the mold for the vacuum forming process.
When I tried to hollow out the bottom part, the mdf came loose unfortunately. So I repeated the glue up for the bottom part with some glued up birch, which is a lot denser).
After turning and hollowing it out, I finally sealed it up with a few coats of poly-urethane lacquer.
Step 4: Housing - Vacuum Forming the Top Part
I created a vacuum forming machine like in this instructable and used it with a sheet of HDPE and the top part of the mdf egg as a mold.
- It's really important to have a good seal (I used window sealing tape after a few unsuccesful tries...)
- Use a strong vacuum (first I used a big shop vac, but it only can suck much air/minute, but it's not good at creating a vacuum. My second try with a dyson vac worked out pretty well)
- You need to heat the HDPE sheet very uniformly (first I tried to do it with a heat gun, but when one part of the sheet was ok, the other became hard again..., I then switched to an oven, which worked good and fast)
- HDPE turns transparent when it is hot enough.
After I had created the top part, I cut a small ring to strengthen the structure of the relatively thin top part.
Step 5: Electronics - Materials
I used a raspberry Pi together with an mcp3008 to capture analog sensor input from up to 8 sensors with only 2 pins.
To drive the LED I used those circuits (especially number 4)
- Raspberry Pi (model b)
- Wi-Fi USB-stick
- Materials to create circuit number 4 from above mentioned instructable
- 3 high power RGB LEDs (I used cree xp-e rgb)
- heat sink for LEDs (ATTENTION: the one I used is far too small, I will replace it with a bigger one)
- 12V fan
- 2 Thermistors
- 1 photo-resistor
- 2 accelerometers with digital output and 3.3V
- 3 push-buttons
- mcp3008 (it's an adc chip suitable for the raspberry Pi)
- speaker + amplification circuitry (I used some old active computer speakers running on 5V)
- 4 optocouplers (one for each LED and the fan)
- Power supply that outputs 5 and 12V at ~2Amps (~20-30W)
lots of wire and jumper cables and some other bits and pieces (resistors)
- Soldering station
- Lab power supply
Step 6: Electronics - Circuit Design and Implementation
I designed the basic circuit in 123d (no PCB design, as I built it using perfboard)
Not all components are described exactly, it should just give me a rough idea, what pins are used and to check connections afterwards.
Basically the raspberry Pi is hooked up to a mcp3008 ADC via it's spi pins. Input 4 to 7 on the adc are pulled low with a 10k resistor, which is needed for the thermistors (and I used it for the photoresistor, too). Pins 0-3 are not pulled low, the first 2 of them are connected to the two accelerometers. All those components run on 3.3V so no level shifting is needed.
The accelerometers are only connected on one of the three axis (z-axis) as I only want to detect motion, not direction.
Pin 17 is connected to a push button for general interaction.
Pins 18, 22, 23, 27 (21 on model A raspberry pis) are connected to optocouplers to drive all the 12V stuff (those are probably not needed, but makes it easy to interface my mosfets which didn't switch on with 3.3V + I've decoupled the raspberry pi from the 12V line).
Pin 4 is connected to a transistor to switch the sound-hardware on and off (See the "Problems step" at the end of this instructable).
All the components are connected via pin headers and jumper cables.
The LEDs are driven with this LED driver (#4) but instead of a pwm the 12v line runs through the optocoupler and a resistor to the mosfet. The line is then switched on and off to provide the pwm. The led drivers are also glued to the heatsink of the leds and are not soldered to the perfboard.
To drive the fan I had to insert another MOSFET which is switched by the optocoupler (the optocoupler produced to much resistance, so that the fan would not start to turn, if connected directly).
I soldered everything on a perfboard which acts as a shield to the raspberry pi. All LED-drivers, fan, buttons, sound-switch and sensors are connected via pin-headers.
To keep the height low I soldered the pins on diagonally.
The 12V, 5V and gnd line are also connected to the board.
I soldered a micro-USB plug to power the raspberry Pi over the board.
Step 7: Circuit - Light and Sound and Sensors
I used three cree xp-e rgb LEDs glued to a heatsink. the driver circuit from the previous step is also glued on the heatsink.
unfortunately the heatsink gets quite hot in this configuration, so I will change to a bigger one later (see "software step" for temporary solution).
Each color has 3 connections: 12V, gnd and control. Those are connected to the shield from the previous step.
For sound output I've torn apart some old active pc speakers which run on 5V. I used the complete board and just switch it on off via pin 4 via a transistor. The board is connected via the 3.5mm jack to the raspberry (see the "Problems step" why I had to build in a possibility to switch it off).
I soldered jumper cables to all the sensors and the LEDs so that I could plug them onto the shield easily.
Step 8: Putting Everything Together
As you can see in the first images, I drilled a lot of small holes for the fan, 2 bigger ones for the ldr and the thermistor, as well as 2 smaller holes for the accelerometers and 1 bigger hole for the power supply line. I also drilled some holes on the side where the speaker is mounted to get better accoustics.
To hold the heat sink with the LEDs I cut 2 small strips of wood, which fit perfectly in the spacing of the heat sink.
The raspberry Pi is screwed to the bottom, the fan is screwed to the holes and the speaker is screwed to the side.
The shield is plugged onto the Pi and the sound-board is duct-taped on the opposite side of the speaker.
I used 3 push buttons in paralell which are positioned around the top of the bottom part of the enclosure. Therefore when you press on the top part of the enclosure the buttons get pressed.
When connecting the sensors and LEDs I taped the excessive wires to the side of the housing to keep everything somewhat tidy inside.
I put the motion sensors below the upper layer of the mattress, to have them as close to the body as possible without noticing them.
Step 9: Software
I used a "mean" steack (mongodb, express.js, angular js and node js) to implement everything in software.
You can find the current (really, really alpha) source code on github
There're several reasons why I tried this combination:
- I wanted to try it in a real projetc
- It's the same language in frontend/backend/db
On an embedded project like this we have the problem of shared resources (sound and light in our case). So only one process can access the resource at any given time, as we have multiple operation modes (light, mood light, alarm, audiobook mode), those services could block each other. So to keep everything simple I decided for a very easy strategy: when a process wants to access a resource, another possibly currently running process is stopped, so that the resource can be used again by the new process. In our case, this is possibly also one of the best solutions: none of the processes does really need a resource + the only time triggered process is the alarm: the alarm should always get the resource when it starts, also when something else is running. All other processes are user triggered (and we only have one user), so we probably want the process to claim the resource.
Interfacing the LEDs: pwm with Pi-blaster
Usually the raspberry Pi does only have 1 or 2 pwm ports. For this project however, I needed at least 4 of them so I used the pi-blaster project to drive multiple ports with pwm. I had the problem of flicker while dimming the LEDs, so I had to switch to an earlier version which does not have the problem. Furthermore I had to change the sources to use pcm-mode by default, otherwhise pi-blaster uses the sound module to produce pwm which results in really disgusting noise on the speakers. Furthermore I had to adjust the ports: Port 21 was renamed to 27 in the latest raspberry Pi version.
As explained in the intro I decided to log all the sensor values in mongodb to view them later on and analyse them. There's a great library for interfacing with the mcp3008 chip for node. The log entries can be queried with a REST api. On the frontend I used flot, a jquery library for plotting charts.
Logging the accelerometers was a bit more difficult, because I basically wanted to log "Is there motion" not "what is the direction of the motion". Therefore I continuously logged the absolute difference between 2 measurements and built a sliding average over 100 samples (1 sample every millisecond) leading to 10 measurements per second. When the average exceeds a certain threashold (empirically determined) an event is fired, so that the alarm-scheduler and other modules can take according actions. As the sample frequency for movement is pretty high, I only log values when they change a certain amount from the last saved value. otherwhise it would be too much I/O for the raspberry slowing everything down (plus it would take forever to display the data).
Alarms are also stored in mongodb and the node-cron library is used to start them. They can be edited via a REST api. On the front-end I used a gradient picker and a sound-picker to configure the sunrise-light and the mood sounds.
To have a preview of the currently selected color without too much delay, I added socket support to guarantee a fast communication when picking color values. when editing the light gradient, the selected color is always previewed on the weggup. The sound/light gradient can also be completely previewed and all sounds can be played seperately. The volume of every sound can be adjusted seperately, as well if it should be repeated or not.
The sound files are read from a certain directory on the raspberry Pi, which is also shared via samba.
To realise the sleep cycle functionality the alarm scheduler listens to the movement event from the logger and checks if the next light sleeping phase lies within a certain timeframe between wake up time and a defined time prior to this to reschedule the alarm. The main problem is to forecast the next light sleeping phase. At the moment I use a constant duration of 3 hours per sleep cycle. When I will have gathered more movement data I will adjust this accordingly or find another method of predicting the next light sleep phase (depending on the collected data).
To play sound mplayer processes are spawned in the background in slave mode, so that they can be easily controlled from node. I will possibly change to another player, as hardware requirements, and therefore delays are quite high with mplayer.
The single button interface
When pressing the top of the housing, the internal button gets pressed. This event causes the weggup to turn on bright light, acting as a lamp. When pressing the button, while anything is running, this process is stopped immediately. I.e. the button acts as a "shut off anything that is running" switch, and when nothing is running, it acts as a "lights on" switch.
All the modules can be started and stopped from a web interface. The configuration of all parameters can also be controlled there. I've implemented a simple common settings manager for all the modules, so I can add new ones easily (when i find some time, I will create custom settings pages for all the modules, which are more comfortable to use).
- Audiobook: the audiobook module reads one file after another from a certain directory. After 10 Minutes of reading it turns down the volume by 50%. When the listener moves in the bed and a motion event is fired, the volume turns up and continues another 10 minutes. When the listener has fallen asleep no motion event will be fired and the audiobook stops playing. The position of the last motion time is stored so that the playback begins at a point where the listener was certainly awake.
- moodlight: it changes its color every 10 +/- rand(5) seconds fading from color to color, The total brightness can be configured (the color vector is normalized to have approximately the same brightness all the time).
- light: turns on the light with a configurable color. This module is started when you press on top of the enclosure.
Step 10: Problems During Realisation
PWM and sound
As the raspberry Pi does not support pwm for that many channels, I had to use the pi-blaster library. However it uses the audio module of the Pi to produce it's pwm. Therefore pi-blaster must be launched with the --pwm switch, or the source has to be adjusted accordingly.
Sound in general
The raspberry Pi has veeeery bad sound quality when not using a very good power supply. Unfortunately my power supply was not that good. Therefore I had a constant noise in the background. Additionaly the wi-fi stick draws a lot of power so on each transmitted packet you could hear small beep. This was not very noticable when listening to audio, but when there was no audio running, it was really annoying and would definitely not aid you in falling asleep. I tried adding another capacitor on the power supply line to smooth out the signal, but the beeps from the wi-fi stick did not disappear. Therefore I added another transistor to switch the sound on and off completely. I had to adjust the software accordingly to switch on the soundboard before playing sound, and off when playing is finished.
This was the first time I worked with acceleration sensors. They are quite interesting: when you press your finger on them they can basically record your pulse, but when you put them on a (really) soft mattress you get barely any useful signals out of them, except when touching them directly. Plus they produce a lot of noise. Originally I planned to locate them at the upper corners of the mattress, but I had to move them directly under the sleeper (fortunately they are not really noticable). Furthermore detecting motion was harder than I thought: you must have a high sample frequency to not miss any spikes and you cannot simply take averages (which would help to clear the noise) because on every "up" movement there follows a "down" movement, which basically negate each other. So you have to track differences and add up their absolute values. In the afterthought that's absolutely clear, I just had not thought of that before;-)
1W high power LEDs produce a lot of heat. It was the first time I worked with those so I had no experience on how big the heatsink has to be. Unfortunately I chose one that is way too small (I'm already looking for a bigger one which still fits inside the housing). For the meantime I did some regulations in software: basically I added active cooling via a fan that switches on, when the temperature rises too high. Furthermore I reduce the brightness by 50% at a few degrees more. When it still gets too hot, I turn off the LEDs completely. As anther security mechanism, I turn off all LEDs when the application crasheos in the shell script that launches the application. Another problem is that the enclosure doesn't have any ventilation openings in the top, so heat is building up there quite rapidly. I Probably will make a small hole at the very top, I just have to find a way, to stop light from directly shining out of that hole.
Step 11: Conclusion and Further Ideas
This instructable showed you the process and development (and the problems;-)) of my way to a better sleeping experience. This instructable is no step by step guide showing you how to reconstruct the weggup, but it should give you the necessary ideas, concepts and experience about problems to be able to build your own and improve it furthermore.
As we have a box with a few sensors, sound and light there's a lot of additional functionality that can be built in.
Here are a few ideas of what I would like to implement at a later time:
- Moodsound: play moodsounds to fall asleep more easily (similar to the audiobook module)
- News reader: when the light is switched on in the morning, news are fetched from the web and read to you via text-to-speech
- Sleep feedback calendar: tell the weggup how your sleep experience was. This data can then be evaluated manually or automatically to find out the paramaters that give you a good sleep
- lucid dreaming aid: Most lucid dreaming devices start blinking in red a certain frequency at a certain point of sleep, while sending some sub-conscious sound waves. Thish should also be possible with this device.
Thanks for reading:-)