Home > Mobile >  How to display python variables on a web page and an LCD
How to display python variables on a web page and an LCD

Time:01-30

I'm trying to display time and temperature and other variables on an LCD display, and on a web page (local network only) when it's accessed. This is running on a Raspberry pi Zero 2 W, using python. My thinking is, the flask app should be running in the background, and serving up the template when it's called. Meanwhile, the timer should interrupt every second and cause the LCD display to be updated.

The LCD display works as it should, with the data refreshed every second, as long as the flask server is not active (commented out the "flask_app.run..."). But when flask is enabled, the web page works but the display does not.

I'm about at my limit of understanding python and flask -- can you see what's wrong here? Thanks.

# Display data from furnace to raspberry pi zero W
#
import time
from flask import Flask, render_template, request
import RPi.GPIO as GPIO
import sys
import datetime
import SDL_DS3231
import smbus
from gpiozero import Button
import lcddriver

heatLEDPin = 5
heatPin = 27
GPIO.setmode(GPIO.BCM)
GPIO.setwarnings(False)
GPIO.setup(heatLEDPin, GPIO.OUT)
GPIO.output(heatLEDPin,GPIO.LOW)
GPIO.setup(heatPin, GPIO.IN)
thermostatOn = Button(heatPin)


ds3231 = SDL_DS3231.SDL_DS3231(1, 0x68)

flask_app = Flask(__name__)
@flask_app.route('/')

def index():
    print ("here")
    display = ['1258','87','1259','2','61.2','on']
    datetimestr = str(ds3231.read_datetime())
    temperature = (ds3231.getTemp()*9/5 32)
   
    return render_template('index.html',
                           datetimestr = datetimestr,
                           temperature = temperature,
                           m24=display[0],
                           p24=display[1],
                           m30=display[2],
                           p30=display[3],
                           heat=display[5])

# Define functions
def mainLoop():
        # === Main loop ===
       # Get the time
        datetimestr = str(ds3231.read_datetime())
        month = int(datetimestr[5:7])
        day = int(datetimestr[8:10])
        hour = int(datetimestr[11:13])
        second = int(datetimestr[14:16])
        mylcd.lcd_display_string("%s" % datetimestr,1)
        mylcd.lcd_display_string(("Temp:%5.1f  Heat off" % (ds3231.getTemp()*9/5 32)),4)

# Main program

print ("")
print ("Test SDL_DS3231 Version 1.0 - SwitchDoc Labs/n/n")
print ("Program Started at:"  time.strftime("%Y-%m-%d %H:%M:%S"))
print ("")
print ("DS3231=\t\t%s" % ds3231.read_datetime())
print ("DS3231 Temp=", ds3231.getTemp()*9/5 32)

interval = 1000000000 # system clock seconds
lastTime = 0


mylcd = lcddriver.lcd()
mylcd.lcd_clear()
#mylcd.lcd_backlight("On")  # Backlight is hard wired
mylcd.lcd_display_string("Hello world",1)

if __name__ == '__main__':
#    flask_app.run(debug=True, host='0.0.0.0')

# Loop
    while True:
        thisTime = time.time_ns()
        if (thisTime - lastTime >= interval):
            lastTime = thisTime
            mainLoop()

CodePudding user response:

Once you call flask_app.run(), that is a blocking call...it will stay inside that function forever. Therefore, when flask_app.run() is uncommented, your LCD timer loop never gets executed. My suggestion is to use a multithreaded approach where one thread takes care of the flask app and the other thread takes care of other board-level I/O that you want to do. Here's a simplistic working example where the flask app uses the main thread and a simulated LCD process updates a counter (the console simulates your LCD):

from flask import Flask
import threading
import time

# Using a global here for simplicity in this demo
# Globals are generally bad practice, so you would maintain
# the status of "lcd_counter" in a more elegant way
# (e.g. through a shared module, through classes, etc.)
# A simple global serves the purpose for this demo
# of a flask server running in parallel to another process
# emulating some I/O, printing to the console, etc.
lcd_counter = 0

flask_app = Flask(__name__)

@flask_app.route("/")
def hello_world():
    # See comment about global above
    global lcd_counter
    return f'<p>LCD counter = {lcd_counter}</p>'

def lcd_update():
    # This prints the value of the counter to the console to simulate sending it to the LCD
    # See comment about global above
    global lcd_counter
    while True:
        print(f'{lcd_counter}')
        time.sleep(1.0)
        lcd_counter  = 1

if __name__ == '__main__':
    # Start a background thread to control/update the LCD
    # You'll also want to devise a graceful way to shutdown your whole app
    # by providing a kill signal to your threads, for example (beyond the scope of this answer)
    thread_LCD = threading.Thread(target=lcd_update, name='lcd_counter')
    thread_LCD.start()
    # Now run the flask web server in the main thread
    # debug=False to avoid Flask printing duplicate info to the console
    flask_app.run(debug=False, host='0.0.0.0')
  •  Tags:  
  • Related