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();
}
}
-
1Please post a Minimal, Complete, and Verifiable exampleduck– duck2016年12月15日 07:55:23 +00:00Commented Dec 15, 2016 at 7:55
1 Answer 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;