Tag Archives: Magnetic Encoder

4 months later…

The closest I'll ever get to driving a Tesla. Ecstatic!

The closest I’ll ever get to driving a Tesla. Ecstatic!

Hay guys! No updates for the past 4 months, but things will be turning around shortly. Many things happened this summer – mostly good things and some bad things. Anyway, I’m going to be continuing things where I left them off so abruptly in May.

Truth be told, I’ve been working on the telescope in my free time for the last 3 weeks.  This is what it can do so far:

First, I removed the old motor mount :

20150818_170711

Old altitude motor mounting hardware : acrylic plates and large metal frankenstein bolts.
Old altitude motor mounting hardware : acrylic plates and large metal frankenstein bolts.

Then I lasercut new mounting frame plates out of plywood. It came together rather nicely.

I designed and laser cut it myself.
I designed and laser cut it myself.

One reason I had to redesign the frame was to include a way to mount the altitude axis magnetic rotary encoder. The top plate extends over the 3D-printed worm gear. I had to 3D-print a piece that sits on the original printed worm gear, to which I attached the magnet part of the magnetic encoder. Long story short, it wasn’t too hard to design and fabricate, and now it works.

Assembled : Altitude Axis worm gear, and frame, and magnetic encoder.
Assembled : Altitude Axis worm gear, and frame, and magnetic encoder.

And I’ve done some more changes to the driver tester’s UI.

Newer UI - made for testing the Telescope driver functions
Newer UI – made for testing the Telescope driver functions

I’m currently trying to figure out how make the telescope rotate at a specific speed (degree/second). It would require me to poll the encoder at two different times, and calculate the angle it has moved versus the amount of time passed between polls. Sounds easy enough, but I have other ideas I want to try out. In theory, most of the major imperfections and flaws of the mechanical system could be overcome with enough software. I think…

David

Coding Hard? or Hardly Coding? – New Developments

From the movie Castaway, starring Tom Hanks
From the movie Castaway, starring Tom Hanks

Good news everyone! I’ve adopted a github thing, and I named it “Motorized-Telescope-Project”. Isn’t it adorable?

https://github.com/dharbott/Motorized-Telescope-Project

I started exploring GitHub because I need a place to store my code online, and this seemed appropriate. Not only that, my code is in a state where the important bits are functional, fragile, and bug-free. I’ve only used a concurrent version control system once a long time ago, so there will probably be a learning curve. This motor library business is new territory for me, so I’ll be experimenting with lots of bad code. Don’t expect me to arrive at a final version any time soon.

This is good news. This is evolution. I now have a github.

* * *

Let’s move onto the code, shall we? There was one major issue concerning the 12-bit magnetic encoder. As you rotate the magnet beneath the encoder, it outputs some value corresponding to the angle of that magnet relative to the encoder. The magnetic encoder outputs a value between 0 and 4095, because the encoder can count as fine as 4096 degrees per revolution – much finer than simply 360 degrees per revolution. The problem is, it only outputs a number between 0 and 4095. So it just wraps back around to the beginning once you cross over 4095, and vice verse.

This doesn’t work with the way I’m doing the GOTO function, so I started with some notes. I needed a way to measure the angular distance from the current angle to the angle we want it to be :

clockwise, distance
  if target < current
    distance is target + 4096 - current
  if target > current
    distance is target - current

And I turned it into this :

int getCWDistance (int current, int target) {
  return (target - current + ((target < current)*4096));
}

If you noticed, there’s a boolean statement within the last half of the return statement : (target < current). Based on the notes, the distance will always be (target – current), but in certain cases you have to add 4095 otherwise we’ll end up with a negative number that doesn’t make sense. When the boolean statement (target < current) gets evaluated, the value within those parenthesis becomes true/false. But in C, true also has a numerical value 1, and false also has a numerical value of 0. We can actually apply the boolean values of true and false in mathematical statements, such as I did there.

So now we have a way of measuring the angular distance of where I am pointing, to where I want to point to. My simple GOTO function tells the motor to run at full speed until it gets closer to the target angle. Then it slows to half speed until it gets to within several degrees, and then it moves at it’s “slowest capable speed” until it reaches the actual target angle. So far during testing, it’s been able to hit the target angle spot on, plus or minus 1 if the table shakes. The momentum of the entire telescope may be a factor. But that is not a big problem. Also, none of the bearings or gears are greased. That is a big problem…

