Team612 / 612-2016

FRC Team 612's 2016 code for First Stronghold
GNU General Public License v2.0
9 stars 6 forks source link

Converting raw data of PWM waveform to encoder output #137

Closed Ahmad-Bamba closed 8 years ago

Ahmad-Bamba commented 8 years ago

Electrical wants to use a magnetic encoder (the am5 AS51145B) as an absolute encoder to measure the position on the robot. This encoder is a PWM input device, meaning it takes outside information (in this case, an external magnet) and converts it to a waveform for other devices to use. Unfortunately, the roboRIO has no PWM input, only PWM output (which is used for Talons and Servo motors). The closest we have is an AnalogInput channel, which gets the raw values of the encoder, NOT the waveform. To make matters worse, we don't have the period of the waveform, so its even harder to convert these raw values into a wave we can use to interpret the clicks on the encoder.

@toastertaster and I (mainly @toastertaster) were trying to figure out a way to get around this. Its a hard problem, but if anyone has any info on what to do about it feel free to share or something.

Ahmad-Bamba commented 8 years ago

So, according to this obscure pdf I found the typical PWM frequency of this encoder is around 244 Hz. The period is around 4098 microseconds. To be honest I'm not really sure what to do with this information.

Bobobalink commented 8 years ago

This might be a good use of an Arduino as a translator between PWM and something that the roboRIO can use. We have those laying around. Arduinos are significantly easier to program arbitrary code on than the mess of commands and subsystems that we're using for the roboRIO.

I can probably jank together some Arduino code on Monday's meeting if we haven't figured something better out.

Ahmad-Bamba commented 8 years ago

That seems like a good start. Although, in my experience, reliable and accurate communication between an Arduino and the roboRIO (usually though I2C) is harder than it needs to be. Also, CAD would need to make another mount for an Arduino, and electrical+mechanical would need to find a place to put it.

A quick search shows that you can use pulseIn() to read PWM signals. Provided it's hooked up properly.

Bobobalink commented 8 years ago

TBH I was thinking of literally making it a digital or analog in, depending on what the roboRIO actually needs we can do most of the processing on the arduino and make the roboRIO just get a signal (on/off or voltage) from the arduino. Would make a lot of things, actually...

Ahmad-Bamba commented 8 years ago

Digital Input would probably work best.

The am5 is supposed to be an absolute encoder, so as long as we're talking about doing all the possessing on the Arduino we should focus on returning absolute (or relative) position in degrees and sending that to the roboRIO via digital output. In theory, the pulses would translate into the direction the magnet is moving in, and we would use that to calculate the position of the arm.

We would need to some serious testing to get a better idea of how the raw output of the encoder translates to what's going on in real life. I suspect the PDF I found would be instrumental in understanding this.

Bobobalink commented 8 years ago

Yeah, but what digital input can we actually use? PWM is already the easiest way to communicate digitally, and you said I2C is a PITA... I'm not gonna write my own communication protocol between an arduino and the roboRIO... Analog is quick and dirty and probably rather crap, but it'd work. I'm open to suggestions though, if we have time to make other things work better

Ahmad-Bamba commented 8 years ago

I'm fairly sure you can wire the Arduino to the Digital I/O slot on the roboRIO? I might be wrong.

But Analog would probably work just as fine, as WPI has a class for it already.

Bobobalink commented 8 years ago

You can hook it up fine, but the DigitalInput class seems to only return an 'on' or 'off' signal, which isn't enough to actually read an angle. There is an I2C class, but it doesn't output the read data (???). I'll keep looking when I have more time (at the meeting)

ZachPerkins1 commented 8 years ago

I don't mean to be "that guy", but is the extra effort we have to go through to get the absolute encoder working actually worth the benefit of having an absolute encoder over a relative encoder? I mean, sure, we would have to make sure that the shooter starts at around the same place each round with a relative encoder, but we would also be able to focus on our actual get-the-shooter-to-it's-position-algorithm without fretting over communication problems. Of course I'm likely overlooking many issues, and the supply of relative encoders that the team has could potentially be a problem. I just though it might be something to think about, seeing as we're only 2 days out from bag and tag.

