0

Want to implement timeout for RPS counter after for instance 1 second. Since here I use status change for RPS calculation, I suppose that if the state is either HIGH or LOW for more than one seconds then rps should return 0.

However, it does not work. What is the problem.

float rps[4]={0.00,0.00,0.00,0.00};
unsigned long int PRINT_PERIOD = 1000;
unsigned long int lastTimePrinted = 0;
int lastReedState[4];
unsigned long lastTransition[4]={0,0,0,0};
//int reedState[4];
//unsigned long now[4]={0,0,0,0};
float rps_result[4]={0,0,0,0}; 
float rps_resul[4];   
//unsigned long revolutionTime[4]={0,0,0,0};

unsigned long int LT;  // Last Time
unsigned long int PT;  // Passed Time
unsigned long int TT;  // Time



void setup(){


 Serial.begin(9600);

 DDRD &= ~_BV (7); // pinMode (7, INPUT);       // rps_1
 DDRB &= ~_BV (0); // pinMode (8, INPUT);       // rps_2
 DDRC &= ~_BV (1); // pinMode (A1, INPUT);      //  rps_3
 DDRD &= ~_BV (2); // pinMode (2, INPUT);       //  rps_4

delay(85);



}

float rps_out(int k){

    //static int lastReedState;
    //static unsigned long lastTransition;
    //static float rps_result; 
    //float rps_result;
    int reedState;
    unsigned long now;    
    unsigned long revolutionTime;

   if ( k == 0 )     reedState = (PIND & _BV (7)) == 0; // digitalRead (7);
   else if ( k==1 )  reedState = (PINB & _BV (0)) == 0; // digitalRead (8);
   else if ( k==2 )  reedState = (PINC & _BV (1)) == 0; // digitalRead (A1);
   else if ( k==3 )  reedState = (PIND & _BV (2)) == 0; // digitalRead (2);

    // On a rising transition of the reed switch:
    if (reedState == HIGH && lastReedState[k] == LOW) {                   // HIGH  LOW   measuring the low period    // LOW HIGH measuring the high period 
        // Compute time since last valid transition.
        //unsigned long now = micros();
        //unsigned long revolutionTime = now - lastTransition;       // measuring the High period
         now = micros();
         revolutionTime = now - lastTransition[k];       // measuring the High period
        // Compute the rps

        //if(revolutionTime[k] == 0 ) return 0;

        if(revolutionTime == 0 ) rps_result[k] = 0;     // avoid deviding by zero

         rps_result[k] = 1.00 / (12.00*revolutionTime) *1000000.00;  // 12 is rotary encoders resolution 

        // Remember this transition.
        lastTransition[k] = now;   

    }

    // Remember last state.
    lastReedState[k] = reedState;

////////////////////////////////////////////////////////////   timeout 

    if(reedState == HIGH || reedState == LOW  ) {


       PT = millis();
       TT = PT - LT;       
    if( TT > 1000)  rps_result[k] = 0;

     LT = PT;

}

//////////////////////////////////////////////////////////////////


    if(rps_result[k] < 1) return 0.00;
    return rps_result[k]; 

}


void loop() {


   rps[0] = rps_out(0);
   rps[1] = rps_out(1);
   rps[2] = rps_out(2);
   rps[3] = rps_out(3);

    if (millis() - lastTimePrinted >= PRINT_PERIOD) {   



     Serial.print(rps[0]);
     Serial.print(',');
     Serial.print(rps[1]); 
     Serial.print(',');
     Serial.print(rps[2]);
     Serial.print(',');
     Serial.println(rps[3]);



      lastTimePrinted = millis();

     }

}
1
1

Since you need less that 1 second between changes, the minimal RPS would be 60.

So just change if(rps_result[k] < 1) return 0.00; to if(rps_result[k] < 60) return 0.00;

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.