Go to Post I'd like to welcome all the rookie teams to FIRST. Hang on tight! It is a wild, crazy and fun ride that will impact your lives for decades to come. - Sayrah [more]
Home
Go Back   Chief Delphi > Technical > Programming > C/C++
CD-Media   CD-Spy  
portal register members calendar search Today's Posts Mark Forums Read FAQ rules

 
Reply
Thread Tools Rate Thread Display Modes
  #1   Spotlight this post!  
Unread 13-03-2012, 02:13
synthmusic synthmusic is offline
Registered User
FRC #3574
 
Join Date: Feb 2012
Location: Seattle
Posts: 5
synthmusic is an unknown quantity at this point
Reading an absolute encoder via PWM in C++

Hello all!

We are trying to get a reading from a sensor, the MAE3 from US Digital. Basically it outputs a PWM signial that shows its position by varying the width from 1 to 4096 uS. We're having trouble finding the right code that will grab that pulse width from the FPGA in a stable manner.

We can grab it in OperatorControl to show the signal is there, but the value varies by close to 10%, and often jumps to extreme numbers, assuming because we are in the main teleop loop.

Any pointers to the right object to use to get the PW correctly?

Thanks!!

"bBallAngle" is meant to show the number of microseconds elapsed for the width

Code:
bBallAngleSensor = new DigitalInput(2,11);

...

if (bBallAngleSensor->Get() == 1)
{
    // these for loops are to prevent a while lock.  if it loops 5000 times it will fall out
    // but a legit change will break;
    for (int i = 0; i < 5000; i++)
    {
        if (bBallAngleSensor->Get() == 0)
        {
            break;
        }
    }
    startTimeAngle = GetFPGATime();
    for (int i = 0; i < 5000; i++)
    {
        if (bBallAngleSensor->Get() == 1)
        {
            break;
        }
    }
    bBallAngle = GetFPGATime() - startTimeAngle;
}
Reply With Quote
  #2   Spotlight this post!  
Unread 13-03-2012, 10:40
RufflesRidge RufflesRidge is offline
Registered User
no team
 
Join Date: Jan 2012
Location: USA
Posts: 989
RufflesRidge has a brilliant futureRufflesRidge has a brilliant futureRufflesRidge has a brilliant futureRufflesRidge has a brilliant futureRufflesRidge has a brilliant futureRufflesRidge has a brilliant futureRufflesRidge has a brilliant futureRufflesRidge has a brilliant futureRufflesRidge has a brilliant futureRufflesRidge has a brilliant futureRufflesRidge has a brilliant future
Re: Reading an absolute encoder via PWM in C++

You could probably use the Counter object and GetPeriod() method to make the FPGA keep track of the pulses instead of doing it in your code.
Reply With Quote
  #3   Spotlight this post!  
Unread 13-03-2012, 10:45
Ether's Avatar
Ether Ether is offline
systems engineer (retired)
no team
 
Join Date: Nov 2009
Rookie Year: 1969
Location: US
Posts: 8,043
Ether has a reputation beyond reputeEther has a reputation beyond reputeEther has a reputation beyond reputeEther has a reputation beyond reputeEther has a reputation beyond reputeEther has a reputation beyond reputeEther has a reputation beyond reputeEther has a reputation beyond reputeEther has a reputation beyond reputeEther has a reputation beyond reputeEther has a reputation beyond repute
Re: Reading an absolute encoder via PWM in C++

Quote:
Originally Posted by RufflesRidge View Post
You could probably use the Counter object and GetPeriod() method to make the FPGA keep track of the pulses instead of doing it in your code.
If you use the GetPeriod() method in a Counter object on a PWM signal, is there a way to specify that you want the elapsed time between rising and falling edges? If not, how would you use this with a PWM signal ?


Reply With Quote
  #4   Spotlight this post!  
Unread 13-03-2012, 10:51
RufflesRidge RufflesRidge is offline
Registered User
no team
 
