4. Fledex: Clock Example
Mix.install([
{:fledex, "~>0.5"}
])
# we define a couple of aliases to not have to type that much
alias Fledex.Animation.Manager
alias Fledex.Driver.Impl.Kino
alias Fledex.Leds
alias Fledex.LedStrip
{:ok, pid} = Manager.start_link()
:ok
Intro
The goal of this project is to create a clock that displays its hour, minute and second on the trip. We use the kino driver as output and we limit the amount of leds to a reasonable number. Therefore we can’t really display every second and every minute. We can get a bit creative in how we display it.
But before we get there, we first initiate our led strip.
Preparational steps
First we register a strip (we name it :clock
) with our Fledex.Animation.Manager
and we use the default settings for the Kino
driver.
Then we modify the led strip to update with a very low frequency. Our clock only updates every second and therefore it’s unnecessary that we update it more often than that. To avoid any issues due to some runtime delays, we update it twice every second. Thereby the second indicator will never jump an led.
# we start with the default configuration but change the timer update frequency to 500ms
:ok = Manager.register_strip(:clock, [{Kino, []}], timer_update_timeout: 500)
:ok
Defining our clock
We now register our animations for the :clock
led strip. We define 4 animations. One for the seconds, minutes, and hours and one as help to make it easier to read the lock by having an indicator in every 5 intervals.
Each animation consists of two elements:
-
def_func
this defines a function that will be called to define a sequence of LEDs (how many LEDs and which colors). The function receives atrigger
(amap
) that can contain various information, but at least contains a counter with the name of the led strip (i.e. in our case with the name:counter
). We will use this to define a sequence of the correct length and color the fist led. In this function we don’t use thetrigger
-
send_config_func
this defines a function that will be called after the LED strip has been defined (seeFledex.Leds.send/2
for more details and options). We will use this to rotatae the led sequence (dependent on thetrigger
that we also get here as input) in such a way that the colored dot will come to the correct position in the sequence. We also explicitly specify the direction of our rotation. We can rotate to the left or the right.
Note: we get the time by simply making a call to Time.utc_now/0
and adjusting it to our timezone (UTC+1) (Time.add/2
). We then extract (through pattern matching) the information we are intersted in (second, minute, hour)
Our :help
“animation” defines an led sequence of 5 leds (the first one being colored) and repeats that pattern 12 times. This is not a real animation, since we output a static pattern every time.
config = %{
seconds: %{
type: :animation,
def_func: fn _triggers ->
Leds.leds(60) |> Leds.light(:red)
end,
send_config_func: fn _triggers ->
# we work with utc times and adjust, so we don't need to load a timezone library
%{hour: _hour, minute: _minute, second: second} = Time.utc_now() |> Time.add(1, :hour)
# Logger.info("#{second}")
%{offset: second, rotate_left: false}
end
},
minutes: %{
type: :animation,
def_func: fn _triggers ->
Leds.leds(60) |> Leds.light(:green)
end,
send_config_func: fn _triggers ->
# we work with utc times and adjust, so we don't need to load a timezone library
%{hour: _hour, minute: minute, second: _second} = Time.utc_now() |> Time.add(1, :hour)
# Logger.info("#{second}")
%{offset: minute, rotate_left: false}
end
},
hours: %{
type: :animation,
def_func: fn _triggers ->
Leds.leds(60) |> Leds.light(:blue)
end,
send_config_func: fn _triggers ->
# we work with utc times and adjust, so we don't need to load a timezone library
%{hour: hour, minute: _minute, second: _second} = Time.utc_now() |> Time.add(1, :hour)
# Logger.info("#{second}")
%{offset: hour, rotate_left: false}
end
},
help: %{
type: :animation,
def_func: fn _triggers ->
Leds.leds(5)
|> Leds.light(:ash_gray)
|> Leds.repeat(12)
end
}
}
Starting our animation
Now that we have defined our configuration we can start our animation, by registering our animations-configuration to our Fledex.Animation.Manager
by calling register_config/2
. That’s it!
Manager.register_config(:clock, config)
If you are searching for your led strip then scoll up. It’s displayed where you have registered your led strip with the Fledex.Animation.Manager
.