4

I'm running some testing using Python on a Raspberry Pi. Hardware is a series of SPDT relays connected to a darlington array (ULN2803) which is connected to the GPIO of a raspberry Pi B.

If I set a GPIO pin high, the corresponding relay pulls. If I set it low, it releases. I can use a loop to set all GPIO:s high, and all relays pulls, except the last one(?). But if I run time.sleep() after the loop has set all pins high, they all get set low automagicly.

Check the code below; When it runs, it iterates through eight GPIO:s, setting one high at a time, and sleeps for 200ms between each. This works, but the last one does not get activated. After that, it sleeps for 1s, which causes all pins to go low. And then it starts iterating through them again, backwards, turning them off. As soon as its starting backwards, on first iteration, all go high again. Why is that? It does not occur within a loop, just between them. It is like when the sleep() is run outside the loop, everything reverts to how it was before the program was started.

import RPi.GPIO as GPIO
import time

GPIO.setmode(GPIO.BCM)
iopins = [4,7,8,9,10,11,17,18]

try:
    for x in iopins:
        GPIO.setup(x, GPIO.OUT)
        GPIO.output(x,0)

    while True:
        for x in iopins: #turn on.
            time.sleep(0.2)
            GPIO.output(x, GPIO.HIGH)

        time.sleep(1) #<-- causes all GPIOs to pull low...

        for y in reversed(iopins): #Turning off.
            GPIO.output(y, GPIO.LOW) #<--here all GPIOs pulls high upon first iteration
            time.sleep(0.2)

finally:
    GPIO.cleanup()

Another strange thing is that if the array IOPINS only contain one entity it does not work.

Kartoch
  • 7,610
  • 9
  • 40
  • 68
Rushdie
  • 41
  • 2
  • Just a comment. In python arrays are called lists. – Diego Herranz Sep 17 '13 at 12:20
  • What happens if you run some other code outside the "turn on" loop, other than sleep? Does the same behavior happen? For instance, can you check the status of the pins after they've been turned on, where the `sleep(1)` statement is now? This would at least tell you what the program thinks the pins' states are. – darthbith Sep 17 '13 at 12:32
  • @darthbith Doesn't matter, the same thing happens. If I replace the sleep(1) with a loop that iterates through the pins and print the results, the same thing happen. However, the results when calling GPIO.input(x) states that it thinks the pins are high... – Rushdie Sep 17 '13 at 16:00
  • @Rushdie So your python reads the pins as in the high position but you can physically see that the relays are in the low position? That is very strange... unfortunately I can't help you with that :-) As for the other thing about only containing one entity, how are you assigning the IOPIN when it's just one? If you put `IOPINS = 3` it won't work because you can't loop through `3`. You have to say `IOPINS = [3]` to make it an iterateable list. – darthbith Sep 17 '13 at 21:48
  • @darthbith Strange indeed. Python reads the pins as high, but they are physically low. I keep thinking that it has to do with the GC doing something? Yea, to assign one entity to the list I used [value]. – Rushdie Sep 19 '13 at 07:21
  • @Rushdie, when you encounter an issue as such you better go to basics. I suggest you to remove the darlington array. Then Connect 8 LED s to your 8 GPIO pins via 1k current limiting resistors each. Ground cathodes (common cathode mode). Then run the code and see if the LEDs light up correctly. Because when I tried your code on my RPi, my LED's lit up exactly the way you want. – retromuz Nov 13 '13 at 15:03

1 Answers1

0

If you remove time.sleep(1) the last relay does not work because it's activated and deactivated right after. You could swap the order in the last for loop:

import RPi.GPIO as GPIO
import time

GPIO.setmode(GPIO.BCM)
iopins = [4,7,8,9,10,11,17,18]

try:
    for x in iopins:
        GPIO.setup(x, GPIO.OUT)
        GPIO.output(x,0)

    while True:
        for x in iopins: #turn on.
            time.sleep(0.2)
            GPIO.output(x, GPIO.HIGH)

        for y in reversed(iopins): #Turning off.
            time.sleep(0.2)
            GPIO.output(y, GPIO.LOW)                

finally:
    GPIO.cleanup()
Diego Herranz
  • 2,857
  • 2
  • 19
  • 34
  • That's how I wrote it the first time, but it really doesn't matter. The last relay doesn't get pulled anyhow. It is like it misses the last part of the **list**, and this is why it can't be run with only one entity in it. I'm new to this; am I missing something trivial in the code? – Rushdie Sep 17 '13 at 16:05
  • Have you tried to add more pins to iopins to see if that way 18 works? – Diego Herranz Sep 18 '13 at 13:34
  • Yea, that works. It is like the last entity in the list gets lost in space. My gut tells me: 'trivial coding error'. But I cant find it :) – Rushdie Sep 19 '13 at 07:26
  • You have the time.sleep(0.2) in the for loop for turning off the relays before GPIO.output(y, GPIO.LOW) as my example, right? – Diego Herranz Sep 19 '13 at 08:17