Commit 9579bcc9 authored by Jake Read's avatar Jake Read
Browse files

first!

parents
# MachineKit Encoder
## Motivation
w/ AS5304 / AS5306
Pins for Quadrature Input on ATSAMS70?
A key limitation in my previous work here was encoder positioning. I wanted to use a ring magnet and off-axis linear sensor to decode rotary position - the trouble was I could only find one supplier of ring magnets with the right pole spacing, and it was ~38mm ID. The whole gist of the mechanical design here is to bring the diameter way up, so this was not satisfactory, or, at least, it was a constraint.
Here I am going to try to use discrete magnets in an assembly of my own... I am basically just building a big ring magnet, and trying to read that.
## Problems
I am using an AS5304 (4mm poles) or an AS5406 (2.4mm poles). Each has 160 positions per magnetic period. This translates to a resolution of 25um and 15um steps, respectively. If I wrap this around some diameter D I have that
angular resolution = 360 / (((PI x D)/pole_length) x 160)
Of course, I have to set the circumference equal to an integer value of magnets. I wrote a quick spreadsheet for this, and get that w/ a Diameter ~ 100mm (where the gearbox currently stands) I can get 0.017 deg/step with a 2.4mm pole pair, and ~ 0.03 deg/step with a 4mm pole spacing. Nice.
![rough spreadsheet](https://gitlab.cba.mit.edu/jakeread/mkencoder/raw/master/images/spreasheet-resolution-approx.jpg)
Now, this is not so straightforward. The important thing to remember is that **Resolution != Accuracy** - while I have ~ 0.03 deg / step, those steps are not exactly mapped perfectly in a circle. I will actually be referencing magnets that are glued in place - so my glueing and magnet placement would have to be *perfect* for Resolution to = Accuracy. In addition, not all magnetic fields will be identical, etc. Everything is crooked.
In addition to these mappings between poles, I will have some deviation, I'm sure, within the poles. As in, the magnets will likely have small gaps (finding a magnet which is perfectly 4mm across... not likely) and so I expect readings to kind of sine-wave around linear.
This can be overcome in implementation by mapping in memory a lookup table, with respect to some 'home' position, of how measured ticks of the encoder match up with reference positions. For example, I would rotate the encoder to known positions (with some other, higher precision system) and map readings -> known values.
This is not ideal! And it requires a deal of labor, some good routines and memory-storage games, and a reference point.
In this exercise (which I am trying to keep bounded)<sup>1</sup> I will try only to measure this deviation-from-perfection. Or, at least, deviation from some other, better positioning system.
At best, I hope to cancel periodic deviation (i.e. map the sine-wave between individual poles into a more linear interpolation. my encoders have an Index pulse (on every top-of-pole) that I can use as a reference point for this.
## Design
Without further ado, here's a sketch of how I plan to build the encoder:
![layout test](https://gitlab.cba.mit.edu/jakeread/mkencoder/raw/master/images/layout-encoder-test.jpg)
And then, a system to put *that* encoder in set positions, while measuring...
* while pole pairs are 4.0mm apart, poles are 2mm long - magnets are 2mm across.
In some moment of foresight, I want to find an encoder with a bigger pole spacing - I think that 2mm is tooo small and seems likely to drive me to madness in assembly. Time to DigiKey it up! None are available, boo. The other option is to truly roll my own encoder, using Hall Effect Sensors with variable output, look at the sine waves, and do encoding from there. This is becoming a challenging project.
OK, nevermind. I'm going back to on-chip quadrature de-quadraturing (or, mag field -> quadrature).
I made a home for the board
![board-in-fusion-begin](https://gitlab.cba.mit.edu/jakeread/mkencoder/raw/master/images/board-in-fusion-begin.jpg)
And started laying out a schematic. Had to build the footprint in Eagle.
![board schematic](https://gitlab.cba.mit.edu/jakeread/mkencoder/raw/master/images/board-schematic.jpg)
If you're wondering why I have SPI pins labelled, it's because I'm actually connecting this to a plug on my Networking Switch - these are the pinouts. Instead of SPI I will just configure those pins to do GPIO.
THIS is a big what-if for me. As in, what if I get my switch boards back from the fab and it turns out I can't get GPIO to work on these particular pins? I have trapped myself. !
I also have voltage dividers set up here - the AS5304 drives 5v, and I don't want to pump that into my puny 3v3 logic lines on the ATSAMS70.
I also have a jumper / pin header footprint setup on the Analog Out pin - this will let me read the strength of the magnetic fields, making sure I am aligned.
Ideally, I would tie these to an ADC on the ATSAM, but I haven't broken any of those out on the BLDC encoder board... this is a long chain of interconnects. I am rethinking my overall switch -> peripheral strategies now. A good learning / systems design moment. OR I could tie it to some kind of comparator, and have an LED turn on only when that voltage was in a particular range. *shrugguy*
OK, Routed
![board routed](https://gitlab.cba.mit.edu/jakeread/mkencoder/raw/master/images/board-routed.jpg)
Exporting to mods from Eagle is a bit of a pain. In the fullness of time I would write a MOD to do GERBERS -> Milling, however.
Layers -> none
Layers -> Top, Pads
export image monochrome
Layers -> none
Layers -> Bottom, pads
export image monochrome
... ok
Back to my layout, and working back into my sheet, I'm going to add magnets here:
![cad magnet circle](https://gitlab.cba.mit.edu/jakeread/mkencoder/raw/master/images/cad-magnet-circle.jpg)
And then to test this against some reference, I'm going to use a stepper motor. With the current diameter I'll have 0.05 deg resolution (or, I would ideally) - this means I would need 1/32 microstepping to match up on a stepper motor - I want my reference to have a bit more resolution than what I'm measuring, so I'll try to find a stepper motor with 400 steps / rev, and do 1/32 microstepping on that. Then I have 0.028 deg / step. I'll also bring the diameter down on my encoder to 58 poles, so I'll have 0.077 deg / step there. This means I have about 3x the resolution on my reference than I do on my measured-thing, and intuitively that feels like a good spec. Thumbs up.
ALSO - I knew I should check this, and I'm glad I did - here's a #2 and a #0 screw - the #2 contacts the encoder ring. Noice.<sup>2</sup>
![cad screw clearance](https://gitlab.cba.mit.edu/jakeread/mkencoder/raw/master/images/cad-screw-clearance.jpg)
Final touches, I'm going to make a mount for a NEMA17 Motor on the back, and a little teeny desktop stand.
![cad stand](https://gitlab.cba.mit.edu/jakeread/mkencoder/raw/master/images/cad-stand.jpg)
OK, check it oot
![cad check](https://gitlab.cba.mit.edu/jakeread/mkencoder/raw/master/images/cad-check.jpg)
## Fab: the board
So I milled this board on the Roland SRM-20. I'm plugging this into my other ongoing work... here's [my brushless motor controller](https://gitlab.cba.mit.edu/jakeread/mkbldcdriver) that rides below my even-more-unresolved networking chip. Those ports you see on the left of the bldc-driver are for other GPIO, including this encoder.
Ramble ramble, here it is:
![board assembled](https://gitlab.cba.mit.edu/jakeread/mkencoder/raw/master/images/board-assembled.jpg)
And you can see the AS5304 here
![board as5304](https://gitlab.cba.mit.edu/jakeread/mkencoder/raw/master/images/board-5304.jpg)
Also, a moment of appreciation for the new *Leica* microscope that showed up at the CBA soldering station. Has variable zoom, and generally is very lovely.
![microscope appreciation](https://gitlab.cba.mit.edu/jakeread/mkencoder/raw/master/images/microscope-appreciation.jpg)
## Fab: the kit
I printed the hardware on the Eden. The Eden's washing-up station is currently broken, and I spent the better part of an afternoon trying to cobble together a fittings-and-adapters solution to unbreak it, to no avail. I await McMaster parts.
## Programming
I'm using my ATSAMS70 Switch (link?) - I actually used this project as an excuse to bring the GPIO (in SAM-speak, this is just 'PIO' and stands for Parallel Input and Output). Looks like it's datasheet-o-clock again...
## Measurements
I want to be like Sam. Sam measures *everything* and he does it really beautifully. This is some of the functionality I really want to be able to bring into mods - the ability to quickly pull test data out of systems, do computation with it, and learn.
With that motivation, I want to take this chance to run a test cast of that. The Goal here:
- Use one of the 'network switches' (or are they routers? vagueness rules in this project at the moment)<sup>3</sup>
- Gateway it to MODS
- Build a basic interface to do this test, where I spin the stepper around a few times and measure devation from 'linear' rotation between the stepper and the encoder.
- Pull this data out and chart it in mods, using javascript to do the maths.
- Have some conclusions, or solutions, to whatever I see in this data.
# Footnotes
1. But I am also planning on actually using this encoder in my implementation of an arm, and later in linear applications, so having an idea of how to *really* pull this off is - I am hoping - something that will come to me. But I make no plans as such. Seems hard.
2. Ideally I would solder small threaded-things on to the back of the PCB, then I could mount it from the rear and really pinch the rest of it against the plate. Also this would allow me to adjust the encoder position with the ring already in place.
3. In any case, they are modular hardware - ATSAMS70 chip w/ a 40 pin extension header that I plan to do 'stuff' with. I want a good backbone for motion control, a chip to get cozy with.
\ No newline at end of file
[Eagle]
Version="08 03 02"
Platform="Windows"
Globals="Globals"
Desktop="Desktop"
[Globals]
AutoSaveProject=1
UsedLibraryUrn="urn:adsk.eagle:library:217"
UsedLibraryUrn="urn:adsk.eagle:library:325"
UsedLibraryUrn="urn:adsk.eagle:library:371"
UsedLibrary="D:/Dropbox (Personal)/CBA/doc/libraries/eagle/fab.lbr"
UsedLibrary="D:/Dropbox (Personal)/CBA/doc/libraries_jake/eagle/jake/tag-connect-2030.lbr"
UsedLibrary="D:/Dropbox (Personal)/CBA/doc/libraries_jake/eagle/jake/tag-connect-2050.lbr"
UsedLibrary="D:/Dropbox (Personal)/CBA/doc/libraries_jake/eagle/sparkfun/SparkFun-Connectors.lbr"
UsedLibrary="C:/EAGLE 8.3.2/lbr/ltspice/Comparators.lbr"
UsedLibrary="C:/EAGLE 8.3.2/lbr/ltspice/Digital.lbr"
UsedLibrary="C:/EAGLE 8.3.2/lbr/ltspice/FilterProducts.lbr"
UsedLibrary="C:/EAGLE 8.3.2/lbr/ltspice/Misc.lbr"
UsedLibrary="C:/EAGLE 8.3.2/lbr/ltspice/Opamps.lbr"
UsedLibrary="C:/EAGLE 8.3.2/lbr/ltspice/Optos.lbr"
UsedLibrary="C:/EAGLE 8.3.2/lbr/ltspice/PAsystem.lbr"
UsedLibrary="C:/EAGLE 8.3.2/lbr/ltspice/PowerProducts.lbr"
UsedLibrary="C:/EAGLE 8.3.2/lbr/ltspice/References.lbr"
UsedLibrary="C:/EAGLE 8.3.2/lbr/ltspice/SpecialFunctions.lbr"
UsedLibrary="C:/EAGLE 8.3.2/lbr/ltspice/capmeter.lbr"
UsedLibrary="C:/EAGLE 8.3.2/lbr/ltspice/diode.lbr"
UsedLibrary="C:/EAGLE 8.3.2/lbr/ltspice/lt-spice-simulation.lbr"
UsedLibrary="C:/EAGLE 8.3.2/lbr/ltspice/lt-supply.lbr"
UsedLibrary="C:/EAGLE 8.3.2/lbr/ltspice/rload.lbr"
UsedLibrary="C:/EAGLE 8.3.2/lbr/ltspice/sym.lbr"
UsedLibrary="D:/Dropbox (Personal)/CBA/doc/libraries_jake/eagle/marekr/borkedlabs-passives.lbr"
UsedLibrary="D:/Dropbox (Personal)/CBA/doc/libraries_jake/eagle/marekr/borkedlabs-connectors.lbr"
[Win_1]
Type="Library Editor"
Loc="-11 -11 3828 2054"
State=1
Number=3
File="D:/Dropbox (Personal)/CBA/doc/libraries/eagle/fab.lbr"
View="-5.72372 -5.73775 3.74202 7.02998"
WireWidths=" 0.0762 0.1016 0.127 0.15 0.2 0.2032 0.254 0.3048 0.4064 0.508 0.6096 0.8128 1.016 1.27 2.54 0.1524"
PadDiameters=" 0.3048 0.4064 0.6096 0.8128 1.27 1.4224 1.6764 1.778 1.9304 2.1844 2.54 3.81 6.4516 0 0.8382 1.016"
PadDrills=" 0.25 0.3 0.35 0.4 0.45 0.5 0.55 0.65 0.7 0.75 0.8 0.85 0.9 1 0.6 0.8382"
ViaDiameters=" 0.65 0.7 0.75 0.8 0.85 0.9 0.95 1 1.05 1.1 1.15 1.2 1.3 0 0.8382 1.016"
ViaDrills=" 0.25 0.3 0.4 0.45 0.5 0.55 0.6 0.65 0.7 0.75 0.8 0.85 0.9 1 0.35 0.8382"
HoleDrills=" 0.25 0.3 0.4 0.45 0.5 0.55 0.6 0.65 0.7 0.75 0.8 0.85 0.9 1 0.35 0.8382"
TextSizes=" 0.254 0.3048 0.4064 0.6096 0.8128 1.016 1.27 1.4224 1.6764 1.9304 2.1844 2.54 3.81 5.08 6.4516 1.778"
PolygonSpacings=" 0.254 0.3048 0.4064 0.6096 0.8128 1.016 1.4224 1.6764 1.778 1.9304 2.1844 2.54 3.81 5.08 6.4516 1.27"
PolygonIsolates=" 0.254 0.3048 0.4064 0.6096 0.8128 1.016 1.27 1.4224 1.6764 1.778 1.9304 2.1844 2.54 3.81 6.4516 0"
MiterRadiuss=" 0.254 0.3175 0.635 1.27 2.54 1 2 2.5 5 7.5 10 0"
DimensionWidths=" 0 0.127 0.254 0.1 0.26 0.13"
DimensionExtWidths=" 0.127 0.254 0.1 0.13 0.26 0"
DimensionExtLengths=" 1.27 2.54 1 2 3 0"
DimensionExtOffsets=" 1.27 2.54 1 2 3 0"
SmdSizes=" 0.3048 0.1524 0.4064 0.2032 0.6096 0.3048 0.8128 0.4064 1.016 0.508 1.27 0.6604 1.4224 0.7112 1.6764 0.8128 1.778 0.9144 1.9304 0.9652 2.1844 1.0668 2.54 1.27 3.81 1.9304 5.08 2.54 6.4516 3.2512 1.27 0.635"
WireBend=0
WireBendSet=0
WireCap=1
MiterStyle=0
PadShape=0
ViaShape=1
PolygonPour=0
PolygonRank=0
PolygonThermals=1
PolygonOrphans=0
TextRatio=8
DimensionUnit=1
DimensionPrecision=2
DimensionShowUnit=0
PinDirection=3
PinFunction=0
PinLength=2
PinVisible=3
SwapLevel=0
ArcDirection=0
AddLevel=2
PadsSameType=0
Layer=21
Package="2X5_1.27MM_PTH"
[Win_2]
Type="Board Editor"
Loc="0 0 3839 2065"
State=1
Number=2
File="jtag-tagadapter.brd"
View="-3.16167 -1.71773 17.4692 20.8593"
WireWidths=" 0.0762 0.127 0.15 0.2032 0.3048 0.508 0.6096 0.8128 1.016 1.27 2.54 0.254 0.4064 0.2 0.1016 0.1524"
PadDiameters=" 0.254 0.3048 0.4064 0.6096 0.8128 1.016 1.27 1.4224 1.6764 1.778 1.9304 2.1844 2.54 3.81 6.4516 0"
PadDrills=" 0.2 0.25 0.3 0.35 0.4 0.45 0.5 0.55 0.65 0.7 0.75 0.8 0.85 0.9 1 0.6"
ViaDiameters=" 0.55 0.6 0.65 0.7 0.75 0.8 0.85 0.9 0.95 1 1.05 1.1 1.15 1.2 1.3 0"
ViaDrills=" 0.2 0.25 0.3 0.4 0.45 0.5 0.55 0.6 0.65 0.7 0.75 0.8 0.85 0.9 1 0.35"
HoleDrills=" 0.2 0.25 0.3 0.4 0.45 0.5 0.55 0.6 0.65 0.7 0.75 0.8 0.85 0.9 1 0.35"
TextSizes=" 0.254 0.3048 0.4064 0.6096 0.8128 1.016 1.27 1.4224 1.6764 1.9304 2.1844 2.54 3.81 5.08 6.4516 1.778"
PolygonSpacings=" 0.254 0.3048 0.4064 0.6096 0.8128 1.016 1.4224 1.6764 1.778 1.9304 2.1844 2.54 3.81 5.08 6.4516 1.27"
PolygonIsolates=" 0.254 0.3048 0.4064 0.6096 0.8128 1.016 1.27 1.4224 1.6764 1.778 1.9304 2.1844 2.54 3.81 6.4516 0"
MiterRadiuss=" 0.254 0.3175 0.635 1.27 2.54 1 2 2.5 5 7.5 10 0"
DimensionWidths=" 0 0.127 0.254 0.1 0.26 0.13"
DimensionExtWidths=" 0.127 0.254 0.1 0.13 0.26 0"
DimensionExtLengths=" 1.27 2.54 1 2 3 0"
DimensionExtOffsets=" 1.27 2.54 1 2 3 0"
SmdSizes=" 0.3048 0.1524 0.4064 0.2032 0.6096 0.3048 0.8128 0.4064 1.016 0.508 1.27 0.6604 1.4224 0.7112 1.6764 0.8128 1.778 0.9144 1.9304 0.9652 2.1844 1.0668 2.54 1.27 3.81 1.9304 5.08 2.54 6.4516 3.2512 1.27 0.635"
WireBend=1
WireBendSet=0
WireCap=1
MiterStyle=0
PadShape=0
ViaShape=1
PolygonPour=0
PolygonRank=1
PolygonThermals=1
PolygonOrphans=0
TextRatio=8
DimensionUnit=1
DimensionPrecision=2
DimensionShowUnit=0
PinDirection=3
PinFunction=0
PinLength=2
PinVisible=3
SwapLevel=0
ArcDirection=0
AddLevel=2
PadsSameType=0
Layer=1
[Win_3]
Type="Schematic Editor"
Loc="0 0 3839 2065"
State=1
Number=1
File="jtag-tagadapter.sch"
View="17.9982 -33.4177 152.758 16.6728"
WireWidths=" 0.0762 0.1016 0.127 0.15 0.2 0.2032 0.254 0.3048 0.4064 0.508 0.6096 0.8128 1.016 1.27 2.54 0.1524"
PadDiameters=" 0.254 0.3048 0.4064 0.6096 0.8128 1.016 1.27 1.4224 1.6764 1.778 1.9304 2.1844 2.54 3.81 6.4516 0"
PadDrills=" 0.2 0.25 0.3 0.35 0.4 0.45 0.5 0.55 0.65 0.7 0.75 0.8 0.85 0.9 1 0.6"
ViaDiameters=" 0.55 0.6 0.65 0.7 0.75 0.8 0.85 0.9 0.95 1 1.05 1.1 1.15 1.2 1.3 0"
ViaDrills=" 0.2 0.25 0.3 0.4 0.45 0.5 0.55 0.6 0.65 0.7 0.75 0.8 0.85 0.9 1 0.35"
HoleDrills=" 0.2 0.25 0.3 0.4 0.45 0.5 0.55 0.6 0.65 0.7 0.75 0.8 0.85 0.9 1 0.35"
TextSizes=" 0.254 0.3048 0.4064 0.6096 0.8128 1.016 1.27 1.4224 1.6764 1.9304 2.1844 2.54 3.81 5.08 6.4516 1.778"
PolygonSpacings=" 0.254 0.3048 0.4064 0.6096 0.8128 1.016 1.4224 1.6764 1.778 1.9304 2.1844 2.54 3.81 5.08 6.4516 1.27"
PolygonIsolates=" 0.254 0.3048 0.4064 0.6096 0.8128 1.016 1.27 1.4224 1.6764 1.778 1.9304 2.1844 2.54 3.81 6.4516 0"
MiterRadiuss=" 0.254 0.3175 0.635 1.27 2.54 1 2 2.5 5 7.5 10 0"
DimensionWidths=" 0 0.127 0.254 0.1 0.26 0.13"
DimensionExtWidths=" 0.127 0.254 0.1 0.13 0.26 0"
DimensionExtLengths=" 1.27 2.54 1 2 3 0"
DimensionExtOffsets=" 1.27 2.54 1 2 3 0"
SmdSizes=" 0.3048 0.1524 0.4064 0.2032 0.6096 0.3048 0.8128 0.4064 1.016 0.508 1.27 0.6604 1.4224 0.7112 1.6764 0.8128 1.778 0.9144 1.9304 0.9652 2.1844 1.0668 2.54 1.27 3.81 1.9304 5.08 2.54 6.4516 3.2512 1.27 0.635"
WireBend=0
WireBendSet=31
WireCap=1
MiterStyle=0
PadShape=0
ViaShape=1
PolygonPour=0
PolygonRank=0
PolygonThermals=1
PolygonOrphans=0
TextRatio=8
DimensionUnit=1
DimensionPrecision=2
DimensionShowUnit=0
PinDirection=3
PinFunction=0
PinLength=2
PinVisible=3
SwapLevel=0
ArcDirection=0
AddLevel=2
PadsSameType=0
Layer=91
Views=" 1: 17.9982 -33.4177 152.758 16.6728"
Sheet="1"
[Win_4]
Type="Control Panel"
Loc="0 0 3839 2065"
State=1
Number=0
[Desktop]
Screen="3840 2160"
Window="Win_1"
Window="Win_2"
Window="Win_3"
Window="Win_4"
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment