I've been trying to solve this problem for hours, to no avail. So, I've been trying to run an OLED screen for showing the weather, time, etc. I wrote the script with a while loop so it can run virtually forever. However, I also want to be able to start the script with a GPIO pull-up, and end it with yet another high GPIO pin. Using the on-off script to start the OLED script works flawlessly with variables, yet the script seems to be blind to the variable changes my "Off-GPIO" tries to introduce. Here's my code:
from oledscriptwithfunc import oledfunc
from reset import rstfunc
import RPi.GPIO as GPIO
var = None
def button_callback(channel):
print("Initializing..")
oledfunc(2) # set on-off variable to two so while loop can start (see next block of code)
def offbutton(channel):
print("Ending program..")
oledfunc(1) # set on-off variable as off..
rstfunc() # reset OLED screen
GPIO.setwarnings(False)
GPIO.setmode(GPIO.BCM)
GPIO.setup(10, GPIO.IN, pull_up_down=GPIO.PUD_DOWN)
GPIO.setup(9, GPIO.IN, pull_up_down=GPIO.PUD_DOWN)
GPIO.add_event_detect(10,GPIO.RISING,callback=button_callback) # GPIO on "switch"
GPIO.add_event_detect(9,GPIO.RISING,callback=offbutton) # GPIO off "switch"
message = input("Press enter to quit\n")
GPIO.cleanup()
--------------------------oledscriptwithfunc.py-------------
def oledfunc(var): # function used in previous script, var is set by GPIO
var = var
import digitalio
import threading
import busio
import board
from PIL import Image, ImageDraw, ImageFont
i2c = busio.I2C(board.SCL, board.SDA)
import requests
import adafruit_ssd1306
oled = adafruit_ssd1306.SSD1306_I2C(128, 32, i2c, addr=0x3c)
oled.fill(0)
oled.show()
image = Image.new("1", (128, 32))
draw = ImageDraw.Draw(image)
draw.rectangle((0, 0, 128, 32), outline=255, fill=255)
font = ImageFont.load_default()
import datetime
oled.image(image)
oled.show()
import time
timer1 = time.perf_counter()
while var != 1: # used for on-off toggle
timer2 = time.perf_counter()
if int((timer2 - timer1)) in range(0,1) or int((timer2 - timer1)) % 1800 == 0:
response = requests.get("https://api.openweathermap.org/data/2.5/weather?lat=xxxx&lon=xxxxx&lang=de&units=metric&appid=xxxxxxxxxxxxxxxxxx")
data = response.json()
for weatherdata in data['weather']:
status = weatherdata['description']
redvar = data['main']
temp = redvar['temp']
temptext = "{}C".format(temp)
else:
while var != 1: # on-off toggle variable
t_end = time.time() + 10
while time.time() < t_end:
now = datetime.datetime.now()
testvar = now.strftime("%d-%m-%Y")
vartwo = now.strftime("%M:%S")
newvr = int(now.strftime("%H"))
newervr = newvr + 2
text = testvar + " " + "{}:".format(newervr) + "{}".format(vartwo)
draw.rectangle((0, 0, 128, 32), outline=255, fill=255)
draw.rectangle((6, 6, 122, 26), outline = 0, fill = 0)
(font_width, font_height) = font.getsize(text)
draw.text((oled.width//2 - font_width//2, oled.height//2 - font_height//2),
text, font=font, fill=255)
oled.image(image)
oled.show()
draw.rectangle((0, 0, 128, 32), outline = 0, fill = 0)
(font_width, font_height) = font.getsize(temptext)
draw.text((oled.width//2 - font_width//2, oled.height//2 - font_height//2),
temptext, font=font, fill=255)
oled.image(image)
oled.show()
time.sleep(5)
draw.rectangle((0, 0, 128, 32), outline = 0, fill = 0)
text = status
(font_width, font_height) = font.getsize(text)
draw.text((oled.width//2 - font_width//2, oled.height//2 - font_height//2),
text, font=font, fill=255)
oled.image(image)
oled.show()
time.sleep(5)
I apologize if there is a lot of bad code in here, I'm just starting out with programming and Python. I hope I've explained the issue well enough. To summarize: With the "var" variable, I want to be able to turn "oledscriptwithfunc.py" on and off. The problem is that I can only start it, but never change the variable again so I can turn it off. I've commented the most important/non-functional bits of the code. Please ignore the OLED setup/weather API calls, I just thought I should include it to show the entire inner-workings of the code. Is there something conflicting, or am I just using the wrong method to make this work?
Alright, after some tinkering, I found a solution! I discovered that RPi.GPIO has a simple way to check a pin's state with input.GPIO(channel). [This teached me a valuable lesson: Always read the documentation] I just did some simple if and while statements to solve my issue. This way has its caveats on its own, but it does what I want it to do.