Exemplo n.º 1
0
def test_requests_http_example():
  r = requests.get('http://www.example.com')

  if (r[0] != 200):
    lcd.print('error found during fetching www.example.com with requests lib\n')
  else:
    lcd.print('test request to www.example.com done\n')
Exemplo n.º 2
0
def webserver_start():
    global scanlist
    from microWebSrv import MicroWebSrv

    lcd.clear()
    lcd.setCursor(0, 0)
    ssid_name = "M5Stack-" + node_id[-4:]
    wlan_ap.active(True)
    wlan_ap.config(essid=ssid_name, authmode=network.AUTH_OPEN)
    addr = socket.getaddrinfo('0.0.0.0', 80)[0][-1]
    print('WiFi AP WebServer Start!')
    print('Connect to Wifi SSID:' + ssid_name)
    print('And connect to esp via your web browser (like 192.168.4.1)')
    print('listening on', addr)
    lcd.image(0, 0, '/flash/img/1-1.jpg', type=lcd.JPG)
    lcd.font(lcd.FONT_DejaVu24)
    lcd.setTextColor(lcd.BLACK, lcd.WHITE)
    lcd.print('Wi-Fi SSID', 150, 145, lcd.BLACK)
    lcd.print(ssid_name, 125, 170, lcd.RED)
    webserver = MicroWebSrv(routeHandlers=routeHandlers)
    scanlist = wlan_sta.scan()
    if not wlan_sta.active():
        wlan_sta.active(True)
    while True:
        if len(wlan_ap.status('stations')) > 0:
            break
        time.sleep_ms(200)
    lcd.image(0, 0, '/flash/img/1-2.jpg', type=lcd.JPG)
    webserver.Start(threaded=False)
Exemplo n.º 3
0
    def show(self):
        super().show()
        lcd.print('Setup light from/to', lcd.CENTER, 85)

        self._lightSchedule = [
            kippenstalConfig.getLight1From().split(':')[0],
            kippenstalConfig.getLight1From().split(':')[1],
            kippenstalConfig.getLight1To().split(':')[0],
            kippenstalConfig.getLight1To().split(':')[1],
            kippenstalConfig.getLight2From().split(':')[0],
            kippenstalConfig.getLight2From().split(':')[1],
            kippenstalConfig.getLight2To().split(':')[0],
            kippenstalConfig.getLight2To().split(':')[1],
        ]

        self._lightEditors = [
            NumberEditor(0, self._lightSchedule[0], 0, 23, '{:02d}'),
            NumberEditor(1, self._lightSchedule[1], 0, 59, '{:02d}'),
            NumberEditor(2, self._lightSchedule[2], 0, 23, '{:02d}'),
            NumberEditor(3, self._lightSchedule[3], 0, 59, '{:02d}'),
            NumberEditor(4, self._lightSchedule[4], 0, 23, '{:02d}'),
            NumberEditor(5, self._lightSchedule[5], 0, 59, '{:02d}'),
            NumberEditor(6, self._lightSchedule[6], 0, 23, '{:02d}'),
            NumberEditor(7, self._lightSchedule[7], 0, 59, '{:02d}')
        ]

        lcd.setCursor(0, 125)
        self._print('Light 1:  ', self._lightEditors[0], self._lightEditors[1],
                    self._lightEditors[2], self._lightEditors[3])
        lcd.setCursor(0, 155)
        self._print('Light 2:  ', self._lightEditors[4], self._lightEditors[5],
                    self._lightEditors[6], self._lightEditors[7])

        self._lightEditors[0].startEditing(self)
Exemplo n.º 4
0
def main_loop():
    while True:
        try:
            # Ensure network is connected.
            # https://github.com/espressif/arduino-esp32/issues/653
            connect_wifi()

            now = time.time()
            dateStart = now - GRAPH_DURATION
            resp = requests.get(DATA_SOURCE + "?count=" +
                                str(GRAPH_MAX_POINTS) + "&find[date][$gte]=" +
                                str(dateStart)).json()

            current = resp[0]
            bg_color = get_bg_color(current["sgv"], current["date"])
            lcd.clear(bg_color)

            lcd.font("UbuntuMono-B40.fon")
            lcd.setTextColor(color=BLACK, bcolor=bg_color)
            lcd.print(
                text_transform_bg(current["sgv"]) + " " +
                text_transform_direction(current["direction"]), lcd.CENTER, 20)

            draw_graph(resp, dateStart, now)
            print("Response is", resp[0]["sgv"])

        except RuntimeError as e:
            print("Some error occured, retrying! -", e)
        time.sleep(180)
