Sleep Tracker & Display

Introduction to Device

Issue I'm addressing

I've been tracking my sleep for the past three-ish years, since about when I first noticed a problem with my circadian rhythm. The original sleep-tracking documents I kept either by hand or in a PhotoShop file. At the beginning of this school year I updated the process to Excel, and that's where I've been logging it since. The device constructed is meant to assist me with entering all the data into a uniform format while also functioning as a stand-alone display or art-object.

Basic use

24 buttons on the front can be used to enter data. Each button corresponds to the LED above it, which can display a state of black, white, or "no data". A switch on the side toggles between a 'write mode' where data can be entered, and a 'lock mode' where data cannot be changed and accidentally overwritten. A dial on the side can be used to scroll through dates, or pressed to save entered data to a file on a SD card. On the top, the date and year corresponding to the data on the LEDs is shown. The button to the left of the date steps back one day, the button on the right steps forward one day.

Demos and Documentation

demoTrim.mp4

Changing dates and inputting data

Using the "+" and "-" buttons to step forwards or backwards by one day. 

Scrolling the encoder also steps on a one day interval, but can do it in quicker succession.

Dim lights meaning "no data" is true in Write and Lock modes.

I would not have to hit "overwrite" first if I was in Write mode enterring data to a day for the first time.

Switching from Write to Lock and back instead of stepping forward and back a few dates would also change the unsaved day to displaying grey.

scrollFast.mp4

Scrolling through all dates

All data alredy input and saved. 

Sped up 1000x, original takes about 6 min.

LagCompare.mp4

Lag comparison

Top video begins on a date that's line 105 of file.

Bottom video begins on a date that's line 749 of file. (770 total lines)

Turning encoder at the same speed and amount of rotation in both videos. 

Dates are found from a linear search, so you can see the search exiting quicker on earlier days. All "no data" days have to check all lines, so they have the most lag regardless of their date.

Technical Details

Process and problems solved

This project did happen on the time scale planned for class, and occurred in a few stages. The first stage ended when I had dragged the project into Fall Break, suffered difficulties from the lazer cutter, and was frustrated at the unweildy-ness of it all. The array on the front of the device initially used 24 push buttons- which all needed individual pins on the Arduino and then individual variables logging state changes in code. The final straw was when the buttons didn't line up nicely in assembling the box, and it was a good thing the project was dropped then.

I picked up the project again after finals. The most noticible differences in this attempt (besides a cleaner schedule and not starting from scratch) were that I'd gotten a bit more confident with writing code, and I replaced the buttons with capacitive touch sensors. Each touch sensor has 8 inputs, so I could replace the 24 buttons with 3 devices on the SDA/SCL line. This greatly reduced the ammount of wire-clutter and also meant inputs could be handles as 3 arrays rather than 24 individual variables. Also, being able to swipe your finger across a sensor rather than depressing a button feels more fluid and would be less tedious. There was some worrying and trouble shooting regarding how to extend wires from the capacitive touch sensors to their exterior "buttons" without electrical signals crossing, but this was solved by creating webbings with tape, hotglue, and the natural stiffness of the wires to hold them apart. Coaxial wires seemed to be not insulated enough, and were too thick to keep entirely from touching (or to reliably soulder properly).

Three capacitive touch sensors, RTC, and two 7-segment displays on the SDA/SCL line.

Testing sending a signal through wires to the touch sensors.

Current "buttons" in array are cap nuts with the bevel fit through acrylic face and signal wire screwed into back.

Previous push button array, which is fit slightly jagged. 

When I'd left off, all (or most) of the components had been wired enough to test if they'd work, but were not finished being implemented. Most of the code was for corresponding a button to turn on or off it's LED on the array. Pressing the encoder could write a line to a file on the SD card, but the RTC was not on so it was only tracking "days since 09/20/2020". Plus turning the rotary encoder too fast would cause it to skip (could be by 100+ days).

The encoder has been changed so now it adds +1 or -1 to a variable seprate from it's own reading of it's position to stop the jumping. Having the display day being the encoder's variable + sum from "+" and "-" buttons fixed the problem with being able to scroll under the min day. Figured having a 'min day' would keep someone from wasting time searching for data that wasn't there.

There were also some difficulties with how the LED strip library handled arrays (Pololu LED colors), but I think that was mostly solved on the first attempt. What happened this time was that the arrays for the touch-sensors and LEDs visually line up and face foreward, but in software are written backwards. This means that every time I save to file or display data from the file I first need to reverse the order of the array. I believe this was caused by accidentally installing something upsidedown.

