A clock - both analogue and digital - consisting of
- ESP8266-Wemos-D1-Mini,
- TM1637 4digit 7-segment display
- SG90 mini-servo and some cheap peripheral components like
- a LDR
- 18B20 temperature sensor
- 4 NeoPixel LEDs
- mini hour glass (10 minutes)
To add to the confusion, it will not only display the atomic internet time but turn the emptied hourglass, show the temperature and the brightness of the display will respond to the ambient light, while the background of the hourglass is changed in color.
The IP address of the web interface is cut into four parts and displayed at startup.
The circuit should be self-explanatory
... the same now in bright colors on a breadboard:
The very simple webinterface to show only a few features of ANNEX:
The ANNEX-code for this project:
Code: [Local Link Removed for Guests]
' ################## S A N D C L O C K #########################
' 4 digits digital watch + 10 minutes hourglass
VERSION$ = "v3.3e"
' 11/2019 Peter.Neufeld@gmx.de min:ANNEX_1.39b6
' - ESP8266-Module: WEMOS-D1-Mini
' - Display: 4digit 7segment TM1637
' - Servo: analog servo (e.g. SG90)
' - Backlight: 4*NeoPixel-LED
' - Temperatur sensor: DS18B20
' - Light sensor: LDR at analog-input
'GPIO-Mapping for WEMOS- und NodeMCU-boards
D0=16:D1= 5:D2= 4:D3= 0:D4=2
D5=14:D6=12:D7=13:D8=15:D9=3:D10=1
SERVO_PIN = D5 'Servo at GPIO14=D5
TM_DATA = D2 'TM1637 Data at GPIO4=D2
TM_CLOCK = D1 'TM1637 Clock at GPIO5=D1
TM_BRIGHT = 7 'TM1637 brightnes
TURN_TIME = 10 'turn glass each xx minutes
SERVO_LEFT = 180
SERVO_RIGHT = 0
SERVO_POS = 0
BLINK = 0 '255= red colon at TM1637
ADC_DARK = 450 'max ADC-value,while LDR dark
' depends on LDR and Pullup-resistor
LED1_STATUS = 0 'Background-LEDs: 0=automatik mode, 1=manual
STATUS$ = "Mode: AUTOMATIC"
ADC_IN = 0: t$="":TEMP$="":HH=0:MM=0:SS=0 ' working variables
R=0:G=0:B=0
'----Setup sensors and actuators ------------------
SERVO.SETUP 1, SERVO_PIN
TM1637.SETUP TM_DATA, TM_CLOCK
'!!! NeoPixel-data-output at D4=GPIO2 only!!!
NEO.setup 4 '4 cascaded NeoPixel-LEDs
gosub web_page
onHtmlReload web_page
onhtmlchange web_page
gosub TOGGLE_SERVO 'turn sandclock 180deg
gosub SHOW_IP 'show assigned IP-adress
'Start main routines with timer once per second
TIMER0 1000, MAIN_ROUTINE
wait
end
'###############################################################
'SUBROUTINES################################################
'###############################################################
MAIN_ROUTINE:
HH=val(left$(time$,2)) 'double-digit hours
MM=val(word$(time$,2,":")) 'double-digit minutes
SS=val(right$(time$,2)) 'double-digit seconds
gosub LIGHT_SENSOR 'Get strength of the ambient light
if SS > 24 and SS mod 25 < 6 then
gosub SHOW_TEMP 'Show temperature every 25s for 5s
else
gosub SHOW_TIME 'TM1637-refresh (time and :)
endif
gosub BACKGROUND_LEDS
'Turn hourglass every TURN_TIME minutes after full hour
if SS = 0 and MM mod TURN_TIME = 0 then gosub TOGGLE_SERVO
t$=time$
refresh 'refresh webpage
return
'###############################################################
LIGHT_SENSOR:
'Light sensor for adjusting the brightness of the LED display
' bright = low value on the ADC (~ 30)
' dark = high values at the ADC (> 500)
ADC_IN = ADC
if ADC_IN > ADC_DARK then ADC_IN=ADC_DARK
TM_BRIGHT = int(8-(ADC_IN/(ADC_DARK/7)))
return
'###############################################################
SHOW_TEMP:
'Get only two digits from temperature (quick and dirty:-)
TEMP$= right$(" " + word$(TEMPR$(D6,1),1,".")+ " C",4)
'Display temperature on TM1637 display every 25 s
if SS mod 24 = 1 then
TM1637.PRINT " C", TM_BRIGHT, 0
else
TM1637.PRINT TEMP$, TM_BRIGHT, 0
endif
return
'###############################################################
SHOW_TIME:
BLINK = 255 - BLINK 'toggle colon in TM1637
'Show time and toggled colon again
TM1637.PRINT left$(time$,2)+mid$(time$,4,2),TM_BRIGHT,BLINK
return
'###############################################################
TOGGLE_SERVO:
if SERVO_POS = SERVO_LEFT then
for SERVO_POS = SERVO_LEFT to SERVO_RIGHT Step -4
servo 1, SERVO_POS
pause 100
next SERVO_POS
SERVO_POS = SERVO_RIGHT
else
FOR SERVO_POS = SERVO_RIGHT to SERVO_LEFT step 4
servo 1, SERVO_POS
pause 100
NEXT SERVO_POS
SERVO_POS = SERVO_LEFT
endif
return
'###############################################################
BACKGROUND_LEDS:
'Set background LEDs
if R+G+B = 0 then
'take generated RGB values, if sliders not in use
NEO.strip 0,3,SS mod 20,30-(SS mod 30),20-(SS mod 20)
else
'manual adjusted slider or textbox values for R, G, B
NEO.strip 0,3,R,G,B
endif
return
'###############################################################
SHOW_IP:
'shows the 4 parts of the IP address on the TM1637 display
TM1637.PRINT "IP ", 7, 255
pause 2000
for i = 1 to 4
TM1637.PRINT word$(REPLACE$(IP$, " ", "."),i,"."), 7, 0
pause 1500
next i
pause 4000
return
'###############################################################
WEB_PAGE:
cls
a$ = "<center><h2> - S A N D C L O C K - "+ VERSION$ +" - </h2>"
a$ = a$ + "<br>" + textbox$(t$,"cssTB")
a$ = a$ + METER$(SS,0,60,"cssMET")
a$ = a$ + textbox$(TEMP$,"cssTB")+"<br><br>"
a$ = a$ + "<br>R: "+ slider$(R, 0,255)+ textbox$(R,"cssTB")
a$ = a$ + "<br>G: "+ slider$(G, 0,255)+ textbox$(G,"cssTB")
a$ = a$ + "<br>B: "+ slider$(B, 0,255)+ textbox$(B,"cssTB")
a$ = a$ + "<br>"+ LED$(LED1_STATUS)
a$ = a$ + "<br>"+ textbox$(STATUS$)
a$ = a$ + "<br>"+ BUTTON$("automatic / manual",MAN_AUTO,"cssBT")
' simple adaptation of the appearance
a$ = a$ + cssid$("cssTB"," width:70px;text-align:center")
a$ = a$ + cssid$("cssMET"," transform:rotate(-90deg);")
a$ = a$ + cssid$("cssBT","font-size:1.8em;border-radius:1.4em;")
html a$
a$ = ""
return
'################################################################
MAN_AUTO:
'Called from the MANUAL / AUTO button from the web interface
'Switches the backlight mode.
LED1_STATUS= 1 - LED1_STATUS 'Switch Webpage LED1 red / green
IF LED1_STATUS = 0 then
R=0: G=0: B=0
STATUS$="Mode: AUTOMATIC"
else
R=20: G=100: B=20
STATUS$="Mode: MANUAL "
endif
refresh
return
I'm not very proud of this setup - but it's just the back and it works