Mirror with some correction
Dependencies: mbed FastIO FastPWM USBDevice
AEAT6012/AEAT6012.h@116:7a67265d7c19, 2021-10-01 (annotated)
- Committer:
- arnoz
- Date:
- Fri Oct 01 08:19:46 2021 +0000
- Revision:
- 116:7a67265d7c19
- Parent:
- 102:41d49e78c253
- Correct information regarding your last merge
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
mjr | 100:1ff35c07217c | 1 | // AEAT-6012-A06 interface |
mjr | 100:1ff35c07217c | 2 | // |
mjr | 100:1ff35c07217c | 3 | // The Broadcom AEAT-6012-A06 is a magnetic absolute rotary position encoder |
mjr | 100:1ff35c07217c | 4 | // with a 12-bit digital position output. It encodes the rotational angle of |
mjr | 100:1ff35c07217c | 5 | // magnet, which is meant to be attached to a shaft that's positioned |
mjr | 100:1ff35c07217c | 6 | // perpendicular to the sensor. The 12-bit reporting means that the angle |
mjr | 100:1ff35c07217c | 7 | // is resolved to one part in 4096 around one 360 degree rotation of the |
mjr | 100:1ff35c07217c | 8 | // shaft, so each increment represents 360/4096 = 0.088 degrees of arc. |
mjr | 100:1ff35c07217c | 9 | // |
mjr | 100:1ff35c07217c | 10 | // For Pinscape purposes, we can use this sensor to track the position of |
mjr | 100:1ff35c07217c | 11 | // a plunger by mechanically translating the linear motion of the plunger |
mjr | 100:1ff35c07217c | 12 | // to rotational motion around a fixed point somewhere off the axis of the |
mjr | 100:1ff35c07217c | 13 | // plunger: |
mjr | 100:1ff35c07217c | 14 | // |
mjr | 100:1ff35c07217c | 15 | // =X=======================|=== <- plunger, X = connector attachment point |
mjr | 100:1ff35c07217c | 16 | // \ |
mjr | 100:1ff35c07217c | 17 | // \ <- connector between plunger and shaft |
mjr | 100:1ff35c07217c | 18 | // \ |
mjr | 100:1ff35c07217c | 19 | // * <- rotating shaft, at a fixed position |
mjr | 100:1ff35c07217c | 20 | // |
mjr | 100:1ff35c07217c | 21 | // As the plunger moves, the angle of the connector relative to the fixed |
mjr | 100:1ff35c07217c | 22 | // shaft position changes in a predictable way, so by measuring the rotational |
mjr | 100:1ff35c07217c | 23 | // position of the shaft at any given time, we can infer the plunger's |
mjr | 100:1ff35c07217c | 24 | // linear position. The relationship between the plunger position and shaft |
mjr | 100:1ff35c07217c | 25 | // angle isn't precisely linear - it's sinusoidal. So we need to apply a |
mjr | 100:1ff35c07217c | 26 | // little trigonometry to recover the linear position from the angle. |
mjr | 100:1ff35c07217c | 27 | // |
mjr | 100:1ff35c07217c | 28 | // The AEAT-6012-A06 has an extremely simple electronic interface. It uses |
mjr | 100:1ff35c07217c | 29 | // a three-wire serial protocol: CS (chip select), CLK (data clock), and |
mjr | 100:1ff35c07217c | 30 | // DO (digital data out). The data transmission is one-way - device to |
mjr | 100:1ff35c07217c | 31 | // host - and simply consists of the 12-bit position reading. There aren't |
mjr | 100:1ff35c07217c | 32 | // any "commands" or other fancy business to deal with. Between readings, |
mjr | 100:1ff35c07217c | 33 | // CS is held high; to intiate a reading, hold CS low, then toggle CLK to |
mjr | 100:1ff35c07217c | 34 | // clock out the bits. The bits are clocked out from MSb to LSb. After |
mjr | 100:1ff35c07217c | 35 | // clocking out the 12 bits, we take CS high again to reset the cycle. |
mjr | 100:1ff35c07217c | 36 | // There are also some timing requirements spelled out in the data sheet |
mjr | 100:1ff35c07217c | 37 | // that we have to observe for minimum clock pulse time, time before DO |
mjr | 100:1ff35c07217c | 38 | // is valid, etc. |
mjr | 100:1ff35c07217c | 39 | // |
mjr | 100:1ff35c07217c | 40 | // There's a 10-bit variant of the sensor (AEAT-6010) that's otherwise |
mjr | 100:1ff35c07217c | 41 | // identical, so we've made the data size a parameter so that the code can |
mjr | 100:1ff35c07217c | 42 | // be re-used for both sensor types (as well as any future variations with |
mjr | 100:1ff35c07217c | 43 | // other resolutions). |
mjr | 100:1ff35c07217c | 44 | |
mjr | 100:1ff35c07217c | 45 | template<int nBits> class AEAT601X |
mjr | 100:1ff35c07217c | 46 | { |
mjr | 100:1ff35c07217c | 47 | public: |
mjr | 100:1ff35c07217c | 48 | AEAT601X(PinName csPin, PinName clkPin, PinName doPin) : |
mjr | 100:1ff35c07217c | 49 | cs(csPin), clk(clkPin), DO(doPin) |
mjr | 100:1ff35c07217c | 50 | { |
mjr | 100:1ff35c07217c | 51 | // hold CS and CLK high between readings |
mjr | 100:1ff35c07217c | 52 | cs = 1; |
mjr | 100:1ff35c07217c | 53 | clk = 1; |
mjr | 100:1ff35c07217c | 54 | } |
mjr | 100:1ff35c07217c | 55 | |
mjr | 100:1ff35c07217c | 56 | // take a reading, returning an unsigned integer result from 0 to 2^bits-1 |
mjr | 100:1ff35c07217c | 57 | int readAngle() |
mjr | 100:1ff35c07217c | 58 | { |
mjr | 100:1ff35c07217c | 59 | // Note on timings: the data sheet lists a number of minimum timing |
mjr | 100:1ff35c07217c | 60 | // parameters for the serial protocol. The parameters of interest |
mjr | 100:1ff35c07217c | 61 | // here are all sub-microsecond, from 100ns to 500ns. The mbed |
mjr | 100:1ff35c07217c | 62 | // library doesn't have a nanosecond "wait", just the microsecond |
mjr | 100:1ff35c07217c | 63 | // wait, so we can't wait for precisely the minimum times. But we |
mjr | 100:1ff35c07217c | 64 | // don't have to; the parameters are all minimum waits to ensure |
mjr | 100:1ff35c07217c | 65 | // that the sensor is ready for the next operation, so it's okay |
mjr | 100:1ff35c07217c | 66 | // to wait longer than the minimum. And since we only have to move |
mjr | 100:1ff35c07217c | 67 | // a small number of bits (10-12 for the current sensor generation), |
mjr | 100:1ff35c07217c | 68 | // we don't have to be ruthlessly efficient about it; we can afford |
mjr | 100:1ff35c07217c | 69 | // to putter around for a leisurely microsecond at each step. The |
mjr | 100:1ff35c07217c | 70 | // total delay time for the 12-bit sensor even with the microsecond |
mjr | 100:1ff35c07217c | 71 | // delays only amounts to 25us, which is negligible for the plunger |
mjr | 100:1ff35c07217c | 72 | // read operation. |
mjr | 100:1ff35c07217c | 73 | |
mjr | 100:1ff35c07217c | 74 | // hold CS low for at least t[CLKFE] = 500ns per data sheet |
mjr | 100:1ff35c07217c | 75 | cs = 0; |
mjr | 100:1ff35c07217c | 76 | wait_us(1); |
mjr | 100:1ff35c07217c | 77 | |
mjr | 100:1ff35c07217c | 78 | // clock in the bits |
mjr | 100:1ff35c07217c | 79 | int result = 0; |
mjr | 100:1ff35c07217c | 80 | for (int i = 0; i < nBits; ++i) |
mjr | 100:1ff35c07217c | 81 | { |
mjr | 100:1ff35c07217c | 82 | // take clock low for >= T[CLK/2] = 500ns |
mjr | 100:1ff35c07217c | 83 | clk = 0; |
mjr | 100:1ff35c07217c | 84 | wait_us(1); |
mjr | 100:1ff35c07217c | 85 | |
mjr | 100:1ff35c07217c | 86 | // take clock high |
mjr | 100:1ff35c07217c | 87 | clk = 1; |
mjr | 100:1ff35c07217c | 88 | |
mjr | 100:1ff35c07217c | 89 | // wait for the data to become valid, T[DOvalid] = 375ns |
mjr | 100:1ff35c07217c | 90 | wait_us(1); |
mjr | 100:1ff35c07217c | 91 | |
mjr | 100:1ff35c07217c | 92 | // read the bit |
mjr | 100:1ff35c07217c | 93 | result <<= 1; |
mjr | 100:1ff35c07217c | 94 | result |= (DO ? 1 : 0); |
mjr | 100:1ff35c07217c | 95 | } |
mjr | 100:1ff35c07217c | 96 | |
mjr | 100:1ff35c07217c | 97 | // done - leave CS high between readings |
mjr | 100:1ff35c07217c | 98 | cs = 1; |
mjr | 100:1ff35c07217c | 99 | |
mjr | 102:41d49e78c253 | 100 | // The orientation in our mounting design reads the angle in the |
mjr | 102:41d49e78c253 | 101 | // reverse of the direction we want, so flip it. |
mjr | 102:41d49e78c253 | 102 | result = 4095 - result; |
mjr | 102:41d49e78c253 | 103 | |
mjr | 100:1ff35c07217c | 104 | // return the result |
mjr | 100:1ff35c07217c | 105 | return result; |
mjr | 100:1ff35c07217c | 106 | } |
mjr | 100:1ff35c07217c | 107 | |
mjr | 100:1ff35c07217c | 108 | protected: |
mjr | 100:1ff35c07217c | 109 | // CS (chip select) pin |
mjr | 100:1ff35c07217c | 110 | DigitalOut cs; |
mjr | 100:1ff35c07217c | 111 | |
mjr | 100:1ff35c07217c | 112 | // CLK (serial clock) pin |
mjr | 100:1ff35c07217c | 113 | DigitalOut clk; |
mjr | 100:1ff35c07217c | 114 | |
mjr | 100:1ff35c07217c | 115 | // DO (serial data) pin |
mjr | 100:1ff35c07217c | 116 | DigitalIn DO; |
mjr | 100:1ff35c07217c | 117 | }; |