web based clock

Post details of your projects here.
basicchip
Posts: 1090
Joined: Fri Oct 19, 2012 2:39 am
Location: Weeki Watchee, FL
Contact:

Re: web based clock

Post by basicchip »

Tweaked the time server to handle recognized time zones listed here https://secure.php.net/manual/en/timezones.php

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

Code: Select all

<!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>



basicchip
Posts: 1090
Joined: Fri Oct 19, 2012 2:39 am
Location: Weeki Watchee, FL
Contact:

Re: web based clock

Post by basicchip »

Care package from Digikey came in so I can finish up the ambient light sensor. Also ordered some LPC54005s for other boards we are experimenting with.

Speaking of light I already decreased the brightness at night, but it still acts like a night light for me. I am far sighted which my eye doc told me is why I have excellent night vision. Just me and the cats wandering around at in the dark in the house.

basicchip
Posts: 1090
Joined: Fri Oct 19, 2012 2:39 am
Location: Weeki Watchee, FL
Contact:

Re: web based clock

Post by basicchip »

Well the light sensor is a pretty simple circuit.
lightDark.jpg
lightDark.jpg (6.64 KiB) Viewed 17642 times
The real variable is what resistor to choose. I went from 1 M to 2 M to 3 M. Then I put the bezel in front which cuts out a lot of light, and may end up increasing the resistor size more. Waiting for night to test ambient room light vs dark to set that value. Most likely the display will go full bright with room lights on at night, and then dim way down.

basicchip
Posts: 1090
Joined: Fri Oct 19, 2012 2:39 am
Location: Weeki Watchee, FL
Contact:

Re: web based clock

Post by basicchip »

Buttoned up the project today. I ended up putting the light sensor poking out of the top slightly. With that 10 M would probably be the correct resistor. So now every 5 seconds the AD is read to set the brightness of the display, may do some final adjustment of the AD vs brightness tonight. I left it possible to program the ARMstamp or ESP8266 without disassembly. But it looks pretty good where it will live in the bedroom.
clock6.jpg
clock6.jpg (157.51 KiB) Viewed 17640 times
Birds nest of wires hidden inside
clock7.jpg
clock7.jpg (96.94 KiB) Viewed 17640 times
USB connections for power only (original clock power) and for debug
clock8.jpg
clock8.jpg (79.6 KiB) Viewed 17640 times
And a closeup of the light sensor -- the equivalent of deadbugging SMT parts
clock9.jpg
clock9.jpg (37.39 KiB) Viewed 17640 times
The resistor in the light sensor is now 15M. Using values that high you have to be careful of oils from your hands, flux ... Meaning you need to clean it up as those can have significant impacts on resistance. Still playing with the values, clipping on the high end above 55000 calling that full bright, and below 3000 calling it all dark. I seem to be playing with the settings each night. I had 20 /1000 PWM on the low end was too dim to easily read in a dark room so upped it to 25 that seems better. But it still is a bit of a night light.

olzeke51
Posts: 414
Joined: Sat May 17, 2014 4:22 pm
Location: South Carolina

Re: web based clock

Post by olzeke51 »

Lookin' good on the mantel. You're right, these LEDs do make a 'nite lite".
So when will the clock send the ambient light level to the thermostat to modify
the temperature settings to accomodate the changing sunrise and/or Daylight Savings!!!??
'
I have/am using a simple programmable furnace control to control a furnace controller, but
I have hooked up a standard light socket to the relay output contacts. So the room temp
setting is way hi/low at the different times !!!! My son saved the furnace controller from
one of his jobs - part of it is kaput. I have it turn on the 'nite setting/lite' to remind me to
wind down from my computer so I can go to sleep easier....
''fun with parts----
Gary

basicchip
Posts: 1090
Joined: Fri Oct 19, 2012 2:39 am
Location: Weeki Watchee, FL
Contact:

Re: web based clock

Post by basicchip »

"Final" code for the clock, yeah right

timeLord.bas

Code: Select all


#include "WiFiLogin.bas"

#include <STRING.bas>

#define TIME_LORD

#define OFFLINE		-1
#define NO_NET		-2

