How to get up in the morning: the forceful approach

Topics: Projects | September 15, 2009 @ 5:00 PM

I have phenomenal amounts of trouble getting up in the morning.  I’ve tried all sorts of things: alarm across the room, multiple alarms strategically placed to guide me to the bathroom for a shower, spacing alarms apart temporally, using my cell phone so that I think someone is calling, and a couple of others that aren’t coming to mind right this moment.  No matter what, I always turn the alarm(s) off and go back to sleep.  There was one time when I actually got up and got ready – showered, brushed, shaved, and even ate breakfast (which I almost never do) – but I had a few minutes before I had to leave, and in that time I fell asleep.  I’ve missed countless classes because of this problem.

Why do I have so much trouble?  Hard to say.  Growing up, my parents always managed me and woke me up – I could always turn my alarm off because I knew my parents would wake me up.  And when they did, I would go back to sleep until I heard them coming again, at which point I at least sat up so that I wouldn’t get yelled at.  I never really learned to control myself in the morning, and as little self-discipline I have when conscious, when sleeping or sleepy it all goes out the window and I’m basically some sort of animal that single-mindedly pursues sleep (if only I pursued sex like that…).

That’s half of the set-up.  The other half is that in January (2009), I was starting the last semester of my computer engineering degree, and I needed a design project.  What better problem to solve than waking up in the morning?  We can worry about “helping people” later, after we, you know, wake up in the morning.

No, this isn’t just for sleep zombies (a.k.a. lazy asses) like me

In all seriousness, this isn’t a problem just for the undisciplined.  People with AD/HD can often have trouble getting up in the morning, and some people just naturally sleep for longer than they can afford.  It’s been shown that some people genetically need less sleep, and I think it’s safe to assume that some people on the other end of the spectrum genetically need more sleep (don’t question my science!).

Previous approaches to this problem are woefully insufficient.  They all rely on the assumption that forcing the user to get out of bed (for whatever reason, e.g. to find the alarm (that moves around) or hunt down a stop mechanism) is enough to wake the user up.  If that were the case, simply putting a very loud alarm in the bathroom would be sufficient.  Look at this video:

The point at the end when he puts the thing back on the table right next to his bed is where I would just fall back into bed.  A similar argument applies for this one:

Even if you have to get out of bed to get the thing, you still have to put it back.  I need a solid chunk of time to wake up (anywhere from 10 to 30 minutes), something interesting to grab my attention (porn?), or a shower.  Failing any of those, I just need something that will keep me from getting back into bed.

The engineer’s solution

As I mentioned above, I needed an embedded design project for CMPE 490, the design project course that all computer engineers must take.  My partner and I were banging out ideas when it occurred to me that my sleep issue would be a potential problem to solve.  If the problem is that I always get back into bed, why not devise a solution that not only gets me out of bed, but also keeps me out?  The obvious solution is to get a wife, but that’s out-of-budget, and wouldn’t solve my search for a project.  So it occurred to me that if I could use weight sensors to detect whether or not I was in bed, it would be possible to have an alarm that came on during a period of time if I was detected as being in bed.  Of course, to meet the requirements we would need to use the address and data lines, so hooking the alarm clock up to the Internet for control via Google Calendar seemed like a good idea as well.  Thus was TICK-TOCK, the Tenacious Internet-Capable Klock that is Tremendously Obstinate and Cannot be Killed, born (backronyms, anyone?).

I won’t talk too much about what our project specifically encompassed – it had an LCD screen, which I didn’t do in my own design, for example.  You can see the code and various design documents at its Google Code page.  More interesting is the general idea (plus, by describing it publicly, I’m preventing the idea from being patented – open source FTW).  Essentially, this is an Internet-controlled weight-sensitive alarm clock, and it’s really barebones: it doesn’t even display the time.

There are some assumptions fundamental to my design:

  1. There is a fundamental psychological difference for the user between being awake and being sleepy.  If the user decides that he doesn’t care about whatever he has in the morning and wants to skip it, and he does so while fully awake (e.g. the previous day), that’s a deeper issue that isn’t going to be helped just by making sure he gets out of bed.
  2. The user won’t sleep on the couch, or will have another weight-sensor alarm clock for the couch as well.
  3. The user won’t sleep on the floor.
  4. The user won’t muffle the alarm clock (e.g. wrap it in sheets or towels and put it in a closet far far away).  To counter this, the noise could also be very loud.
  5. The user won’t destroy the alarm clock.  Part of the way to help this is to make the alarm clock expensive – a $5 alarm clock may be expendable, but not a $100 or $200 one.

Granted these assumptions, my solution to the problem is as follows:

  1. Check the user’s Google Calendar to see if there is an alarm event at the current time, and if so, “arm” the alarm.  Alarm events are specified in periods of time, so that e.g. from 7AM to 9AM the alarm is armed.  This example is what I use for 9AM classes.
  2. Detect whether or not the user is in bed using weight sensors.
  3. If the alarm is armed, make some sort of loud annoying noise if the user is detected to be in bed.  Do the same if the user has removed the weight sensors from the bed in an attempt to fool the alarm clock.
  4. Make sure the user can’t turn the alarm off by any means except destruction of the device or getting out of bed.  This means a sturdy unopenable case, as well as battery switchover so that, if removed from wall power, the alarm can keep going on battery.

And that, I believe, is what I need to wake up in the morning.

Technical details

Of course, that’s just a brief non-technical description that gets the general idea across.  The actual implementation details become more technical, but should still be readable.  Note that I don’t have any schematics available; this is just because they’re all done by hand and I’m too lazy to computerify them.  I also don’t have any source code available because this is a very basic prototype and therefore the code is pretty nasty (and also has my username and password stored in the code in cleartext).  But the next sections should get the idea across, and if anyone asks to see some more details I’m not opposed to that (obviously, being a huge open-source fan).

The base system & networking

For our CMPE 490 project, we used the AT91M5880A microcontroller, which features an ARM7TDMI microprocessor and built-in ADCs.  We used the evaluation board, the AT91EB55, which cannot run Linux, and since it was provided as part of the course we couldn’t mess with the board itself to try and make it run Linux.

For my own prototype, I was able to get a free TS-7260,  so I used that.  This SBC runs Linux out-of-the-box.  Why do I keep wanting to run Linux?  Other than the obvious reason (it’s awesome), the big thing is that it provides a full networking stack.  Who the hell wants to write their own?  On top of that, I’d need an NTP implementation as well to keep track of time (since we can’t trust the user to set it).  For the CMPE 490 project, we hacked together some stuff that sent out TCP and UDP packets of the correct format (for both NTP and HTTP for interfacing with Google), and that on its own was a pain in the ass.  Imagine how much more work it would be to write a full stack!

Anyway, this SBC has two onboard ADCs (I needed four, but I’ll come back to that later), a serial port, an Ethernet port, a couple of USB ports (unfortunately, couldn’t get WiFi working, so I ended up having to use a 50-foot CAT5 cable, and I had to snake it through a wall too), and some other stuff that I don’t need.  It doesn’t have a sound driver, though, and takes 4.5-20VDC for power.  It doesn’t have an RTC, so like I mentioned above I keep an NTP daemon running (there’s an RTC available as an expansion, but it’s not really necessary since NTP works just fine).

Weight sensors

Originally, we had used FlexiForce sensors to handle the weight sensing.  These things are piezoresistive, so they have an electrical resistance that changes (decreases) with increasing force (if you look at their data sheet, conductance increases roughly linearly with increasing force).  These sensors are expensive, however, and after a lot of searching I was able to find a place (in Canada, too!) that sold some force-sensing resistors (FSRs).  These work pretty much the same way, but I’m pretty sure they’re not piezoresistive.  It doesn’t matter, as I don’t need anything particularly precise.

To measure these with ADCs, which need voltage, the “proper” way is to use op-amps.  I’m too lazy for that, however, and I just hooked the FSRs up as resistors in a voltage divider circuit, where the FSRs are hooked up to the supply voltage.  Since their resistance is huge under no load, the output of the circuit is very close to 0V under no load, and increases from there.  I did some experimenting to find a good value for the pull-down resistors (300 ohms, I believe).

As I mentioned above, the TS-7260 only has two available ADCs, but I use four weight sensors (four corners of the bed).  To get around this, I hooked up two FSRs in parallel and used that in a voltage divider circuit.  Some experimenting showed that this worked quite well.  Once hooked up to the ADCs, I simply read the direct values (i.e. I don’t bother converting to voltage) from the two ADCs and add them together.  I did some testing with the combined value to see what ranges would constitute no load, bed, and bed + me.  I made no considerations for more than one person (how can you tell I live a very lonely life?).

Noise

Originally, I used a 555 timer IC to create a tone that I sent to a speaker.  However, this was too soft, so I looked at getting an amplifier IC.  Turns out the IC I chose has an example circuit to generate a 1kHz tone (see the data sheet), so I didn’t even need the 555 in the end.  I used some slightly different capacitor values, so the tone I get isn’t exactly 1kHz, but it’s loud and annoying, and that’s what counts.  My tuner tells me it’s an E minus about 35-40 cents, and some quick tests tell me it’s around E5, so the tone that it’s generating is roughly 645Hz.

To turn the noise on, I hooked up a DIO line (set as output) of the SBC to a switch IC; the DIO controls whether or not the amp IC gets power.  This didn’t work well at first, since the output line couldn’t really hold that well and power ended up going through to the IC anyway.  In hindsight, I should have used an SPDT switch, but since I already had everything set up and didn’t want to hunt for and buy another IC, I tried using a pull-down resistor on the switch’s input line, which worked perfectly.  Basically, if the output line is floating or even low, the resistor provides a strong path to the circuit’s ground, so the switch sees ground and doesn’t provide power to the amp IC.  I chose the smallest value for the resistor that I could that didn’t force the output line to provide too much current when high (according to its spec).

Power

I was originally going to use a power management IC, but after not really understanding how to use it, I took a friend’s expert advice and just hooked up the DC output of a 6V transformer to 4 Energizer 2450 mAh AA NiMH batteries hooked up in series.  I did have to drop the 6V though, so for that I used a diode, which also prevents any current from going back into the transformer if it gets disconnected from the wall.  The resulting voltage powers everything, and I don’t expect current consumption to be more than a couple hundred mA (tops!) so those batteries ought to last a long time before dying.

There is a problem, however, that I didn’t realize until after I had soldered everything together and put it in a case (built by a mechanical engineer friend of mine).  The batteries have an initial drop at the very beginning (after being charged) where they drop to their nominal voltage.  For some reason, after a few minutes (maybe 20 or so), the SBC starts resetting, which causes the alarm to go on for reasons beyond my understanding, but I’m pretty sure it’s related to the drop in battery voltage.  However, 20 minutes is enough of a deterrent that I won’t even try to unplug it from the wall, so it’s something that works as-is for now but would have to be fixed in any revisions.

The case

The case is tremendously important, as for a while I had a fully-working system that I could just turn off by unplugging from the wall and removing a battery.  A mechanical engineer friend of mine took an afternoon to help build me a case (thanks, Jordan!).  The idea is that this case cannot be opened by any regular means, so that I can’t access the innards.  We basically built an aluminum case that is riveted shut.  We used bubble wrap to pad the insides and keep various circuit parts from touching each other or the case.

Access

To access the SBC, I have physical access to the ports it provides.  While the weight sensors are under my bed, the device has to be pretty close to the bed (i.e. in my bedroom), and I don’t have anything with a serial port that I could use to interface with it.  So I need to use SSH to access it; the only problem with this is that I could then SSH in to disable it when it goes off!

The solution is to just kill SSH once I know it works as it should.  However, I’d like to avoid doing that if possible, and just that fact is enough of a deterrent for me to SSH in to kill it.  This is because if I do kill SSH, to fix anything (software that is, the hardware is inaccessible), I’d have to use a serial connection, which means removing the device from my room and bringing it to my desktop machine, which is a pain in the ass (e.g. to take the weight sensors out from under the bed and put them back).  So until I actually find myself using SSH to disable it, I’ll leave it running.

Bringing it all together

I think I’ve covered everything except for the software itself.  I was able to use sample code to work the ADCs and DIO line, so that was easy.  But there is still the matter of the overall controlling software.