I was having trouble deciding about if I could save a day as "no data", but decided that it'd be pointless to have "nothing in file for this date, no data" and "there is something in file, it says "no data"" be seperate things. If a LED is grey, it won't save. I went with having to manually save rather than auto-saving if a day changed because it felt un-obtrusive, and I wanted to prioritize clear indicators of what was and wasn't saved and what did and didn't have data. The first touch when entering data on a new day turns all the LEDs (except the one being touched) white because I'm awake the majority of the time, so doing it this way means fewer characters have to be manually changed. 

To find if a day exists, it searches the file linearly from top to bottom, checking the first 4 characters of each line (days since 09/20/2020). I went with this before I knew lag would be visible on a longer list, but also because I didn't know if days might be input out of order due to user error and overwriting. I probably could've made the file auto-write chronoligically, used a faster search algorithm, or searched based off the current day and looked for what's adjascant.

First itteration of device with front opened up, from around the time the project was due.

Close up on wiring of the first itteration. Was initially using an Arduino Mega because the Uno didn't have enough digital pins for the 24 button inputs. Soldered button version of the array in front right.

Interior of current itteration with front opened up. Touch sensors are on the red protoboards in the center, with wires leading to the backs of their external caps being spaced by pink tape. Arduino in the front right with signifigantly fewer wires.

Problems unsolved

The slide potentiometer, which was going to be used to scroll through dates even quicker than the rotary encoder, does not work. It takes ~6 min to scroll all the way through with the rotary encoder. The reading I get back from it is pretty much unusable (decreases gradually then sharply dips down and back up ~90% of the way across, and is jagged). Also, the box is not fully glued together because I noticed sometimes even slightly jostling it would cause it to short, and I wanted time to solve that. This issue is caused by magic but probably fixed by hotglue. The side not pictured in documentation- the one for power in and SD card access- is open and missing a part I didn't have time to lazer cut. With the file, I got lazy and "overwrite" means "overwrite", not "delete"- it just replaces the selected line with "x"'s. Kind of wanted to stain the box dark brown just for looks.

Code

I ended up being happy with how it turned out the second time, and felt like I had actually improved because I was managing to do the entire project in like 100 fewer lines that I had needed for about the half of it I had when I'd left off. Here's a diagram of what the code does, and a copy paste of it.

Input and Returned Data

Sleep charts

I've been using the same format for visualization since I started tracking my sleep, and these charts are where I pulled data from to input into the device. The grids I use in them feel intuitive and legible to me, so they became the basis for how I designed my device- the row of 24 LEDs who's state is either 'black' or 'white'In these charts a row is 24 squares across, 1 square equals 1 hour, 1 row equals a full day. The leftmost column represents the hour of Midnight-1AM, the rightmost represents 11PM-Midnight. A black square is an hour I was asleep for, a white square (or any color other than black) is an hour I was awake for. I publish all the charts here in Google Drive. (I feel like I could've had an aside here about keeping this data public, and how that stands regarding intimacy online and of discussing illness, and with sleep as a generally private moment- but if so I'd circle back to it later.)

The first few charts are filled in PhotoShop

Charts (sometimes only hours and dates) filled in notebook

Current Excel chart, including collumns to calculate averages

Reading the file

The device saves data onto the SD card in a .txt file following this format: 

0001 09/21/2020 wwwwwwwwwwwwwwwwwwwbbbbb

0002 09/22/2020 bbbbwwwwbbbbbbbbbbbbbbbb

0003 09/23/2020 bwwwwwwwbbbwwwwwbbbbbbbb

0004 09/24/2020 wwwwwwwwwwwbbbbbbbwwwwww

0005 09/25/2020 wwwwwbbbwwbbwwbbbbwwwwww

0006 09/26/2020 wwwwwwwwbbbbbbbbbbwwwwww

0007 09/27/2020 wwwwwwwwwwwwbbbbbbbwwwww

Each line reads as: Days since Sept 20, 2020, date, and 24 characters to represent a row in the sleep chart ('b' = black, asleep. 'w' = white, awake). Each value is seperated by a space or a new line. Sept 20, 2020 is the first date ever logged, and at the time of writing, I have data on 748 out of 1196 days since then (63%). It's the plan to continue logging sleep, although it may end up converted to another method in the future. 

Here's the first plotting I came up with of the cleaned data. 

I think the sleep data is an intresting way to visualize a life.


( Skip straight to page 4 if you just want to look at the charts )