Arnaud VALLEY / Mbed 2 deprecated Pinscape_Controller_V2_arnoz

Dependencies:   mbed FastIO FastPWM USBDevice

Committer:
mjr
Date:
Thu Nov 28 23:18:23 2019 +0000
Revision:
100:1ff35c07217c
Child:
101:755f44622abc
Added preliminary support for AEAT-6012 and TCD1103 sensors; use continuous averaging for pot sensor analog in; more AltAnalogIn options for timing and resolution

Who changed what in which revision?

UserRevisionLine numberNew contents of line
mjr 100:1ff35c07217c 1 // Toshiba TCD1103 linear image sensors
mjr 100:1ff35c07217c 2 //
mjr 100:1ff35c07217c 3 // This sensor is similar to the original TSL1410R in both its electronic
mjr 100:1ff35c07217c 4 // interface and the theory of operation. The details of the electronics
mjr 100:1ff35c07217c 5 // are different enough that we can't reuse the same code at the hardware
mjr 100:1ff35c07217c 6 // interface level, but the principle of operation is similar: the sensor
mjr 100:1ff35c07217c 7 // provides a serial interface to a file of pixels transferred as analog
mjr 100:1ff35c07217c 8 // voltage levels representing the charge collected.
mjr 100:1ff35c07217c 9 //
mjr 100:1ff35c07217c 10 // As with the TSL1410R, we position the sensor so that the pixel row is
mjr 100:1ff35c07217c 11 // aligned with the plunger axis, with a backlight, and we detect the plunger
mjr 100:1ff35c07217c 12 // position by looking for an edge between a light area (where the backlight
mjr 100:1ff35c07217c 13 // is unobstructed) and a dark area (where the plunger rod is blocking the
mjr 100:1ff35c07217c 14 // backlight). The optical sensor area of the TSL1410R is large enough to
mjr 100:1ff35c07217c 15 // cover the entire plunger travel distance, so the physical setup for that
mjr 100:1ff35c07217c 16 // sensor is a simple matter of placing the sensor near the plunger, so that
mjr 100:1ff35c07217c 17 // the plunger casts a shadow on the sensor. The TCD1103, in contrast, has a
mjr 100:1ff35c07217c 18 // small optical sensor area, about 8mm long, so in this case we have to use
mjr 100:1ff35c07217c 19 // a lens to reduce the image of the plunger by about 10X (from the 80mm
mjr 100:1ff35c07217c 20 // plunger travel distance to the 8mm sensor size). This makes the physical
mjr 100:1ff35c07217c 21 // setup more complex, but it has the advantage of giving us a focused image,
mjr 100:1ff35c07217c 22 // allowing for better precision in detecting the edge. With the unfocused
mjr 100:1ff35c07217c 23 // image used in the TSL1410R setup, the shadow was blurry over about 1/50".
mjr 100:1ff35c07217c 24 // With a lens to focus the image, we could potentially get as good as
mjr 100:1ff35c07217c 25 // single-pixel resolution, which would give us about 1/500" resolution on
mjr 100:1ff35c07217c 26 // this 1500-pixel sensor.
mjr 100:1ff35c07217c 27 //
mjr 100:1ff35c07217c 28
mjr 100:1ff35c07217c 29 #include "edgeSensor.h"
mjr 100:1ff35c07217c 30 #include "TCD1103.h"
mjr 100:1ff35c07217c 31
mjr 100:1ff35c07217c 32 template <bool invertedLogicGates>
mjr 100:1ff35c07217c 33 class PlungerSensorImageInterfaceTCD1103: public PlungerSensorImageInterface
mjr 100:1ff35c07217c 34 {
mjr 100:1ff35c07217c 35 public:
mjr 100:1ff35c07217c 36 // Note that the TCD1103 has 1500 actual image pixels, but the serial
mjr 100:1ff35c07217c 37 // interface provides 32 dummy elements on the front end (before the
mjr 100:1ff35c07217c 38 // first image pixel) and 14 dummy elements on the back end (after the
mjr 100:1ff35c07217c 39 // last image pixel), for a total of 1546 serial outputs.
mjr 100:1ff35c07217c 40 PlungerSensorImageInterfaceTCD1103(PinName fm, PinName os, PinName icg, PinName sh)
mjr 100:1ff35c07217c 41 : PlungerSensorImageInterface(1546), sensor(fm, os, icg, sh)
mjr 100:1ff35c07217c 42 {
mjr 100:1ff35c07217c 43 }
mjr 100:1ff35c07217c 44
mjr 100:1ff35c07217c 45 // is the sensor ready?
mjr 100:1ff35c07217c 46 virtual bool ready() { return sensor.ready(); }
mjr 100:1ff35c07217c 47
mjr 100:1ff35c07217c 48 // is a DMA transfer in progress?
mjr 100:1ff35c07217c 49 virtual bool dmaBusy() { return sensor.dmaBusy(); }
mjr 100:1ff35c07217c 50
mjr 100:1ff35c07217c 51 virtual void init()
mjr 100:1ff35c07217c 52 {
mjr 100:1ff35c07217c 53 sensor.clear();
mjr 100:1ff35c07217c 54 }
mjr 100:1ff35c07217c 55
mjr 100:1ff35c07217c 56 // get the average sensor scan time
mjr 100:1ff35c07217c 57 virtual uint32_t getAvgScanTime() { return sensor.getAvgScanTime(); }
mjr 100:1ff35c07217c 58
mjr 100:1ff35c07217c 59 protected:
mjr 100:1ff35c07217c 60 virtual void readPix(uint8_t* &pix, uint32_t &t, int axcTime)
mjr 100:1ff35c07217c 61 {
mjr 100:1ff35c07217c 62 // start reading the next pixel array (this waits for any DMA
mjr 100:1ff35c07217c 63 // transfer in progress to finish, ensuring a stable pixel buffer)
mjr 100:1ff35c07217c 64 sensor.startCapture(axcTime);
mjr 100:1ff35c07217c 65
mjr 100:1ff35c07217c 66 // get the image array from the last capture
mjr 100:1ff35c07217c 67 sensor.getPix(pix, t);
mjr 100:1ff35c07217c 68 }
mjr 100:1ff35c07217c 69
mjr 100:1ff35c07217c 70 virtual void getStatusReportPixels(
mjr 100:1ff35c07217c 71 uint8_t* &pix, uint32_t &t, int axcTime, int extraTime)
mjr 100:1ff35c07217c 72 {
mjr 100:1ff35c07217c 73 // The sensor's internal buffering scheme makes it a little tricky
mjr 100:1ff35c07217c 74 // to get the requested timing, and our own double-buffering adds a
mjr 100:1ff35c07217c 75 // little complexity as well. To get the exact timing requested, we
mjr 100:1ff35c07217c 76 // have to work with the buffering pipeline like so:
mjr 100:1ff35c07217c 77 //
mjr 100:1ff35c07217c 78 // 1. Call startCapture(). This waits for any in-progress pixel
mjr 100:1ff35c07217c 79 // transfer from the sensor to finish, then executes an SH/ICG pulse
mjr 100:1ff35c07217c 80 // on the sensor. The pulse takes a snapshot of the current live
mjr 100:1ff35c07217c 81 // photo receptors to the sensor shift register. These pixels have
mjr 100:1ff35c07217c 82 // been integrating starting from before we were called; call this
mjr 100:1ff35c07217c 83 // integration period A. So the shift register contains period A.
mjr 100:1ff35c07217c 84 // The SH/ICG then grounds the photo receptors, clearing their
mjr 100:1ff35c07217c 85 // charge, thus starting a new integration period B. After sending
mjr 100:1ff35c07217c 86 // the SH/ICG pulse, startCapture() begins a DMA transfer of the
mjr 100:1ff35c07217c 87 // shift register pixels (period A) to one of our two buffers (call
mjr 100:1ff35c07217c 88 // it the EVEN buffer).
mjr 100:1ff35c07217c 89 //
mjr 100:1ff35c07217c 90 // 2. Wait for the current transfer (period A to the EVEN buffer)
mjr 100:1ff35c07217c 91 // to finish. The minimum integration time is the time of one
mjr 100:1ff35c07217c 92 // transfer cycle, so this brings us to the minimum time for
mjr 100:1ff35c07217c 93 // period B.
mjr 100:1ff35c07217c 94 //
mjr 100:1ff35c07217c 95 // 3. Now pause for the requested extra delay time. Period B is
mjr 100:1ff35c07217c 96 // still running at this point (it keeps going until we start a
mjr 100:1ff35c07217c 97 // new capture), so this pause adds the requested extra time to
mjr 100:1ff35c07217c 98 // period B's total integration time. This brings period B to
mjr 100:1ff35c07217c 99 // exactly the requested total time.
mjr 100:1ff35c07217c 100 //
mjr 100:1ff35c07217c 101 // 4. Call startCapture() to end period B, move period B's pixels
mjr 100:1ff35c07217c 102 // to the sensor's shift register, and begin period C. This
mjr 100:1ff35c07217c 103 // switches DMA buffers, so the EVEN buffer (with period A) is now
mjr 100:1ff35c07217c 104 // available, and the ODD buffer becomes the DMA target for the
mjr 100:1ff35c07217c 105 // period B pixels.
mjr 100:1ff35c07217c 106 //
mjr 100:1ff35c07217c 107 // 5. Wait for the period B pixels to become available, via
mjr 100:1ff35c07217c 108 // waitPix(). This waits for the DMA transfer to complete and
mjr 100:1ff35c07217c 109 // hands us the latest (ODD) transfer buffer.
mjr 100:1ff35c07217c 110 //
mjr 100:1ff35c07217c 111 sensor.startCapture(axcTime); // begin transfer of pixels from incoming period A, begin integration period B
mjr 100:1ff35c07217c 112 sensor.wait(); // wait for scan of A to complete, as minimum integration B time
mjr 100:1ff35c07217c 113 wait_us(long(extraTime) * 100); // add extraTime (0.1ms == 100us increments) to integration B time
mjr 100:1ff35c07217c 114 sensor.startCapture(axcTime); // begin transfer of pixels from integration period B, begin period C; period A pixels now available
mjr 100:1ff35c07217c 115
mjr 100:1ff35c07217c 116 // wait for the DMA transfer of period B to finish, and get the
mjr 100:1ff35c07217c 117 // period B pixels
mjr 100:1ff35c07217c 118 sensor.waitPix(pix, t);
mjr 100:1ff35c07217c 119 }
mjr 100:1ff35c07217c 120
mjr 100:1ff35c07217c 121 // reset after a status report
mjr 100:1ff35c07217c 122 virtual void resetAfterStatusReport(int axcTime)
mjr 100:1ff35c07217c 123 {
mjr 100:1ff35c07217c 124 // It takes us a while to send all of the pixels, since we have
mjr 100:1ff35c07217c 125 // to break them up into many USB reports. This delay means that
mjr 100:1ff35c07217c 126 // the sensor has been sitting there integrating for much longer
mjr 100:1ff35c07217c 127 // than usual, so the next frame read will be overexposed. To
mjr 100:1ff35c07217c 128 // mitigate this, make sure we don't have a capture running,
mjr 100:1ff35c07217c 129 // then clear the sensor and start a new capture.
mjr 100:1ff35c07217c 130 sensor.wait();
mjr 100:1ff35c07217c 131 sensor.clear();
mjr 100:1ff35c07217c 132 sensor.startCapture(axcTime);
mjr 100:1ff35c07217c 133 }
mjr 100:1ff35c07217c 134
mjr 100:1ff35c07217c 135 // the low-level interface to the TSL14xx sensor
mjr 100:1ff35c07217c 136 TCD1103<invertedLogicGates> sensor;
mjr 100:1ff35c07217c 137 };
mjr 100:1ff35c07217c 138
mjr 100:1ff35c07217c 139 template<bool invertedLogicGates>
mjr 100:1ff35c07217c 140 class PlungerSensorTCD1103: public PlungerSensorEdgePos
mjr 100:1ff35c07217c 141 {
mjr 100:1ff35c07217c 142 public:
mjr 100:1ff35c07217c 143 // Note that the TCD1103 has 1500 actual image pixels, but the serial
mjr 100:1ff35c07217c 144 // interface provides 32 dummy elements on the front end (before the
mjr 100:1ff35c07217c 145 // first image pixel) and 14 dummy elements on the back end (after the
mjr 100:1ff35c07217c 146 // last image pixel), for a total of 1546 serial outputs.
mjr 100:1ff35c07217c 147 PlungerSensorTCD1103(PinName fm, PinName os, PinName icg, PinName sh)
mjr 100:1ff35c07217c 148 : PlungerSensorEdgePos(sensor, 1546), sensor(fm, os, icg, sh)
mjr 100:1ff35c07217c 149 {
mjr 100:1ff35c07217c 150 }
mjr 100:1ff35c07217c 151
mjr 100:1ff35c07217c 152 protected:
mjr 100:1ff35c07217c 153 PlungerSensorImageInterfaceTCD1103<invertedLogicGates> sensor;
mjr 100:1ff35c07217c 154 };