Mk.32
March 30, 2012, 9:13pm
1
Hi all,

We’ve heard that the WIPlib Encoder method getRate() is inconsistent, so we’re trying to write out our own (better) without any success. Any suggestions?

Code:

```
private static double currGet = 0.0;
public static double getRate() {
double prevGet = currGet;
currGet = shooterEncoder.get();
int scalar = 50;
double rateDegreePerSec = Math.abs(currGet-prevGet)*scalar;
double rpm = rateDegreePerSec/6.0;
System.out.println("Rate: " + rpm);
return rpm;
}
```

Ether
March 30, 2012, 10:58pm
2
It’s not entirely clear what you mean by “without any success”. I will assume what you meant is that you are getting a signal, but it is very noisy.

```
private static double currGet = 0.0;
public static double getRate() {
double prevGet = currGet;
currGet = shooterEncoder.get();
int scalar = 50;
double rateDegreePerSec = Math.abs(currGet-prevGet)*scalar;
double rpm = rateDegreePerSec/6.0;
System.out.println("Rate: " + rpm);
return rpm;
}
```

In the above code, you are not using the actual elapsed time since the previous sample to compute rate. You are assuming the scheduler’s timing jitter can be ignored. Try reading a high-res system clock and dividing the delta_counts by the actual elapsed time.

Also, if you are not sampling the encoder at 1x, you might try that also:

Mk.32
March 30, 2012, 11:39pm
3
Sorry for the confusion, we are getting data back however it is very noisy and unstable.

Ether
March 31, 2012, 1:02am
4
Unstable.

Try using 1x instead of 4x, and try using actual measured elapsed time since last sample instead of a fixed scale factor.

If that doesn’t work, check to make sure your encoder disk is installed properly.

Mk.32
March 31, 2012, 3:18am
5
Here is a quick re-write I did, using all the above comments. Encoder is set to 1x.

Wouldn’t get to test till next Wednesday. But comments are welcome.

```
public static void shooterEncoderStart() {
shooterEncoder.start();
shooterEncoder.setDistancePerPulse(1.0 / 360.0);
}
public static void shooterEncoderReset() {
shooterEncoder.reset();
}
public static double getRate() {
double get1 = shooterEncoder.get();
double time = Timer.getFPGATimestamp();
double get2 = shooterEncoder.get();
time -= Timer.getFPGATimestamp();
double rateDegreePerSec = Math.abs(get2-get1)/Math.abs(time);
return rateDegreePerSec/6.0; //RPM
}
```

Ether
March 31, 2012, 9:46am
6

Mk.32:

Here is a quick re-write I did, using all the above comments. Encoder is set to 1x.

Wouldn’t get to test till next Wednesday. But comments are welcome.

```
public static double getRate() {
double get1 = shooterEncoder.get();
double time = Timer.getFPGATimestamp();
double get2 = shooterEncoder.get();
time -= Timer.getFPGATimestamp();
double rateDegreePerSec = Math.abs(get2-get1)/Math.abs(time);
return rateDegreePerSec/6.0; //RPM
}
```

The above won’t work. “get1” and “get2” will be equal to each other and you’ll always return zero.

You want to get the encoder count and the time once per iteration, and compare those values to the previous iteration.

Pseudocode:

```
new_counts = get_counts();
new_time = get_time();
rate = (new_counts - previous_counts)/(new_time - previous_time);
previous_counts = new_counts;
previous_time = new_time;
```

Mk.32
March 31, 2012, 4:33pm
7
Thank you for the help Ether, I will try it out next meeting!