Hei!
olen aloittelija vasta näissä hommissa.
Mitä koodista pitää muuttaa kun nyt se päivittää lämpötilat vasta kun ikkunan sulkee?
#!/usr/bin/env python import time import RPi.GPIO as GPIO import Adafruit_DHT from Tkinter import * maxTemp = 20 webasto = 27 pin = 4 pin2 = 17 GPIO.setmode(GPIO.BCM) GPIO.setup(27,GPIO.OUT) GPIO.setwarnings(False) humidity2, temperature2 = Adafruit_DHT.read_retry( Adafruit_DHT.DHT22, pin2 ) humidity, temperature = Adafruit_DHT.read_retry( Adafruit_DHT.DHT22, pin ) while True: master = Tk() def callback(): global maxTemp maxTemp += 1 print maxTemp def callback2(): global maxTemp maxTemp -= 1 print maxTemp sisa = Message(master, text="Sisalampo") sisa.configure(font='helvetica 10') sisa.pack() lamposisa = Text(master, height=1, width=4) lamposisa.configure(font='helvetica 18') lamposisa.pack() lamposisa.insert(END, temperature) ulko = Message(master, text="Ulkolampo") ulko.configure(font='helvetica 10') ulko.pack() lampoulko = Text(master, height=1, width=4) lampoulko.configure(font='helvetica 18') lampoulko.pack() lampoulko.insert(END, temperature2) lisa = Button(master, text = "+", command = callback) lisa.config( foreground="red", font='helvetica 18', height = 2, width = 2) lisa.pack() lamponaytto = Text(master, height=1, width=2) lamponaytto.configure(font='helvetica 18') lamponaytto.pack() lamponaytto.insert(END, maxTemp) miinus = Button(master, text = "-", command = callback2) miinus.config( foreground="blue", font='helvetica 18', height = 2, width = 2) miinus.pack() if temperature < maxTemp: GPIO.output(webasto,True) else: GPIO.output(webasto,False) print "Sisalampo={0:f}*C Kosteus={1:f}%".format(temperature, humidity) print "Ulkolampo={0:f}*C Kosteus={1:f}%".format(temperature2, humidity2) master.mainloop() GPIO.cleanup()
En tarkkaan ymmärrä, mitä tarkoittaa ”se päivittää lämpötilat”. Päivittää minne? Sensorilta muuttujiin? Ruudulle? Lämmityslaitteelle tiedoksi? Koodissa on kuitenkin ihan selviä virheitä, joten eiköhän seuraava teksti auta jonkin verran.
Tk-ikkuna käytännössä näkyy siinä vaiheessa, kun päästään kohtaan master.mainloop(). Ohjelmassa ei ole esimerkiksi ajastettua toimintaa, joten ikkuna vain on ja odottaa painalluksia tai sulkemista. Ikkunassa olevat painikkeet kyllä muuttavat maxTemp-muuttujan arvoa, mutta callback-funktioissa ei tehdä sillä mitään, joten ohjelma ei siinä kohti ainakaan ”päivitä lämpötiloja”.
Kun ikkuna suljetaan, koodin suoritus jatkuu mainloop-rivistä. Silloin siis mennään while-silmukan alkuun ja yritetään luoda uusi ikkuna. Tässä kohti suoritetaan (uudestaan) myös GPIO.output ja sitä seuraava print. Ehkä tämä on se tarkoittamasi vaihe, jossa ohjelma ”päivittää lämpötilat”.
Ilmeisesti ohjelman alussa luetaan lämpötilan sensorilta. Sitä ei lueta missään vaiheessa uudestaan, joten ohjelma ei säädä lämmitintä järkevästi vaan toimii koko ajan sen mukaan, mikä lämpötila oli käynnistysvaiheessa.
Ohjelma olisi varmaan hyödyllisempi, jos lämpötilan lukeminen ja päivitys tapahtuisivat ajastetussa funktiossa. Erillistä while-silmukkaa ei tarvita, koska Tk:n mainloop jo sisältää silmukan.
Siis: Ota while-silmukka pois. Laita sekä lämpötilan lukeminen että ohjaus yhteen funktioon. Samassa funktiossa pitää päivittää ikkunassa näytettävät tiedot. Suorita funktio ajastetusti sekä tarvittaessa esim. käyttäjän painaessa nappia.
Tässä on ohjelmalle uusi rakenne (muutaman TODO-kohdan kera):
# TODO: Tänne muuttujien ja GPIO:n alustukset, kuten ennenkin. # Callbackeja muutetaan vähän (ja nimetään kuvaavammin): def callback_increase_temperature_max(): global temperature_max temperature_max += 1 päivitys() # ks. tämä funktio alempana. # Sitten luodaan ikkuna: master = Tk() # TODO: Tähän väliin muu ikkunan sisältö. # Harkitse tarkkaan, mitä ikkunaan laitat... # Tekstejä ei vielä lisätä, vain tyhjät tekstikentät. # Tekstin tyypiksi helpoin on Label. # Tämä funktio lukee sensorin ja toimii sen mukaan: def päivitys(): global humidity_in, temperature_in global humidity_out, temperature_out global temperature_max humidity_out, temperature_out = Adafruit_DHT.read_retry(Adafruit_DHT.DHT22, pin2) humidity_in, temperature_in = Adafruit_DHT.read_retry(Adafruit_DHT.DHT22, pin) if temperature_in < temperature_max: GPIO.output(webasto, True) else: GPIO.output(webasto, False) # Tässä pitää myös päivittää ikkunan sisältö. # Esim. jos temperature_max_label = Label(), se päivitetään näin: temperature_max_label.configure(text = temperature_max) # TODO: Vastaavasti näytetään muut arvot. # Tämä funktio suoritetaan sekunnin välein: def silmukka(): global master master.after(1000, silmukka) päivitys() # Suoritetaan silmukkafunktio kerran, jotta ikkunan sisältö tulee oikeaksi # ja silmukan seuraava suorituskerta tulee ajastettua sekunnin päähän. silmukka(master) # Aloitetaan Tk:n suoritus. Tämä loppuu, kun ikkuna suljetaan. master.mainloop() GPIO.clean()
Kiitos! Sehän alkoi toimimaan. On vaan tuo lämpötilojen lukeminen antureilta niin hidasta, että päivittäessä jumiutuu koko ohjelma muutamaksi sekunniksi.
Voisit siinä tapauksessa lukea anturit vaikka 10 sekunnin välein erillisessä säikeessä (thread), jolloin lukeminen ei jumittaisi ohjelmaa.
Aihe on jo aika vanha, joten et voi enää vastata siihen.