Exemplo n.º 5
0
    def __init__(self,
                 client_id,
                 server,
                 port,
                 user=None,
                 password=None,
                 keepalive=300):
        if m5base.get_start() != 1:
            autoConnect(lcdShow=True)
            lcd.clear()
        else:
            raise ImportError('mqtt need download...')

        if user == '':
            user = None

        if password == '':
            password = None

        self.mqtt = MQTTClient(client_id, server, port, user, password,
                               keepalive)
        self.mqtt.set_callback(self._on_data)
        try:
            self.mqtt.connect()
        except:
            lcd.clear()
            lcd.font(lcd.FONT_DejaVu24)
            lcd.setTextColor(lcd.RED)
            lcd.print('connect fail', lcd.CENTER, 100)
        self.topic_callback = {}
        self.mqttState = True
        self.ping_out_time = time.ticks_ms() + 60000
Exemplo n.º 6
0
def enrolCb():
	global IGNORE_FINGER
	IGNORE_FINGER = True
	clrscrn()
	lcd.setTextColor(lcd.RED)
	lcd.print("Counting\nRegistered\nUsers")
	finger.uart.read()
	finger.uart.write(b'\xf5\t\x00\x00\x00\x00\t\xf5')
	sleep_ms(50)
	pkt = finger.uart.read(8)
	while len(pkt) != 8: pkt = finger.uart.read(8) 
	print(pkt)
	if pkt[0] != 0xf5 or pkt[1] != 0x09:
		clrscrn()
		tone(TONE_DENY)
		lcd.print("TRY AGAIN\n:(")
		sleep_ms(1000)
		mainScrn()
	usrid = pkt[3]
	clrscrn()
	lcd.setTextColor(lcd.GREEN)
	lcd.print("Enrol #"+str(usrid)+"\n")
	lcd.setTextColor(lcd.WHITE)
	lcd.print("Place Finger\non Sensor")
	finger.addUser(usrid+1, 1)
	while not finger.state.startswith("Add user success"):
		print(finger.state)
		sleep_ms(200)
	clrscrn()
	lcd.setTextColor(lcd.GREEN)
	lcd.print("Enrol Finger\n\nSUCCESS")
	IGNORE_FINGER = False
	sleep_ms(500)
	mainScrn()
Exemplo n.º 7
0
 def _print(self, cursor, editor1, editor2, editor3, separator):
     lcd.setCursor(cursor[0], cursor[1])
     editor1.printToLcd()
     lcd.print(separator)
     editor2.printToLcd()
     lcd.print(separator)
     editor3.printToLcd()
Exemplo n.º 8
0
def printResult():
    lcd.clear()
    lcd.print('Date: ' + timestamp[0], 10, 10)
    lcd.print('Blue = Destination, Red = North', 10, 20)
    # lcd.print(
    #     'Location: ' + str(current_coord[0]) + ', ' + str(current_coord[1]), 10,
    #     30)
    # lcd.print("Azimuth Arg: {}".format(azimuth_arg), 10, 50)
    # lcd.print("Azimuth: {}".format(azimuth), 10, 70)

    rad = calcTargetRadian(current_coord, target_coords)
    # lcd.print("Rad: {}".format(rad), 10, 90)
    # lcd.print("Target Rad: {}".format(str((rad + azimuth) % 360)), 10, 110)
    lcd.lineByAngle(161, 119, 0, 120, round(azimuth), lcd.RED)
    lcd.lineByAngle(160, 120, 0, 120, round(azimuth), lcd.RED)
    lcd.lineByAngle(161, 121, 0, 120, round(azimuth), lcd.RED)

    lcd.lineByAngle(161, 119, 0, 120, round(rad + azimuth) % 360, lcd.BLUE)
    lcd.lineByAngle(160, 120, 0, 120, round(rad + azimuth) % 360, lcd.BLUE)
    lcd.lineByAngle(161, 121, 0, 120, round(rad + azimuth) % 360, lcd.BLUE)

    print('Date: ' + timestamp[0])
    print('Location: ' + str(current_coord[0]) + ', ' + str(current_coord[1]))
    print("Azimuth Arg: {}".format(azimuth_arg))
    print("Azimuth: {}".format(azimuth))
    print("Rad: {}".format(rad))
    print("Target Rad: {}".format(str((rad + azimuth) % 360)))