#define LPC11U37			' fake out pre-processor while testing on LPC824

' globals

hr = 0			' define hour
min = 0			' define minute
retry_count=0	' retries during time check 3:39 AM and initial startup

#include "displayCLOCK.bas"

dim CMDstr(200) as string
dim RESPONSEdata (3000) as byte

#define LF		10
#define CR		13
#define COMMA	","
#define PROMPT	">"
#define DQUOTE	chr(34)


dim build_gets (255) as string
build_idx_gets = 0	

' return empty string until CR/LF seen  -- maybe timeout too

function incremental_gets (wate) 
	dim c
	
	c=RXD(1)
	if c = -1 then return 0
	if c = LF then 
		build_gets(build_idx_gets)=0
		build_idx_gets = 0			
		return 1		
	endif
	if build_idx_gets=0 then
		if c = PROMPT then 
			build_gets(build_idx_gets)=c
			wait (10)							' try to read in the space
			c = RXD(1)
			if c > 0 then 
				build_gets(build_idx_gets+1)=c
				build_idx_gets += 1
			endif
			build_gets(build_idx_gets+1)=0
			build_idx_gets = 0			
			return 1		
		endif
	endif
	
	build_gets(build_idx_gets) = c
	build_idx_gets += 1
	if wate = 0 then
		print chr(c);
		return 0
	endif
	
	return 0
end function

sub sendLua (byref ATstr() as string) 
	dim i, c
	
	wait(1000)
	
	i=0
	c = ATstr(i)
	while (c)
		TXD(1)=c
		i=i+1
		c = ATstr(i)
'		wait(20)
	loop

	TXD(1) = CR
	TXD(1) = LF
	
	while incremental_gets(1) = 0
	loop
	print build_gets
	wait(50)
end sub



dim build_debug (255) as string
build_idx_debug = 0	

' return empty string until CR/LF seen  -- maybe timeout too

function incremental_debug () 
	dim c
	
	c=RXD(0)
	if c = -1 then return 0
	if c = CR then 
		build_debug(build_idx_debug)=CR
		build_idx_debug += 1
		build_debug(build_idx_debug)=0
		sendLua(build_debug)

		build_idx_debug = 0	
		
		return 0		
	endif
	
	build_debug(build_idx_debug) = c
	build_idx_debug += 1
	
	return 0
end function

#ifdef LPC824
#define ESP_RESET	15
#else
#define ESP_RESET	58
#endif

web_hr = 0 
web_min = 0

sub wifi_gettime
	dim start
	
	web_hr = 	OFFLINE
	web_min = 	OFFLINE			
	
	Baud(1)=75000		' UART used for ESP8266 connection

	build_idx_gets = 0	
	build_idx_debug = 0	
	
	print "RESET ESP8266"
	
	IO(ESP_RESET)=0
	wait(500)
	IO(ESP_RESET)=1		' reset ESP8266
	wait(1000)
	
	start = TIMER
	while (TIMER - start < 100000)
		incremental_gets(0)				' dump whatever comes out
		if strstr (build_gets, "csum") = 0 then exit
	loop
	Baud(1)=9600	
	
	wait(1000)
	sendLua("wifi.setmode(wifi.STATION)")
		
	if retry_count and 1 then
		CMDstr = "wifi.sta.config(" + DQUOTE + SSID1 + DQUOTE + COMMA + DQUOTE + PASSWORD1 + DQUOTE + ")"
	else
		CMDstr = "wifi.sta.config(" + DQUOTE + SSID2 + DQUOTE + COMMA + DQUOTE + PASSWORD2 + DQUOTE + ")"
	endif
	
	print "connect to WiFi"
	
	sendLua(CMDstr)					' connect to my Wifi
	sendLua("wifi.sta.connect()")
	wait(1000)
	sendLua("print(wifi.sta.status())")
	while incremental_gets(1) = 0
	loop
	print build_gets	
	
	print "loop2"
	
	while incremental_gets(1) = 0
	loop
	print build_gets	
		
	
	sendLua("sk=net.createConnection(net.TCP, 0)")
	CMDstr = "sk:on(" + DQUOTE + "receive" + DQUOTE + ", function(sck, c) print(c) end )"
	sendLua(CMDstr)
	CMDstr = "sk:connect(80," + DQUOTE + "coridium.us" + DQUOTE + ")"
	sendLua(CMDstr)
	
	CMDstr = "sk:send("+ DQUOTE + "GET /time.php HTTP/1.1\r\nHost: coridium.us\r\n\r\n" + DQUOTE + ")"
	sendLua(CMDstr)
		
	start = TIMER
	while (TIMER - start < 9000000)
		if incremental_gets(1) = 1 then				' dump whatever comes out
			print build_gets
			if strstr(build_gets, "time is-") = 0 then
				web_hr = build_gets(8) - "0"
				if build_gets(9) = ":" then
					web_min = (build_gets(10) - "0")*10
					web_min += build_gets(11) - "0"
				else
					web_hr = web_hr * 10 + build_gets(9) - "0"
					web_min = (build_gets(11) - "0")*10
					web_min += build_gets(12) - "0"			
				endif
				exit
			endif
		endif
	loop
	
	wait(1000)
	sendLua("wifi.sta.disconnect()")
	start = TIMER
	while (TIMER - start < 2000000)
		if incremental_gets(1) = 1 then				' dump whatever comes out
			print build_gets
		endif
	loop
	print "done wifi_gettime"