Join Date: Jan 2012
Location: USA
Posts: 989
RufflesRidge has a brilliant futureRufflesRidge has a brilliant futureRufflesRidge has a brilliant futureRufflesRidge has a brilliant futureRufflesRidge has a brilliant futureRufflesRidge has a brilliant futureRufflesRidge has a brilliant futureRufflesRidge has a brilliant futureRufflesRidge has a brilliant futureRufflesRidge has a brilliant futureRufflesRidge has a brilliant future
Re: Reading an absolute encoder via PWM in C++

Quote:
Originally Posted by Ether View Post
If you use the GetPeriod() method in a Counter object on a PWM signal, is there a way to specify that you want the elapsed time between rising and falling edges? If not, how would you use this with a PWM signal ?


Doh! You're right, it would give you the period between either consecutive rising or consecutive falling edges which isn't what you want.
Reply With Quote
  #5   Spotlight this post!  
Unread 13-03-2012, 11:01
Ether's Avatar
Ether Ether is offline
systems engineer (retired)
no team
 
Join Date: Nov 2009
Rookie Year: 1969
Location: US
Posts: 8,043
Ether has a reputation beyond reputeEther has a reputation beyond reputeEther has a reputation beyond reputeEther has a reputation beyond reputeEther has a reputation beyond reputeEther has a reputation beyond reputeEther has a reputation beyond reputeEther has a reputation beyond reputeEther has a reputation beyond reputeEther has a reputation beyond reputeEther has a reputation beyond repute
Re: Reading an absolute encoder via PWM in C++


There is a PWM class in WPILib but I don't know if that's only for outputting PWM or if it also supports reading PWM inputs.

Reply With Quote
  #6   Spotlight this post!  
Unread 13-03-2012, 11:05
RufflesRidge RufflesRidge is offline
Registered User
no team
 
Join Date: Jan 2012
Location: USA
Posts: 989
RufflesRidge has a brilliant futureRufflesRidge has a brilliant futureRufflesRidge has a brilliant futureRufflesRidge has a brilliant futureRufflesRidge has a brilliant futureRufflesRidge has a brilliant futureRufflesRidge has a brilliant futureRufflesRidge has a brilliant futureRufflesRidge has a brilliant futureRufflesRidge has a brilliant futureRufflesRidge has a brilliant future
Re: Reading an absolute encoder via PWM in C++

Quote:
Originally Posted by Ether View Post

There is a PWM class in WPILib but I don't know if that's only for outputting PWM or if it also supports reading PWM inputs.

It's for output. This thread made me curious so I did a little digging and found this thread on the FIRST forums which may be helpful ("working" stuff appears to be at the end)
Reply With Quote
  #7   Spotlight this post!  
Unread 13-03-2012, 11:44
apalrd's Avatar
apalrd apalrd is offline
More Torque!
AKA: Andrew Palardy (Most people call me Palardy)
VRC #3333
Team Role: College Student
 
Join Date: Mar 2009
Rookie Year: 2009
Location: Auburn Hills, MI
Posts: 1,347
apalrd has a reputation beyond reputeapalrd has a reputation beyond reputeapalrd has a reputation beyond reputeapalrd has a reputation beyond reputeapalrd has a reputation beyond reputeapalrd has a reputation beyond reputeapalrd has a reputation beyond reputeapalrd has a reputation beyond reputeapalrd has a reputation beyond reputeapalrd has a reputation beyond reputeapalrd has a reputation beyond repute
Re: Reading an absolute encoder via PWM in C++

In LabVIEW, you can configure a Counter for "Semi-Period" mode, which measures the pulse width of either high or low pulses instead of time between edges. This is what you want. Is there something similar in C++? (Since it's FPGA-level, I assume there's an interface in C++)
__________________
Kettering University - Computer Engineering
Kettering Motorsports
Williams International - Commercial Engines - Controls and Accessories
FRC 33 - The Killer Bees - 2009-2012 Student, 2013-2014 Advisor
VEX IQ 3333 - The Bumble Bees - 2014+ Mentor

"Sometimes, the elegant implementation is a function. Not a method. Not a class. Not a framework. Just a function." ~ John Carmack
Reply With Quote
  #8   Spotlight this post!  
