import machine
import utime
import time
import math
import tm1637
from machine import Pin, SoftI2C
import ds1307
#################
# Pin Assignments
#################
# -> Thermoresistor Pin
thermistor = machine.ADC(28)
# -> RGB Led Pins
red = machine.PWM(machine.Pin(15))
green = machine.PWM(machine.Pin(14))
blue = machine.PWM(machine.Pin(13))
# -> TM1637 Pins
tm = tm1637.TM1637(clk=machine.Pin(21), dio=machine.Pin(20))
# -> DS1307(Real Time Clock) Pins
rtc_sda = machine.Pin(19, machine.Pin.IN)
rtc_scl = machine.Pin(18, machine.Pin.IN)
# uses SoftI2C class and pins for Raspberry Pi pico
i2c0 = SoftI2C(scl=rtc_scl, sda=rtc_sda, freq=100000)
# rtc - Real Time Clock
ds1307rtc = ds1307.DS1307(i2c0, 0x68)
# -> buttons Pin
modeBtn = machine.Pin(12, machine.Pin.IN, machine.Pin.PULL_UP)
normalmodeBtn = machine.Pin(11, machine.Pin.IN, machine.Pin.PULL_UP)
maxmodeBtn = machine.Pin(9, machine.Pin.IN, machine.Pin.PULL_UP)
minmodeBtn = machine.Pin(10, machine.Pin.IN, machine.Pin.PULL_UP)
timemodeBtn = machine.Pin(8, machine.Pin.IN, machine.Pin.PULL_UP)
###########
# Settings
###########
# Button Debounce Settings
debounce_time = 0.05 # 50 ms
# -> Button debouncing time settings
last_press_time = 0
last_normalmode_press_time = 0
last_minmode_press_time = 0
last_maxmode_press_time = 0
last_timemode_press_time = 0
last_timemodecolon_time = 0
# -> Button debouncing pressed settings
modeBtn_isPressed = 0
normalmodeBtn_isPressed = 0
maxmodeBtn_isPressed = 0
minmodeBtn_isPressed = 0
timemodeBtn_isPressed = 0
# Display Settings
# -> Temperature Display Settings
# Farenheit or Celsius variable (0=Far,1=Cel)
displayTempMode = 1
# -> Time Display Settings
# 24 hour or 12 hour (0=24hr,1=12hr)
displayTimeMode = 0
# if true blinks the time colon every 1 second, if false it stays on constantly
displayTimeBlinkColon = True
# used to save current state of colon
displayTimeModeColon = False
# -> Normal Mode variable
# 0 - Live Temperature Reading
# 1 - Maximum Temperature Read
# 2 - Minimum Temperature Read
# 3 - Current Time(24 hour | 12 Hour)
displayNormalMode = 0
# -> Max and min settings
# -> Farenheit Settings
maxFTemp = -1000
minFTemp = 1000
# -> Celsius Settings
maxCTemp = -1000
minCTemp = 1000
# RGB Led Settings
# -> RGB Indicator Map
# [TempF, [Red,Green,Blue]]
tempclrIndicatorMap = [
# Below 32(Min) - White
[32,[255,255,255]],
# Below 50 - Light Blue
[45,[178,247,255]],
# Below 60 - Blue
[55,[0, 0, 255]],
# Below 75 - Yellow
[75,[255, 251, 0]],
# Below 100 - Orange
[100,[255,128,0]],
# Below 1000(Max) - Red
[1000,[255,0,0]]
]
# -> PWM Settings
# PWM(Pulse Width Modulation) Signal Frequency
red.freq(1000)
green.freq(1000)
blue.freq(1000)
# Functions and Methods
# Mapping Function
def interval_mapping(x, in_min, in_max, out_min, out_max):
return (x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min
# Color Value To Duty Mapping Function
def color_to_duty(rgb_value):
rgb_value = int(interval_mapping(rgb_value,0,255,0,65535))
return rgb_value
# Color Setting RGB Led Function
def color_set(red_value,green_value,blue_value):
red.duty_u16(color_to_duty(red_value))
green.duty_u16(color_to_duty(green_value))
blue.duty_u16(color_to_duty(blue_value))
# Formats a string compatible with the TM1637 display
def temp_to4Digit(temp,indicator):
tempstr = "{}".format(temp)
if len(tempstr) == 1:
tempstr = " " + tempstr
elif len(tempstr) == 2:
tempstr = " " + tempstr
elif len(tempstr) == 3:
tempstr = tempstr
return tempstr + indicator
# Formats a string compatible with the TM1637 display
def time_to4Digit(hrstr,minstr,hrmode):
tmphr = int(hrstr)
tmpmin = int(minstr)
if hrmode == False:
if (tmphr > 12):
tmphr = tmphr - 12
elif tmphr == 0:
tmphr = 12
#Display 24hr
tmphrstr = "{}".format(tmphr)
if len(tmphrstr) == 1:
tmphrstr = "0" + tmphrstr
elif len(tmphrstr) == 2:
tmphrstr = tmphrstr
tmpminstr = "{}".format(tmpmin)
if len(tmpminstr) == 1:
tmpminstr = "0" + tmpminstr
elif len(tmpminstr) == 2:
tmpminstr = tmpminstr
return tmphrstr + tmpminstr
# Loops thru a indicator map of temps and RGB arrays and determines
# what temp indicator should be used
def rgbcolorfromtemp(temp):
indicatormaplen = len(tempclrIndicatorMap)
uboundindex = (indicatormaplen - 1)
lboundindex = 0
for xindex in range(0, indicatormaplen):
clrindicator = tempclrIndicatorMap[xindex]
tempindicator = int(clrindicator[0])
rgbindicator = clrindicator[1]
if temp < tempindicator or xindex >= uboundindex:
color_set(rgbindicator[0],rgbindicator[1],rgbindicator[2])
break;
print ("----------------------------------")
print ("- Temperature and RTC Clock Test -")
print ("----------------------------------")
print ("Adjust the realtime temperature with the ntc temperature sensor")
print ("-> RGB Led will change color depending how hot or cold temperature is")
print ("Display time mode by pressing time button")
print ("Toggle between 24hr/12hr time mode by pressing time button again")
print ("Toggle between Celsius/Farenheight display mode by pressiung C/F button")
print ("Display real time temperature live mode by pressing live button")
print ("Display maximum detected temperature mode by pressing max button")
print ("Display minimum detected temperature mode by pressing min button")
#############
# System Loop
#############
while True:
# Read Temperature Value
temperature_value = thermistor.read_u16()
time.sleep(0.02)
# Math the Value
Vr = 3.3 * float(temperature_value) / 65535
Rt = 10000 * Vr / (3.3 - Vr)
temp = 1/(((math.log(Rt / 10000)) / 3950) + (1 / (273.15+25)))
# Convert To Celsius And Farenheight
# Celsius
Cel = temp - 273.15
# Celsius Min and Max
if int(Cel) >= int(maxCTemp):
maxCTemp = Cel
if int(Cel) <= int(minCTemp):
minCTemp = Cel
# Farenheight
Fah = Cel * 1.8 + 32
# Farenheit Min and Max
if int(Fah) >= int(maxFTemp):
maxFTemp = Fah
if int(Fah) <= int(minFTemp):
minFTemp = Fah
# print ('Celsius: %.2f C Fahrenheit: %.2f F' % (Cel, Fah))
# print ('Min: (%.2f C | %.2f F) Max: (%.2f C | %.2f F)' % (minCTemp, minFTemp,maxCTemp,maxFTemp))
# Modes
# 0 - Real Time Temp Mode
# 1 - Max Temp Mode
# 2 - Min Temp Mode
# 3 - Time Mode
#print('display logic')
if displayNormalMode == 0:
# Temp Display Mode
# Select temp display from variable and update on the display
if displayTempMode == 0:
tmStr = temp_to4Digit(int(Fah), "f")
else:
tmStr = temp_to4Digit(int(Cel), "c")
tm.show(tmStr)
time.sleep(0.02)
elif displayNormalMode == 1:
# Max Display Mode
if displayTempMode == 0:
tmStr = temp_to4Digit(int(maxFTemp), "f")
else:
tmStr = temp_to4Digit(int(maxCTemp), "c")
tm.show(tmStr)
time.sleep(0.02)
elif displayNormalMode == 2:
# Min Display Mode
if displayTempMode == 0:
tmStr = temp_to4Digit(int(minFTemp), "f")
else:
tmStr = temp_to4Digit(int(minCTemp), "c")
tm.show(tmStr)
time.sleep(0.02)
elif displayNormalMode == 3:
# Time Mode
current_rtc_time = ds1307rtc.datetime
timeHour = current_rtc_time[3]
timeMin = current_rtc_time[4]
timeSec = current_rtc_time[5]
is24hr = True
if displayTimeMode == 1:
is24hr = False
if displayTimeBlinkColon == True:
# Colon Blink 1 time per second
if timeSec != last_timemodecolon_time:
if displayTimeModeColon == True:
displayTimeModeColon = False
else:
displayTimeModeColon = True
else:
# Colon Stuck On
displayTimeModeColon = True
tm.show(time_to4Digit(timeHour,timeMin,is24hr),displayTimeModeColon)
last_timemodecolon_time = timeSec
time.sleep(0.02)
else:
# Else Default the display mode to normal
displayNormalMode = 0
# Map What Color RGB LED should be from the faherenheit
# temperature reading
#print('rgb change call')
rgbcolorfromtemp(int(Fah))
time.sleep(0.02)
# Buttons
#print('button calls')
# Check temp mode for change
# Debounce check
# Make sure mode btn not already being pressed
# only if the value of the signal is high
current_time = time.ticks_ms()
#print("modeBtn: {}".format(modeBtn.value()))
if modeBtn.value() == 1 and modeBtn_isPressed == 0 and time.ticks_diff(current_time, last_press_time) > debounce_time * 1000:
last_press_time = time.ticks_ms()
modeBtn_isPressed = 1
# Only change main display if its time and change it to live
if displayNormalMode > 2:
displayNormalMode = 0
# Toggle the display mode
if displayTempMode == 0:
displayTempMode = 1
else:
displayTempMode = 0
# Wait until button is released for debouncing handling
while modeBtn.value() == 1 and time.ticks_diff(current_time, last_press_time) > debounce_time * 1000:
#print('mode loop')
time.sleep(debounce_time)
elif modeBtn.value() == 0:
# only change ispressed if the mode button is no longer pressed
modeBtn_isPressed = 0
# Check time mode button for change
# Debounce check
# Make sure mode button not already being pressed
# only if the value of the signal is high
current_time = time.ticks_ms()
#print("timemodeBtn: {}".format(timemodeBtn.value()))
if timemodeBtn.value() == 1 and timemodeBtn_isPressed == 0 and time.ticks_diff(current_time, last_timemode_press_time) > debounce_time * 1000:
last_timemode_press_time = time.ticks_ms()
timemodeBtn_isPressed = 1
# Only change the 24 hour display mode if already in time mode
if displayNormalMode == 3:
# Flip flop from 24hr to 12hr
if displayTimeMode == 0:
displayTimeMode = 1
else:
displayTimeMode = 0
displayNormalMode = 3
# Wait until button is released for debouncing handling
while timemodeBtn.value() == 1 and time.ticks_diff(current_time, last_timemode_press_time) > debounce_time * 1000:
#print('time loop')
time.sleep(debounce_time)
elif timemodeBtn.value() == 0 and timemodeBtn_isPressed == 1:
# only change ispressed if the mode button is no longer pressed
timemodeBtn_isPressed = 0
# Check max mode button for change
# Debounce check
# Make sure mode button not already being pressed
# only if the value of the signal is high
current_time = time.ticks_ms()
#print("maxmodeBtn: {}".format(maxmodeBtn.value()))
if maxmodeBtn.value() == 1 and maxmodeBtn_isPressed == 0 and time.ticks_diff(current_time, last_maxmode_press_time) > debounce_time * 1000:
last_maxmode_press_time = time.ticks_ms()
maxmodeBtn_isPressed = 1
displayNormalMode = 1
# Wait until button is released for debouncing handling
while maxmodeBtn.value() == 1 and time.ticks_diff(current_time, last_maxmode_press_time) > debounce_time * 1000:
#print('max loop')
time.sleep(debounce_time)
elif maxmodeBtn.value() == 0 and maxmodeBtn_isPressed == 1:
# only change ispressed if the mode button is no longer pressed
maxmodeBtn_isPressed = 0
# Check min mode button for change
# Debounce check
# Make sure mode button not already being pressed
# only if the value of the signal is high
current_time = time.ticks_ms()
#print("minmodeBtn: {}".format(minmodeBtn.value()))
if minmodeBtn.value() == 1 and minmodeBtn_isPressed == 0 and time.ticks_diff(current_time, last_minmode_press_time) > debounce_time * 1000:
last_minmode_press_time = time.ticks_ms()
minmodeBtn_isPressed = 1
displayNormalMode = 2
# Wait until button is released for debouncing handling
while minmodeBtn.value() == 1 and time.ticks_diff(current_time, last_minmode_press_time) > debounce_time * 1000:
#print('min loop')
time.sleep(debounce_time)
elif minmodeBtn.value() == 0 and minmodeBtn_isPressed == 1:
# only change ispressed if the mode button is no longer pressed
minmodeBtn_isPressed = 0
# Check normal mode button for change
# Debounce check
# Make sure mode button not already being pressed
# only if the value of the signal is high
current_time = time.ticks_ms()
#print("normalmodeBtn: {}".format(normalmodeBtn.value()))
if normalmodeBtn.value() == 1 and normalmodeBtn_isPressed == 0 and time.ticks_diff(current_time, last_normalmode_press_time) > debounce_time * 1000:
last_normalmode_press_time = time.ticks_ms()
normalmodeBtn_isPressed = 1
displayNormalMode = 0
# Wait until button is released for debouncing handling
while normalmodeBtn.value() == 1 and time.ticks_diff(current_time, last_normalmode_press_time) > debounce_time * 1000:
#print('normal loop')
time.sleep(debounce_time)
elif normalmodeBtn.value() == 0 and normalmodeBtn_isPressed == 1:
# only change ispressed if the mode button is no longer pressed
normalmodeBtn_isPressed = 0
time.sleep(0.02)
C/F
Time
Live
Max
Min