Exemplo n.º 9
0
 def _showText(self, timercallbackvar=None):
     text = self.text
     if len(text) > self.limit:
         chunk = text[self._iterator:self._iterator + self.limit]
         if self._delayState < self.delay:
             self._delayState += 1
         else:
             self._iterator += self._itdir
         if self.sliding:
             if self._itdir == 1 and self._iterator >= (len(text) - self.limit):
                 self._itdir *= -1
                 self._delayState = 0
             if self._itdir == -1 and self._iterator == 0:
                 self._itdir *= -1
                 self._delayState = 0
         else:
             txtlen = len(text)
             if self._iterator >= txtlen - self.limit and self._iterator <= txtlen:
                 lcd.fillRect(self.x + len(chunk) * 4, self.y, 180, self.y + 15, 0)
             if self._iterator > txtlen and self._iterator < self.limit + txtlen:
                 offset = self.limit + txtlen - self._iterator 
                 chunk = ' ' * offset + text[:self._iterator - txtlen]
             if self._iterator >= self.limit + txtlen:
                 self._iterator = 0
         lcd.print(chunk, self.x, self.y, self.color)
     else:
         lcd.print(text, self.x, self.y, self.color)
Exemplo n.º 10
0
def GPSwatch():
    n = 0
    tm_last = 0
    satellites = dict()
    satellites_used = dict()
    while True:
        utime.sleep_ms(100)
        len = gps_s.any()
        if len>0:
            b = gps_s.read(len)
            for x in b:
                if 10 <= x <= 126:
                    stat = gps.update(chr(x))
                    if stat:
                        tm = gps.timestamp
                        tm_now = (tm[0] * 3600) + (tm[1] * 60) + int(tm[2])
                        if (tm_now - tm_last) >= 10:
                            n += 1
                            tm_last = tm_now
                            print("{} {}:{}:{}".format(gps.date_string(), tm[0], tm[1], int(tm[2])))
                            str = '%.10f %c, %.10f %c' % (gps.latitude[0], gps.latitude[1], gps.longitude[0], gps.longitude[1])
                            print(str)
                            lcd.clear()
                            lcd.print(str, 10, 0)
                            if gps.satellite_data_updated():
                                putSatellites(satellites, gps.satellite_data, tm_now)
                            putSatellitesUsed(satellites_used, gps.satellites_used, tm_now)
                            drawGrid()
                            drawSatellites(satellites, satellites_used)
                            if (n % 10) == 0:
                                print("Mem free:", gc.mem_free())
                                gc.collect()
Exemplo n.º 11
0
def disconnect(offline=OFFLINE_MODE):
    lcd.print("Disconnecting...", 10, 10, lcd.RED)
    if offline:
        return
    if not wifisetup.isconnected():
        wlan = network.WLAN(network.STA_IF)  # create station interface
        wlan.active(False)                   # activate the interface
    lcd.print("done")
Exemplo n.º 12
0
def reconnect(offline=OFFLINE_MODE):
    lcd.print("Reconnecting...", 10, 10, lcd.RED)
    if offline:
        return
    if not wifisetup.isconnected():
        wifisetup.auto_connect()
        sync_rtc()
    lcd.print("done")
Exemplo n.º 13
0
def fingerOKCb(user_id, access):
	global IGNORE_FINGER
	if IGNORE_FINGER: return
	GAME_RUNNING = False
	clrscrn()
	lcd.print("Welcome\nUser #"+str(user_id))
	tone(TONE_DELIGHT)
	sleep_ms(1000)
	mainScrn()
Exemplo n.º 14
0
    def show(self):
        super().show()
        lcd.print('Setup date & time', lcd.CENTER, 85)

        self._initDateTimeEditors()
        self._print((75, 125), self._dateTimeEditors[0], self._dateTimeEditors[1], self._dateTimeEditors[2], '-')
        self._print((95, 165), self._dateTimeEditors[3], self._dateTimeEditors[4], self._dateTimeEditors[5], ':')

        self._dateTimeEditors[0].startEditing(self)
