Friday, November 25, 2011

Pythagoras v2 Drawings

Some drawings.
Working out calibration. Third time's the charm!
I like this face.
Self Portrait
Test of accuracy and capability. Nine hours to draw

Monday, November 21, 2011

Lightdial Update

The PCBs are in!
Mostly populated.
After wrangling with 0402 package SMD components, soldering these 1206 package components is such a relief.

Fixing the Analog Signal

Routing an analog signal all over the place with ribbon cable and no filtering and no buffering made it extremely susceptible to any bit of noise, not to mention the voltage sag due to the loading of the ADC. Given that I'm using 5k pots and I need precision to roughly 0.3 degrees, the loading effects are quite significant. How to fix? Twisted wires, buffers, and some hardcore low pass filters.

The new revised board

 Twisted Wires
My friends advised I twist the wires to help reduce noise. To be honest, I'm not sure how it works with non-differential signals, but I supposed it was simple enough to implement, and it does clean up the rats nest. And so, twisted wires.

Low Pass Filtering

Nothing fancy like Chebyshev or Butterworth. Just a simple RC filter that does the trick. Using the formula 1/(2 * pi * R * C) = -3db frequency, a 3.9 kOhm resistor along with 2 uF capacitor, I get a cutoff frequency of around 20 Hz, which is plenty high enough for a mechanical system such as this. The schematic looks like this.
On the oscilloscope, it turns the input (black) into a nice smoothed line (red).
Sorry, I don't have a legitimate oscope capture. I promise it looked like this!

Learning About Op-Amp Response Ranges

To fix the loading problem by adding in some op-amp buffers. Using unity feedback, I boost the current supply from a couple microamps to a couple milliamps. Excellent for keeping a stable voltage. The schematic looks like this.

When I tried out my new circuit, the circuit seemed great. Until I hit the low ranges. Then the output shot straight up, as such. 
 And it does so at 1.3 V, suspiciously close to two diode voltages (0.7 volts). The problem is that op amps are normally not designed to operate near their rail voltages. Here I use +5 and 0 volts, with an input voltage of 0 to 3.3 volts. Thus, it craps out near zero volts.

The solution is some rail to rail op amps. I used some op amps from TI, the so called TLV2774 Quad 2.7-V High-Slew-Rate Rail-to-Rail Output Operational Amplifier. It is rail to rail, so it can operate near its supply voltages, has four op amps in one package, though I only need three, and has input bias current in the picoamps. Also, free samples!

The entire circuit looks like this, with incredibly stable output voltage.
Digital Filtering

In addition to the analog filtering, I implemented some (relatively) long working digital filter. It takes 24 samples at 100 microsecond intervals. It then drops the lower eight samples and upper eight samples, and averages the middle eight samples. Yeah filtering!