endsub

check_time = 0

sub each_minute
	' check for time drift / daylight savings  -- this is inside an interrupt so set a flag to check the time
  
'	if (min and 3) = 0 then check_time = 1		' enable this one for checking each 4 minutes
	if hr=3 and min = 39 then check_time = 1
endsub



main:

hr = OFFLINE
min = 0

wait(2000)

#ifndef LPC824
init_scan()
set_brite(MAX_BRIGHT)
#endif

for retry_count=0 to 9
	wait (retry_count=0 * 5000)		' initially don't wait, then up to 45 seconds of retries
	wifi_gettime
	if web_min <> OFFLINE then
		hr = web_hr
		min = web_min
		exit
	endif
next 
retry_count=0

if hr=OFFLINE then hr=WEB_ERR

while 1
	if check_time then
		print "check time"
		retry_count=0
		while 1
			wifi_gettime
			if web_min <> OFFLINE then
				hr = web_hr
				min = web_min
				exit
			endif
			retry_count += 1
			wait(1000)
		loop
		check_time = 0
		retry_count=0
		print "update complete"
	endif

	x = AD(6) >> 6
	set_brite(x)
	wait(5000)	
loop

And here is the code for the display drive

displayCLOCK.bas

Code: Select all


'	web clock display drive

#include "LPC11U3x.bas"

#ifndef TIME_LORD
	hr=0
	min=0
#endif

#ifdef TIME_LORD
forward_declarations:
	gosub each_minute
#else
	sub each_minute
	endsub
#endif

#define OFFLINE -1
#define WEB_ERR	-2


'      -15-
'    |      |
'    13     12
'    |      |
'      -14-    colon/alarm 10
'    |      |
'    9      11
'    |      |
'      -8-

#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 		
#define SEG_n	&H4A00 		
#define SEG_E	&HE300 		
#define SEG_r	&H4200 		

#define ALL_SEG	&HFF00

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

#define MAX_BRIGHT	990
#define MIN_BRIGHT	20		' 250 was still a night light as was 100 and 50 too

sub set_brite(x)
	if x > MAX_BRIGHT then x = MAX_BRIGHT
	if x < MIN_BRIGHT then x = MIN_BRIGHT
'	if (T3_MR0 < x+10) and (T3_MR0 > x-10) then return
	print "dim to ",x
	T3_MR0 = x
endsub


#define US_TIME

' user TIMER1 (32 bit) to interrupt each minute

INTERRUPT SUB TIMER1IRQ
	T1_IR = 1	      ' Clear interrupt
	
	if hr < 0 then return
  
  	min += 1
	if min > 59 then
		min = 0
		hr += 1
		if hr > 23 then
			hr = 0
		endif
	endif
	
	gosub each_minute				' call back to network program each minute
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  = 48-1                         '1 MHz tick
	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
	
	print hex(max_cnt), hex(dothis)
