LedBorg Running on DiddyBorg Coding Problem

Hi,

I've had my DiddyBorg for about a year now and have been upgrading it over time. My latest upgrades include the LedBorg, XloBorg, TriBorg+, Headlights/Tail Lights, and OS Shutdown switch. In the past I've added the UltraBorg to which I added 4 distance sensors and put the Pi Camera on a couple of Servos.

Now, I've taken your Diddyborg-Web software and Ultraborg-Web software, and Forum Software and combined it all together through an amazing amount of trial and error. Although I have programed in the very distant past and it does help some I am still finding it hard to follow the flow at times. Some gaps in this flow I have concluded can only be occurring through Magic! You guys our good. One such example is my current problem.

1. I want the LedBorg to use the wiringpi pwm example you provided to display a continuous array of changing colors. I want the Lighton and Lightoff buttons to control this. I have tried many incantations of your example code to get this working on the DiddyBorg (works great as a standalone example). I have created a global variable borglights to use as a control for turning it on/off. In Lighton it would be set to True and in Lightoff it would be set to False.

So, it turns out that so long as the code is running in the “for hue in range(300):” loop, then all buttons appear disabled (THIS is the Magical part). Early on I tried all manner of “break”, only to find out the Buttons don't work while the loop is running (or so it appears). So could you help me out with this? The code example (Class used to implement the web server) I provided is just one of many variations I tried. See the Lighton, Lightoff sections plus the setup part at top of listing.

2. I had the headlights and OS switch working until I started using the LedBorg. It is using the wiringpi pwm so I have temporarily commented out the GPIO method I was using. I imagine I have to use the wiringpi method now. I know there is also a wiringpi gpio method but is that compatible with the wiringpi pwm method? I just don't know?

So, if I could ask you to please give me one example of turning on/off a single Led in a compatible method, that would be great.

Thanks

Images: 
piborg's picture

The problem is that when you reach the while borglights loop it does not get to the end of the handle function.
Each button press makes a call to this function, so the next press is still waiting for the previous one to finish first.

The proper way around this problem is to use threads.
By creating a new thread we can have the LedBorg code running separately to the web handling code.

First we are going to need the borglights to the globals list:

# Global values
global PBR
global lastFrame
global lockFrame
global camera
global processor
global running
global watchdog
global movementMode
global heading
global borglights

It seems like you already have in the handle function, keep that as well.

Second we need to create a new thread class for the LedBorg loop:

# LedBorg colour thread
class LedBorgLoop(threading.Thread):
    def __init__(self):
        super(LedBorgLoop, self).__init__()
        self.start()

    def run(self):
        # This method runs in a separate thread
        global borglights
        global running
        while running:
            # CODE FOR THE LOOP WILL GO HERE

Next we can move your LedBorg loop code into the thread (I have removed the print lines:

# LedBorg colour thread
class LedBorgLoop(threading.Thread):
    def __init__(self):
        super(LedBorgLoop, self).__init__()
        self.start()

    def run(self):
        # This method runs in a separate thread
        global borglights
        global running
        while running:
            while borglights:
                if not borglights:
                   break
                # Loop over a set of different hues:
                for hue in range(30):
                    if not borglights:
                       break
                    # Get hue into the 0 to 3 range
                    hue /= 100.0
                    # Decide which two channels we are between
                    if hue < 1.0:
                       # Red to Green
                       red = 1.0 - hue
                       green = hue
                       blue = 0.0
                    elif hue < 2.0:
                       # Green to Blue
                       red = 0.0
                       green = 2.0 - hue
                       blue = hue - 1.0
                    else:
                       # Blue to Red
                       red = hue - 2.0
                       green = 0.
                       blue = 3.0 - hue
                    # Set the chosen colour  
                    SetLedBorg(red, green, blue)
                    # Wait a short while
                    if not borglights:
                       break
                    time.sleep(0.1)
            time.sleep(0.2)

I have then made some slight adjustments to allow the running or borglights flag to cause an early exit.
Also the final sleep has been moved up so it is outside the while borglights loop to stop the thread being to "busy" when it has no work to do.

# LedBorg colour thread
class LedBorgLoop(threading.Thread):
    def __init__(self):
        super(LedBorgLoop, self).__init__()
        self.start()

    def run(self):
        # This method runs in a separate thread
        global borglights
        global running
        while running:
            while borglights:
                # Loop over a set of different hues:
                for hue in range(30):
                    # Check if we need to end early
                    if (not borglights) or (not running):
                       break
                    # Get hue into the 0 to 3 range
                    hue /= 100.0
                    # Decide which two channels we are between
                    if hue < 1.0:
                       # Red to Green
                       red = 1.0 - hue
                       green = hue
                       blue = 0.0
                    elif hue < 2.0:
                       # Green to Blue
                       red = 0.0
                       green = 2.0 - hue
                       blue = hue - 1.0
                    else:
                       # Blue to Red
                       red = hue - 2.0
                       green = 0.
                       blue = 3.0 - hue
                    # Set the chosen colour  
                    SetLedBorg(red, green, blue)
                    time.sleep(0.1)
            time.sleep(0.2)

We now have a thread which should work, we just need to load it correctly.
I would put this where the other threads are started, before the httpServer = ... line:

# Setup the LedBorg colour thread
ledBorgThread = LedBorgLoop()

The thread should end on its own when the running flag is set to False at the end of the script.

Thanks,

1. Your thread code worked straight away. I was kind of at the end of the line trying to figure this thing out. Initially I had tried to add it as another Movement mode trying to separate it form the light switches but quickly gave up on that, with the lockout of the buttons being the last straw. So, this has solved that problem and helped a lot going forward.

2. Also, I did rewrite the Headlight code using the wiringpi method (Pinmode,digital Read/Write) which seems to work fine. I was only concerned that using 2 wiringpi modes (Pwm the other) methods at the same time could cause a conflict. But it does seem to work OK.

3. So moving on, I created 3 new buttons and rename two other. I now have a new button for headlights and the previous button for LedBorg lights, and the existing button for All lights off.

4. Also, I added 2 navigation buttons Nav1 and Nav2 for future project (they function as manual mode right now). They would drive to a destination using various methods TBD, could be as simple as go directly across the room going around obstacles, park at a location, and maybe record the route to do it again, I do have an XloBorg that may help with that, or maybe use some timing method, so future TBD. I also renamed semi auto to Search, which could be as simple as search for an IR beam or beacon and park there or something much more interesting such as optical recognition method, there is the follow the Ball code, maybe have it lock in the Ball parameters and then go look for it, or maybe facial recognition (That would be hard). So these are just a bunch of ideas for future project.

As a final thought, I think you Robot Vehicles and Circuit Boards are excellent, but the Crown Jewell of your business in my opinion maybe your software and software support. Otherwise I might just have a DiddyBorg with some simple sample code that doesn't really do anything. Instead I have the Diddy-Web, UltraBorg-Web, PS3 code (which works great) plus the Forum. This code functions as is, write out of the box, but also gives something to build of off, if so inclined.

Thanks again...

Subscribe to Comments for &quot;LedBorg Running on DiddyBorg Coding Problem&quot;