In other Code News : I managed to get the Arduino to read in a number over Serial communication. I found the function parseInt() in the Serial Library, so it makes my job a lot easier. Basically, you can type in a number, press enter, and the telescope will rotate it’s base until it arrives at that angle. It’s a lot more exciting than it sounds, so if I remember, I’ll take video next time. So far, I got the base to rotate left and right. I haven’t gotten to making the telescope tilt up/down yet. But implementing that won’t be difficult, now that everything else is working.

Once the altitude motor GOTO function is working, all we need is to get the Raspberry PI online and connected, so it can start sending some real numbers.

Looking ahead, our next big challenge will be finding a suitable program to do plate-solving : Plate-solving is a method in which we use a digital photograph of what we see through the eyepiece, pick out known constellations, and orient ourselves in relation to the universe.

Maybe I’ll pick something more interesting to talk about next time.

Cheers!

-david

Arcstronominutes

A while ago, we purchased a pair of 12-bit magnetic angular encoders from Digikey. They’re not real expensive, and they have a resolution of 0.0879 degrees. If you’re up for it, check out Angular Measurements on Cool Cosmos.

Now, let’s do some math:

For 12 bits, the encoder output value can range from 0 to 2^12, so:
    2^12 = 4096
and, there are 360 degrees in a full revolution, so:
    4096 count / 360 degrees = 11.38 count / degree
and, 60 arcminutes make up one degree, so:
    (60 arcminutes / degree) * (1 degree / 11.38 count) = 5.27 arcminutes / count

That means our 12-bit magnetic encoders have a resolution of 5.27 arcminutes. This is great! It’s about a tenth the width of your pinky, if you held your pinky at arms length towards the sky.

All you need is a hand

Not bad. One of the tasks of the Motor Library will be to take some angular measurement (which will consist of degrees, arcminutes, and arcseconds) and translate it into a 12-bit number, and vice versa. This is because one of the motor library’s primary functions is a GOTO function, which may receive a pair of angles as input. The library function ought to translate those pairs of angles into a 12-bit equivalent, so we have something to compare with the output of the 12-bit magnetic encoder. (An alternative way to do it is to convert the 12-bit magnetic encoder’s output into an angle, every time we poll the sensor, then compare it to the target angle. It might be more efficient the first way, who knows?)

The only problem I foresee is that it’s non-trivial to physically re-orient the magnet within the magnetic encoder, so it will probably cross over the 0-degree position. Crossing over means we might go from 12 degrees to 0 degrees to end up at 350 degrees. This is one of the reasons we might use the motor’s quadrature rotary encoder to indicate position. The only solution I can think of is a function like this

if our motion is clockwise {
    if current > target {
        subtract 4096 from current for an adjusted current position
    }
    keep spinning while adjusted current position is less than target
}
else if our motion is counterclockwise {
    if current < target {
        add 4096 to current for an adjusted current position
    }
    keep spinning while adjusted current position is more than target
}
else {}

There may be a way to do it better. I will think of one later.

Anyhow, what the GOTO function would do is A) slowly accelerate the azimuth motor and altitude motor, B) continue rotating until it approaches the target angles, C) slowly and gradually decelerate the azimuth motor and altitude motor, until it actually lands on the target angles. Now, getting it to land exactly on the target angles will be tricky.

As a part of the library, there will be some set of functions which will test the speeds of the motors and the amount of overshoot that occurs when told to stop (or slow down). Basically, we’re going to teach the arduino to anticipate how much overshoot. This may or may not involve us learning how to code PID. (In fact, we might even use PID for parts A and C to ensure smooth acceleration, and in part B for constant speed. With all the other potential overhead, it might be hand coded. But for now, we could implement one just to see how it works??)

Where does this leave us? Well, we need to finish the motor instruction buffer – because I want to try out canned operations like part A), B), and C) in one smooth motion. The next step is we write the conversion functions for the 12-bit magnetic encoder. And, write up the funky code that handles crossing over the 0-degree line.

-david