ENDSUB

'	Timer3 interrupt will now drive the character, using PWM_count to index through the 4 digits

PWM_count = 0		' globals used in TIMER3 interrupt
PWM_toggle = 0		

const DIGIT_IO = { 45, 46, 47, 48 }

INTERRUPT SUB TIMER3IRQ
	dim dig, show_hr as integer
	
	T3_IR = 8	      ' Clear interrupt
	
	show_hr=hr
#ifdef US_TIME
	if show_hr > 12 then show_hr = hr - 12
	if show_hr = 0  then show_hr = 12
#endif	

	select PWM_count
		CASE 0
			INPUT ( DIGIT_IO(3))
			
			if show_hr = OFFLINE then 
				dig = DIGarray(0)
			elseif show_hr = WEB_ERR then 
				dig = SEG_n
			else 
				dig = DIGarray(show_hr /10)
			endif
						
			if dig <> DIGarray(0) then				' if leading digit is 0, display blank
				IO( DIGIT_IO(0)) = 0
			endif
			
#ifdef TIME_LORD
			if retry_count and 1 then 
				IO( DIGIT_IO(0)) = 0
				dig = &H2000
			endif
#endif		
			GPIO_DIR(0) = (GPIO_DIR(0) & &HFFFF00FF) + dig
			GPIO_CLR(0) = ALL_SEG					' drive low or tristate above
			
			PWM_count = 1
		CASE 1
			INPUT( DIGIT_IO(0))
		
			if show_hr = OFFLINE then 
				dig = SEG_o
			elseif show_hr = WEB_ERR then 
				dig = SEG_o
			else 
				dig = DIGarray(show_hr MOD 10)
			endif
			
			IO( DIGIT_IO(1)) = 0
	
			GPIO_DIR(0) = (GPIO_DIR(0) & &HFFFF00FF) + dig + IF(PWM_toggle , &H400 , 0)
			GPIO_CLR(0) = ALL_SEG					' drive low or tristate above
			
			PWM_toggle = IF(PWM_toggle , 0 , 1)		' the colon is TOO bright so display at 50%

			PWM_count = 2
		CASE 2
			INPUT( DIGIT_IO(1))
		
			if show_hr = OFFLINE then dig = SEG_f else dig = DIGarray(min / 10)
			
			if show_hr <> WEB_ERR then IO( DIGIT_IO(2)) = 0		' display no n  -- skip this digit

			GPIO_DIR(0) = (GPIO_DIR(0) & &HFFFF00FF) + dig
			GPIO_CLR(0) = ALL_SEG					' drive low or tristate above
			
			PWM_count = 3
		CASE 3
			INPUT( DIGIT_IO(2))
		
			if show_hr = OFFLINE then 
				dig = SEG_f
			elseif show_hr = WEB_ERR then 
				dig = SEG_n
			else 
				dig = DIGarray(min MOD 10)
			endif
			
			IO( DIGIT_IO(3)) = 0

			GPIO_DIR(0) = (GPIO_DIR(0) & &HFFFF00FF) + dig
			GPIO_CLR(0) = ALL_SEG					' drive low or tristate above

			PWM_count = 0
		CASE ELSE
			PWM_count = 0		' should not be needed
	END SELECT
	
ENDSUB


#define EMC0	4		' bit positions for external match control
#define EMC1	6
#define EMC2	8
#define EMC3	10

#define EMC_NOP	0
#define EMC_CLR	1
#define EMC_SET	2
#define EMC_TGL	3