Unread 13-03-2012, 12:33
Alexander Meyer Alexander Meyer is offline
Registered User
FRC #2358 (Bearbotics)
Team Role: Mentor
 
Join Date: Jan 2010
Rookie Year: 2010
Location: Lake Zurich, Illinois
Posts: 36
Alexander Meyer is on a distinguished road
Re: Reading an absolute encoder via PWM in C++

The C++ Counter class has a semiperiod mode as well, though I have never used it.
Reply With Quote
  #9   Spotlight this post!  
Unread 13-03-2012, 12:36
Ether's Avatar
Ether Ether is offline
systems engineer (retired)
no team
 
Join Date: Nov 2009
Rookie Year: 1969
Location: US
Posts: 8,043
Ether has a reputation beyond reputeEther has a reputation beyond reputeEther has a reputation beyond reputeEther has a reputation beyond reputeEther has a reputation beyond reputeEther has a reputation beyond reputeEther has a reputation beyond reputeEther has a reputation beyond reputeEther has a reputation beyond reputeEther has a reputation beyond reputeEther has a reputation beyond repute
Re: Reading an absolute encoder via PWM in C++

Quote:
Originally Posted by Alexander Meyer View Post
The C++ Counter class has a semiperiod mode as well, though I have never used it.
Code:
/**
 * Set Semi-period mode on this counter.
 * Counts up on both rising and falling edges. 
 */
I didn't look at the code, but the description doesn't sound like what is needed.


Reply With Quote
  #10   Spotlight this post!  
Unread 14-03-2012, 16:53
synthmusic synthmusic is offline
Registered User
FRC #3574
 
Join Date: Feb 2012
Location: Seattle
Posts: 5
synthmusic is an unknown quantity at this point
Re: Reading an absolute encoder via PWM in C++

Thanks everyone!

To avoid a hail of quotes, I'll simply summarize:

I tried the Counter class, but it didn't seem to want to do much more than, well, count. Every attempt at .GetPeriod() returned infinity, clearly hitting this Counter code:

