Forum Update - Announcement about May 10th, 2018 update and your password.

How do you use "PUB Start : OK"?

lardomlardom Posts: 1,492
edited September 14 in Propeller 1 Vote Up0Vote Down
I'm debugging an RF project on a single Propeller. So far I have successfully controlled one servo with a potentiometer but when I tried to control two servos using code I have successfully used in the past it fails. ...I think it's because I have run out of cogs. I created a test to check if the syntax, and logic, was correct using a single Propeller and it worked.
I am going to re-test with two Propellers and I don't expect a major problem.
If I knew how to use "PUB Start : okay" I could save myself some grief. How do I do it?
Larry

If the grass is greener on the other side...it's time to water your lawn.

Comments

  • 25 Comments sorted by Date Added Votes
  • The tile is not to intuitive.

    You know, of course, you are going to be asked to supply the offending code. : )
    Infernal Machine
  • @Publison, My goal is to post it to the OBEX but at this point it's not readable yet.
    This is the method
    PUB Start : result
     
        stop       
        cog := cognew(Main, @Stack) + 1        'calibrate bits
        result := cog
    
    This is the object tree:
    Object%20Tree.PNG
    My naming conventions don't make sense to anyone else but me so I'll save that for the final step but if you need more code to understand what I'm asking I'll do it.
    Larry

    If the grass is greener on the other side...it's time to water your lawn.
  • You would generally do something like this:
      if (myobject.start() == false)
        ' Houston, we have a probem
    
    This assumes, of course, that one has been added to the cognew return value and then returned to the caller.

    It seems like you should have a multi-servo driver cog for your project; there is no need to have a new cog for each servo.
    Jon McPhalen
    Hollywood, CA
    It's Jon or JonnyMac -- please do not call me Jonny.
  • RaymanRayman Posts: 8,631
    edited September 13 Vote Up0Vote Down
    I think the Parallax Library servo object can do 32 servos with 1 cog...

    Look for: Servo32v7_RampDemo.spin that uses Servo32v7.spin in the library...
    Prop Info and Apps: http://www.rayslogic.com/
  • Or RTFM,

    As Jon pointed out this is a small trick used in most P1 examples.

    The cognew() call returns -1 on failure or 0 to 7 as ID of the cog started.

    To stop a cog later you might need its ID and need to now if it is started.

    if you directly save the return value you will need to compare it with -1 for failure and >-1 for SUCCESS

    if you save the return value with a added 1 then you can compare like Jon showed.


    Because 0==false <>0 == true

    Mike
    I am just another Code Monkey.
    A determined coder can write COBOL programs in any language. -- Author unknown.
    Press any key to continue, any other key to quit

    The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this post are to be interpreted as described in RFC 2119.
  • JonnyMac wrote: »
    It seems like you should have a multi-servo driver cog for your project; there is no need to have a new cog for each servo.
    I do have a working multi-servo driver. The problem I was that I could not send values to it from a transmitter object. I had been trying for two days to figure out why I was able to pass values to a single-servo driver but not to the two-servo driver. It made no sense, so today I decided to post my problem. Then I took my bicycle to the bike trail to clear my head.
    When I got back I was prepared to separate the tx half from the rx half. I tested it one more time and this time it worked.
    I'm actually disappointed that I didn't have a genuine issue: Maybe I should have given it one more day but when I get stuck I think it's better to ask for help even if I look stupid.
    On the positive side, I'm almost there in terms of what I wanted to accomplish.
    Larry

    If the grass is greener on the other side...it's time to water your lawn.
  • It might be helpful to share your protocol.
    Jon McPhalen
    Hollywood, CA
    It's Jon or JonnyMac -- please do not call me Jonny.
  • What's with the thread title Larry? Are you cryptic for a reason?

    Maybe a title that goes "how to use "PUB Start : okay" would be more suitable, and also some code.

    Tachyon Forth - compact, fast, forthwright and interactive
    useforthlogo-s.png
    --->CLICK THE LOGO for more links<---
    Latest binary V5.4 includes EASYFILE +++++ Tachyon Forth News Blog
    P2 SHORTFORM DATASHEET +++++ TAQOZ documentation
    Brisbane, Australia
  • lardomlardom Posts: 1,492
    edited September 14 Vote Up0Vote Down
    @JonnyMac, I made a screenshot of the terminal: "253" tells the Prop that I want to control the two servos. It's followed by two values, 0 to 127. This is refreshed 50 times a sec. I will add a second mode, "254", in a demo.
    What's with the thread title Larry? Are you cryptic for a reason?

    Maybe a title that goes "how to use "PUB Start : okay" would be more suitable, and also some code.

    Wow, I screwed that up. :blush: Thanks for using a tactful word!
    158 x 127 - 2K
    Larry

    If the grass is greener on the other side...it's time to water your lawn.
  • Peter JakackiPeter Jakacki Posts: 7,577
    edited September 14 Vote Up0Vote Down
    Hey Larry, if you go back and edit the very first post in this thread you can change the thread title. Easy as that.

    You really need to post your code or a lot more detail but if you are worried about anyone copying it, I wouldn't be. You can always pm the code to someone whom you trust though.

    P.S. Even your questions are cryptic :)

    Tachyon Forth - compact, fast, forthwright and interactive
    useforthlogo-s.png
    --->CLICK THE LOGO for more links<---
    Latest binary V5.4 includes EASYFILE +++++ Tachyon Forth News Blog
    P2 SHORTFORM DATASHEET +++++ TAQOZ documentation
    Brisbane, Australia
  • lardomlardom Posts: 1,492
    edited September 14 Vote Up0Vote Down
    @Peter Jakacki, I changed the title. People would see the misleading title in 'search' which is not a good thing.
    I'm not so concerned about keeping my code secret. My goal is to share it 'but' I 'am' concerned about asking someone to wade through a whole project which is still largely unreadable. It's a big 'scratch pad'.
    OTOH, when I have a working demo I really would appreciate if a professional member of this forum would proofread it so I could present it to the rest of the community. That's asking a lot but I want it to be 'headache free' if someone downloads it from the OBEX.
    edit: Yeah, my questions are "cryptic". Learning to ask the right questions is a skill in itself. Very often I have to work at defining a problem.
    Larry

    If the grass is greener on the other side...it's time to water your lawn.
  • Peter JakackiPeter Jakacki Posts: 7,577
    edited September 14 Vote Up0Vote Down
    If you want it to be "headache free" then that's a good thing but you can start by not being concerned about requesting the forum to wade through it, that's what we do. Besides even if we respond to the request we are under no obligation anyway but I'm sure there are a few that won't be able to stop themselves from helping :)

    I have my local Dropbox folders that I work from which are synched across my computers through the cloud and to which I share the link for anyone who wants to wade through at their leisure. What they do with it is up to them.

    Tachyon Forth - compact, fast, forthwright and interactive
    useforthlogo-s.png
    --->CLICK THE LOGO for more links<---
    Latest binary V5.4 includes EASYFILE +++++ Tachyon Forth News Blog
    P2 SHORTFORM DATASHEET +++++ TAQOZ documentation
    Brisbane, Australia
  • cavelambcavelamb Posts: 679
    edited September 14 Vote Up0Vote Down
    The manual says COGNEW returns -1 if no cogs are available or the COG ID if successful.

    stop
    cog := cognew(Main, @Stack) + 1 'calibrate bits
    result := cog
    This looks like you are adding 1 to the COG ID.
    That would make it a bit hard to communicate with the cog you started.
    cog := cognew(Main, @Stack)
    if cog == -1 ' we have a problem
    else
    result := cog
  • msrobotsmsrobots Posts: 1,992
    edited September 14 Vote Up0Vote Down
    As I said it is a convention used, thinking of it, you might be right but usually you never use the cogID except on stopping a cog.

    Variables in the VAR section get initialized to 0 on program load.
    so this
    VAR
    long cog
    
    PUB stop
      if (cog) 
        cogstop(cog-1)
        cog := 0
    
    PUB start
      stop
      cog := cognew(Main, @Stack) + 1 'calibrate bits
      result := cog
    
    PUB doSomething
      if start
         …
         …
         stop
    

    Now doSomething calls start and start
    will have cog as 0 when loaded so the first stop inside of start will not try to stop any cog since cog is 0 and 0 is false
    then start will try to start a cog and if successful write the cogID+1 into cog and result. On failure it sets both values to 0.
    if start was successful doSomething does something and calls stop. if not then doSomething does nothing.

    now compare to using the cogID as is.

    First you need to make sure that at program start cog is -1. So you need to put it in the DAT section to initialize it at program start.
    DAT
    cog long -1
    
    PUB stop
      if (cog>-1) 
        cogstop(cog)
        cog := -1
    
    PUB start
      stop
      cog := cognew(Main, @Stack)  'calibrate bits
      result := cog
    
    PUB doSomething
      if start>-1
         …
         …
         stop
    

    Now doSomething calls start and start
    will have cog as -1 when loaded so the first stop inside of start will not try to stop any cog since cog is -1 and cog>-1 is false
    then start will try to start a cog and if successful write the cogID into cog and result. On failure it sets both values to -1.
    if start was successful doSomething does something and calls stop. if not then doSomething does nothing.

    as you might see both variants do basically the same, but the second one is slightly larger (4 subtraction vs 1 subtraction and on addition)

    Enjoy!

    Mike
    I am just another Code Monkey.
    A determined coder can write COBOL programs in any language. -- Author unknown.
    Press any key to continue, any other key to quit

    The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this post are to be interpreted as described in RFC 2119.
  • JonnyMacJonnyMac Posts: 6,084
    edited September 15 Vote Up0Vote Down
    This looks like you are adding 1 to the COG ID.
    Adding one to the return value from cognew is standard practice. This allows a simple true/false test on the value (see my example above).
    That would make it a bit hard to communicate with the cog you started.
    No, it doesn't. When you start a cog that requires communication you must setup a mailbox -- this is done with cognew by passing a hub address through the par register.
    Jon McPhalen
    Hollywood, CA
    It's Jon or JonnyMac -- please do not call me Jonny.
  • I stand corrected.
    Maybe the OP does too?
  • Finally, it's working! I rewrote about 50% of my dual-servo driver.
    The problem was just bad code. It does take me a while to spot bugs but finding the solution is something I enjoy a lot.
    I'm going to take a short break and then jump right back in. I want to start work on the second mode of operation.
    Larry

    If the grass is greener on the other side...it's time to water your lawn.
  • Why not post the code so that others can review and comment?
    Jon McPhalen
    Hollywood, CA
    It's Jon or JonnyMac -- please do not call me Jonny.
  • JonnyMac wrote: »
    Why not post the code so that others can review and comment?

    There is a lot in it that I learned from you such as the receiver object listens to pin 1, which is controlled by the tx object.
    When I run it with the 433Mhz modules the rx values are exactly the same as cog-to-cog. That is huge.
    It's set up to run on the serial terminal.
    Larry

    If the grass is greener on the other side...it's time to water your lawn.
  • Have you considered learning to use the counters for generating precision pulses? It's actually very easy -- I use this strategy all the time in a varied of ways. Since you have need for a 2-servo object, I've attached my Spin-only, dual servo object that uses this technique.

    The high-wait-low strategy will always be off just a bit due to the Spin instruction fetch/decode overhead. Let me illustrate.

    First, let me show you how to time-test a section of code.
      elapsedtix := -cnt
    
      ' put code to test here
      
      elapsedtix += cnt - 544
    
      term.dec(elapsedtix)
    
    Note that there is a - 544 in the mix to remove Spin overhead from the test result.

    Now, let's update that to generate a 1ms pulse in the manner you're using.
      dira[16]~~
      
      elapsedtix := -cnt
    
      outa[16]~~
      waitcnt(cnt + clkfreq/1000)
      outa[16]~
      
      elapsedtix += cnt - 544
    
      term.dec(elapsedtix)
    
    The result is 81488, not 80000 which would be exactly 1ms. No, it's not a big error, but when dealing with servos, this could make a difference. This is why I uses the counter modules for servo pulses. I've attached a simple 2-channel servo driver to show you how that works. The driver even includes simple ramping.
    Jon McPhalen
    Hollywood, CA
    It's Jon or JonnyMac -- please do not call me Jonny.
  • @JonnyMac, Thank you. It bears repeating, you are one of the best. Making the project 'headache free' means I have to allow for digital servos and that means I need to generate precision pulses.
    You may remember that I set out to do the same thing with IR. The IR signal is a bit tougher to work with. Combined with my failure to get the dual-servo driver to work I put the IR version aside. I'll get back to it when I'm done with the RF version.
    A precision servo pulse for an IR driver is even more critical because the IR detector is finicky.
    Larry

    If the grass is greener on the other side...it's time to water your lawn.
  • Peter JakackiPeter Jakacki Posts: 7,577
    edited September 16 Vote Up0Vote Down
    Hey Larry, I think you could probably simplify your algorithms. I did a Q&D conversion of your SendCode routine into Tachyon and this is what it looks like.
    39000          := zero       ( adjust simply for scope timing instead of 48000 )
     zero 2*        := one
     one 2*         := start
     CLKFREQ 50 /   := pause
    
    pub SendCode ( code -- )
        1 HIGH start WAITX 1 LOW zero WAITX
        8 FOR 
          1 HIGH zero WAITX DUP 1 AND IF zero WAITX THEN
          1 LOW zero WAITX 2/
        NEXT
        DROP pause WAITX   
        ;
    

    BTW - You top file has multiple repeat loops as if you were testing but of course only the first one gets to loop.
    Here's the Tachyon code for your incrementing code loop
    BEGIN 256 FOR I SendCode NEXT AGAIN
    
    Original Spin code:
    repeat 
        number := index++
        Tx.SendCode(number)
        if index > 255
          index~
    

    Then I type "$71 SendCode" and this is what I got:
    800 x 480 - 40K

    Tachyon Forth - compact, fast, forthwright and interactive
    useforthlogo-s.png
    --->CLICK THE LOGO for more links<---
    Latest binary V5.4 includes EASYFILE +++++ Tachyon Forth News Blog
    P2 SHORTFORM DATASHEET +++++ TAQOZ documentation
    Brisbane, Australia
  • A precision servo pulse for an IR driver is even more critical because the IR detector is finicky.
    Did you ever see the move, Jerry Maguire? Let me paraphrase a statement from Jerry to his client, Rod. "Help us help you."
    IR in and out is pretty straightforward. Your statement vis-a-vis a servo pulse for an IR driver makes no sense to me? Do you mean a precision pulse for gating? Easy to do, and more than one way to skin that cat. Please understand, I'm trying to be helpful. I think the most difficult part of this process is explaining exactly what you're after, and not holding back details that would allow others to assist.
    Jon McPhalen
    Hollywood, CA
    It's Jon or JonnyMac -- please do not call me Jonny.
  • @Peter Jakacki, I'm going to learn Tachyon. I toggled the 433Mhz transmitter with waitcnt(clkfreq / 3000 + cnt) and got a square wave for about 20 seconds. When I toggled it using waitcnt(clkfreq / 2800 + cnt) the square wave was steady. That's too fast for Spin but I want to take advantage of that speed for projects that I have in mind for myself...and I have quite a few.
    Larry

    If the grass is greener on the other side...it's time to water your lawn.
  • lardom wrote: »
    @Peter Jakacki, I'm going to learn Tachyon. I toggled the 433Mhz transmitter with waitcnt(clkfreq / 3000 + cnt) and got a square wave for about 20 seconds. When I toggled it using waitcnt(clkfreq / 2800 + cnt) the square wave was steady. That's too fast for Spin but I want to take advantage of that speed for projects that I have in mind for myself...and I have quite a few.

    Great, you will have lots of interactive fun. But try this in Tachyon:
    1 APIN 3 KHZ
    
    You will see a steady 3kHz square wave on P1 using a counter.

    Tachyon Forth - compact, fast, forthwright and interactive
    useforthlogo-s.png
    --->CLICK THE LOGO for more links<---
    Latest binary V5.4 includes EASYFILE +++++ Tachyon Forth News Blog
    P2 SHORTFORM DATASHEET +++++ TAQOZ documentation
    Brisbane, Australia
Sign In or Register to comment.