Page 1 of 1

Assistance with Real time alteration of delay times between multiple lights turning on/off using button inputs

Posted: Thu Nov 30, 2017 4:47 am
by EarthFan
Hi!

I'm having some trouble changing how long lights are on/off for within a loop. I'm using one of the standard 8 relay boards to do this. What I currently have is 2 buttons (momentary push buttons) that increase/decrease the delay times between the lights turning on/off and 1 button that starts the on/off sequence. The specific problem I am having is that the button inputs do not have a real-time affect on the delay times. For example, if the loop is programmed to start with 4 second delays between the on/off switching and the increase button is held down it will only affect the delay time when the loop is complete and repeats. If i just press one of the input buttons momentarily there is no change in the delay time at all.

I'm looking for a way to instantaneously change this before the loop has finished executing without restarting the loop and losing the current position of the light cycle. Say for example I have 8 lights in a horizontal line programmed to turn off/on going from left - right every 2 seconds until the eighth light is reached and then the cycle reverses. I would like to be able to change the delay time between the lights on the fly without the whole "cycle" restarting.

I have looked into interrupts / multi-threading, but I'm not sure if it's the correct course of action.

If you could suggest some solutions, I would be very grateful.

Any help would be greatly appreciated! Thanks !

Here's my current code:

Code: Select all

import time
import RPi.GPIO as GPIO
GPIO.setmode(GPIO.BCM)

GPIO.setup(2, GPIO.OUT) # relay 1
GPIO.setup(3, GPIO.OUT) # relay 2
GPIO.setup(4, GPIO.OUT) # relay 3
GPIO.setup(17, GPIO.OUT) # relay 4
GPIO.setup(22, GPIO.OUT) # relay 5
GPIO.setup(10, GPIO.OUT) # relay 6  
GPIO.setup(9, GPIO.OUT) # relay 7
GPIO.setup(11, GPIO.OUT) # relay 8


GPIO.output(2, GPIO.HIGH)
GPIO.output(3, GPIO.HIGH)
GPIO.output(4, GPIO.HIGH)
GPIO.output(17, GPIO.HIGH)
GPIO.output(22, GPIO.HIGH)
GPIO.output(10, GPIO.HIGH)
GPIO.output(9, GPIO.HIGH)
GPIO.output(11, GPIO.HIGH)


start_button= 14
decrease_button=23
increase_button = 25
GPIO.setup(start_button,GPIO.IN,pull_up_down=GPIO.PUD_UP)
GPIO.setup(increase_button,GPIO.IN,pull_up_down=GPIO.PUD_UP)
GPIO.setup(decrease_button,GPIO.IN,pull_up_down=GPIO.PUD_UP)




while(1):


         while GPIO.input(start_button) == 0:
                time1 = 1
                while(1):

                        print "initiating sequence:"
                        GPIO.output(2, GPIO.HIGH)
                        GPIO.output(3, GPIO.HIGH)
                        #time.sleep(time1)
                        print time1

                        GPIO.output(2, GPIO.LOW)
                        GPIO.output(3, GPIO.LOW)
                        time.sleep(time1)
                        GPIO.output(2, GPIO.HIGH)
                        GPIO.output(3, GPIO.HIGH)
                        time.sleep(time1)
                        
                        if GPIO.input(decrease_button) == 0:
                                time1+=.5
                                print "speed decreased by 1 second"
                                print time1
                                #time.sleep(1)  

                        if GPIO.input(increase_button) == 0:
                                time1-=.5
                                print "speed increased by 1 second"
                                print time1
                                #time.sleep(1)

Re: Assistance with Real time alteration of delay times between multiple lights turning on/off using button inputs

Posted: Thu Nov 30, 2017 11:41 am
by OutoftheBOTS
if you use time.sleep() for your paise then this can't be changed on the fly. I have created my own waiting fuction, it is basically how the time.sleep works but we can alter this 1.

I have also used call backs for live updates of your wait time :)

Code: Select all

