Shop OBEX P1 Docs P2 Docs Learn Events
Programming Style? — Parallax Forums

Programming Style?

RogerNRogerN Posts: 19
edited 2009-12-29 06:53 in Robotics
Looking through the Boe-Bot manual I see they use subroutines and For Next loops to move the Boe-Bot around. I started out programming microcontrollers and stamps with that style of programming and then learned to program PLCs. Changing from one style of programming to another introduced a learning curve but the results were well worth it, thought others might be interested. The problem with the examples in the manual is that many times only one thing is being done at a time. The style of programming I'm thinking of would allow you to monitor your sensors and control your servos all at the same time.

For example the book might have something like this:

For I = 1 to 50
gosub Back_Up
pause 20
next

Instead, you could do something like:
main:

Backup = 50
If Backup > 0 then gosub Back_Up

pause 15 'Using 15 MS estimating loop to take around 5ms with more code than this example
goto main

Back_Up:
pulsout 12, 650
pulsout 13, 850
Backup = Backup -1
return

The idea is that in the 2nd example is backing up (or anything else) never prevents other code from running. All control would be based on nothing holding the program up and using flags and conditions to decide what to do. Perhaps to control movement, If Backup > then Back_Up, If Turn Left or Right > 0 then Turn left or right, If Back_Up = 0 and Turn = 0 then Move_Forward. The whole loop would be executed at approximately 50 cycles per second and program flow would be based on making conditions true or false.

Anyway after I get my Boe-Bot assembled after Christmas I'll try to get something working in the programming style I'm thinking of and post it. Though it sometimes makes writing the code more difficult, it allows for another task to be inserted in the loop easily and gives the capability of running and monitoring multiple items. Maybe some are already is programming in a similar style?

RogerN