sub setupPWM (cycleTime, highTime)		' times in micro-seconds
	DIM prescale as integer

	prescale = 48		' as the peripherals run at 48 MHz

	' treat them all like 16 bits
	
	while (cycleTime >= &H10000) 
		cycleTime = cycleTime >> 1
		highTime = highTime >> 1
		prescale = prescale << 1
	loop
	prescale = prescale - 1				' counts to n-1
	cycleTime = cycleTime - 1			' counts to n-1
		
	' enable counters CT16B0 and CT16B1
	SYSCON_SYSAHBCLKCTRL = SYSCON_SYSAHBCLKCTRL or (1<<7) or (1<<8)

	T3_TCR =	0
	
	IOCON_PIO0_21 = IOCON_PIO0_21 or &H00000401				'  P0.21  MAT function and open drain

	T3_MR0 = cycleTime / 2
	T3_EMR = ((EMC_CLR<<EMC0) or 1)		' clear MAT0 on match
	T3_PWMC = &H09						' PWM mode on 0, 3
	T3_PR =	prescale
	T3_TC =	0
'	T3_MCR = 1<<10 		'Reset on MR3
	T3_MCR = 3<<9 		'Interrupt and Reset on MR3
	T3_MR3 = cycleTime
	T3_TCR =	1		' Enable counter and PWM
	
	T3_IR = 8			' clear any interrupt
	PWM_count = 0
	PWM_toggle = 0

	TIMER3_ISR   = ADDRESSOF ( TIMER3IRQ ) + 1      'set function of VIC   -- need the +1 for Thumb operation
	VICIntEnable OR= (1<<TIMER3_IRQn)  				'Enable interrupt

end sub

		
#define MINUT_PCLK	60000000			' 60 seconds at 1 MHz	

'	the crystal is about 50 ppm accurate -- which is about 2 minutes / month
'	about once a day I will check the time and adjust this value +/- 100 and save in Flash
	
	
#define SCAN_TIME	1000			' in microseconds - 5000 visible flicker, and 2000 maybe visible

#ifdef TIME_LORD				' this has been included by the main program == otherwise make it standalone
sub init_scan()
#else
main:
#endif
	setupPWM(SCAN_TIME,MAX_BRIGHT)					' near full bright for now

#ifdef TIME_LORD
	hr = OFFLINE
	min = 25
	ON_TIMER(MINUT_PCLK , ADDRESSOF TIMER1IRQ)		
end sub
#else
	hr = 10
	min = 25
	ON_TIMER(MINUT_PCLK / 300, ADDRESSOF TIMER1IRQ)		' testing for now
' now that everything is interrupt drive need to keep running
	
	while 1
		for lo = 90 to 990 step 100
			T3_MR0 = lo
'			print lo
			wait (2000)
		next
	loop
#endif		
And WifiLogin.bas

Code: Select all

const SSID1="talk2bruce"
const SSID2="talk2bruce_too"
const PASSWORD1="password"
const PASSWORD2="12345678"		' and if you use this you are nuts

TodWulff
Posts: 70
Joined: Fri Oct 19, 2012 4:03 am
Location: The Mitten State - Shores of Lake Huron

Re: web based clock

Post by TodWulff »

basicchip wrote:
Sat Dec 29, 2018 3:55 am
... had to capture that from FB
LOL!

basicchip
Posts: 1090
Joined: Fri Oct 19, 2012 2:39 am
Location: Weeki Watchee, FL
Contact:

Re: web based clock

Post by basicchip »

Still using an older nodemcu, have not had success with the cloud built versions, and no time to figure out why.

So here is the flash application and firmware I am using--

https://www.coridium.us/files/esp_flash_nodemcu.zip

TodWulff
Posts: 70
Joined: Fri Oct 19, 2012 4:03 am
Location: The Mitten State - Shores of Lake Huron

Re: web based clock

Post by TodWulff »

basicchip wrote:
Mon Dec 31, 2018 4:23 pm
... downloaded so many things, not sure where it came from, but I will put a copy up at the website (KISS !)
LOL! I am right there with you. Have about 10-12 different packages downloaded. :lol:

olzeke51
Posts: 414
Joined: Sat May 17, 2014 4:22 pm
Location: South Carolina

Re: web based clock

Post by olzeke51 »

Hello Basicchip,
Clock still 'ticking' away??
'
Is the '824 firmware available , that you used in the clock?
I realize it is not an official product. I kindof miss the old store option of 'Misc" for purchases, etc.
I am playing around with the 800-DIP..no real issues ... but curious
Thnx,
Olzeke

PS - delete this if inappropriate - Gary

Post Reply