Night Clock - blinkt vs unicorn pHat

I am incredibly shortsighted (-10.75/10.25) and so can’t get clear focus on anything further than about two inches from my eyes without corrective lenses. This makes checking the time at night a bit fraught - wall clocks are hopeless and most digital displays need me to heave myself over to my bedside table to make sense of them. I could put my glasses on but that’s a signal to my body to get up and so it isn’t very helpful at getting back to sleep. One consequence of my perpetually-unfocussed vision of that lights tend to turn themselves into hazy circles when I look at them. This gave me an idea for a clock I can use at night.

Basically the idea is that I use a specific number of lights to represent the time. Now, I very rarely wake up before 1am so i decided I could use five LEDs to give me the hour times - if one LED is on it’s 1am, two LEDs is 2am, etc. The kids have me up between 5am and 6am so I only need them to go up to five. I’d also like to have three LEDs to show me the quarter-hours - one for quarter past, two for half past, three for quarter to the next hour. Five LEDs for the hour and three for the quarters are also both numbers the brain can process without having to do counting.

This means that I need eight LEDs in a row to give me an approximate time that I can glance at without waking myself up too much. I originally thought that just a Blinkt plus Pi Zero would be an appropriate display but it occurred to me that a Unicorn pHat has four rows of eight LEDs and so might allow me to use the extra LEDs for some other function in future.

Could anyone give me some guidance regarding using the Blinkt or the Unicorn pHat for this particular project? What might be the downsides of each one?

Thanks in advance,
oatmaster

I’d be thinking about the spacing between the individual LEDs — would adjacent LEDs blur into one glowing blob?

I think you’d be best using the Unicorn pHAT, and I have a suggestion for you!

This is my first post on the forum, and I currently speak French / German / Italian better than Python. I’m going to see if I can draw my idea and post it!!

Craig.

So, my suggestion is using the Unicorn pHAT, have a vertical bar (1 x 4) to represent the first four hours with a space in between each bar for clarity.

Quarter hours are represented by a horizontal line: row 2 for quarter-past, row 3 for half-past, and row 4 for quarter-to.

The fifth hour is represented by a ‘full house’ of LEDs, with blank lines representing the quarter hours, following the above pattern.

Hope this helps!

Craig.

p.s. examples drawn:

01:00 - 01:14, 01:15 - 01:29

02:30 - 02:44, 02:45 - 02:59

03:00 - 03:14, 03:15 - 03:29

05:00 - 05:14, 05:15, 05:29

1 Like

Regarding the spacing of the LEDs, they are a little bit more separated on the Blinkt compared to the Unicorn pHAT so they may not blur together. I did also think I could vary the colours to make them more distinct - I suspect this would need real-world testing to decide.

I like the idea of the pattern, it’s certainly something to try. I wonder a little about whether my brain would be able to process the patterns without having to work too hard but I think it’d probably be ok.

Just occurred to me that I could possibly vary the colours based on the number of minutes to give a more graded time but that might be a bit too imprecise.

I guess the main thing would be to make it clear that “it’s too early, go back to sleep!!”

I’m hoping to build a ‘sunrise’ clock (around £100 to buy!) using Unicorn Rainbow Technology, which is how I discovered your post.
I’ll probably build a second one for my son, but with added ship’s foghorn…

Sunrise clock is a good idea - I get a bit of SAD myself and this could be helpful for me too. My Night Clock could feasibly switch to sunrise mode at a certain time…

I’ve got a working version of the Night Clock to test tonight, I’ll have to solve the problem of keeping time on an offline Pi Zero but that’s for another day. Also; my code is pretty clunky but seems to work.

Have you thought about a RTC module (Re.al Time Clock)if you don’t want it online

I think that might be what I’ll need to do. For now my plan is to connect it to my local network, set the time and then unplug it and put it at my bedside really quick so it doesn’t lose too much time. My otherwise next step might be to come up with a method to set the current time via buttons but that is a little beyond me for now.

You can get teeny RTCs that pop right on the Pi, careful you don’t get a supercap tho’