Precision in measuring voltage is absolutely essential. Unlike a standard cartesian robot, where a little imprecision creates a constant offset, incorrect calibration in the arms causes the robot to not draw on a plane, but on some curved surface (I don't exactly know what it looks like, as it is some complex surface).

And so, with this new precision, a new video of the drawing!
Comparison of the output, with version 1 on the left and 2 on the right.
What an improvement!

Sunday, November 6, 2011

LightDial: A Bulbdial Cousin

For the final project for Georgia Tech's ECE 4175, by teammate and I decided to make a Bulbdial-like clock. It can be called an "artificial sundial" of sorts. Lights around a center post shine onto it, and the shadow of the post makes the hands of the clock. The original bulbdial does something smart, and uses charlieplexing to handle the large number of LEDs (for n pins, they can have n(n-1) LEDs running on them).

However, we have project requirements to fulfill. We have to use an SPI device as part of the design. So we thought might as well go all in and drive each channel independently with a massive shift register. We decided on Texas Instruments' 24 channel LED driver, the TLC5951. Two of them, so we can have 24 minute hand positions and 12 hour hand positions for a total of 36 independently driven LEDs. Sorry, no second hand, or we will go crazy laying out and wiring them all together.

The benefit of this design is that all LEDs can be lit at full power, for alarm clock functionality or something. The downside is that there are a lot of wires.

After some layout wrangling, its a board! The EAGLE files can be found in the links below.

And, that's about as far as I have gotten. Soon, once I check some things with my professor, I will send the board to fab.


Design files:

Wednesday, November 2, 2011

Pythagoras: Moving the Steppers

How do I move the steppers now? I can no longer simply send a position, like in version one. Something else will have to be cooked up.

After much thought...

I decided on a method quite similar to how version one was controlled in that incremental sense. However, I will have to extend the "moving in increments" to the motors too. In a nutshell, the manipulator moves a small increment forward along the path. Through inverse kinematics, I then get a set of new arm angles. Given the current angles of the arm, I then calculate the number of stepper steps it will take for all the arms to reach the new angles. I then distribute the steps for all of the arms so that they all finish at the same time, providing a good enough approximation for straight line travel. Confusing, isn't it?

Example time!

Given the arms angles are all at zero degrees. The step size is five degrees. Every program cycle, an arm either steps or doesn't step.

Then, the manipulator moves. The requested arm angles are 10, 20, and 30 degrees for arms one, two, and three, respectively. This means it will take the steppers at least six steps to meet the requested arm angles (30 degrees difference, 5 degrees step, 30 / 5 = 6 steps). So this means each cycle, arm one moves 1.67 degrees, arm two 3.33 degrees, and arm three 5 degrees. But arms one and two move less than one stepper step size each cycle. What do?

We create an auxiliary set of arm angles. They represent the ideal positions of the arms, following the increments of the step even if they are less than a step size.

At the end of program cycle one, we have:
  • Ideal:  Motor 1: 1.67 Motor 2: 3.33 Motor 3: 5
  • Actual: Motor 1: 0    Motor 2: 0    Motor 3: 0
The difference for motor three is greater than or equal to one stepper step size, so it takes a step, its actual angle updates to 5. Continuing, the pattern,
  • Ideal:  Motor 1: 3.33 Motor 2: 6.66 Motor 3: 10
  • Actual: Motor 1: 0    Motor 2: 0    Motor 3: 5

Updates to:
  • Ideal:  Motor 1: 3.33 Motor 2: 6.66 Motor 3: 10
  • Actual: Motor 1: 0    Motor 2: 5    Motor 3: 10
Fast forwarding:  
  • Ideal:  Motor 1: 5.00 Motor 2: 10   Motor 3: 15
  • Actual: Motor 1: 5    Motor 2: 10   Motor 3: 15

  • Ideal:  Motor 1: 6.16 Motor 2: 13.3 Motor 3: 20
  • Actual: Motor 1: 5    Motor 2: 10   Motor 3: 20

  • Ideal:  Motor 1: 8.33 Motor 2: 16.6 Motor 3: 25
  • Actual: Motor 1: 5    Motor 2: 15   Motor 3: 25

  • Ideal:  Motor 1: 10.0 Motor 2: 20.0 Motor 3: 30
  • Actual: Motor 1: 10   Motor 2: 20   Motor 3: 30

As you can see, all the motors reach their targets at the same time! However, how do you control motor speed then? The same as in version one, by using small increments of the manipulator. Since the algorithm is set to "consumes" at least one cycle, even if no stepper moves, by having very small increments the algorithm spends most of its time moving the manipulator and not much time moving the steppers.

Just the nasty details of actually implementing it. Its a good thing I already did it. Of course, the obligatory video:

The steppers here are moving slowly at 1/2 microstepping, so they are quite loud. But it is a good demonstration of the capability for different speeds, as well as a proof of concept.

There is one problem

Lack of experience with analog signals has come to get me. Noise is all over the place in the feedback from the potentiometers, so much that the manipulator home position differs by an inch between resets. That's not very good precision there. Coming up is the solution. Hint: Twisted wires, op-amp buffers, analog low pass filters supplementing hardcore digital filters.