From 60c78175a3af54d491292726ca47980c34a0fe30 Mon Sep 17 00:00:00 2001 From: Andrew de Quincey Date: Wed, 26 May 2021 00:49:55 +0100 Subject: [PATCH] add beeper to display --- config.py | 19 +++++++++++-------- kiln-display.py | 46 +++++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 56 insertions(+), 9 deletions(-) diff --git a/config.py b/config.py index 10d3a24..7848323 100644 --- a/config.py +++ b/config.py @@ -49,6 +49,9 @@ gpio_sensor_di = 10 # only used with max31856 ### value is used. sensor_time_wait = 2 +# GPIO to use for the beeper +gpio_beeper = 12 + ######################################################################## # @@ -57,7 +60,7 @@ sensor_time_wait = 2 # These parameters work well with the simulated oven. You must tune them # to work well with your specific kiln. Note that the integral pid_ki is # inverted so that a smaller number means more integral action. -pid_kp = 25 # Proportional +pid_kp = 25 # Proportional pid_ki = 200 # Integral pid_kd = 200 # Derivative @@ -66,11 +69,11 @@ pid_kd = 200 # Derivative # # Initial heating and Integral Windup # -# During initial heating, if the temperature is constantly under the +# During initial heating, if the temperature is constantly under the # setpoint,large amounts of Integral can accumulate. This accumulation # causes the kiln to run above the setpoint for potentially a long # period of time. These settings allow integral accumulation only when -# the temperature is within stop_integral_windup_margin percent below +# the temperature is within stop_integral_windup_margin percent below # or above the setpoint. This applies only to the integral. stop_integral_windup = True stop_integral_windup_margin = 10 @@ -96,20 +99,20 @@ sim_R_ho_air = 0.05 # K/W " with internal air circulation # If you change the temp_scale, all settings in this file are assumed to # be in that scale. -temp_scale = "f" # c = Celsius | f = Fahrenheit - Unit to display +temp_scale = "f" # c = Celsius | f = Fahrenheit - Unit to display time_scale_slope = "h" # s = Seconds | m = Minutes | h = Hours - Slope displayed in temp_scale per time_scale_slope time_scale_profile = "m" # s = Seconds | m = Minutes | h = Hours - Enter and view target time in time_scale_profile # emergency shutoff the profile if this temp is reached or exceeded. # This just shuts off the profile. If your SSR is working, your kiln will -# naturally cool off. If your SSR has failed/shorted/closed circuit, this +# naturally cool off. If your SSR has failed/shorted/closed circuit, this # means your kiln receives full power until your house burns down. # this should not replace you watching your kiln or use of a kiln-sitter -emergency_shutoff_temp = 2264 #cone 7 +emergency_shutoff_temp = 2264 #cone 7 -# If the kiln cannot heat or cool fast enough and is off by more than +# If the kiln cannot heat or cool fast enough and is off by more than # kiln_must_catch_up_max_error the entire schedule is shifted until -# the desired temperature is reached. If your kiln cannot attain the +# the desired temperature is reached. If your kiln cannot attain the # wanted temperature, the schedule will run forever. kiln_must_catch_up = True kiln_must_catch_up_max_error = 10 #degrees diff --git a/kiln-display.py b/kiln-display.py index f6f232a..83686b0 100644 --- a/kiln-display.py +++ b/kiln-display.py @@ -1,6 +1,5 @@ #!/usr/bin/env python -from os import supports_dir_fd import websocket import json import time @@ -9,7 +8,9 @@ import argparse import digitalio import board import adafruit_rgb_display.st7789 as st7789 +import RPi.GPIO as GPIO from PIL import Image, ImageDraw, ImageFont +import config # This is designed to drive an Adafruit Mini PiTFT 1.3" (https://www.adafruit.com/product/4484) # @@ -22,10 +23,33 @@ from PIL import Image, ImageDraw, ImageFont # non-numpy fallback code will consume much CPU. +def beep(delay): + GPIO.output(config.gpio_beeper, GPIO.HIGH) + time.sleep(delay) + GPIO.output(config.gpio_beeper, GPIO.LOW) + + +def morse(code): + for c in code: + if c == '.': + beep(0.25) + + elif c == '-': + beep(0.5) + + time.sleep(0.25) + + def display(hostname, minupdatesecs, font_ttf): status_ws = websocket.WebSocket() storage_ws = websocket.WebSocket() + # setup beeper GPIO + GPIO.setmode(GPIO.BCM) + GPIO.setwarnings(False) + GPIO.setup(config.gpio_beeper, GPIO.OUT) + GPIO.output(config.gpio_beeper, GPIO.LOW) + # Configuration for CS and DC pins for Raspberry Pi cs_pin = digitalio.DigitalInOut(board.CE0) dc_pin = digitalio.DigitalInOut(board.D25) @@ -57,6 +81,7 @@ def display(hostname, minupdatesecs, font_ttf): charth = int(display.height / 2) # main loop + state = 'idle' cur_profile = None last_update = datetime.datetime.now() while True: @@ -82,6 +107,25 @@ def display(hostname, minupdatesecs, font_ttf): continue + if state == 'idle' and cur_profile: + state = 'profile_tempok' + + elif state != 'idle' and not cur_profile: + state = 'idle' + morse('-.-.') # (C) Profile Complete + + if state == 'profile_tempok': + tempdelta = abs(msg.get('temperature', 0) - msg.get('target', 0)) + if tempdelta > 5: + state = 'profile_catchup' + morse('....') # (H) Temp bad + + elif state == 'profile_catchup': + tempdelta = abs(msg.get('temperature', 0) - msg.get('target', 0)) + if tempdelta < 1: + state = 'profile_tempok' + morse('-') # (T) Temp ok + # we don't need to update ALL the time if (datetime.datetime.now() - last_update).total_seconds() < minupdatesecs: continue