Exemplo n.º 15
0
def drawGrid():
    for x in range(40, 121, 40):
        lcd.circle(160, 120, x, lcd.DARKGREY)
    for x in range(0, 360, 45):
        lcd.lineByAngle(160, 120, 0, 120, x, lcd.DARKGREY)
    for x in (('N', 165, 10), ('E', 295, 115), ('S', 165, 220), ('W', 15, 115)):
        lcd.print(x[0], x[1], x[2])
    for x in (('90', 155, 108), ('60', 195, 108), ('30', 235, 108), ('0', 275, 108)):
        lcd.print(x[0], x[1], x[2])
    def show(self):
        super().show()
        lcd.print('Setup light threshold', lcd.CENTER, 85)

        self._numberEditor = NumberEditor(1, kippenstalConfig.getLightThreshold(), 0, 2000, '{:04d}')
        self._numberEditor.printToLcdCenter(125)
        self._numberEditor.startEditing(self)

        lcd.print('Now: {}'.format(kippenstal.currentLightSensorValue), lcd.CENTER, 165)
Exemplo n.º 17
0
def _tryingmine(httpClient, httpResponse,routeArgs):
    lcd.clear(0x000000)
    lcd.font('hp.fon')
    lcd.setCursor(0,0)
    lcd.print(routeArgs['message'])
    httpResponse.WriteResponseOk( headers         = None,
                                 contentType     = "text/html",
                                 contentCharset = "UTF-8",
                                 content          = "OK" )
Exemplo n.º 18
0
    def show(self):
        super().show()
        lcd.print('Door Schedule On/Off', lcd.CENTER, 85)

        lcd.setCursor(160, 125)
        value = 'On' if kippenstalConfig.isDoorOpenerScheduleEnabled(
        ) else 'Off'
        self._stringSelector = StringSelector(value, ['On', 'Off'])
        self._stringSelector.printToLcd()
        self._stringSelector.startEditing(self)
Exemplo n.º 19
0
def connect_wifi(shouldPrint=False):
    sta_if = network.WLAN(network.STA_IF)
    print('connecting to network...')
    if shouldPrint:
        lcd.print("Connecting to " + secrets['ssid'] + "\n")
    sta_if.active(True)
    sta_if.connect(secrets['ssid'], secrets['password'])
    while not sta_if.isconnected():
        pass

    return sta_if
Exemplo n.º 20
0
    def show(self):
        ScreenManager.isShown(self)
        self._isShown = True

        lcd.clear(lcd.WHITE)
        lcd.setColor(lcd.BLACK)
        lcd.font(lcd.FONT_Tooney, transparent=True)
        lcd.print('speckbosch', lcd.CENTER, 10)
        lcd.font(lcd.FONT_DejaVu24, transparent=True)
        lcd.print('Chicken Shed Mgr {}'.format(self._getVersion()), lcd.CENTER,
                  45)
Exemplo n.º 21
0
def connect():
    station = network.WLAN(network.STA_IF)
    station.active(True)
    station.connect("nstudents", "nnnedjpwireless")
    while station.isconnected() == False:
        lcd.print(".")
        time.sleep(0.5)
        pass
    lcd.print("\n")
    lcd.println("connected")
    lcd.println(str(station.ifconfig()))
Exemplo n.º 22
0
def drawSatellites(sats, sats_used):
    for k, v in sats.items():
        print(k, v[0])
        if v[0][0] != None and v[0][1] != None:
            l = int((90 - v[0][0]) / 90.0 * 120.0)
            lcd.lineByAngle(160, 120, 0, l, v[0][1])
            x = 160 + sin(radians(v[0][1])) * l
            y = 120 - cos(radians(v[0][1])) * l
            color = lcd.GREEN if k in sats_used else lcd.RED
            lcd.circle(int(x), int(y), 4, color, color)
            lcd.print(str(k), int(x) + 9, int(y) - 7)