Bobobalink commented 8 years ago

I have no opinion on abs vs rel encoders, I sort of assumed this was our only option. If we have a better option than bodging together an arduino with pwm, I'd love to hear it.

On the subject of reading PWM directly, I realized that the whole "we don't know the clock" thing is utterly irrelevant. The way PWM works is that the rising edge of each pulse is perfectly regular. The variance is what percentage of the total clock time the signal waits before falling back to zero. Lemme try some lovely ascii art to demonstrate

   1        2        3        4
   ---|--------|--------|--------|
+5v    ____     ______   _
+0v___|    |___|      |_| |_______
   ... 5/8  ...  7/8   . 2/8 .....

The top row is the "clock signal", then the waveform, then the PWM output (in a fraction of the total period) Generally PWM is actually measured in the elapsed time between rising edge (0 to +5) and falling edge (+5 to 0), but this makes a bit more sense and I didn't want to make up numbers.

It'd still be kind of a PITA and I don't know quite how to do it, but I'm pretty sure we could do terrible things to a Counter object to read this, like how @WardBenjamin and I set up the hall effect sensor.

WardBenjamin commented 8 years ago

Yeah, according to some other teams you can actually do exactly that. Basically, you just set up a digital input pin with a counter, and then you do (literally exactly) what we do in PIDEdgeCounter except for without the edge-detection-specific code, or with a little different edge detection (read both edges and then figure out which is which). I can whip this up tomorrow in like 15 minutes.

I apologize for not figuring this out sooner. Source: http://forums.usfirst.org/showthread.php?12086-Measuring-PWM-input-signals

WardBenjamin commented 8 years ago

Alternatively, we could solve the problem from the hardware side, using a low pass filter to convert PWM into analog. Then we could read it on an analog in pin.

Bobobalink commented 8 years ago

Ok, I'm not sure exactly what your implementation of a lowpass filter would be, but I completely approve of just putting a bigass capacitor across the PWM lines and pretending it's analog, that makes me happy on every level.

Bobobalink commented 8 years ago

LOL there's a PulseLength mode of the counter... yeah I'm pretty sure that'll work just about perfectly. I guess we have backup plans now... Lesson Learnt: actually read documentation

Ahmad-Bamba commented 8 years ago

The PulseLength() from Counter won't work because the am5's actual output is raw data.

Like, if we hook up this encoder it outputs "4" or "300", not a PWM signal. The methods in counter wouldn't work that way.

Bobobalink commented 8 years ago

If it's a pwm signal it'll work fine, the angle is probably just mapped from like 20% to 80% pulse width... Do you have a data sheet? I'll look at the actual protocol if it isn't pwm

Bobobalink commented 8 years ago

Ayyyyy look what I found http://ams.com/eng/content/download/50206/533867/file/AS5145_Datasheet_EN_v6.pdf

Pwm ranges from 0% at 0 degrees to 100% at 360 degrees

Aaand the data sheet has a suggested circuit to change the pwm line into analog

So we're doing this now, complaints will be eliminated with extreme predjudice

Ahmad-Bamba commented 8 years ago

I already linked that data sheet so I couldve saved you 5 minutes of Googling.

That said, I did miss the circuit to convert to Analog. You could probably have electrical do that. I'll make John do it personally for wasting our time :P

Bobobalink commented 8 years ago

You linked a shitty first tutorial, not the actual data sheet.

The actual data sheet shows that it does, in fact, output pwm as the 'raw data'. I have no idea what you mean by 'raw data' that isn't pwm, but rest assured, this thing outputs pwm.

Bobobalink commented 8 years ago

Edit: oh, awkward, I never actually clicked on that link... Sorry. The rest of my comment still stands though

WardBenjamin commented 8 years ago

Well, we now know that a low-pass filter works. Closing because we are apparently working with another sensor now.