Introduction: Web Connected Digital Clock

Found a $10 digital clock at Amazon. Now to customize it to get the time from the internet.

Supplies

ARM Stamp programmable in BASIC available here

Step 1: Connect Digit Drive and Segment Drive for Multiplexed Display

I started with a cheap off the shelf big number digital clock. First I removed the existing clock chip. Then did some probing around and located the 7 segment connections, which can be driven directly by the microprocessor. Then found the 4 digit drivers which were transistors which the microprocessor can drive. And then wired those up.

Step 2: Test the Connections

As an experiment I wrote a BASIC program to drive all the lines, to check the wiring and measure the current, which in this case was 82 mA

Next was to write the code to scan the lines.

' web clock display drive

IO(7)=0 ' PMOS drive -- will be PWM someday

for y=45 to 48

IO(y)=0 ' digit drive

for x=8 to 15

IO(x)=0 ' segment drive

wait(500)

IO(x)=1

next x

DIR(y)=0 ' disable drive on segment

next y

Step 3: Code to Display Time and PWM to Control Brightness

Next I added a PMOS transistor in the power supply to all the digit drivers. With that driven by pulse width modulation will control the brightness of the display. Here is the BASIC code to display the time.

' web clock display drive
#include "LPC11U3x.bas"

' globals

hr = 0 ' define hour

min = 0 ' define minute

#define SEG_0 &HBB00

#define SEG_1 &H1800

#define SEG_2 &HD300

#define SEG_3 &HD900

#define SEG_4 &H7800

#define SEG_5 &HE900

#define SEG_6 &HEB00

#define SEG_7 &H9800

#define SEG_8 &HFB00

#define SEG_9 &HF800

#define SEG_o &H4B00

#define SEG_f &HE200

const DIGarray = { SEG_0, SEG_1, SEG_2, SEG_3, SEG_4, SEG_5, SEG_6, SEG_7, SEG_8, SEG_9, SEG_o, SEG_f }

#define DIG_WAIT 1

#define US_TIME

sub display_time(err, hr, min)

dim hr10, hr1, min10, min1, i

#ifdef US_TIME

if hr > 12 then hr -= 12

if hr = 0 then hr = 12

#endif

hr10 = hr / 10

hr1 = hr MOD 10

min10 = min / 10

min1 = min MOD 10

for i=0 to 1

if hr10 then

IO(45) = 0

endif

GPIO_DIR(0) = (GPIO_DIR(0) & &HFFFF00FF) + DIGarray(hr10)

GPIO_CLR(0) = DIGarray(hr10)

wait(DIG_WAIT)

INPUT(45)

IO(46) = 0

GPIO_DIR(0) = (GPIO_DIR(0) & &HFFFF00FF) + DIGarray(hr1) + IF(i , &H400 , 0)

GPIO_CLR(0) = DIGarray(hr1) + IF(i , &H400 , 0)

wait(DIG_WAIT)

INPUT(46)

IO(47) = 0

GPIO_DIR(0) = (GPIO_DIR(0) & &HFFFF00FF) + DIGarray(min10)

GPIO_CLR(0) = DIGarray(min10)

wait(DIG_WAIT)

INPUT(47)

IO(48) = 0

GPIO_DIR(0) = (GPIO_DIR(0) & &HFFFF00FF) + DIGarray(min1)

GPIO_CLR(0) = DIGarray(min1)

wait(DIG_WAIT)

INPUT(48)

next i

endsub

' user TIMER1 (32 bit) to interrupt each minute

INTERRUPT SUB TIMER1IRQ

T1_IR = 1 ' Clear interrupt

min += 1

if min > 59 then

min = 0

hr += 1

if hr > 23 then

hr = 0

endif

endif

ENDSUB

SUB ON_TIMER ( max_cnt, dothis )

TIMER1_ISR = dothis + 1 'set function of VIC -- need the +1 for Thumb operation

SYSCON_SYSAHBCLKCTRL OR= (1<<10) ' enable TIMER1

T1_PR = 0 'no prescale -- will adjust the value for more accurate time

VICIntEnable OR= (1<<TIMER1_IRQn) 'Enable interrupt

T1_MR0 = max_cnt-1 ' set up match number of ms

T1_MCR = 3 ' Interrupt and Reset on

MR0 T1_IR = 1 ' clear interrupt

T1_TC = 0 ' clear timer counter

T1_TCR = 1 ' TIMER1 Enable

ENDSUB

#define MINUT_PCLK 2880000000 ' 60 seconds at 48 MHz

main:

hr = 9

min = 33

ON_TIMER(MINUT_PCLK , ADDRESSOF TIMER1IRQ)

IO(7) = 0 ' PWM some day -- need to move to P0_22 ??

while 1

display_time(0, hr, min)

loop

Step 4: Make an Internet Connection

Use an ESP8266 for a WiFi connection. After poking around the web for a while the best solution was nodemcu version 0.9.6 and an older esp8266_flasher worked the best.

https://www.electrodragon.com/w/File:Nodemcu_20150704_firmware.zip

Then a simple PHP webpage to serve time from the internet--

<!DOCTYPE html>

<html lang=en>

<head>

<title>Coridium Time Server</title>

</head>

<body>

<?php

$timezone = htmlspecialchars($_GET["zone"]);
if ( $timezone == "")

$timezone = 'America/Los_Angeles';

$tz_object = new DateTimeZone($timezone);

$datetime = new DateTime();

$datetime->setTimezone($tz_object);

echo "time is-",$datetime->format('H:i:s');

echo "<br>";

echo "date is-",$datetime->format('m/d/Y');

?>

</body>

</html>

That webpage is so you can request

coridium.us/time.php -- and you well get US Pacific time zone

or

coridium.us/time.php?zone=Europe/London

No error checking and most likely never will be

And the Lua to read that --

> wifi.sta.config("your_SSID","your_PASSWORD")
> wifi.sta.connect() ...

> sk=net.createConnection(net.TCP, 0)

> sk:on("receive", function(sck, c) print(c) end )

>sk:connect(80,"coridium.us")

>sk:send("GET /time.php HTTP/1.1\r\nHost: coridium.us\r\nConnection: keep-alive\r\nAccept: */*\r\n\r\n")

And you get back time as

time is-09:38:49
date is-12/31/2018

Step 5: Add BASIC Code to Parse the Time From the Web

This is a subset of the full BASIC program, that full program can be viewed at the link in the final step.

if strstr(build_gets, "time is-") = 0 then

hr = build_gets(8) - "0"

if build_gets(9) = ":" then

min = (build_gets(10) - "0")*10

min += build_gets(11) - "0"

else

hr = hr * 10 + build_gets(9) - "0"

min = (build_gets(11) - "0")*10

min += build_gets(12) - "0"

endif

endif

Step 6: Add a Light Sensor and Code to Dim the Display

A photo transistor was added to sense the ambient light in the room. Without it the display is bright enough to wake the dead (me) at night.

The analog voltage of the output of the photo transistor is read and the pulse width modulation sets the overall brightness of the display.

Step 7: Button Up the Clock and Start Using It.

The final version displays the time, and at around 3 AM it goes out to the web to read the current time. This also handles day light saving time.

The motivation for this project was the power failures we experience here in the mountains and the need to reset clocks or replace batteries to keep them alive.

This has been a quick overview of the project.

Full details of this DIY web connected clock.