Any idea how well they’d work with a HAT already attached (on Top)? I think I know what a supercap is but I don’t know the implications of them.

Oh and the first overnight test worked quite well. I connected it to the network to get the time then unplugged and moved it to bedside - it only lost a minute or so doing that. There’s a couple of small changes I need to make to my patterns for legibility and the default brightness of 50% is way too high.

Supercaps may be fine if your Pi is only disconnected from power for short periods of time. The capacitor will eventually discharge and stop keeping time. You can get RTCs with proper batteries which will keep time for ~2 years without being attached to another power source.

My clunky first attempt at a sunrise clock, basically brute-forcing the transitions rather than doing anything clever. It cycles through the visible spectrum from red to blue then to white, probably should be a different pattern. Maybe red, orange, yellow, white.

[code]#!/usr/bin/env python

import time

import unicornhat as unicorn
#period in seconds between steps - multiply by 81 to get total duration
interval = 18
unicorn.set_layout(unicorn.AUTO)
unicorn.rotation(0)

unicorn.clear()
#step1
unicorn.brightness(0.2)
unicorn.set_all(255, 0, 0)
unicorn.show()
time.sleep(interval)
#step2
unicorn.brightness(0.21)
unicorn.set_all(255, 0, 0)
unicorn.show()
time.sleep(interval)
#step3
unicorn.brightness(0.22)
unicorn.set_all(255, 0, 0)
unicorn.show()
time.sleep(interval)
#step4
unicorn.brightness(0.23)
unicorn.set_all(255, 0, 0)
unicorn.show()
time.sleep(interval)
#step5
unicorn.brightness(0.24)
unicorn.set_all(255, 0, 0)
unicorn.show()
time.sleep(interval)
#step6
unicorn.brightness(0.25)
unicorn.set_all(255, 0, 0)
unicorn.show()
time.sleep(interval)
#step7
unicorn.brightness(0.26)
unicorn.set_all(255, 0, 0)
unicorn.show()
time.sleep(interval)
#step8
unicorn.brightness(0.27)
unicorn.set_all(255, 0, 0)
unicorn.show()
time.sleep(interval)
#step9
unicorn.brightness(0.28)
unicorn.set_all(255, 0, 0)
unicorn.show()
time.sleep(interval)
#step10 - start fade to orange
unicorn.brightness(0.29)
unicorn.set_all(255, 0, 0)
unicorn.show()
time.sleep(interval)
#step11
unicorn.brightness(0.3)
unicorn.set_all(255, 15, 0)
unicorn.show()
time.sleep(interval)
#step12
unicorn.brightness(0.31)
unicorn.set_all(255, 30, 0)
unicorn.show()
time.sleep(interval)
#step13
unicorn.brightness(0.32)
unicorn.set_all(255, 45, 0)
unicorn.show()
time.sleep(interval)
#step14
unicorn.brightness(0.33)
unicorn.set_all(255, 60, 0)
unicorn.show()
time.sleep(interval)
#step15
unicorn.brightness(0.34)
unicorn.set_all(255, 75, 0)
unicorn.show()
time.sleep(interval)
#step16
unicorn.brightness(0.35)
unicorn.set_all(255, 90, 0)
unicorn.show()
time.sleep(interval)
#step17 - orange
unicorn.brightness(0.36)
unicorn.set_all(255, 100, 0)
unicorn.show()
time.sleep(interval)
#step18
unicorn.brightness(0.37)
unicorn.set_all(255, 115, 0)
unicorn.show()
time.sleep(interval)
#step19
unicorn.brightness(0.38)
unicorn.set_all(255, 130, 0)
unicorn.show()
time.sleep(interval)
#step20
unicorn.brightness(0.39)
unicorn.set_all(255, 145, 0)
unicorn.show()
time.sleep(interval)
#step21
unicorn.brightness(0.4)
unicorn.set_all(255, 160, 0)
unicorn.show()
time.sleep(interval)
#step22
unicorn.brightness(0.41)
unicorn.set_all(255, 175, 0)
unicorn.show()
time.sleep(interval)
#step23
unicorn.brightness(0.42)
unicorn.set_all(255, 190, 0)
unicorn.show()
time.sleep(interval)
#step24
unicorn.brightness(0.43)
unicorn.set_all(255, 205, 0)
unicorn.show()
time.sleep(interval)
#step25
unicorn.brightness(0.44)
unicorn.set_all(255, 220, 0)
unicorn.show()
time.sleep(interval)
#step26
unicorn.brightness(0.45)
unicorn.set_all(255, 235, 0)
unicorn.show()
time.sleep(interval)
#step27 - yellow
unicorn.brightness(0.46)
unicorn.set_all(255, 255, 0)
unicorn.show()
time.sleep(interval)
#step28
unicorn.brightness(0.47)
unicorn.set_all(205, 255, 0)
unicorn.show()
time.sleep(interval)
#step29
unicorn.brightness(0.48)
unicorn.set_all(155, 255, 0)
unicorn.show()
time.sleep(interval)
#step30
unicorn.brightness(0.49)
unicorn.set_all(105, 255, 0)
unicorn.show()
time.sleep(interval)
#step31
unicorn.brightness(0.5)
unicorn.set_all(55, 255, 0)
unicorn.show()
time.sleep(interval)
#step32 - green
unicorn.brightness(0.51)
unicorn.set_all(0, 255, 0)
unicorn.show()
time.sleep(interval)
#step33
unicorn.brightness(0.52)
unicorn.set_all(0, 255, 18)
unicorn.show()
time.sleep(interval)
#step34
unicorn.brightness(0.53)
unicorn.set_all(0, 255, 36)
unicorn.show()
time.sleep(interval)
#step35
unicorn.brightness(0.54)
unicorn.set_all(0, 255, 54)
unicorn.show()
time.sleep(interval)
#step36
unicorn.brightness(0.55)
unicorn.set_all(0, 255, 72)
unicorn.show()
time.sleep(interval)
#step37
unicorn.brightness(0.56)
unicorn.set_all(0, 255, 90)
unicorn.show()
time.sleep(interval)
#step38
unicorn.brightness(0.57)
unicorn.set_all(0, 255, 108)
unicorn.show()
time.sleep(interval)
#step39
unicorn.brightness(0.58)
unicorn.set_all(0, 255, 126)
unicorn.show()
time.sleep(interval)
#step40
unicorn.brightness(0.59)
unicorn.set_all(0, 255, 144)
unicorn.show()
time.sleep(interval)
#step41
unicorn.brightness(0.6)
unicorn.set_all(0, 255, 162)
unicorn.show()
time.sleep(interval)
#step42
unicorn.brightness(0.61)
unicorn.set_all(0, 255, 180)
unicorn.show()
time.sleep(interval)
#step43
unicorn.brightness(0.62)
unicorn.set_all(0, 255, 198)
unicorn.show()
time.sleep(interval)
#step44
unicorn.brightness(0.63)
unicorn.set_all(0, 255, 216)
unicorn.show()
time.sleep(interval)
#step45
unicorn.brightness(0.64)
unicorn.set_all(0, 255, 234)
unicorn.show()
time.sleep(interval)
#step46
unicorn.brightness(0.65)
unicorn.set_all(0, 255, 252)
unicorn.show()
time.sleep(interval)
#step47 - cyan
unicorn.brightness(0.66)
unicorn.set_all(0, 255, 255)
unicorn.show()
time.sleep(interval)
#step48
unicorn.brightness(0.67)
unicorn.set_all(0, 219, 255)
unicorn.show()
time.sleep(interval)
#step49
unicorn.brightness(0.68)
unicorn.set_all(0, 183, 255)
unicorn.show()
time.sleep(interval)
#step50
unicorn.brightness(0.69)
unicorn.set_all(0, 147, 255)
unicorn.show()
time.sleep(interval)
#step51
unicorn.brightness(0.7)
unicorn.set_all(0, 111, 255)
unicorn.show()
time.sleep(interval)
#step52
unicorn.brightness(0.71)
unicorn.set_all(0, 75, 255)
unicorn.show()
time.sleep(interval)
#step53
unicorn.brightness(0.72)
unicorn.set_all(0, 39, 255)
unicorn.show()
time.sleep(interval)
#step54
unicorn.brightness(0.73)
unicorn.set_all(0, 3, 255)
unicorn.show()
time.sleep(interval)
#step55 - blue
unicorn.brightness(0.74)
unicorn.set_all(0, 0, 255)
unicorn.show()
time.sleep(interval)
#step56
unicorn.brightness(0.75)
unicorn.set_all(22, 22, 255)
unicorn.show()
time.sleep(interval)
#step57
unicorn.brightness(0.76)
unicorn.set_all(44, 44, 255)
unicorn.show()
time.sleep(interval)
#step58
unicorn.brightness(0.77)
unicorn.set_all(66, 66, 255)
unicorn.show()
time.sleep(interval)
#step59
unicorn.brightness(0.78)
unicorn.set_all(88, 88, 255)
unicorn.show()
time.sleep(interval)
#step60
unicorn.brightness(0.79)
unicorn.set_all(110, 110, 255)
unicorn.show()
time.sleep(interval)
#step61
unicorn.brightness(0.8)
unicorn.set_all(132, 132, 255)
unicorn.show()
time.sleep(interval)
#step62
unicorn.brightness(0.81)
unicorn.set_all(154, 154, 255)
unicorn.show()
time.sleep(interval)
#step63
unicorn.brightness(0.82)
unicorn.set_all(176, 176, 255)
unicorn.show()
time.sleep(interval)
#step64
unicorn.brightness(0.83)
unicorn.set_all(198, 198, 255)
unicorn.show()
time.sleep(interval)
#step65
unicorn.brightness(0.84)
unicorn.set_all(220, 220, 255)
unicorn.show()
time.sleep(interval)
#step66
unicorn.brightness(0.85)
unicorn.set_all(242, 242, 255)
unicorn.show()
time.sleep(interval)
#step67 - white
unicorn.brightness(0.86)
unicorn.set_all(255, 255, 255)
unicorn.show()
time.sleep(interval)
#step68
unicorn.brightness(0.87)
unicorn.set_all(255, 255, 255)
unicorn.show()
time.sleep(interval)
#step69
unicorn.brightness(0.88)
unicorn.set_all(255, 255, 255)
unicorn.show()
time.sleep(interval)
#step70
unicorn.brightness(0.89)
unicorn.set_all(255, 255, 255)
unicorn.show()
time.sleep(interval)
#step71
unicorn.brightness(0.9)
unicorn.set_all(255, 255, 255)
unicorn.show()
time.sleep(interval)
#step72
unicorn.brightness(0.91)
unicorn.set_all(255, 255, 255)
unicorn.show()
time.sleep(interval)
#step73
unicorn.brightness(0.92)
unicorn.set_all(255, 255, 255)
unicorn.show()
time.sleep(interval)
#step74
unicorn.brightness(0.93)
unicorn.set_all(255, 255, 255)
unicorn.show()
time.sleep(interval)
#step75
unicorn.brightness(0.94)
unicorn.set_all(255, 255, 255)
unicorn.show()
time.sleep(interval)
#step76
unicorn.brightness(0.95)
unicorn.set_all(255, 255, 255)
unicorn.show()
time.sleep(interval)
#step77
unicorn.brightness(0.96)
unicorn.set_all(255, 255, 255)
unicorn.show()
time.sleep(interval)
#step78
unicorn.brightness(0.97)
unicorn.set_all(255, 255, 255)
unicorn.show()
time.sleep(interval)
#step79
unicorn.brightness(0.98)
unicorn.set_all(255, 255, 255)
unicorn.show()
time.sleep(interval)
#step80
unicorn.brightness(0.99)
unicorn.set_all(255, 255, 255)
unicorn.show()
time.sleep(interval)
#step81
unicorn.brightness(1)
unicorn.set_all(255, 255, 255)
unicorn.show()
time.sleep(interval)
[/code]

Thinking about it, what I’m basically doing starting red then adding green to max, removing red to min, adding blue to max, taking green to min then taking all to max. Now that I see it like that I can see a much better way to transition it all.