Exemplo n.º 23
0
    def _draw_once(self):
        '''最初に一度だけ描画する処理'''
        # 枠を表示 (デバッグ用)
        #lcd.rect(0, 0, self.width + 1, self.height + 1, lcd.BLACK)

        # 温度計の液溜め部分(正式には「球部」)の円を描画
        lcd.circle(self.circle_x, self.circle_y, self.circle_radius,
                   self.color, self.color)

        # 目盛りの間隔 (摂氏度)
        tick = 10

        # 目盛りとグラフの隙間のピクセル数
        m = 2

        # 目盛りの長さ (ピクセル)
        l = 8

        # 目盛りと軸の数字の隙間のピクセル数
        m2 = 4

        # フォントの設定
        lcd.font(lcd.FONT_Default, color=self.axis_color, transparent=True)

        # TODO: ラベルを描画
        label_x = self.bar_x - m - l - m2 - lcd.textWidth(self.label)
        label_y = self.y
        lcd.text(label_x, label_y, self.label)

        # フォントの設定
        lcd.font(lcd.FONT_Default, color=self.axis_color, transparent=True)

        # フォントサイズ
        font_width, font_height = lcd.fontSize()
        half_font_height = int(round(font_height / 2))

        min_ylabel = int(math.ceil(self.min_value / 10)) * 10
        for i in range(min_ylabel, self.max_value + 1, tick):
            y1 = self._calc_y(i)

            # 目盛り (左)
            lcd.line(self.bar_x - m - l, y1, self.bar_x - m, y1,
                     self.axis_color)

            # 目盛り (右)
            lcd.line(self.bar_x + self.bar_width + m, y1,
                     self.bar_x + self.bar_width + m + l, y1, self.axis_color)

            # 目盛りラベル
            tick_label = '{}'.format(i)
            lcd.print(tick_label,
                      self.bar_x - m - l - m2 - lcd.textWidth(tick_label),
                      y1 - half_font_height, self.axis_color)
Exemplo n.º 24
0
def main():
    start_wifi()
    print('started wifi and tools')
    # move to lowest line on M5STACK display
    lcd.setCursor(0, 227)
    lcd.setColor(lcd.WHITE)
    lcd.print("RTC Clock 1")
    
    # initiate rtc
    print("Synchronize time from NTP server with TZ=US Central ...")
    rtc.ntp_sync(server="hr.pool.ntp.org", tz="CST6CDT5,M4.1.0/2,M10.5.0/2")  #https://prom-electric.ru/media/uclibc-zoneinfo-list.txt
    _thread.start_new_thread ("clock",watch, ())
Exemplo n.º 25
0
def watch():
    while True:
        # start position for Date
        if not rtc.synced():                                                            # set color to sync status    
            lcd.setColor(lcd.RED)
        else: 
            lcd.setColor(lcd.GREEN)
#       lcd.setCursor(92, 227)                                                          # uncomment if you need date on display
#       lcd.print("Date {}".format(utime.strftime("%Y-%m-%d", utime.localtime())))      # uncomment if needed
        # start position for time only
        lcd.setCursor(213, 227)                                                         # uncomment if date active (see upper lines)
        lcd.print(" Time {}".format(utime.strftime('%H:%M:%S', utime.localtime())))
        utime.sleep(1)
Exemplo n.º 26
0
def temp():
    adc = machine.ADC(PIN)  # ADコンバータのインスタンスを生成
    lcd.font(font)  # フォントを指定
    lcd.clear()  # 画面をクリア

    while True:
        t = 0
        for i in range(MULTISAMPLES):
            t = t + adc.read() / 10  # ADコンバータを読み、温度に変換
        t = t / MULTISAMPLES
        lcd.print('\r', X0, Y0)  # 表示位置以降をクリア
        lcd.print("%4.1f" % t, X0, Y0)  # 温度を表示
        time.sleep(5)
