Complete the HDMI Timer we built in Part 1, getting the software running and installing the display.
Now that we have the PCB hardware sorted in Part 1, we’re going to tackle the rest of the setup, including the code.
You’ll need to load up the hdmi_gaming_timer.ino sketch into the Arduino IDE, and compile onto your ATmega328P. If you don’t have an ATmega programmer, you can simply use an Arduino UNO itself, then remove the chip and install it into your PCB. Take care with the orientation, as it is easily reversed.
Once this is done, you can install the screen. It’s a simple shield, which is accommodated for in our PCB.
A touch screen panel was a logical choice for the interface, given the need for user input in a variety of different ways, and of course the visual output.
With everything firmly installed, and the tests performed on the PCB in Part 1, you should now be able to power up the unit.
With power applied, you should see the screen illuminate and boot. If you don’t, immediately disconnect power and revisit the testing phase of the instructions in Part 1.
The sketch (Arduino code) for this project is relatively long at 1100 lines, but is written to be easily understood and modified if desired. If you look into the sketch, you’ll see that a lot of it is based around manipulating the GUI. It easily fits within what can be the challengingly small storage limits of an Arduino, or as in this case the 328P microcontroller, which is at the heart of our beloved Arduino.
While some people may want to use this timer as a simple reminder/time restriction device, it’s expected that a key use is parents limiting a child’s screen time. For this reason, we have implemented a simple PIN to lock out adjustments to the settings. Kids are very savvy and would quickly work out how to suspend or reset the timer. We’ve also catered for a restart and other attempted “workarounds”.
Here are a few of our concepts from within the code, which you can easily review within the sketch.
Running the Screen
We designed this project with the Jaycar XC4630 LCD panel. Other LCD panels may work. The equivalent Altronics screen does work, however, minor code alterations are required to get it working due to differences in driver chip.
This LCD panel has a good resolution of 320 x 240 and has some level of hardware graphics acceleration, which means it’s relatively easy to draw filled or unfilled shapes like circles, rectangles etc. There is 1 font included and text can be drawn in a number of sizes.
Displaying Text On Screen
Due to the nature of how text is drawn on the LCD, code similar to the following is used:
tft.fillRect(FromX, FromY, ToX, ToY, FILL_COLOUR);
tft.print("Text to print");
Writing say ‘123’ over ‘456’ does not erase the previous 456. It just makes a mess. To show new text where text has previously been written it is necessary to draw a filled rectangle over it.
You then choose the font size. Size 2 is good for general text. Size 3 is double the size of size 2. Size 26 will just about fill the screen with 2 characters.
The next step is to choose a text colour. Several have been defined. It is important to set the colour with each text print as the colour may have been set to something unexpected in other parts of your sketch.
Next, position your cursor to the x and y co-ordinates of the position where you’d like your text to appear. Finally, you can print the text.
Responding to the Touchscreen
The display is 320 pixels wide and 240 high, but the touch is detected as 1024 by 1024 and has some dead area at the edges. We do a little magic to map the active area to the screen size.
We found it easy enough to test for touching an area by using absolute co-ordinates. For example, while reading the initial PIN code it is easy to determine the button being touched (if any), by determining if a touch is in a particular column. Column 1 being 1, 4 and 7, column 2 being 2, 5 and 8 etc, then doing similar to determine the row.
Continuous touching of the screen will generate a stream of touch events. A simple ‘debounce’ delay eliminates the problem of multiple touch detections for a brief touch, but if the user continues to touch the same area, multiple touches may be registered.
Storing a PIN
The Personal Identification Number (PIN) is stored in EEPROM, which is a small amount of non-volatile (contents remain after power off) storage. Consider that a brand new Arduino or 328P as we have used will have nothing valid in it’s EEPROM.
We have to be able to determine this so if a new device is detected, we initialise the EEPROM by writing a “magic number” into it. If we see the magic number in future we know that the stored PIN is valid. The EEPROM has a large but finite number of times its contents can be changed. In our application, it won’t be changed nearly often enough to damage it.
The Timer Function
This project is designed around allowing x number of minutes of access to a gaming console etc. While it would be possible to count whole minutes, and indeed, the display gives the impression that that is what is happening, we have to consider monitoring the touch ‘controls’ too.
To do this we actually count seconds with a check of the controls being touched at each count. The final minute is handled a little differently. We have made provision for a piezo buzzer to be added to ‘sound’ the last 10 seconds. As these are not looked upon favourably in the office, we omitted it in the final build.
Enclosing this device took a little consideration and planning. HDMI can be susceptible to EMF and other interference fairly easily, due to its low voltage and very high frequencies.
Our first choice would be to enclose this build in a full die-cast aluminium case to help shield everything. However, our touchscreen makes this near impossible to create a clean cut-out for the screen.
Therefore, we’ve developed a 3D printable custom case, as usual, with the addition of aluminium foil to assist in creating some EMF shielding in the case. It’s arguably not as effective as a metal case, but the ease of construction provides some huge benefits.
You can find the case files in the digital resources. The case itself is fairly straightforward, providing mounting for everything.
In order to mount the PCB, you must first remove the screen so you can get to the mounting holes. Support posts are built into the case itself, to screw in directly with 4 x M3 screws.
Before you mount the PCB, optionally line the case with aluminium foil. Using craft glue and a paintbrush isn’t a bad way to achieve this (trying to use one single large piece is virtually impossible).
It takes a little jiggling to get everything lined up perfectly, as we’ve kept it fairly snug. This was done intentionally to avoid issues with HDMI cables with bulky plugs. While the connector is very well standardised, some manufacturers of cables use larger-than-standard grips.
USING THE TIMER
While most of the user interface is fairly straightforward, we thought it would be prudent to go through a few of the features quickly.
Most functions also require the entering of a PIN in order to disallow unauthorised “extension” of gameplay.
You’ll be prompted to enter a PIN. If this is your first boot, you’ll be asked to set your preferred PIN. If you have previously set it, enter your PIN. You’ll then see the Home Screen.
The menu provides you with options for 1 hour and 2 hour timers, no timer (i.e. - permanently on), setting your own custom timer duration, and change PIN. Basically, all the functions we need.
The 1hr and 2hr timers are one-touch options to set the timer. You can easily amend their duration within the code if you have a different preference. To activate, simply touch the preferred timer.
This permanent-on function is great for when you want standard operation of your HDMI device, whether it’s your computer or TV, for an extended period.
his custom timer function provides controls to set whatever time limit is desired, in 15 minute increments. It’s entirely possible to modify the 15 minute increment to 5 or even 1 minute increments, however, we decided 15 minutes was a good general place to start.
To set the time, simply use the up / down controls for the hours and minutes. There is no need for seconds here, so the provision has not been made.
Entirely self-explanatory, allowing you to update the PIN any time a timer is not already active.
WHERE TO FROM HERE?
Our PCB includes a full set of headers for unrestricted access to the GPIO (however you can’t use GPIO that’s already in use unless you modify the code, of course). This allows you to expand the timer however you’d like.
Perhaps, you can automatically power-down all of your devices when the timer expires (using safe methods such as interfacing with remote control powerboards, of course - playing with mains power is not something to be taken lightly). Maybe you’d like to expand it with a WiFi shield and send push notifications so you know when the timer has run out, even if you’re not near the device. The opportunities are endless!