Close

First Axis Encoder

A project log for Big Ol' Modular CNC

It's Time.

eric-hertzEric Hertz 12/23/2015 at 16:143 Comments

Yesterday: FINALLY figured out the pinout of this encoder's circuit... Apparently it's just two photodiodes, two photo-transistors, and four resistors. Even most computer-mice I've seen have more sophisticated circuits, usually involving two resistors for each transistor... and some, I think, even tied the transistor's output to the diode, as a sort of amplifier feedback-loop. The signals coming out are usually somewhat sinusoidal, requiring a comparator at the receiving end... or at the very-least a forgiving Schmitt-trigger. Most motor-mounted encoders I've seen, even the ones made of discrete components like this one, have comparators or some other sort of digital-output-driver at the transmitting-end... would certainly help with noise-immunity... This motor's marked 1982, so maybe they were using analog power-control rather'n PWM, then switching noise wouldn't be as big a concern...

Regardless, the output swings from 0V to 2.1V with a 5V source. My microcontroller's digital inputs (despite schmitt-triggers) are rated for 3.5V VIH-min. So, not surprised it didn't detect any movement with my first attempt.

All that math was to determine whether I could get away with putting a pull-up resistor on the outputs to get it in range of a digital input... I calculated (based on the maximum output voltage) that the phototransistors look like a 4.56k resistor when fully-illuminated. So I'd need a ~2k pull-up resistor (in parallel to the transistor) to achieve 3.5V. Unfortunately, that would mean that the completely-dark case looks like a voltage-divider with a 2k upper-resistor and a 3.3k lower-resistor, so the output-voltage would be too high for VIL-Max = 1V.

