Mirror with some correction

Dependencies:   mbed FastIO FastPWM USBDevice

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?

UserRevisionLine numberNew 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 };