2

I want to program a simple thermostat, but for some reason the commands GPIO.output(21, 1) or GPIO.output(21, 0) do not change anything.

In a similar vein, GPIO.setup(20, GPIO.OUT, initial=0) does indeed setup the pin for output, but it's automatically on, despite the initial=0...

Here's the code:

import RPi.GPIO as GPIO

GPIO.setmode(GPIO.BCM)
GPIO.setup(20, GPIO.OUT, initial=0)
ventein = GPIO.output(20, 1)
ventaus = GPIO.output(20, 0)

calling ventein or ventaus further down the line does not do anything. The pin is just always on. I suspected that maybe it has something to do with user permissions, so I added both root and the user to the gpio group - didn't do anything.

Toggling the pin with the gpio command line tool works just fine. What could be the problem?

And here's the complete code, just in case:

from w1thermsensor import W1ThermSensor
import RPi.GPIO as GPIO
import time

GPIO.setmode(GPIO.BCM)
GPIO.setup(20, GPIO.OUT, initial=0)
ventein = GPIO.output(20, 1)
ventaus = GPIO.output(20, 0)

muro = W1ThermSensor(W1ThermSensor.THERM_SENSOR_DS18B20, "011445ff9daa")
murotemp = muro.get_temperature()

try:
    while True:
        if murotemp > 20:
            ventein
            print(murotemp)
            print("Temperatur ist hoeher als 20 Grad, schalte ein...")
            time.sleep(0.5)
            muro = W1ThermSensor(W1ThermSensor.THERM_SENSOR_DS18B20, "011445ff9daa")
            murotemp = muro.get_temperature()

        elif murotemp < 20:
            ventaus
            print(murotemp)
            print("Temperatur ist niedriger als 20 Grad, schalte aus...")
            time.sleep(0.5)
            muro = W1ThermSensor(W1ThermSensor.THERM_SENSOR_DS18B20, "011445ff9daa")
            murotemp = muro.get_temperature()


except KeyboardInterrupt:
    GPIO.cleanup()
    print("exiting...")
  • 1
    First, you do nothing when murotemp == 20 it's normal ? – Ephemeral Jul 14 at 13:35
  • Yes, probably I should make it "if murotemp => 20: " – Viktor Gruber Jul 14 at 13:42
  • 1
    And, ventein = GPIO.output(20, 1) ventaus = GPIO.output(20, 0) are not in the loop in a conditionnal scope or other... then you init the same GPIO number at HIGH and then at LOW state for the global scope. That it's a logic problem because you use the same pin for ventein and ventaus – Ephemeral Jul 14 at 13:42
  • 1
    Yes if you want to check at 20 Grad – Ephemeral Jul 14 at 13:45
  • 1
    Thanks Ephemeral! – Viktor Gruber Jul 14 at 13:51
2

You need to replace ventein with GPIO.output(20, 1) and ventaus with GPIO.output(20, 0).

You seem to think you have declared them as functions - you have not.

  • Thanks! That was the problem. (you are probably rightly suspecting it, I'm a bloody beginner, haha.) – Viktor Gruber Jul 14 at 13:53
  • 1
    I hope you will be pleased to know this is a common mistake and one which I think is quite logical to make. It's like assigning a macro in other languages. – joan Jul 14 at 16:56
6

As joan's answer has already pointed out the misunderstanding here is likely how to define and use a function in Python. Joan's approach will sure solve the immediate problem and make the program work. I will however address the underlying issue that is not so much related to the Pi but general Python programming.

So how to go about defining and using a function, from here:

  • Function blocks begin with the keyword def followed by the function name and parentheses ( ( ) ).
  • Any input parameters or arguments should be placed within these parentheses. You can also define parameters inside these parentheses.
  • The first statement of a function can be an optional statement - the documentation string of the function or docstring.
  • The code block within every function starts with a colon (:) and is indented.
  • The statement return [expression] exits a function, optionally passing back an expression to the caller. A return statement with no arguments is the same as return None.

So instead of

ventein = GPIO.output(20, 1)

this is what you're looking for:

def ventein():
    GPIO.output(20, 1)

Note the def keyword, the function name (ventein), the parentheses (empty in this case as no arguments are required), and the colon. The final return is ommitted in this case as it is optional if you do not want to pass anything back to the caller.

And when calling this new function instead of:

try:
    while True:
        if murotemp > 20:
            ventein

it should read:

try:
    while True:
        if murotemp > 20:
            ventein()
  • Many thanks :) this is very helpful. – Viktor Gruber Jul 14 at 14:39

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.