Comments

  • ZootZoot Posts: 2,227
    edited 2009-12-22 07:24
    It's a pretty common technique -- blast through your main loop as quickly as possible and set flags and/or counters so individual routines get run when/if they need to without any one routine holding up the works. Essentially, it's a kind of Finite State Machine. Take it further than your example though -- assign each action or module a state and a timer, and use those to determine what actions will take place, rather than counters for each action per se (backup, forward, etc).

    e.g.

    
    Main:
    IF timer > 0 THEN 
       timer = timer - 1
    ENDIF
    
    IF state = 0 THEN
       IF sensors < 100 THEN
          state = 1
          timer = 100
       ENDIF
    ELSEIF state = 1 THEN
        IF timer > 0 THEN
             ' pulse backup
        ELSE
             state = 2
             timer = 50
         ENDIF
    ELSEIF state = 2 THEN
             Led = ~Led ' blink light
             IF timer > 0 THEN
                 IF sensorLeft < 100 THEN
                 ' pulse turn right
                 ELSEIF sensorRight < 100 THEN
                 ' pulse turn left
                ENDIF
              ELSE
                 state = 0
             ENDIF
    ENDIF
    
    GOTO Main
    
    
    



    Keep in mind that many of the examples in the Parallax literature are designed for utter clarity and simple explanation, rather than sophistication of technique, so that users of varying ages and skill levels can get their platforms moving and doing things.

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    When the going gets weird, the weird turn pro. -- HST

    1uffakind.com/robots/povBitMapBuilder.php
    1uffakind.com/robots/resistorLadder.php
  • RogerNRogerN Posts: 19
    edited 2009-12-22 13:58
    Great, that's what I was hoping to see. I've done a good bit of PLC programming for companies but I'm a newbie at converting ladder logic to PBasic. I like that your example uses one timer and one state because of the limited variables available in the Basic Stamp. All the examples I saw in the Boe-Bot manual put the processor in a for next loop for reverse and turns, preventing other stuff from getting processed. Are there source examples that you know of where the loop goes through, or user source examples, posted somewhere?

    Also, to make the loop run at a precise time, I'm considering making some sort of 50 Hz oscillator, then at the end of the loop it waits on the oscillator instead of pausing without knowing actual execution time. One possibility for the timer would be a small 8 pin PIC, I don't know of a better way right now.

    RogerN
  • ZootZoot Posts: 2,227
    edited 2009-12-22 16:57
    I don't know if another micro is necessary for timing -- a 555 would do. For my part, I often use a DS1307 RTC -- it has a square-wave out pin that can be configured to different frequencies. I set it for 1hz, which gives 1/2 second edges to count (and of course having date/time/day is nice too). The host micro does something like this:

    
    
    realHalfSecs VAR Byte
    sqWaveIn PIN 0
    
    '.....
    
    Main:
    
        IF realHalfSecs.BIT0 <> sqWaveIn THEN
            realHalfSecs = realHalfSecs + 1 ' this is a free-wheeling counter that can be post-scaled for timing blinking lights, etc
    
           ' update various state machine timers; these all count down in 1/2 second intervals
            IF timer0 > 0 THEN
               timer0 = timer0 - 1
            ENDIF
    
            IF timer1 > 0 THEN
               timer1 = timer1 - 1
            ENDIF
    
        ENDIF
    
        ' more code
       
       GOTO Main
    
    



    The above works great as long as the main loop never takes more than a 1/2 second. The only hitch is when reloading a countdown timer, you may get a "quick" half second if the next edge comes around sooner (likely), but for real time apps like robotics and the like, it's great because you can basically load a timer and know that the state will execute for 8.5 seconds or 3.5 seconds, etc. (technically, a timer loaded with 8 will actually result in a time of 8.0-8.5 seconds depending on when the edge comes around, though there are other tricks for loading the timer right after an edge on the square wave so you can count on the "true" time).

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    When the going gets weird, the weird turn pro. -- HST

    1uffakind.com/robots/povBitMapBuilder.php
    1uffakind.com/robots/resistorLadder.php
  • danieldaniel Posts: 231
    edited 2009-12-23 06:04
    RogerN said...
    Are there source examples that you know of where the loop goes through, or user source examples, posted somewhere?

    There are. Here is one link www.bluebelldesign.com/FSM_explain.htm that discusses Finite State Machines (and Subsumption Architecture). Ignore the subsumption stuff if you want, but observe how the FSMs are coded. Work thru the examples; the elegance of the technique will match your expectations. The discussion also contains a link to the article I've learned much from, namely www.bluebelldesign.com/Robot%20Subsumption%20DLC.pdf. Here is an Instructable www.instructables.com/id/Obstacle-Avoiding-Robot-with-a-Personality!/step7/Fill-up-Bobs-Brain/ that explains a robot programmed with FSM/Subsumtion, linking back to the Blue Bell Design articles.

    There are other resources that should be mentioned. They include:

    Tracy Allen's FSM discussion at emesystems.com/BS2fsm.htm (sometime take a look at Tracy's other Stamp information 'a page up' at emesystems.com/BS2index.htm).

    Using the Parallax search engine to search the 'Site' for 'finite state' yields some interesting results. I think you will see that this link all but shouts PLC at you: www.parallax.com/Resources/ApplicationsContests/Industrial/TrafficLight/tabid/340/Default.aspx.

    Some of the Nuts & Volts articles may be of use. For example, program #44.1 in Timing is Everything www.parallax.com/Portals/0/Downloads/docs/cols/nv/vol1/col/nv44.pdf has code that attempts to replicate the determinism of the PLC's scan/sweep periodicity.


    Finally, Wikipedia has a good, but terse, explanation of the FSM en.wikipedia.org/wiki/Finite-state_machine, and references a book I encountered several years ago--a book that quite changed how I thought about programming--www.state-machine.com/psicc/. Neither of these references are directly related to the BasicStamp, but they may help put a larger context around what you learn when you bump you knees on the edges of the earlier examples.


    Daniel
  • RogerNRogerN Posts: 19
    edited 2009-12-23 14:59
    I don't know if another micro is necessary for timing -- a 555 would do. said...
    I thought about a 555 timer and it's a possibility. The 8 Pin PIC I was thinking about are $0.84 Qty. 1 from Digi-Key. Their advantage that I could see would be that I can output the pulse I'm wanting plus serial communicate maybe a timing word, so I would know if I missed any counts.

    I'm wanting my timing to work very similar to your example but I'm hoping for 1/50 of a second instead of a half second, and wait on the timer pulse either at the beginning of main or at the end. If I use the BS2 I guess I would have to keep the instruction count pretty low, that's part of the reason I'm trying to use the BS2px. Maybe I could execute a few instructions one time through the loop, a few others the next time, a few others the next time, etc. Maybe get pulsouts every 20ms and execute other code based on the lower 4 bits of the timer.

    If timer lower nibble = 0, read ping sensors, calculate & logic, pulse out to servos, wait on timer input
    If timer lower nibble = 1, read light sensors, calculate & logic, pulse out to servos, wait on timer input
    If timer lower nibble = 2, read wisker switches, calculate & logic, pulse out to servos, wait on timer input
    ...

    Perhaps select case would be more efficient, I have a lot of learning to do.

    RogerN
  • RogerNRogerN Posts: 19
    edited 2009-12-23 15:30
    Sorry about previous post where I attempted to quote from Zoot, I don't see a "Preview" option.

    Daniel,
    Thanks for all the links, now I have some reading to do smile.gif I'm not real sure yet if what I'm wanting to do is a finite state machine or not. I guess my basic goal is to convert from PLC logic to PBasic and/or learn to program more efficiently and accomplish multiple tasks in the most timely and efficient manner that I can. I see a lot of questions on the forums that wouldn't be a problem if the programming was done to work like a PLC.

    Currently on my Board of Education, I have a compass, a 2 axis accelerometer, and the Ping sensor. I'm planning to add whisker switches and light sensors, and a servo for the Ping sensor. Might take some creative programming to get it all running and still pulse the servos every 20ms.

    RogerN
  • danieldaniel Posts: 231
    edited 2009-12-23 16:17
    RogerN,

    Follow your heart on this, you are on the right track.

    Another methodology, implicitly used as a control structure in many of the examples listed above, is called the Super-Loop Architecture.

    The key concept (at least for what you are wanting to accomplish on the BasicStamp) is that each 'task' must fall-thru, doing one (or a small handful) of steps on each super-loop iteration, rather than spin in a task-local loop to complete the task's action. You will likely find that you will need to interleave the tasks (only working on some of them on each sweep) so that you can update the servo motors PULSOUT in a timely fashion.

    This is generally the same principle of PLC programming, and why in-sweep logic loops are 'discouraged' in many PLC programming shops. blush.gif Ever had a in-sweep loop fail to terminate? blush.gif

    BTW, the FSM or the subsumption techniques will allow you to easily add chunks of program to manage each additional sensor as it is added. I would recommend starting by getting the 'bot to travel a straight line for a defined distance, and then manage the ability to turn in fixed angles, say 30 and 45 degrees left or right. See if you can get the 'bot to traverse a regular polygon (triangle, square, octagon, etc.) by standard dead-reckoning motion. Then integrate the sensors one at a time. You know--walk before you run.

    Enjoy!

    Daniel
  • RogerNRogerN Posts: 19
    edited 2009-12-26 06:08
    Since a BS2 came with my Boe-Bot, and I ordered a BS2px, I could use the BS2 to read commands and pulsout to the servos. The BS2px could read sensors and make navigation decisions and set outputs to go forward, reverse, left, right, stop, and perhaps 4 bits for velocity. That way the BS2 could run a very fast loop and keep up with the servo update rate, the BS2px could run its own loop reading sensors and navigating, to go forward all the BS2px would have to do is set an output to command forward and set a velocity command. May be worth a try and fun to experiment with.

    RogerN
  • danieldaniel Posts: 231
    edited 2009-12-26 14:20
    It does sound fun.

    And all that you have learned in the automation world applies here--at least the principles are the same, the details may vary. I find coordinating independent asynchronous processors to be interesting at times.

    If you wire the interface to the motor control Stamp to a set of header pins, you could first plug in a wire connecting a button-box that allows the manipulation of the command interface bits. Thus details of that subsystem can be worked out independently.

    Given the generally poor resolution of the 'speeds' variations available to standard RC servos converted to continuous rotation (e.g., the BoeBot servos), you may find that 2 bits would be enough to give you three non-zero velocities and the zero-velocity. Or perhaps have 2-bits to encode left, right, straight, stop; and one or two bits to encode a velocity; and one bit for the forward/reverse.

    Post back periodically with your progress or questions.

    Daniel
  • RogerNRogerN Posts: 19
    edited 2009-12-26 20:15
    In PLC programming it amazed me how much you can control with just one processor, in stamp programming it amazes me how little you can control with one processor.
    For example, I programmed a 16 station machine that assembled automotive lamps.
    Station 1 put a socket on an indexing table
    Station 2 put an O-ring on the socket,
    Station 3 did a leak test on O-ring and socket
    Station 4 and 5 put 2 contacts in the socket
    Station 6 tested the contacts were locked in, tried to push them out.
    Station 7 put in an optional 3rd contact if needed
    Station 8 tested 3rd contact push out
    Station 9 did a machine vision inspection for bent contacts
    Station 10 inserted the bulb, picked from tray row and column.
    station 11 verified bulb seated and checked for clear versus amber lamp
    Station 12 did a current test for the lamp filaments, put a pin stamp if bulb tested good
    Station 15 pick-N-place gripper picked completed bulb assembly up and put in a tray, indexed rows & columns.
    Station 16 made sure position was empty from previous station. (just a photo eye)

    All stations ran at the same time plus if any test failed it would track that part, no other operations would be performed on that part, and that part would go into a reject bin. Plus, production data was counted, number good, number bad and reason they were bad. Plus the program nearly doubled in size adding alarms, the cause of the fault had to be displayed on the operator panel. The PLC had 160 inputs and 128 outputs IIRC.

    To see all those operations run at once, and get a completed bulb and tested bulb/socket assembly out of the machine every 6 seconds made a busy looking machine. Then to see Boe-Bots programmed to tie the processor to 1 operation at a time, well, there's a lot of potential room for improvement on the Boe-Bots I think, and that's good news. I'm hoping to get a good program running and post the source code so others can modify for their use.

    RogerN
  • danieldaniel Posts: 231
    edited 2009-12-27 22:13
    I find them both to be amazing.

    I think the key is the perspective introduced by...
    RogerN said...
    The PLC had 160 inputs and 128 outputs IIRC.
    explains the difference in scale. The BS2 has 16 pins that can be either a digital input, a digital output, an analog input or and analog output, and these roles can be changed at any time in the program. The PLC you mention had a main processor and a handful of secondary processors networked by the PLC's backplane. Each of PLC's I/O cards is a separate processor dedicated to just one thing--backplane communication to the main processor and interfacing its small handful of bits (8 or 16 typically) to the backplane (and those bits have only one of the roles enumerated above). I'd suspect that there were maybe another half dozen processors involved in the machine described, e.g, the vision subsystem.

    I'll admit I found the transition from programming VAX and PC computers to programming PLCs rocky in areas, and I truly abominated the Ladder Logic programming methodology at first. I've now programmed machine controls of sufficient complexity, that I can not, for some things, think of a better idiom than the ladder logic presentation to represent the programming intent (although I still find it cumbersome, and terribly slow, at times to use the point, click, and drag visual programming of ladder logic and so sometimes drop into the command line entry of logic).

    Since then, I have come 'full circle', you might say. A machine programmed in VisualBasic with interfaces to digital I/O and a Galil motion control subsystem needed updating. I found that re-writing the I/O & Motion interface in a periodic VB Timer's code in the idiom of the PLC sweep allowed me to substantially reduce both unexplained behaviours and complexity of the programming (those 'unexplained behaviours' were artefacts of the spaghetti-code was the result of the originally implemented code and the accretion of changes).
    RogerN said...
    To see all those operations run at once, and get a completed bulb and tested bulb/socket assembly out of the machine every 6 seconds made a busy looking machine.
    And quite a satisfaction, too. You will get an even bigger kick when you see your little 'bot running about all on its own.
    RogerN said...
    ...to tie the processor to 1 operation at a time,...
    You will find that the instructions that 'tie up' the processor are generally few and usually limited to those that manipulate an I/O pin in some 'analog' fashion--like read a voltage level, or send/receive a burst of communication data. You might think of these as the type of PLC blocks called, at least in the Allen-Bradley PLCs, a Message (MSG) block. They are a type of sub-program that the Stamp calls to accomplish a complex action, and the Stamp's architecture has it wait until that action is completed before solving its next instruction.

    If you would find appreciation of the complexity of some of these Stamp instructions that 'tie up' the processor, I would suggest Scott Edwards'
    The PIC Source Book (www.dontronics.com/see.html). I do not suggest that the Stamp's routines use this underlying code, but the information in Edwards' book shows one way to accomplish a similar behaviour. Treat this as an interesting bit of history--take your complete understanding of the Stamp's instructions from the Parallax instruction and reference books. And the guides Elements of PBASIC Style and PBASIC 2.5 Syntax Enhancement Notes will give some useful tips of the style of crafting the code; find them at www.parallax.com/tabid/440/Default.aspx.

    The programs in the resource books will yield a working 'bot doing exactly what that exercise is attempting to teach the student. It is the program code that you craft changes that generic 'bot to your own 'bot--the one you can hug and cherish. wink.gif

    Daniel
  • RogerNRogerN Posts: 19
    edited 2009-12-28 04:29
    The code that ties up the processor I was referring to was the Pbasic programs written by users. I don't find it much of a problem that sending a 1.5ms pulse takes a little over 1.5ms. For example, roaming with wiskers reads the wisker switches and then goes off to a subroutine to reverse and turn, no other code is running while reversing and turning. I have my ping sensor connected and started making my own program cutting and pasting from the roaming with ping program. Here's one of the subroutines, the commented out parts were from the original

    Task0:
    right = 28 ' This replaced the 4 GOSUBs I commented out of the original
    ' GOSUB Turn_Right
    ' GOSUB Turn_Right
    ' GOSUB Turn_Right
    ' GOSUB Turn_Right
    RETURN

    In the original program each GOSUB Turn_Right was a for next loop sending 7 pulses to turn right, I just loaded a right VAR with 28 and the main loop will cause it to turn right for the next 28 passes through the loop. In the original the boe bot turned right by executing nothing but pulsouts for 28 loops, my change caused the puslouts execute for 28 passes through the main loop. The original program worked the same in the end but made it more difficult to do other tasks at the same time.

    On the PLC program the machine vision and the servo positioners each had their own processors, but the 160 Inputs and 128 outputs only need one program and one processor. I know others exist for bus control etc, but you just need one for all the ladder logic. Since the BS2 reads instructions from a serial EEPROM, it can't be as speedy as a PLC but for 16 I/O it's plenty fast with good programming.

    My feeling is that the BS2 is plenty fast for the I/O and memory available and can do multiple things at once (one at a time fast enough that they appear to be done at once) if the user program is written to not prevent other "rungs" from executing. For example, I can use all the available program memory and write "main: GOTO main" and it will do nothing.

    RogerN
  • danieldaniel Posts: 231
    edited 2009-12-29 00:10
    RogerN,

    It sounds like you have a clear understanding of the capabilities of the BasicStamp, and understand the path to where you want to go with the programming style.

    I look forward to seeing the control structure you develop.

    Daniel
  • danieldaniel Posts: 231
    edited 2009-12-29 06:53
    RogerN,

    I forgot this item in the earlier discussion.

    Parallax offers a Stamp PLC, item 30064, see link www.parallax.com/StoreSearchResults/tabid/768/txtSearch/30064/List/0/SortField/4/ProductID/290/Default.aspx and on that page there is a link to the Stamp PLC Manual (www.parallax.com/Portals/0/Downloads/docs/prod/indl/StampPLC.pdf) with a programming template & suggestions that might be similar to what you are working toward. The source code for the programming suggestions is available from item 30064's page, just above the 'Related Products'.

    Daniel
Sign In or Register to comment.