Mesecons Laboratory

Adventures in digital circuitry.


Clock

14/4/13 - Uberi

Difficulty level: (4/10)

This article assumes you have the Digilines mod, which I generally consider a de facto part of Mesecons. It is still possible to complete it without this mod, but replacing its functionality with fancy wiring is an exercise left to the reader.

Don't you ever wish you had a clock in-game while playing Minetest, just to keep track of all the time you're wasting? Need a timepiece for the top of the main tower in town hall? Let's build one!

Clock

This clock will never need adjustment and works even if you use the /time command! This is made possible using the Digilines RTC.

Step 1: Design

Before we build anything, let me explain how the Digilines RTC works.

The RTC, short for Real Time Clock, is a Digilines device that allows you to obtain the current (in-game) time of day. How does it work? When you plonk an RTC down, you can right-click it to set the channel:

Real Time Clock

Now, whenever you send a digilines signal on that channel, using "GET" as the message, it will in turn send a digilines signal on that same channel, but with the current time as the message.

However, this time isn't just in a standard time format; it's represented as fractional hours. Let's take a look:

/time 0 is midnight.
/time 500 is half-past midnight.
/time 7250 is around 7:15 AM.
/time 1500 is around 3 o'clock PM.

The thousands place and above denotes the hour in 24-hour notation, while the hundreds place and below denotes a fraction of that hour.

When we get to the programming section, there will be a more detailed overview of how to deal with coverting this time into the one we're more used to.

Step 2: Layout

We want the clock to look as nice as possible. Therefore, we start from the display:

Clock display

Well this is a nice display and all, but there's one big problem with it - it doesn't display anything! Let's remedy that situation:

Wired displays

Each digit display has been wired up to a standard seven segment driver supporting the digits 0-9, since that's all we really need. Note that port A faces the lightstone and port C faces the camera in the image above. While the machine can be built in any orientation, I will assume we are using the one shown. Changing the Luacontroller code to work with other orientations is an exercise left for the reader.

For the sake of completeness, here is the code inside each Luacontroller on the leftmost display (the ones column of the minutes):

Top:

if event.type == "program" then
  mem.accept = {[0]=true, [2]=true, [3]=true, [5]=true, [6]=true, [7]=true, [8]=true, [9]=true}
elseif event.type == "digiline" then
  port.a = mem.accept[event.msg.minute]
  port.b, port.d = port.a, port.a
end

Second from top:

if event.type == "program" then
  mem.accept1 = {[0]=true, [4]=true, [5]=true, [6]=true, [8]=true, [9]=true}
  mem.accept2 = {[0]=true, [1]=true, [2]=true, [3]=true, [4]=true, [7]=true, [8]=true, [9]=true}
elseif event.type == "digiline" then
  port.b = mem.accept1[event.msg.minute]
  port.d = mem.accept2[event.msg.minute]
end

Middle:

if event.type == "program" then
  mem.accept = {[2]=true, [3]=true, [4]=true, [5]=true, [6]=true, [8]=true, [9]=true}
elseif event.type == "digiline" then
  port.a = mem.accept[event.msg.minute]
  port.b, port.d = port.a, port.a
end

Second from bottom:

if event.type == "program" then
  mem.accept1 = {[0]=true, [2]=true, [6]=true, [8]=true}
  mem.accept2 = {[0]=true, [1]=true, [3]=true, [4]=true, [5]=true, [6]=true, [7]=true, [8]=true, [9]=true}
elseif event.type == "digiline" then
  port.b = mem.accept1[event.msg.minute]
  port.d = mem.accept2[event.msg.minute]
end

Bottom:

if event.type == "program" then
  mem.accept = {[0]=true, [2]=true, [3]=true, [5]=true, [6]=true, [8]=true, [9]=true}
elseif event.type == "digiline" then
  port.a = mem.accept[event.msg.minute]
  port.b, port.d = port.a, port.a
end

The other displays have nearly the exact same code, except event.msg.minute is replaced with event.msg.tenminute, event.msg.hour, and event.msg.tenhour, from left to right for each digit display.

Step 3: Construction

Now we can wire up the timekeeping unit. First, a Digilines RTC is connected to a Luacontroller that polls it when we need it to:

Clock connected to clock driver

The RTC, unsuprisingly, is set to the channel "clock".

The code inside the Luacontroller is quite simple:

if event.type == "on" then
  digiline_send("clock", "GET")
end

Whenever any of the pins are turned on, it polls the RTC for the current time.

The RTC can now be wired to another Luacontroller that does the calculations to convert the time into the hours and minutes most people are familiar with:

Clock connected to display driver

A blinky plant is a very reliable oscillator. Luacontrollers and microcontrollers have delay capabilities, but they will not last past a server restart. Using a blinky plant ensures the clock will work regardless of the conditions it is in.

The code inside the lower Luacontroller calculates the number of hours and minutes from the time value, and turns them into individual digits to be displayed:

if event.channel == "clock" then
  time = event.msg * 24
  hour = math.floor(time)
  tenhour, hour = math.floor(hour / 10), hour % 10
  time = (time % 1) * 60
  minute = math.floor(time)
  tenminute, minute = math.floor(minute / 10), minute % 10
  digiline_send("", {tenhour=tenhour, hour=hour, tenminute=tenminute, minute=minute})
end

After calculations, it sends off a Digilines signal with all the digits packed into a table. The field names should seem rather familiar - they are the same ones that we used in the displays!

The only thing left to do is ensure the Digilines signal reaches all the displays:

Displays connected to clock

The displays update automatically as time passes by. It works!

Step 4: Improvements

The clock as it is right now doesn't look very good, with all those wires showing. How about an enclosure?

Clock with enclosure

Or perhaps a blimp?

Clock with enclosure

After all, you can't have a world without blimps.

Downloads

All files are available under the same license as this article. The WE schematics can be loaded using the //load command in WorldEdit.

Clock in WorldEdit format (WE)





Creative Commons License
This work is licensed under a Creative Commons Attribution-ShareAlike 3.0 Unported License.