Please help with optimizing function and identifying strange issue

Hi guys,
First post :) I'm currently enrolled in a Intro. Robotics class as part of my degree program and this was last week's homework assignment. I've already submitted it to make sure I'd be in the clear, and it does everything that my teacher wanted it to do, but I'm not happy with how un-optimized that the blink function works. This is an entry level class with no coding experience required, but I do have some C/C++ and robotics experience from CS/Elec. Engi classes I've worked on in the past.
http://pastebin.com/EecQhT3V

So basically, LED 27 is supposed to continuously blink while the servo rotates to it's 90 degree position, and then stop blinking when the servo blinks. The way that it should work in my mind is much different than the way that I was able to get it working. I THINK there should be a way to tell it to blink while that servo is in motion to the 90 degree position, rather than how I did it, which was trial and error with delay values and high/lows till I was able to match it almost perfectly. The problem with the way I did it is a few things, the function is long, for just a blinking light for less than a second. Then, if the servo was ramped down or up, the blinking wouldn't match up. It's just bugging me that I'm sure it could've been written better. The assignment has already been submitted and I'm sure since it does what it was supposed to do, I'll get full credit...but I'm not one for "good enough".

edit:Forgot the strange issue, on that servo to 0 degrees on line 8, I was trying to get a 1 second pause right after it hit 0 degrees, well even when I add a pause(1000); on line 9, it would immediately proceed to the next servo movement with no pause. The workaround that I was able to get working was adding a second pause(1000); right underneath the first. That does in fact pause for the 1 second that I was going for but only if there's a second pause command. The only thing I could think of was maybe the first pause was being used up during line 8's rotation?

Comments

  • 5 Comments sorted by Date Added Votes
  • You have a couple choices here. You need to introduce concurrency. Concurrency is just a big word for "do more than one thing". There are a couple obvious and easy ways to introduce concurrency to this application:

    1) Run each task in its own core of the processor. Cores on the Propeller are known as "cogs"
    2) Use the Propeller's hardware peripherals (the counter module) to blink the LED while the software moves the servo.

    Tonight is a bad night for me to go into teacher mode and find a bunch of links for you, but the above points should at least get you googling the right things. There are lots of examples out there.

    Also, welcome! Sounds like a pretty great school that you're attending if they're teaching with a Parallax Propeller :D
    David
    PropWare: C++ HAL (Hardware Abstraction Layer) for PropGCC; Robust build system using CMake; Integrated Simple Library, libpropeller, and libPropelleruino (Arduino port); Instructions for Eclipse and JetBrain's CLion; Example projects; Doxygen documentation
  • David,
    Greatly appreciate the advice here! I had no idea that the Propeller was as powerful as it is. I'm used to the Arduino, which I thought was a pretty capable board, but 8 cores? Wow!

    I have been reading up on the cog_run stuff and have played with the LED blinking code on the Learn page to visualize what everything is doing. That's interesting stuff. Actually running 2 functions at the same time. I need to think about how that would work with the original code I was working on and maybe figuring out how to stop the cog_run blink function when the servo stops. I seem to be getting warmer though.

    I do enjoy this school's program. We are using the ActivityBot for this robotics class. It's a more specialized kit, made for our program, so we get a few extra toys like Xbee, IR remote, Speaker, accelerometer and stuff like that. I'm enjoying it. Forgot how much I enjoyed coding and robotics

  • edit:Forgot the strange issue, on that servo to 0 degrees on line 8, I was trying to get a 1 second pause right after it hit 0 degrees, well even when I add a pause(1000); on line 9, it would immediately proceed to the next servo movement with no pause. The workaround that I was able to get working was adding a second pause(1000); right underneath the first. That does in fact pause for the 1 second that I was going for but only if there's a second pause command. The only thing I could think of was maybe the first pause was being used up during line 8's rotation?

    You need a pause after the servo move command, otherwise the program keeps executing statements while the servo command is being executed and the servo actually moves. That pause should be at least the amount of time that it takes the servo to move to its commanded position. Then you put in another pause for the delay you want.

    Unless the assigned problem is to get the servo to 90 degrees as fast as possible, I would move it in slow short increments and blink the led each increment. I like David's idea of using the counters (there are 2 per cog) to control both the servo and led blink, although that will add a bit of complexity (once started they run independently of the rest of the program, but they can be started and stopped by the program). I find them a fun and useful aspect of the propeller. If you download the free Propeller Education Kit manual pdf (from the store) there is a chapter on using the counters. It's in the Spin language, but its easy to translate the concepts to C.

    Tom
  • BigBadGhost,

    Andy Lindsay wrote a great introduction series to multicore with the Propeller for our Parallax Learn website: Multicore Approaches

    It's definitely worth a read if you're interested in optimizing programs for the Propeller microcontroller.

    The rest of the Propeller C tutorials will also have code examples and in-depth explanations for many of the sensors and add-ons you're using in your class.
  • I think TWM has the ideal approach for a non-parallel solution - Use a loop with a delay in it to move the servo slowly while blinking the LED. This would work on any system, and doesn't cost you an extra core for such a simple task.

    Pseudo code like this:
      servo(17, 1800);  // set initial position
      pause(2000);    // wait a moment
    
      // Now count backwards from 1800 to 0, in increments of 20 (90 steps total)
      for( int angle=1800; angle>0; angle -= 20 )
      {
        servo(17, angle);
        high(27);
        pause(50);
        low(27);
        pause(50);
      }
    
      pause(2000);  // wait
    
      // Count back up to 1800, in increments of 20
      for( int angle=0; angle<1800; angle += 20 )
      {
        servo(17, angle);
        high(27);
        pause(50);
        low(27);
        pause(50);
      }
    

    There are other approaches. On the Prop, the servo library has a ramping function, so you could probably set the ramp speed, trigger the move, then constantly blink the LED while asking the servo library "have you finished ramping yet?" and then pause when it finishes. The servo library on the Prop already runs in its own core.
Sign In or Register to comment.