This was probably the most pain-in-the-ass part of the project.  I didn’t want to do the software in C/C++, because there is no C or C++ GData API.  I like Python, and the USB flash drive that came with the SBC ran Debian which had a working Python 2.3 (I needed/wanted 2.5), so that floated some hope.  After trying to cross-compile Python 2.5 and being unable to get that working, I tried to get JamVM working so that I could use Java.  This is, of course, no simple task, as I’d also need to get GNU Classpath working.  After exploring that for a few hours, I gave up and came back to Python, and tried compiling Python 2.5 straight on the SBC while in Debian.  This worked!  Except some pain-in-the-ass MD5 stuff that took me hours upon hours to figure out, and unfortunately I can’t even remember now how I fixed it (it may have had something to do with making sure a certain library was available when not running in Debian, but I think it was actually simpler than that – I think I just removed the library so that when I compiled Python it didn’t see it there and accounted for that).

Once I had Python working, I wrote a script that logs into Google, checks my Alarm calendar, and if there is currently an alarm event, it checks the weight sensors.  If the weight sensors are outside of a certain range, the alarm is sounded.  To prevent myself from being able to just delete the event from my calendar when the alarm goes off, I implemented an eight-hour buffer so that any changes between the current time and eight hours from the current time are ignored.

Mass production?

The version I have and am using for myself is strictly a prototype.  I’d definitely do some things differently if I were to mass produce this thing, or even make for a few other people.  For one, I’d do proper power management, for both safety and to ensure that it works correctly.  Another thing I’d do is build a proper interface so that SSH could be disabled but changes still made (e.g. username/password, etc.).  Most people would need a GUI anyway to work something like this.

I would also make my own SBC using a different MCU, perhaps something like the Atmel SAM9G20.  All circuitry could go on one PCB, which would be convenient.  I did some rough math, and parts alone would cost about $100-$150 using unit part costs – this doesn’t include a case or the PCB itself.  So to bring costs down, it would be worth considering ignoring my Linux fixation and writing a proper embedded system in C (including networking, NTP, and TLS stacks) to handle this task.  I could then use cheaper parts, since going for Linux does impose some requirements on what your parts need to be able to do.

The result

So now that I have a fully-working system, how well does it work in practice?  Well, I’ve only used it for a few days, but so far I usually just go and sleep on the couch when the alarm goes off.  However, I’m not as comfortable, so I end up waking up here and there, and while I may run late I do eventually get up as I realize I have somewhere I need to be.  Previously, I just turned my alarm off and went back to sleep.  So it’s definitely an improvement, and seeing as one of the assumptions I made is that the user won’t sleep on the couch, the design works as expected.

I don’t really have a solution for the couch thing other than adding another alarm for the couch.  That seems a bit ridiculous.  Next project: tracking myself around the apartment so that I can be forced to get up and take a shower, rather than get up and sleep on the couch.

…or, just get a wife.

4,721 views | Trackback

