mtgtopdeck
Posts: 22
Joined: Tue Dec 22, 2015 4:27 am

For loop break interupt

Mon Jan 18, 2016 6:54 am

I am now working on the final draft of some code that controls addressable RGB LEDs in a strip and I could use a bit of help.
I want to break out of a for loop as soon as possible "if pw1 != x or pw2 != y"
located in def toggle12() line 228
I can't get it to work. it will loop through the entire image { strip.show(pov.column[x]) } even if pw1 or pw2 changes.

If you see anything else that can be improved I would appreciate the feedback!

Here is the code. With many thanks to Phillip Burgess of Adafruit, and Joan of pigpio

Code: Select all

import time
import pigpio
from dotstar import Adafruit_DotStar
import Image
import random


PWM_GPIO_1 = 12 #PWM input gpio pins
PWM_GPIO_2 = 16
numpixels = 119 #number of pixels in the strip
strip = Adafruit_DotStar(numpixels, 24000000, order='bgr')

filename  = "test1.jpg" #file name of image to be converted

rOffset = 3	#fix RGB color order
gOffset = 2
bOffset = 1

strip.begin()
strip.setBrightness(127)

class pov:# converting an image to a byte array for sending to led strip
	print "Loading {}...".format(filename)
	img       = Image.open(filename).convert("RGB")
	pixels    = img.load()
	width     = img.size[0]
	height    = img.size[1]
	print "%dx%d pixels" % img.size
	gamma = bytearray(256)
	for i in range(256):
		gamma[i] = int(pow(float(i) / 255.0, 2.7) * 255.0 + 0.5)
	print "Allocating..."
	column = [0 for x in range(width)]
	for x in range(width):
		column[x] = bytearray(height * 4)
	print "Converting..."
	for x in range(width):          # For each column of image...
		for y in range(height): # For each pixel in column...
			value             = pixels[x, y]    # Read pixel in image
			y4                = y * 4           # Position in raw buffer
			column[x][y4]     = 0xFF            # Pixel start marker
			column[x][y4 + rOffset] = gamma[value[0]] # Gamma-corrected R
			column[x][y4 + gOffset] = gamma[value[1]] # Gamma-corrected G
			column[x][y4 + bOffset] = gamma[value[2]] # Gamma-corrected B
	print "Displaying..."


class reader:# Reads the Pulse Width signal of a gpio input and returns it's value

   def __init__(self, pi, gpio, weighting=0.0):
      self.pi = pi
      self.gpio = gpio

      if weighting < 0.0:
         weighting = 0.0
      elif weighting > 0.99:
         weighting = 0.99

      self._new = 1.0 - weighting # Weighting for new reading.
      self._old = weighting       # Weighting for old reading.

      self._high_tick = None
      self._period = None
      self._high = None

      pi.set_mode(gpio, pigpio.INPUT)

      self._cb = pi.callback(gpio, pigpio.EITHER_EDGE, self._cbf)

   def _cbf(self, gpio, level, tick):

      if level == 1:

         if self._high_tick is not None:
            t = pigpio.tickDiff(self._high_tick, tick)

            if self._period is not None:
               self._period = (self._old * self._period) + (self._new * t)
            else:
               self._period = t

         self._high_tick = tick

      elif level == 0:

         if self._high_tick is not None:
            t = pigpio.tickDiff(self._high_tick, tick)

            if self._high is not None:
               self._high = (self._old * self._high) + (self._new * t)
            else:
               self._high = t

   def pulse_width(self):       #Returns the PWM pulse width in microseconds.
      if self._high is not None:
         return ((round(self._high/100))*100) #round pwm to nerest hundred
      else:
         return 0.0

   def cancel(self):#      Cancels the reader and releases resources.
      self._cb.cancel()


def hsv2rgb(HSV):#convert HSV 255 values to RGB 255
    H, S, V = HSV
    if S == 0:
        R = V
        G = V
        B = V
        return (R, G, B)
    region = H // 43;
    remainder = (H - (region * 43)) * 6;
    P = (V * (255 - S)) >> 8;
    Q = (V * (255 - ((S * remainder) >> 8))) >> 8;
    T = (V * (255 - ((S * (255 - remainder)) >> 8))) >> 8;
    if region == 0:
        R = V
        G = T
        B = P
    elif region == 1:
        R = Q;
        G = V;
        B = P;
    elif region == 2:
        R = P;
        G = V;
        B = T;
    elif region == 3:
        R = P;
        G = Q;
        B = V;
    elif region == 4:
        R = T;
        G = P;
        B = V;
    else:
        R = V;
        G = P;
        B = Q;
    return R, G, B

"""
six toggle states.
toggle pw1(aux1) has three positions
toggle pw2(gear) has two positions
"""

def toggle31():
	if pw1 == 1900 and pw2 == 1100:
		print("toggle aux 3 pw ={}, toggle gear 1 = {}".format(int(pw1), int(pw2)))
		pi.set_PWM_dutycycle(23, 0) #set MOSFET to low -> 12v LEDs ON
		"""
		cylon,
		"""
		while True:
			i = 0
			while (i < numpixels):
				strip.setPixelColor(i, 0x0000FF)
				strip.show()
				strip.setPixelColor(i, 0x000000)
				time.sleep(0.001)
				i += 1
			i = numpixels - 1
			while (i < numpixels):
				strip.setPixelColor(i, 0xFF0000)
				strip.show()
				strip.setPixelColor(i, 0x000000)
				time.sleep(0.001)
				i -= 1
				if i <= 0:
					break
			break