Exemplo n.º 27
0
    def __init__(self, x, y, w, h, tick_s, tick_e, color, title, value_format):
        self.x = x  # メーターの表示位置
        self.y = y  # メーターの表示位置
        self.w = w  # メーターの表示幅
        self.h = h  # メーターの表示高
        self.tick_s = tick_s  # 目盛の最小値
        self.tick_e = tick_e  # 目盛の最大値
        self.title = title
        self.value_format = value_format  # 値をテキスト表示する際のフォーマット

        self.center_x = x + w // 2  # 針の原点
        self.center_y = y + int(h * 0.9)  # 針の原点
        self.prev_value = tick_s
        self.prev_angle = None

        lcd.roundrect(x, y, w, h, h // 10, lcd.BLACK, lcd.WHITE)
        lcd.arc(self.center_x, self.center_y, int(h * 0.67), int(h * 0.07),
                -50, 50, color, color)
        lcd.arc(self.center_x, self.center_y, int(h * 0.6), 2, -50, 50,
                lcd.BLACK)

        # 目盛の値表示用フォント設定
        if self.w == win_w:
            lcd.font(lcd.FONT_Default, transparent=False)
        else:
            lcd.font(lcd.FONT_DefaultSmall, transparent=True)

        fw, fh = lcd.fontSize()

        tick = tick_s
        tick_i = (tick_e - tick_s) // 4
        for r in range(-50, 51, 5):
            if r % 25 == 0:
                # 目盛の最小値から最大値を4分割して目盛値を表示
                lcd.lineByAngle(self.center_x - 1, self.center_y, int(h * 0.6),
                                int(h * 0.1), r, lcd.BLACK)
                lcd.lineByAngle(self.center_x, self.center_y, int(h * 0.6),
                                int(h * 0.1), r, lcd.BLACK)
                tick_text = str(tick)
                text_width = lcd.textWidth(tick_text)
                lcd.print(
                    tick_text, self.center_x +
                    int(math.sin(math.radians(r)) * h * 0.7) - text_width // 2,
                    self.center_y - int(math.cos(math.radians(r)) * h * 0.7) -
                    fh, lcd.BLACK)
                tick += tick_i
            else:
                # 細かい目盛線を表示
                lcd.lineByAngle(self.center_x, self.center_y, int(h * 0.6),
                                int(h * 0.05), r, lcd.BLACK)
Exemplo n.º 28
0
def fingerDENYCb():
	global IGNORE_FINGER
	if IGNORE_FINGER: return
	GAME_RUNNING = False
	clrscrn()
	lcd.print("Unknown  :(\nFinger")
	tone(TONE_DENY)
	sleep_ms(1000)
	clrscrn()
	lcd.setTextColor(lcd.MAGENTA)
	lcd.print("Hold button\nto skip\nthe game")
	sleep_ms(2000)
	if buttonA.isPressed(): mainScrn()
	else: game_start()
Exemplo n.º 29
0
 def update_clock(self):
     if self._isShown:
         if self._isSleeping:
             return
         elif self._lastInteraction + 120 < utime.time():
             self._sleep()
         else:
             lcd.textClear(90, 85, '                       ', lcd.WHITE)
             lcd.setCursor(105, 85)
             lcd.print("{}".format(
                 utime.strftime('%H:%M:%S', utime.localtime())))
             lcd.textClear(90, 115, '                       ', lcd.WHITE)
             lcd.setCursor(112, 115)
             lcd.print("{} C".format(kippenstal.getTemperature()))
Exemplo n.º 30
0
def minmax():
  global offset
  global rate
  reg = register
  min_temp = 1000
  max_temp = -1000
  for i in range(0, 64):
    val = ustruct.unpack('<h', i2c.readfrom_mem(i2c_address, reg, 2))[0]
    tmp = getval(val)
    if tmp < min_temp:
      min_temp = tmp
    if max_temp < tmp:
      max_temp = tmp
    reg += 2

  diff = max_temp - min_temp
  # add some margin
  diff *= 1.4
  rate = len(colors) / diff
  offset = min_temp * 0.8

  lcd.clear()
  lcd.print('min:    ' + '{:.2f}'.format(min_temp), 0, 0)
  lcd.print('max:    ' + '{:.2f}'.format(max_temp), 0, 10)
  lcd.print('rate:   ' + '{:.2f}'.format(rate), 0, 20)
  lcd.print('offset: ' + '{:.2f}'.format(offset), 0, 30)
Exemplo n.º 31
0
def minmax():
    global offset
    global rate
    reg = register
    min_temp = 1000
    max_temp = -1000
    for i in range(0, 64):
        val = ustruct.unpack('<h', i2c.readfrom_mem(i2c_address, reg, 2))[0]
        tmp = getval(val)
        if tmp < min_temp:
            min_temp = tmp
        if max_temp < tmp:
            max_temp = tmp
        reg += 2

    diff = max_temp - min_temp
    # add some margin
    diff *= 1.4
    rate = len(colors) / diff
    offset = min_temp * 0.8

    lcd.clear()
    lcd.print('min:    ' + '{:.2f}'.format(min_temp), 0, 0)
    lcd.print('max:    ' + '{:.2f}'.format(max_temp), 0, 10)
    lcd.print('rate:   ' + '{:.2f}'.format(rate), 0, 20)
    lcd.print('offset: ' + '{:.2f}'.format(offset), 0, 30)