13 Responses to “How to get up in the morning: the forceful approach”

  1. James Bell Says:
    September 16th, 2009 @ 8:27 AM

    Hey Adit,
    That sounds really cool. It’s also really similar to my job – my company does projects exactly like you did for our clients (pcccinc.com). Though I write everything in C.
    I’m pretty sure that you can find C code for ARM7 stacks somewhere. (I mean free code; I know for sure you can buy it.)
    Oh, and the wife solution works pretty well… except that mine now gets up later than me, so I have to wake her up.

  2. Peter Says:
    September 16th, 2009 @ 10:28 AM

    I’ve got a better solution for you. I mean, the alarm thing is an interesting, but far too timid.

    What you need is a shock collar/bracelet. Basically, when you go to bed, you put this thing on and it locks. The lock would be time sensitive so that you couldn’t unlock for a certain period after it is engaged. So, in the morning, your google alarm goes off and the shock collar activates. It first gives you a prolonged (10 second) shock, to get you out of bed. Then it keeps giving you occasional shocks until you’re outside of say, your wireless network’s range. At that point, it disables the alarm, but not the collar (so you can’t just leave your apartment and come back). Once you’ve been outside of range for say 15 min, then it will disable the lock and let you take it off.

    Maybe, eventually, the pain will train you to get up properly and you won’t need it at all! :P

  3. Aditya Says:
    September 16th, 2009 @ 10:36 AM

    Interestingly, the same friend that helped build the case also suggested shocking myself, perhaps just charging up a capacitor or something.

    The problem with a collar is that it’s difficult. All of the circuitry has to be small and shaped into a toroid. And then there’s the issue of storing enough power to shock me several times.

  4. AdamN Says:
    September 17th, 2009 @ 11:03 AM

    If you plug the toroidal collar into an external power supply, the circuitry wouldn’t need to be so small.

    Precede the shocking by a distinct bell and after a few shocks over a few mornings, you will no longer need the shock – just the fear of the shock will be enough to get you to wake up (thank Pavlov for that insight).

  5. Ariel Says:
    September 17th, 2009 @ 1:16 PM

    Being that tried in the morning means you probably have sleep apnea.

    Do you wake up with a headache? If you take a nap are you more tired after then before? Depression?

    All of those are signs of sleep apnea.

    Are you over weight? Because that can cause sleep apnea (but it can happen without it too).

    If you can afford it, go to a sleep lab. Hmm, your domain is .ca – I wonder if canada pays for sleep labs.

    Try recording yourself sleeping (with audio). See if you stop breathing for 30 seconds or so while sleeping.

    Or just get a CPAP (APAP) machine, with automatic pressure setting, and see if it makes any difference.

  6. Dan Says:
    September 17th, 2009 @ 1:26 PM

    For me, I found that the real trick to getting up when my alarm goes off was just learning to not argue with the alarm clock. When the alarm clock goes off, it’s time to get up. Immediately. No discussion allowed. No thinking “I can sleep 5 more minutes and then just shower faster”, etc. Alarm goes off, get up. End of story. (The Snooze button, of course, is Right Out.)

    If you’ve spent decades building up a “go back to sleep immediately when the alarm goes off” reflex, it might help to retrain yourself with the new reflex under easier circumstances, like in the middle of the afternoon. Just set your alarm to go off in 1 minute, then lie in bed until it does, then get up. Repeat until reprogrammed. (Switching to a new alarm clock might help too, since the new alarm noise and new off button location may help to remind you of your new rules.)

  7. Richard Says:
    September 17th, 2009 @ 1:27 PM

    Aim a spotlight at your head and get it to turn on at the appropriate time.

  8. DigitalBliss Says:
    September 17th, 2009 @ 1:36 PM

    Go into the Army.

    5 bucks say Basic Training will create the habit in you.
    =)

    Cool project!

  9. Chris Says:
    September 17th, 2009 @ 2:23 PM

    Have you tried light as an alarm? Mimicking sunrise.
    Makes a huge difference, especially in winter.
    My current one (
    http://www.lumie.com/shop/products/bodyclock-sunray-100), ten + years old, is on the blink so have been looking at putting together a replacement clock project, perhaps adding gradually rising audio.

  10. Danno Says:
    September 17th, 2009 @ 3:05 PM

    Perhaps a robot that beat you up until you managed to beat it up enough.

  11. Aaron Says:
    September 17th, 2009 @ 5:33 PM

    Sell your couch. ;)

  12. Aditya Says:
    September 17th, 2009 @ 6:36 PM

    Ariel: I’ve considered sleep apnea, but been too lazy/busy to bother looking into it further. I don’t ever wake up gasping for breath or anything like that though (that I can remember…). I also read about this sleep monitoring device that costs a few hundred dollars and checks – the person reporting on it found out that he/she actually was awake for a few hours when he/she slept, but didn’t remember it.

    Dan: That’s one of the things I tried. Didn’t work.

    DigitalBliss: Yeah, but once I’m out I’ll guarantee that I’ll lose the habit.

    Chris: I can’t shut the blinds on my window, because my air conditioner is in the way. So as soon as it becomes light outside, I get it inside as well.

  13. Phil H Says:
    September 24th, 2009 @ 2:35 AM

    White noise may be your answer here. White noise will prevent you sleeping (I don’t know why) but is not particularly annoying when you are awake. This way you just switch the white noise on for the full ‘armed’ duration, 7-9, and going back to bed will achieve nothing. Usefully this works without sensors, so it’s more robust.

    When I was having trouble waking up I set a detuned radio to feed a mains-powered speaker, and a timer plug. Worked well, but now I have the wife solution.

    So use the same setup but have it power a speaker emitting white noise (might be able to generate that with your SBC), and cut a grille in the case.

Comments