def toggle21():
	if pw1 == 1500 and pw2 == 1100:
		print("toggle aux 2 pw ={}, toggle gear 1 = {}".format(int(pw1), int(pw2)))
		pi.set_PWM_dutycycle(23, 0)#set MOSFET to low -> 12v LEDs ON
		"""
		confetti
		"""
		while True:
			randompixel = random.randint(0, 119)
			randomcolor = random.randint(0, 255), 255, 255
			randomhsv = hsv2rgb(randomcolor)
			strip.setPixelColor((randompixel), randomhsv[0], randomhsv[1], randomhsv[2])
			strip.show()
			strip.setPixelColor((randompixel), 0, 0, 0)
			break


def toggle11():
	if pw1 == 1100 and pw2 == 1100:
		print("toggle aux 1 pw ={}, toggle gear 1 pw ={}".format(int(pw1), int(pw2)))
		pi.set_PWM_dutycycle(23, 0)#set MOSFET to low -> 12v LEDs ON
		strip.setPixelColor(0, 0x000000)
		strip.show()
		time.sleep(.2)
		strip.setPixelColor(0, 0xFF0000)
		strip.show()
		time.sleep(.2)


def toggle32():
	if pw1 == 1900 and pw2 == 1900:
		print("toggle aux 3 pw ={}, toggle gear 2 pw ={}".format(int(pw1), int(pw2)))
		pi.set_PWM_dutycycle(23, 255)#set MOSFET to high -> 12v LEDs OFF
		strip.setPixelColor(10, 0x000000)
		strip.show()
		time.sleep(.2)
		strip.setPixelColor(10, 0x0000FF)
		strip.show()
		time.sleep(.2)


def toggle22():
	if pw1 == 1500 and pw2 == 1900:
		print("toggle aux 2 pw ={}, toggle gear 2 pw ={}".format(int(pw1), int(pw2)))
		pi.set_PWM_dutycycle(23, 255)#set MOSFET to high -> 12v LEDs OFF
		strip.setPixelColor(10, 0x000000)
		strip.show()
		time.sleep(.2)
		strip.setPixelColor(10, 0x00FF00)
		strip.show()
		time.sleep(.2)


def toggle12():
	if pw1 == 1100 and pw2 == 1900:
		print("toggle aux 1 pw ={}, toggle gear 2 pw ={}".format(int(pw1), int(pw2)))
		pi.set_PWM_dutycycle(23, 255)#set MOSFET to high -> 12v LEDs OFF
		"""
		image-pov; shows an image line-by-line on the led strip
		"""
		while True:
			for x in range(pov.width):
				strip.show(pov.column[x])
				time.sleep(.01)
				print "showing"
				if pw1 != 1100:
					print "breaking pw1"
					break
				if pw2 != 1900:
					print "breaking pw2"
					break


if __name__ == "__main__":

	SAMPLE_TIME = 0.001

	pi = pigpio.pi()
	p1 = reader(pi, PWM_GPIO_1)
	p2 = reader(pi, PWM_GPIO_2)
	start = time.time()

	pov()#convert the image file

	while True:
#		time.sleep(SAMPLE_TIME)
#		pw1 = p1.pulse_width()
#		pw2 = p2.pulse_width()
		pw1 = 1100 #these are set temporaily to test each
		pw2 = 1900 #toggle without the need for pwm input signal.

		toggle31()
		toggle21()
		toggle11()
		toggle32()
		toggle22()
		toggle12()


User avatar
elParaguayo
Posts: 1943
Joined: Wed May 16, 2012 12:46 pm
Location: London, UK

Re: For loop break interupt

Mon Jan 18, 2016 10:09 am

I think the "break" command in that function will only break you out of the "for" loop and not the "while True". The docs say this:
The break statement, like in C, breaks out of the smallest enclosing for or while loop.
If I've understood you correctly, I'd be inclined to do something like the following:

Code: Select all

def toggle12():
   if pw1 == 1100 and pw2 == 1900:
      print("toggle aux 1 pw ={}, toggle gear 2 pw ={}".format(int(pw1), int(pw2)))
      pi.set_PWM_dutycycle(23, 255)#set MOSFET to high -> 12v LEDs OFF
      """
      image-pov; shows an image line-by-line on the led strip
      """
      running = True  # Set a flag for your loop
      while running:
         for x in range(pov.width):
            strip.show(pov.column[x])
            time.sleep(.01)
            print "showing"
            if pw1 != 1100:
               print "breaking pw1"
               running = False  # Change the flag to end your while loop
               break
            if pw2 != 1900:
               print "breaking pw2"
               running = False  # Change the flag to end your while loop
               break
RPi Information Screen: plugin based system for displaying weather, travel information, football scores etc.

Return to “Python”