Code:
double Counter::GetPeriod()
{
	tCounter::tTimerOutput output = m_counter->readTimerOutput(&status);
	double period;
	if (output.Stalled)
	{
		// Return infinity
		double zero = 0.0;
		period = 1.0 / zero;
	}
	else ...
and I could not convince it that it wasn't stalled so it would fall into the else. I made many iterations in the attempt, so I don't have any meaningful source to post showing it not working, which was my bad, if I try again I'll put something up.

RufflesRidge, I followed that link, and it does look promising, I shall try it out tonight.
Reply With Quote
  #11   Spotlight this post!  
Unread 14-03-2012, 17:12
Alan Anderson's Avatar
Alan Anderson Alan Anderson is offline
Software Architect
FRC #0045 (TechnoKats)
Team Role: Mentor
 
Join Date: Feb 2004
Rookie Year: 2004
Location: Kokomo, Indiana
Posts: 9,112
Alan Anderson has a reputation beyond reputeAlan Anderson has a reputation beyond reputeAlan Anderson has a reputation beyond reputeAlan Anderson has a reputation beyond reputeAlan Anderson has a reputation beyond reputeAlan Anderson has a reputation beyond reputeAlan Anderson has a reputation beyond reputeAlan Anderson has a reputation beyond reputeAlan Anderson has a reputation beyond reputeAlan Anderson has a reputation beyond reputeAlan Anderson has a reputation beyond repute
Re: Reading an absolute encoder via PWM in C++

Quote:
Originally Posted by synthmusic View Post
and I could not convince it that it wasn't stalled
Did you start the counter before trying to read it?
Reply With Quote
  #12   Spotlight this post!  
Unread 14-03-2012, 23:19
Ken Streeter's Avatar
Ken Streeter Ken Streeter is offline
Let the MAYHEM begin!
FRC #1519 (Mechanical Mayhem)
Team Role: Engineer
 
Join Date: Feb 2005
Rookie Year: 2005
Location: Team: Milford, NH; Me: Bedford, NH
Posts: 469
Ken Streeter has a reputation beyond reputeKen Streeter has a reputation beyond reputeKen Streeter has a reputation beyond reputeKen Streeter has a reputation beyond reputeKen Streeter has a reputation beyond reputeKen Streeter has a reputation beyond reputeKen Streeter has a reputation beyond reputeKen Streeter has a reputation beyond reputeKen Streeter has a reputation beyond reputeKen Streeter has a reputation beyond reputeKen Streeter has a reputation beyond repute
Re: Reading an absolute encoder via PWM in C++

Quote:
Originally Posted by synthmusic View Post
We are trying to get a reading from a sensor, the MAE3 from US Digital. Basically it outputs a PWM signial that shows its position by varying the width from 1 to 4096 uS. We're having trouble finding the right code that will grab that pulse width from the FPGA in a stable manner.
I know this probably isn't the answer you're looking for, but just in case you're unable to find a way to easily measure the PWM signals from the cRIO, you could instead use the MAE3 with the analog option instead.

We used the analog version of the MAE3 on robots in 2007-2009 with very good success, including a prototype swerve drive we built in the off-season.
__________________
Ken Streeter - Team 1519 - Mechanical Mayhem (Milford Area Youth Homeschoolers Enriching Minds)
2015 NE District Winners with 195 & 2067, 125 & 1786, 230 & 4908, and 95 & 1307
2013 World Finalists & Archimedes Division Winners with 33 & 469
2013 & 2012 North Carolina Regional Winners with teams 435 & 4828 and 1311 & 2642
2011, 2010, 2006 Granite State Regional Winners with teams 175 & 176, 1073 & 1058, and 1276 & 133
Team 1519 Video Gallery - including Chairman's Video, and the infamous "Speed Racer!"
Reply With Quote
  #13   Spotlight this post!  
Unread 16-03-2012, 20:28
apalrd's Avatar
apalrd apalrd is offline
More Torque!
AKA: Andrew Palardy (Most people call me Palardy)
VRC #3333
Team Role: College Student
 
Join Date: Mar 2009
Rookie Year: 2009
Location: Auburn Hills, MI
Posts: 1,347
apalrd has a reputation beyond reputeapalrd has a reputation beyond reputeapalrd has a reputation beyond reputeapalrd has a reputation beyond reputeapalrd has a reputation beyond reputeapalrd has a reputation beyond reputeapalrd has a reputation beyond reputeapalrd has a reputation beyond reputeapalrd has a reputation beyond reputeapalrd has a reputation beyond reputeapalrd has a reputation beyond repute
Re: Reading an absolute encoder via PWM in C++

Quote:
Originally Posted by Ether View Post
Code:
/**
 * Set Semi-period mode on this counter.
 * Counts up on both rising and falling edges. 
 */
I didn't look at the code, but the description doesn't sound like what is needed.


Wow. The description in LabVIEW is conflicting on this.

In LabVIEW, the Create Counter is polymorphic (there are multiple versions which you can select with a drop-down box). For the Semi-Period mode, the help says this:

Code:
Open Semi Period Mode
Opens a reference to a counter and configures the counter to measure the time between pulses in a signal. You can configure the counter to measure the time between high pulses by setting High Pulse (T) to TRUE. Otherwise the counter measures time between low pulses.
But later, in the connector description, it says this (what I read and assumed it meant pulse-width):
Code:
High Pulse (T) specifies, when TRUE, that the counter measures the length of the high time of the pulse. When FALSE, the counter measures the length of the low time of the pulse.
Since Up/Down mode can also measure single-wire encoders in a similar way to what the Semi Period mode describes, and since Semi Period mode (to me) did not act correctly when the encoder's lines were not of equal width in the light and dark spaces, I am inclined to believe that the Semi-Period mode actually measures pulse width.

The LabVIEW description of Up/Down mode says this:
Code:
Open UpDown Mode
Opens a reference to a counter and configures the counter to detect pulses on the rising or falling edges of a signal. You can specify an up source and a down source but most applications require only one signal per counter. The up source increases the counter and the down source decreases the counter.
We have a non-contact optical sensor and a custom-made disc with black tape, and the tape is not the same width as the bare aluminum space (by quite a bit). In Semi Period mode, when I configure the counter correctly and scale the output to RPM's, the numbers are not the same as the tachometer. When using Up/Down mode, they match the tachometer within 2 rpm. This leads me to believe that Semi Period mode actually measures pulse width, while Up Down mode measures time between rising edges - the time between rising edges does not care if the pulse width is different high than low.
__________________
Kettering University - Computer Engineering
Kettering Motorsports
Williams International - Commercial Engines - Controls and Accessories
FRC 33 - The Killer Bees - 2009-2012 Student, 2013-2014 Advisor
VEX IQ 3333 - The Bumble Bees - 2014+ Mentor

"Sometimes, the elegant implementation is a function. Not a method. Not a class. Not a framework. Just a function." ~ John Carmack
Reply With Quote
  #14   Spotlight this post!  
Unread 19-03-2012, 01:01
synthmusic synthmusic is offline
Registered User
FRC #3574
 
Join Date: Feb 2012
Location: Seattle
Posts: 5
synthmusic is an unknown quantity at this point
Re: Reading an absolute encoder via PWM in C++

Once again, thanks for the ideas! Given other priorities and troubleshooting, we called in an order for the analog version as noted here

Quote:
Originally Posted by Ken Streeter View Post
I know this probably isn't the answer you're looking for, but just in case you're unable to find a way to easily measure the PWM signals from the cRIO, you could instead use the MAE3 with the analog option instead.

We used the analog version of the MAE3 on robots in 2007-2009 with very good success, including a prototype swerve drive we built in the off-season.
And it works beautifully, variances below 1%. Would've liked the detail of the digital one, but working beats detail, at least for now!

Once we get through the competition this year, we'll do some exploratory work on this, because I'd really like to get to a working and stable solution for people to use as an AbsoluteEncoder or some such thing.
Reply With Quote
  #15   Spotlight this post!  
Unread 19-03-2012, 09:37
Jimmy Cao Jimmy Cao is offline
Registered User
AKA: Jimmy Cao
no team
 
Join Date: Sep 2006
Rookie Year: 2004
Location: San Francisco, CA
Posts: 295
Jimmy Cao has a brilliant futureJimmy Cao has a brilliant futureJimmy Cao has a brilliant futureJimmy Cao has a brilliant futureJimmy Cao has a brilliant futureJimmy Cao has a brilliant futureJimmy Cao has a brilliant futureJimmy Cao has a brilliant futureJimmy Cao has a brilliant futureJimmy Cao has a brilliant futureJimmy Cao has a brilliant future
Re: Reading an absolute encoder via PWM in C++

Quote:
Originally Posted by synthmusic View Post
Once again, thanks for the ideas! Given other priorities and troubleshooting, we called in an order for the analog version as noted here



And it works beautifully, variances below 1%. Would've liked the detail of the digital one, but working beats detail, at least for now!

Once we get through the competition this year, we'll do some exploratory work on this, because I'd really like to get to a working and stable solution for people to use as an AbsoluteEncoder or some such thing.
If you want to use the analog version of the MA3, here's a little wrapper for the sensor. It's a bit easier to use than just treating the MA3 as an AnalogInput. Sorry there's no documentation, but feel free to ask me if you have any questions about it.
Attached Files
File Type: h MA3Encoder.h (1.4 KB, 27 views)
File Type: cpp MA3Encoder.cpp (1.5 KB, 37 views)
__________________
Jimmy Cao

Team 469 2006-2010 Student/Alumni
Team 830 2011-2012 Mentor
Reply With Quote
Reply


Thread Tools
Display Modes Rate This Thread
Rate This Thread:

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

vB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Forum Jump


All times are GMT -5. The time now is 12:43.

The Chief Delphi Forums are sponsored by Innovation First International, Inc.


Powered by vBulletin® Version 3.6.4
Copyright ©2000 - 2017, Jelsoft Enterprises Ltd.
Copyright © Chief Delphi