(Much later note, per a comment from @K.C. Lee... How is it I didn't think of running the encoder off 5V, and my microcontroller off 3.3?).

I could modify this encoder's circuit-board pretty easily, there's plenty of space for hacking. Then I could've probably had it running in a couple hours. But I got sidetracked contemplating more-versatile options...

I've been using computer-mouse-encoders in projects over the past year-ish... those are similar in output to this. And I've got a few other encoders of questionable-output. So... what would be more versatile...?

Analog-comparators happened to be an easy-choice for my PIC32-based circuit, choosing a low threshold voltage. But, what if the transistors were low-side...? Then I'd have to change it to a higher threshold-voltage... either software would have to change, or there'd need to be a potentiometer added... Besides that, I only built that on a solderless-breadboard, and now entropy is setting in.

I came across my AVR-based "oneAxisHolder" (soldered) circuit from long ago, while cleaning the workbench... I used this in some early experiments in the past year or so, then switched over to the PIC32. The nice thing about the oneAxisHolder is that it's soldered-up and so far has been basically plug-and-play... RS-232 input to control the position, an encoder input, and a motor output... The PIC32 runs almost the exact same software, but I've improved it a little bit to handle things like using comparator-inputs. That code is *mostly* architecture-agnostic, so porting it back to the AVR would be pretty simple... but the oneAxisHolder's encoder inputs aren't soldered to Analog-comparator pins... And technically the AVR only has a single analog-comparator (though switching its inputs is possible, that wouldn't allow for using interrupts...)

But, they are soldered to pins that have ADCs... so that's a contemplation...

This has been another long-running consideration... With encoders like these, where the output is analog, rather'n digital, (which just happens to be commonly-associated with low-resolution encoders, in my collection) it might be possible to increase the position-resolution by using the analog values and ADCs... That's something that might be difficult, and not exactly in my mind-set at the moment. Thing is, of course, noise will *definitely* couple into these signals... So I forsee something a bit more like having two separate values, one is the Known position (accuracy?) determined by threshold-crossings... The other value would be a Determined position (precision?). It could plausibly be thought of like a floating-point number, but there could be some oddities with relying on it that way... e.g. say the threshold was just recently crossed on one of the quadrature outputs... Now its value decreases slightly... Does that mean it's reversed direction? So, of course, we look at the second encoder output, but its value has changed *extremely* slightly (being at the top of a sine-wave)... did its value change due to motion in the positive direction or the negative direction...? Was it noise that caused the decrease on the first output...? The whole scenario's a bit ambiguous. So, I don't know what this would be useful/reliable for, really... Positioning based on it is questionable... but maybe it could be used in something like speed-control, where we know the motor's always increasing in direction... I dunno.

So, back to versatility: I got to the point where... the oneAxisHolder is really handy, being kinda plug-n-play. Before the last recent use it was at least a couple years since I'd used it, and when I needed it again I just plugged it in (to an entirely different motor/system) and it worked. Nice. But this time it's a no-go, so where do I go from here...? Is it time to switch the pinout for analog-comparators (are they available?)? And think about how I'm going to set that threshold-voltage (versatilely)? Or is it time to start looking into the ADC method...? Or is it time to solder up the PIC32 version...? Or should I just hack this stupid circuit and get the danged axis moving?

And, WTF...? How could this AVR's inputs *possibly* be rated for VIH-Min=3.5V with a 5V source...?! Certainly I've connected 3.3V logic to these things before without a hitch... right? Weird.

I got a bit overwhelmed and wrote most of this up... then found this TTL-level serial buffer/inverter I built a while back...

One of the devices I tried to hack had *inverted* serial output, so I built a jumper-switchable inverter/buffer for it (with LEDs). I used transistors instead of TTL, for some reason I don't really remember... I think I basically just felt like working with some transistors at the time. Oh, and I also wanted it to work as a level-shifter...

I just repurposed the Tx and Rx lines for the quadrature A and B channels, which required swapping one pin from the "device" connector to the "computer" connector. And... It worked! Sorta. One channel worked nearly perfectly... I got something like 4V signal-swing. The other side... almost nada.

Then I vaguely remembered having had some issues with it when I last used it... So I sat down and traced out the circuit and found some little gems I hadn't considered during its design.

For one thing, most of the inputs used only 1k resistors to the bases... so that's a big no-no in this case, connected to an output-resistance of ~3-5k. Even worse in one case, where the LED is driven by a PNP transistor, and the buffer/inverter by NPNs... We've got a voltage-divider attempting to drive a *stronger* voltage-divider (through the transistors). That was the signal that didn't work... replacing its base-transistors with 10k didn't quite do it, either... so I threw a 100k on the PNP transistor's base. Right? Wrong. Let's just say "ish" for both... The LED *barely* changes in brightness, but it does. Of course, the input voltage doesn't actually go high, so the PNP transistor never actually turns off. Duh. Oh well, that's just visual. The fix worked as far as the buffer/inverter go.

The other channel's LED was connected to the *output* side of the buffer/inverter circuit, so it shouldn't be a problem, right...? Wrong. Ish. The output is driven by an NPN transistor, emitter to ground, collector pulled-up with a 1k resistor. Cool. The LED is driven from that through a 1k base-resistor and NPN. Not cool. Another voltage-divider, explaining why the output voltage-swing was less than 5V (but functional).

Later we'll run into some more transistor-based unexpecteds... so it would seem transistors aren't really my forte... I guess I tend to think of them as full-on or full-off most of the time... Right? Wrong. Ish? No, just wrong.

Regardless, at that point, the circuit worked well enough to run motion-experiments! I'll save those results for the next log (or maybe next-to-next). Suffice to say, I had it running all last night, long enough to figure out (rather, verify) some potential issues with my hardware/mechanics.

So tonight I powered it up again to shoot some video of it running... and... now it runs forward every time. Even when I tell it to go in reverse. And, when I tell it to go 4 steps, it goes more like 40. So, we'll come back to that.

Suffice to say, though maybe not the *only* problem, the transistors kicked me in the butt, again. When they're not fully-off or saturated (e.g. when the encoders' *analog* output is somewhere mid-way) the circuit acts as a biased-transistor-circuit should... as an amplifier for tiny changes. And those tiny changes....? Definitely a majority are coming from the PWM of the motor. It's kinda cool, actually, and a reminder that transistors are *amplifiers*, not switches. (Maybe I can use this!)

I don't know what's changed since yesterday to make it run like this... One interesting observation is that the motor itself is responding normally, e.g. when I try to rotate it by hand, it snaps back to where it wants to be, in both directions. One theory is that the PWM coupling into the encoder signals doesn't really change the detected position except maybe one or two ticks. BUT, it's probably triggering *really fast* interrupts (~30kHz!) that might be hogging CPU time that would've been used for my bit-banged UART... So, maybe that helps to explain why I'm getting huge motion when requesting tiny changes, as well as reverse-motion. HOWEVER, again, why didn't I run into this yesterday...? First guess on that was that I moved things around after I turned it off yesterday, some of the wires were close to each other today... but reorienting to yesterday's orientation and separating the wires didn't help. So, I dunno.


Discussions

K.C. Lee wrote 12/24/2015 at 21:19 point

You might be able to increase the value of the 3.3K resistor say to  6.8K or higher.  That might reduce the load enough to raise the output.   It would lower the immunity to ambient light.  Also increasing the IR LED current might help.

  Are you sure? yes | no

Eric Hertz wrote 12/26/2015 at 09:38 point

Good call... I broke down and replaced those 3.3ks with 20k potentiometers, and removed the transistor-circuit entirely. Getting full-swing ~0V -> ~5V, now. Also a shielded-cable probably helps.

Thankfully the encoder's completely enclosed in black casing, so I doubt there's much ambient light getting in.

I'm not certain, but I think my experiments with the mouse-encoders resulted in something like: the photo-transistors respond *faster* with lower-value resistors... (more current...? Or biased outside the saturation-region...?). So far it's not presenting itself as a problem with this setup, but I'm not getting far... it's still going dozens of steps when only one is requested, and still going forward when reverse is requested. 

Pretty certain this is a communication-issue. Looks like my clock's running a bit fast.

  Are you sure? yes | no

Eric Hertz wrote 12/26/2015 at 10:51 point

Stupid me... see next log.

  Are you sure? yes | no