Page 1 of 1

1047 API: Specify a counts per revolution (CPR) value to enable velocity

Posted: Tue Oct 10, 2023 3:58 pm
by stepheneb
Have a 1047 4-channel high speed encoder arriving shortly. Would like to use API to measure velocity.

The user guide states: "Specify a counts per revolution (CPR) value to enable velocity calculation."

There doesn't appear to be a method to set the encoder counts per revolution in the API: https://www.phidgets.com/?prodid=1199#Tab_API

[Q1] I did find that capability in the Phidget Control Panel. Is the capability also available in the API?

[Q2] After setting the encoder counts per revolution to 2000 in the Phidget Control Panel is there a way to access the velocity calculated by the encoder phidget in my onPositionChange() handler?

Re: 1047 API: Specify a counts per revolution (CPR) value to enable velocity

Posted: Tue Oct 10, 2023 4:11 pm
by mparadis
Q1- You're correct that the velocity calculation is a feature of the control panel example, not the API itself. Essentially it's using the timeChange and positionChange variables of the postionChange event to keep a running average velocity.

Q2- You can't have a Phidget channel open in both your own program and the Phidget Control Panel at the same time. The best thing to do would be to copy the logic used in the Control Panel example to do the same calculation in your own event handler. Here's the relevant code (full code publicly available in the C# GUI example for the encoder):

Code: Select all

void enc_change(object sender, Phidget22.Events.EncoderPositionChangeEventArgs e) {
try {
	positionTxt.Text = e.PositionChange.ToString() + " ticks";
	timeTxt.Text = (e.TimeChange).ToString("F3") + " ms";

	if (e.IndexTriggered) {
		indexTxt.Text = encoder.IndexPosition.ToString() + " ticks";
	}

	cumulativePosition.Text = encoder.Position.ToString() + " ticks";

	if (CPR != -1) {
		double timeChangeMinutes = e.TimeChange / 60000.0; // ms -> minutes
		if (prevVelocity == 0)
			timeChangeMinutes += prevTime;
		prevTime = timeChangeMinutes;
		double velocity = (((double)e.PositionChange / CPR) / timeChangeMinutes);

		rpmTxt.Text = velocity.ToString("F0") + " RPM";

		if (Math.Abs(velocity) > 1e5)
			Console.WriteLine(velocity.ToString());
		if(e.PositionChange != 0 || timeChangeMinutes > (1/60.0))
			velocityGraphBox.addData(velocity, encoder.DataInterval);
		prevVelocity = velocity;
	}

	positionGraphBox.addData(encoder.Position, encoder.DataInterval);
} catch (PhidgetException ex) {
	errorBox.addMessage("Error reading position: " + ex.Message);
}
}

Re: 1047 API: Specify a counts per revolution (CPR) value to enable velocity

Posted: Tue Oct 10, 2023 4:28 pm
by stepheneb
Thanks.

In the code you shared I didn't understand how CPR is being set to a value not equal to -1.

I didn't see the C# GUI example looking here: https://www.phidgets.com/?prodid=1199#Tab_Code_Samples -- where else should I look?

Re: 1047 API: Specify a counts per revolution (CPR) value to enable velocity

Posted: Tue Oct 10, 2023 4:38 pm
by mparadis
The CPR variable is set outside of the event handler, and only updated when the value is changed by the user.

You can find the code sample on the page you linked if you scroll past the code sample generator to the table below. It's the visual studio C# GUI example for the encoder object.

Re: 1047 API: Specify a counts per revolution (CPR) value to enable velocity

Posted: Wed Oct 11, 2023 12:36 pm
by stepheneb
Ahh ... I misinterpreted the user guide when it stated: "Specify a counts per revolution (CPR) value to enable velocity calculation.". I thought that this modified the operation at the encoder and perhaps provided better interval timing resolution for calculating velocity.

Re: 1047 API: Specify a counts per revolution (CPR) value to enable velocity

Posted: Thu Oct 12, 2023 8:09 am
by fraser
Yes you are right, the user guide doesn't make it very clear that that is not a function of the device itself, and only a function of the Control Panel Example. The velocity calculations have to be coded in manually when writing your own program. This is done in the onPositionChange event by dividing the positionChange by the timeChange, and multiplying it by the appropriate scaling factors to get the units you want.
I thought that this modified the operation at the encoder and perhaps provided better interval timing resolution for calculating velocity.
Regarding this, in case you are not aware, you can improve the interval timing for better velocity resolution by changing the encoder's "DataInterval." The lowest data interval for the 1047 is 8. so you can use

Code: Select all

en.setDataInterval(8)
to improve the responsiveness of the velocity calculation.

you can get the minimum dataInterval programmatically, this can be found in the API page