import time
import RPi.GPIO as GPIO
GPIO.setmode(GPIO.BCM)

GPIO.setup(2, GPIO.OUT) # relay 1
GPIO.setup(3, GPIO.OUT) # relay 2
GPIO.setup(4, GPIO.OUT) # relay 3
GPIO.setup(17, GPIO.OUT) # relay 4
GPIO.setup(22, GPIO.OUT) # relay 5
GPIO.setup(10, GPIO.OUT) # relay 6  
GPIO.setup(9, GPIO.OUT) # relay 7
GPIO.setup(11, GPIO.OUT) # relay 8


GPIO.output(2, GPIO.HIGH)
GPIO.output(3, GPIO.HIGH)
GPIO.output(4, GPIO.HIGH)
GPIO.output(17, GPIO.HIGH)
GPIO.output(22, GPIO.HIGH)
GPIO.output(10, GPIO.HIGH)
GPIO.output(9, GPIO.HIGH)
GPIO.output(11, GPIO.HIGH)


start_button= 14
decrease_button=23
increase_button = 25
GPIO.setup(start_button,GPIO.IN,pull_up_down=GPIO.PUD_UP)
GPIO.setup(increase_button,GPIO.IN,pull_up_down=GPIO.PUD_UP)
GPIO.setup(decrease_button,GPIO.IN,pull_up_down=GPIO.PUD_UP)

def decrease(): #function for decrease waiting time
  global time1
  time1+=.5
  print "speed decreased by 1 second"
  print time1

def increase(): #fuction for increasing waiting time
  global time1
  time1-=.5
  print "speed increased by 1 second"
  print time1

def waiting(): # for doing the waiting that can be updated live
  global time1
  start_time = time.time
  while time.time - start_time < time1 : pass

#add the event call backs
GPIO.add_event_detect(decrease_button, GPIO.FALLING, callback=decrease)
GPIO.add_event_detect(increase_button, GPIO.FALLING, callback=increase)

time1 = 1 #initlize the waiting time

#wait for start button to press. I am not sure on your wiring so you might need to change 1 to 0 if switch is working backwartds
while GPIO.input(start_button) == 1 : pass 

#main loop
while True:
  print "initiating sequence:"
  GPIO.output(2, GPIO.HIGH)
  GPIO.output(3, GPIO.HIGH)
  waiting()

  GPIO.output(2, GPIO.LOW)
  GPIO.output(3, GPIO.LOW)
  waiting()
  GPIO.output(2, GPIO.HIGH)
  GPIO.output(3, GPIO.HIGH)
  waiting()
  
  


Re: Assistance with Real time alteration of delay times between multiple lights turning on/off using button inputs

Posted: Fri Dec 01, 2017 3:42 am
by EarthFan
I really appreciate that. There are a lot of good concepts within your code i'm beginning to to learn about because of your help. Thanks so much ! ! :D

Re: Assistance with Real time alteration of delay times between multiple lights turning on/off using button inputs

Posted: Sat Dec 02, 2017 8:11 am
by ghp
Hello,
the proposed waiting-method uses a loop which will increase cpu usage a lot. With a small delay in the loop the cpu usage will be much lower. Timing will be a little bit less accurate, though.
Global variables which are read only in a method do not need to be declared as global.

Code: Select all

def waiting(): 
    """for doing the waiting that can be updated live
       uses a global variable 'time1' for delay."""
    start_time = time.time()
    while time.time() - start_time < time1: 
        time.sleep(0.1)

Re: Assistance with Real time alteration of delay times between multiple lights turning on/off using button inputs

Posted: Sat Dec 02, 2017 9:21 pm
by OutoftheBOTS
There is only variable declared global and it is shared between 3 functions and also kept alive for each time the function is called.

If you don't declare it as global each time the function is called it will be created again rather than update the old 1 also to share the variable between the 3 functions it needs to be a global variable.

As for the CPU usage don't worry about it as it won't affect anything and your program will run well