Simple IDE waitpeq and waitpne code problem.

Hi everyone,
I have propeller quickstart board. I like work it but I have a problem. I use waitpeq and waitpne in C code, its not working properly.

int count=0;
while(1)
{
waitpeq(1,0); //wait pin0 to high
waitpne(1,0);// and wait pin0 to low
count++; // count++
}
when p0 to high and low cnt is increasing two.

another problem I don't select different pin for input.
ı use waitpeq(1,2); or waitpeq(1,5)// it is not working.Propeller select pin0 for input, this code only work on pin0.

Please help me.
Thanks in advance

Comments

  • 17 Comments sorted by Date Added Votes
  • It could be a "debouncing" problem - or the lack thereof debouncing. I'm not sure what is setting the pin low, but if it's a button or switch, the input can "bounce" up and down a few times. This could be what you're seeing. Try putting a very small wait in-between the two waitX instructions
    int count=0;
    while(1)
    {
    waitpeq(1,0); //wait pin0 to high
    waitcnt(CNT + 100);
    waitpne(1,0);// and wait pin0 to low
    count++; // count++
    }
    

    By the way, do you see the "C" in the text box formatting bar (here on the forums, not SimpleIDE)? Pressing that and then pasting your code, or pasting your code, highlighting it, and then pressing the "C" will make your code easier to read here on the forums, like mine right above.
    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
    Tag me with "@DavidZemon" if you have a question for me. I will be checking these forums far less for the forseeable future.
  • Based on the propeller.h documentation:

    #define waitpeq ( state, mask )
    Wait until INA equal state & mask.
    Parameters
    state Target value
    mask Ignore masked 0 bits in state

    #define waitpne (state, mask )
    Wait until INA not equal state & mask.
    Parameters
    state Target value
    mask Ignore masked 0 bits in state

    you need a high or low (1 or 0) pin state in the first position and a 1 in the bit corresponding to the pin number (P0 = bit 0 = 0b1 = decimal 1) in the second position.

    try this:
    int count=0;
    while(1)
    {
    waitpeq(1,1); //wait pin0 to high
    
    waitpne(1,1);// and wait pin0 to low (that is not equal high)
    count++; // count++
    }
    

    If the code is entered with p0 = low, the program should wait until the pin goes high. But it will then halt until the P0 = low again.

    Tom
  • todieforteotodieforteo Posts: 4
    edited March 12 Vote Up0Vote Down
    Hi David thank you for reply. I try your code but it is not working. when I delete ' waitcnt' code it is work. wyh didn't work (CNT+100) I don't know.
    I use IR (reciever and transmitter) with op-amp comparator to have clear pulses. I increase delay time for example (CLKFREQ/1000 + CNT) it is good work but ı don't want too much delay time. I am working on RPM counter speed motor.Do you have a different idea in this matter?
    int count=0;
    while(1)
    {
    waitpeq(1,0); //wait pin0 to high
    waitcnt(CNT + 100);
    waitpne(1,0);// and wait pin0 to low
    count++; // count++
    }
    


    twm47099 thank you for your reply. its working but count increase two one pulse. I have to use delay time, I think. Pin select working good thank you for your helps.
    int count=0;
    while(1)
    {
    waitpeq(1,1); //wait pin0 to high
    
    waitpne(1,1);// and wait pin0 to low (that is not equal high)
    count++; // count++
    }
    

  • Hi David thank you for reply. I try your code but it is not working. when I delete ' waitcnt' code it is work. wyh didn't work (CNT+100) I don't know.
    I use IR (reciever and transmitter) with op-amp comparator to have clear pulses. I increase delay time for example (CLKFREQ/1000 + CNT) it is good work but ı don't want too much delay time. I am working on RPM counter speed motor.Do you have a different idea in this matter?
    int count=0;
    while(1)
    {
    waitpeq(1,0); //wait pin0 to high
    waitcnt(CNT + 100);
    waitpne(1,0);// and wait pin0 to low
    count++; // count++
    }
    

    Well, once you get the pin mask in there correctly, as twm47099 mentioned, there are a couple things that could go wrong (that I can think of)

    1) The wait is too short, and it overflows giving you a 53 second wait period. Knowing whether you're compiling as LMM or CMM can help us make a better guess as to what the shortest wait period is.
    2) The pulse is smaller than 100/80,000,000 of a second (for measuring RPM, that's pretty unlikely :) )

    You mentioned that "waitcnt(CLKFREQ / 1000 + CNT)" worked, but that was a longer delay than you wanted. The good news, that gives you lots of wiggle room. CLKFREQ / 1000 should be 80000, assuming an 80 MHz clock frequency. So try a delay of 30 us, or (CLKFREQ * 30 / 1000 / 1000)
    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
    Tag me with "@DavidZemon" if you have a question for me. I will be checking these forums far less for the forseeable future.
  • JonnyMacJonnyMac Posts: 5,854
    edited March 13 Vote Up0Vote Down
    Context matters. What are you doing with the pin? If, for example, you're looking for a button press and release, then debouncing is in order.

    Here's a mechanism I use (converted from Spin) that works like a "click" event in PC program: the button has to be pressed and released.
    void get_button(int pin)                      // debounce selected pin
    {
      int dbmask = 0;
    
      while (dbmask != 0b11110) {                 // 20ms+ press, then release
        pause(5);                                 // loop pad
        dbmask = (dbmask << 1) & 0b11111;         // remove oldest scan, make room for new
        dbmask |= input(pin);                     // put new scan into LSB of dbmask
      }
    }
    
    As you can see, the pin must be held high for at least 20ms, then released -- at that point the code will return to the caller. This function is easy to tune by changing the loop timing an the number of bits used in dbmask.

    For longer duration debouncing, the mask trick isn't always convenient. Here's a bit of code I wrote for a friend's retrofit of a kiddie ride (kiddie ride computer replaced with Propeller and small video player). I have a background cog that run every millisecond. In that cog TTL inputs are scanned. After than, this code is called. It does a long-duration debounce of the coil acceptor.

    (this is Spin -- I'll leave you to convert to C)
    var
    
      long  cstate                                                  ' coin input state
      long  ctimer                                                  ' coin switch input timer
      long  coins                                                   ' coin count
    
    
    pri scan_coins
    
      cstate := ((cstate << 1) | (ttlpins & 1)) & %11               ' update input state
    
      case cstate
        %00 :                                                       ' no input
          if (++ctimer > 0)                                         ' update timer
            ctimer := 0                                             '  clear if not in hold-off
    
        %01:                                                        ' new input
          if (++ctimer => 0)                                        ' if not in hold-off
            ctimer := 1                                             '  start debounce timing
    
        %11 :                                                       ' continued input
          if (ctimer > 0)                                           ' if timer active
            ++ctimer                                                '  increment
    
        %10 :                                                       ' input released
          if (ctimer => DB_MS)                                      ' debounce threshold met?
            ++coins                                                 '  yes, inc coin count
            ctimer := -DB_HOLDOFF                                   '  put input into hold-off
    


    Jon McPhalen
    Hollywood, CA
    It's Jon or JonnyMac -- please do not call me Jonny.
  • todieforteotodieforteo Posts: 4
    edited March 13 Vote Up0Vote Down
    thanks to all for reply. I use very small wait time and its work good.

    JonnyMac thank you for your helps. I use to define binary code such as (0b11110) in simple IDE but its not work. I think, SimpleIDE can't decode binary code.
    Fortunately, I solved this problem by using very small waiting times.(CLKFREQ/10000 + CNT)
    void get_button(int pin)                      // debounce selected pin
    {
      int dbmask = 0;
    
      while (dbmask != 0b11110) {                 // 20ms+ press, then release
        pause(5);                                 // loop pad
        dbmask = (dbmask << 1) & 0b11111;         // remove oldest scan, make room for new
        dbmask |= input(pin);                     // put new scan into LSB of dbmask
      }
    }
    



  • JonnyMacJonnyMac Posts: 5,854
    edited March 13 Vote Up0Vote Down
    Hmmm... it does for me. Again, I'm not a C programmer so I haven't updated SimpleIDE in a long time. The version I'm running is 1.0.2(RC2).

    Here's the complete program that I used to test that function. It is running -- and working! -- on an Activity Board.
    #include "simpletools.h" 
    
    #define BUTTON  0
    #define LED    26
    
    
    void get_button(int pin)                      // debounce selected pin
    {
      int dbmask = 0;
      
      while (dbmask != 0b11110) {                 // 20ms press, the release
        pause(5);                                 // loop pad   
        dbmask = (dbmask << 1) & 0b11111;         // remove oldest scan, make room for new
        dbmask |= input(pin);                     // put new scan into LSB of dbmask
      }  
    }
    
    
    int main()
    {
      low(LED);
     
      while(1)
      {
        get_button(BUTTON);
        toggle(LED);
        pause(1000);
      }  
    }
    

    FOLLOW UP: As I do want to learn C for the Propeller I went ahead and installed the latest version of SimpleIDE (1.1) -- the program still works.
    Jon McPhalen
    Hollywood, CA
    It's Jon or JonnyMac -- please do not call me Jonny.
  • JonnyMac your code work on ABWX Board. But with Quickstart pad it's not quite the same (since pad are not button), and maybe todieforteo encounter this problem on his QS.

    i recorded reading this thread for QS pad
    http://forums.parallax.com/discussion/135794/quickstart-touchpad-tutorial-demo-for-propgcc
  • JonnyMacJonnyMac Posts: 5,854
    edited March 13 Vote Up0Vote Down
    Based on the original code, it doesn't look like he's using the QS pads in the charge/discharge fashion they're intended for (but rarely works -- I hate those things).
    Jon McPhalen
    Hollywood, CA
    It's Jon or JonnyMac -- please do not call me Jonny.
  • JonnyMac , I try again your source code on simpleIDE (1.0.2) its working good. I think, I maked a mistake somethings first try.
    i want to ask you something. can we use binary system to define for pin ?
    for example ;
    waitpeq(%0100, %1100,0) 'Wait for P3 & P2 to be low & high
    

    on spin code , we can use binary numeric system to define pins. This makes our job much easier. we can detect more than one pin in waitpeq function at the same time. is this possible in C code?

    thanks in advance.
  • I believe 0b0100 will be binary in C/C++ - anything prefixed with 0b
    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
    Tag me with "@DavidZemon" if you have a question for me. I will be checking these forums far less for the forseeable future.
  • What David said! :)
    Jon McPhalen
    Hollywood, CA
    It's Jon or JonnyMac -- please do not call me Jonny.
  • DavidZemon wrote: »
    I believe 0b0100 will be binary in C/C++ - anything prefixed with 0b

    While this is generally acceptable syntax with GCC, it is relying on a compiler extension (unless you are using C++14 or later) so it should be avoided if the code is intended to be portable across compilers, or it must be strictly standard compliant (can check for standard compliance by compiling with -Wpedantic).
  • DavidZemon wrote: »
    I believe 0b0100 will be binary in C/C++ - anything prefixed with 0b

    While this is generally acceptable syntax with GCC, it is relying on a compiler extension (unless you are using C++14 or later) so it should be avoided if the code is intended to be portable across compilers, or it must be strictly standard compliant (can check for standard compliance by compiling with -Wpedantic).

    Good to know! So was there no C or C++ standard way to provide binary literals until C++14?
    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
    Tag me with "@DavidZemon" if you have a question for me. I will be checking these forums far less for the forseeable future.
  • DavidZemon wrote: »
    DavidZemon wrote: »
    I believe 0b0100 will be binary in C/C++ - anything prefixed with 0b

    While this is generally acceptable syntax with GCC, it is relying on a compiler extension (unless you are using C++14 or later) so it should be avoided if the code is intended to be portable across compilers, or it must be strictly standard compliant (can check for standard compliance by compiling with -Wpedantic).

    Good to know! So was there no C or C++ standard way to provide binary literals until C++14?

    That is correct. It was considered for C99, but per the revision rationale (open-std.org/jtc1/sc22/wg14/www/C99RationaleV5.10.pdf, bottom of page 51) "A proposal to add binary constants was rejected due to lack of precedent and insufficient utility". I don't agree with that but the standard is what it is. Support wasn't added in C11 either but now that it has been added to C++ maybe it will make it into the next revision of the C standard.

    Another readability feature that was added by C++14 is using single quotes as digit separators (e.g. 0b0101'1010)just as underscores can be used in SPIN/PASM.
  • DavidZemon wrote: »
    DavidZemon wrote: »
    I believe 0b0100 will be binary in C/C++ - anything prefixed with 0b

    While this is generally acceptable syntax with GCC, it is relying on a compiler extension (unless you are using C++14 or later) so it should be avoided if the code is intended to be portable across compilers, or it must be strictly standard compliant (can check for standard compliance by compiling with -Wpedantic).

    Good to know! So was there no C or C++ standard way to provide binary literals until C++14?

    That is correct. It was considered for C99, but per the revision rationale (open-std.org/jtc1/sc22/wg14/www/C99RationaleV5.10.pdf, bottom of page 51) "A proposal to add binary constants was rejected due to lack of precedent and insufficient utility". I don't agree with that but the standard is what it is. Support wasn't added in C11 either but now that it has been added to C++ maybe it will make it into the next revision of the C standard.

    Another readability feature that was added by C++14 is using single quotes as digit separators (e.g. 0b0101'1010)just as underscores can be used in SPIN/PASM.

    Thanks for the info. What the heck is wrong with underscores as digit separators? Java has that too as of Java 7... seems to make a lot more sense than a single quote.
    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
    Tag me with "@DavidZemon" if you have a question for me. I will be checking these forums far less for the forseeable future.
  • DavidZemon wrote: »
    DavidZemon wrote: »
    DavidZemon wrote: »
    I believe 0b0100 will be binary in C/C++ - anything prefixed with 0b

    While this is generally acceptable syntax with GCC, it is relying on a compiler extension (unless you are using C++14 or later) so it should be avoided if the code is intended to be portable across compilers, or it must be strictly standard compliant (can check for standard compliance by compiling with -Wpedantic).

    Good to know! So was there no C or C++ standard way to provide binary literals until C++14?

    That is correct. It was considered for C99, but per the revision rationale (open-std.org/jtc1/sc22/wg14/www/C99RationaleV5.10.pdf, bottom of page 51) "A proposal to add binary constants was rejected due to lack of precedent and insufficient utility". I don't agree with that but the standard is what it is. Support wasn't added in C11 either but now that it has been added to C++ maybe it will make it into the next revision of the C standard.

    Another readability feature that was added by C++14 is using single quotes as digit separators (e.g. 0b0101'1010)just as underscores can be used in SPIN/PASM.

    Thanks for the info. What the heck is wrong with underscores as digit separators? Java has that too as of Java 7... seems to make a lot more sense than a single quote.

    Underscores were set aside for user defined literals in C++11. According to this document, their removal was considered. I have no experience with user defined literals so I have no idea how useful they actually are.
Sign In or Register to comment.