Shop OBEX P1 Docs P2 Docs Learn Events
Seems simple, don't get it — Parallax Forums

Seems simple, don't get it

void button_time()
{
  set_directions(13,8,0b111111);
  
  int t = 20;
  
  while(1)
  {
    int advance = input(15);         // advance shortens magnet off delay
    int retard = input(14);          // retard lengthens magnet off delay
    
     if (retard == 1)
     {
       t = t + 1;
       pause(300);
       
       if (t > 64)                   // Don't allow t to exceed 63
       {
         t = 64;
       }         
     }
     
     if (advance == 1)
     {
       t = t - 1;
       pause(300);
       
       if (t < 1)                    // Keep t 0 or larger
       {
         t = 1;
       }         
     }
     
     delay = t;                      // Pass delay to main function
     set_outputs(13,8,t);            // Put t value on output lights  
    
  
  }
}



I'm trying to vary t between 0 and 63 using 2 pushbuttons, and displaying them on 6 leds. If I use

If (t > 63)
{
t = 63;
}

and

if (t < 0)
{
t = 0;
}


the program jumps off the deep end on zero, and on 63 goes back to 62 after a half second.
I really seems like this should work, but does not.

The main program in cog 0 uses delay as pause(delay);
button_time runs in another cog

I the present form of the code, I get 1 to 63.
Why are my results different than I expect?
What code should I use?

Comments

  • The if statement
     if (t < 1)                    // Keep t 0 or larger
           {
             t = 1;
           }         
    

    doesn't agree with the comment, essentially if "t" is zero, it is changed to 1.

    In your wiring are pins 14 and 15 pulled to low, or are they floating?

    Tom
  • Beavis3215Beavis3215 Posts: 229
    edited 2018-07-04 17:04
    0 to 63 is what Im trying to do
    using my code above 1 to 63 is all I can attain for now.
    if (t > 63)
                  {
          
                    t = 63;
    
                  }
    
               if (t < 0)
                 {
    
                   t = 0;
    
                 }
    

    looks like it should work, but does not.

    pins 14 and 15 are pulled low


    ./*
      Figit Spinner Motor
      
      Pin 19 is on sensor input
      Pin 18 is off sensor input
      Pin 17 is magnet controller output
      Pin 16 is timing light output
      Pin 15 is timing advance input
      Pin 14 is timing retard input
      Pin 13-8 is binary timing output
      
    */
    #include "simpletools.h"            // Include simple tools
    
    void button_time();
    
    static volatile int delay;          // delay is global
    
    int main()                          // Main function
    {
      
     cog_run(button_time,128);          // Push button control runs in other cog
     set_directions(17,16,11);
     
     
      while(1)
      {
        int on_sensor = input(19);
        int off_sensor = input(18);
        if (on_sensor == 1)
        {
          set_output(17,1);             // Turn magnet on
        }
        
        if (off_sensor == 1)
        {
          pause(delay);                 // Delay is assigned in button_time
          set_output(17,0);             // Turn magnet off
          set_output(16,1);             // Timing light on
          pause(5);
          set_output(16,0);             // Timing light off
        }            
      }  
    }
    

    This is the main program
  • Phil Pilgrim (PhiPi)Phil Pilgrim (PhiPi) Posts: 23,514
    edited 2018-07-04 18:40
    Assignments use := not =.

    You can also do this in one line:
    t := t #> 0 <# 63
    

    -Phil
  • Assignments use := not =.

    You can also do this in one line:
    t := t #> 0 <# 63
    

    -Phil

    Don't think you can do that in C ;)
  • Phil Pilgrim (PhiPi)Phil Pilgrim (PhiPi) Posts: 23,514
    edited 2018-07-04 19:57
    Sorry, my head is totally in Spin. Shoulda seen the braces. D'oh!

    -Phil
  • tonyp12tonyp12 Posts: 1,950
    edited 2018-07-04 20:34
    I always check for non zero before subtraction to prevent underflow, even if it "never" should possible be at zero
    if (i && !--i){  // if not zero but now reached zero for example
    

    you could do:
    if (advance == 1 && t) t -=1;
    

    in C, if statements are always break at first false it encounter

  • The pause function is defined in Simple Tools as:
    void pause(int time)                          // pause function definition
    {
      time *= st_pauseTicks;                      // Calculate system clock ticks
      waitcnt(time+CNT);                          // Wait for system clock target
    }
    
    st_pauseTicks should be set to the number of ticks in a millisecond. When you pass a value of zero to the pause function it will execute a waitcnt(0+CNT). This causes the main program to wait until CNT wraps all the way back to its initial value. At 80 MHz that takes about 54 seconds. You can allow delay to go to zero, but don't call the pause function when its zero.

    I'm not sure what the problem is with 63. It seems like that should work fine.
  • David BetzDavid Betz Posts: 14,511
    edited 2018-07-05 02:57
    tonyp12 wrote: »
    I always check for non zero before subtraction to prevent underflow, even if it "never" should possible be at zero
    if (i && !--i){  // if not zero but now reached zero for example
    

    you could do:
    if (advance == 1 && t) t -=1;
    

    in C, if statements are always break at first false it encounter
    Just being picky but it isn't really the if statement that does this. It is the behavior of the && and || operators. It works even outside of an if statement:
    a = (b > c) && (d > e);
    
    C will not evaluate (d > e) if b is <= to c since the entire expression will be false regardless of the value of (d > e).
Sign In or Register to comment.