Arnaud VALLEY / Mbed 2 deprecated Pinscape_Controller_V2_arnoz

Dependencies:   mbed FastIO FastPWM USBDevice

Committer:
mjr
Date:
Tue May 09 05:48:37 2017 +0000
Revision:
87:8d35c74403af
Parent:
86:e30a1f60f783
Child:
100:1ff35c07217c
AEDR-8300, VL6180X, TLC59116; new plunger firing detection

Who changed what in which revision?

UserRevisionLine numberNew contents of line
mjr 82:4f6209cb5c33 1 // Base class for TSL14xx-based plunger sensors.
mjr 82:4f6209cb5c33 2 //
mjr 82:4f6209cb5c33 3 // This provides a common base class for plunger sensors based on
mjr 82:4f6209cb5c33 4 // AMS/TAOS TSL14xx sensors (TSL1410R, TSL1412S, TSL1401CL). The sensors
mjr 82:4f6209cb5c33 5 // in this series all work the same way, differing mostly in the number
mjr 82:4f6209cb5c33 6 // of pixels. However, we have two fundamentally different ways of using
mjr 82:4f6209cb5c33 7 // these image sensors to detect position: sensing the position of the
mjr 82:4f6209cb5c33 8 // shadow cast by the plunger on the sensor, and optically reading a bar
mjr 82:4f6209cb5c33 9 // code telling us the location of the sensor along a scale. This class
mjr 82:4f6209cb5c33 10 // provides the low-level pixel-sensor interface; subclasses provide the
mjr 82:4f6209cb5c33 11 // image analysis that figures the position from the captured image.
mjr 82:4f6209cb5c33 12
mjr 82:4f6209cb5c33 13
mjr 82:4f6209cb5c33 14 #ifndef _TSL14XXSENSOR_H_
mjr 82:4f6209cb5c33 15 #define _TSL14XXSENSOR_H_
mjr 82:4f6209cb5c33 16
mjr 82:4f6209cb5c33 17 #include "plunger.h"
mjr 87:8d35c74403af 18 #include "edgeSensor.h"
mjr 87:8d35c74403af 19 #include "barCodeSensor.h"
mjr 82:4f6209cb5c33 20 #include "TSL14xx.h"
mjr 82:4f6209cb5c33 21
mjr 87:8d35c74403af 22 class PlungerSensorImageInterfaceTSL14xx: public PlungerSensorImageInterface
mjr 82:4f6209cb5c33 23 {
mjr 82:4f6209cb5c33 24 public:
mjr 87:8d35c74403af 25 PlungerSensorImageInterfaceTSL14xx(int nativePix, PinName si, PinName clock, PinName ao)
mjr 87:8d35c74403af 26 : PlungerSensorImageInterface(nativePix), sensor(nativePix, si, clock, ao)
mjr 82:4f6209cb5c33 27 {
mjr 82:4f6209cb5c33 28 }
mjr 82:4f6209cb5c33 29
mjr 82:4f6209cb5c33 30 // is the sensor ready?
mjr 82:4f6209cb5c33 31 virtual bool ready() { return sensor.ready(); }
mjr 82:4f6209cb5c33 32
mjr 87:8d35c74403af 33 // is a DMA transfer in progress?
mjr 87:8d35c74403af 34 virtual bool dmaBusy() { return sensor.dmaBusy(); }
mjr 87:8d35c74403af 35
mjr 82:4f6209cb5c33 36 virtual void init()
mjr 82:4f6209cb5c33 37 {
mjr 82:4f6209cb5c33 38 sensor.clear();
mjr 82:4f6209cb5c33 39 }
mjr 82:4f6209cb5c33 40
mjr 87:8d35c74403af 41 // get the average sensor scan time
mjr 87:8d35c74403af 42 virtual uint32_t getAvgScanTime() { return sensor.getAvgScanTime(); }
mjr 87:8d35c74403af 43
mjr 87:8d35c74403af 44 protected:
mjr 87:8d35c74403af 45 virtual void getStatusReportPixels(
mjr 87:8d35c74403af 46 uint8_t* &pix, uint32_t &t, int axcTime, int extraTime)
mjr 82:4f6209cb5c33 47 {
mjr 86:e30a1f60f783 48 // The sensor's internal buffering scheme makes it a little tricky
mjr 86:e30a1f60f783 49 // to get the requested timing, and our own double-buffering adds a
mjr 86:e30a1f60f783 50 // little complexity as well. To get the exact timing requested, we
mjr 86:e30a1f60f783 51 // have to work with the buffering pipeline like so:
mjr 82:4f6209cb5c33 52 //
mjr 86:e30a1f60f783 53 // 1. Call startCapture(). This waits for any in-progress pixel
mjr 86:e30a1f60f783 54 // transfer from the sensor to finish, then executes a HOLD/SI pulse
mjr 86:e30a1f60f783 55 // on the sensor. The HOLD/SI takes a snapshot of the current live
mjr 86:e30a1f60f783 56 // photo receptors to the sensor shift register. These pixels have
mjr 86:e30a1f60f783 57 // been integrating starting from before we were called; call this
mjr 86:e30a1f60f783 58 // integration period A. So the shift register contains period A.
mjr 86:e30a1f60f783 59 // The HOLD/SI then grounds the photo receptors, clearing their
mjr 86:e30a1f60f783 60 // charge, thus starting a new integration period B. After sending
mjr 86:e30a1f60f783 61 // the HOLD/SI pulse, startCapture() begins a DMA transfer of the
mjr 86:e30a1f60f783 62 // shift register pixels (period A) to one of our two buffers (call
mjr 86:e30a1f60f783 63 // it the EVEN buffer).
mjr 82:4f6209cb5c33 64 //
mjr 86:e30a1f60f783 65 // 2. Wait for the current transfer (period A to the EVEN buffer)
mjr 86:e30a1f60f783 66 // to finish. The minimum integration time is the time of one
mjr 86:e30a1f60f783 67 // transfer cycle, so this brings us to the minimum time for
mjr 86:e30a1f60f783 68 // period B.
mjr 86:e30a1f60f783 69 //
mjr 86:e30a1f60f783 70 // 3. Now pause for the reqeusted extra delay time. Period B is
mjr 86:e30a1f60f783 71 // still running at this point (it keeps going until we start a
mjr 86:e30a1f60f783 72 // new capture), so this pause adds the requested extra time to
mjr 86:e30a1f60f783 73 // period B's total integration time. This brings period B to
mjr 86:e30a1f60f783 74 // exactly the requested total time.
mjr 82:4f6209cb5c33 75 //
mjr 86:e30a1f60f783 76 // 4. Call startCapture() to end period B, move period B's pixels
mjr 86:e30a1f60f783 77 // to the sensor's shift register, and begin period C. This
mjr 86:e30a1f60f783 78 // switches DMA buffers, so the EVEN buffer (with period A) is now
mjr 86:e30a1f60f783 79 // available, and the ODD buffer becomes the DMA target for the
mjr 86:e30a1f60f783 80 // period B pixels.
mjr 82:4f6209cb5c33 81 //
mjr 86:e30a1f60f783 82 // 5. Wait for the period B pixels to become available, via
mjr 86:e30a1f60f783 83 // waitPix(). This waits for the DMA transfer to complete and
mjr 86:e30a1f60f783 84 // hands us the latest (ODD) transfer buffer.
mjr 86:e30a1f60f783 85 //
mjr 86:e30a1f60f783 86 sensor.startCapture(axcTime); // begin transfer of pixels from incoming period A, begin integration period B
mjr 82:4f6209cb5c33 87 sensor.wait(); // wait for scan of A to complete, as minimum integration B time
mjr 82:4f6209cb5c33 88 wait_us(long(extraTime) * 100); // add extraTime (0.1ms == 100us increments) to integration B time
mjr 86:e30a1f60f783 89 sensor.startCapture(axcTime); // begin transfer of pixels from integration period B, begin period C; period A pixels now available
mjr 82:4f6209cb5c33 90
mjr 86:e30a1f60f783 91 // wait for the DMA transfer of period B to finish, and get the
mjr 86:e30a1f60f783 92 // period B pixels
mjr 86:e30a1f60f783 93 sensor.waitPix(pix, t);
mjr 87:8d35c74403af 94 }
mjr 87:8d35c74403af 95
mjr 87:8d35c74403af 96 // reset after a status report
mjr 87:8d35c74403af 97 virtual void resetAfterStatusReport(int axcTime)
mjr 87:8d35c74403af 98 {
mjr 82:4f6209cb5c33 99 // It takes us a while to send all of the pixels, since we have
mjr 82:4f6209cb5c33 100 // to break them up into many USB reports. This delay means that
mjr 82:4f6209cb5c33 101 // the sensor has been sitting there integrating for much longer
mjr 82:4f6209cb5c33 102 // than usual, so the next frame read will be overexposed. To
mjr 82:4f6209cb5c33 103 // mitigate this, make sure we don't have a capture running,
mjr 82:4f6209cb5c33 104 // then clear the sensor and start a new capture.
mjr 82:4f6209cb5c33 105 sensor.wait();
mjr 82:4f6209cb5c33 106 sensor.clear();
mjr 82:4f6209cb5c33 107 sensor.startCapture(axcTime);
mjr 82:4f6209cb5c33 108 }
mjr 87:8d35c74403af 109
mjr 82:4f6209cb5c33 110 // the low-level interface to the TSL14xx sensor
mjr 82:4f6209cb5c33 111 TSL14xx sensor;
mjr 82:4f6209cb5c33 112 };
mjr 82:4f6209cb5c33 113
mjr 86:e30a1f60f783 114 // ---------------------------------------------------------------------
mjr 86:e30a1f60f783 115 //
mjr 86:e30a1f60f783 116 // Subclass for the large sensors, such as TSL1410R (1280 pixels)
mjr 86:e30a1f60f783 117 // and TSL1412S (1536 pixels).
mjr 86:e30a1f60f783 118 //
mjr 86:e30a1f60f783 119 // For the large sensors, pixel transfers take a long time: about
mjr 86:e30a1f60f783 120 // 2.5ms on the 1410R and 1412S. This is much longer than our main
mjr 86:e30a1f60f783 121 // loop time, so we don't want to block other work to do a transfer.
mjr 86:e30a1f60f783 122 // Instead, we want to do our transfers asynchronously, so that the
mjr 86:e30a1f60f783 123 // main loop can keep going while a transfer proceeds. This is
mjr 86:e30a1f60f783 124 // possible via our DMA double buffering.
mjr 86:e30a1f60f783 125 //
mjr 86:e30a1f60f783 126 // This scheme gives us three images in our pipeline at any given time:
mjr 86:e30a1f60f783 127 //
mjr 86:e30a1f60f783 128 // - a live image integrating light on the photo receptors on the sensor
mjr 86:e30a1f60f783 129 // - the prior image being held in the sensor's shift register and being
mjr 86:e30a1f60f783 130 // transferred via DMA into one of our buffers
mjr 86:e30a1f60f783 131 // - the image before that in our other buffer
mjr 86:e30a1f60f783 132 //
mjr 86:e30a1f60f783 133 // Integration of a live image starts when we begin the transfer of the
mjr 86:e30a1f60f783 134 // prior image. Integration ends when we start the next transfer after
mjr 86:e30a1f60f783 135 // that. So the total integration time, which is to say the exposure
mjr 86:e30a1f60f783 136 // time, is the time between consecutive transfer starts. It's important
mjr 86:e30a1f60f783 137 // for this time to be consistent from image to image, because that
mjr 86:e30a1f60f783 138 // determines the exposure level. We use polling from the main loop
mjr 86:e30a1f60f783 139 // to initiate new transfers, so the main loop is responsible for
mjr 86:e30a1f60f783 140 // polling frequently during the 2.5ms transfer period. It would be
mjr 86:e30a1f60f783 141 // more consistent if we did this in an interrupt handler instead,
mjr 86:e30a1f60f783 142 // but that would complicate things considerably since our image
mjr 86:e30a1f60f783 143 // analysis is too time-consuming to do in interrupt context.
mjr 86:e30a1f60f783 144 //
mjr 87:8d35c74403af 145 class PlungerSensorTSL14xxLarge: public PlungerSensorImageInterfaceTSL14xx
mjr 86:e30a1f60f783 146 {
mjr 86:e30a1f60f783 147 public:
mjr 87:8d35c74403af 148 PlungerSensorTSL14xxLarge(int nativePix, PinName si, PinName clock, PinName ao)
mjr 87:8d35c74403af 149 : PlungerSensorImageInterfaceTSL14xx(nativePix, si, clock, ao)
mjr 86:e30a1f60f783 150 {
mjr 86:e30a1f60f783 151 }
mjr 86:e30a1f60f783 152
mjr 87:8d35c74403af 153 virtual void readPix(uint8_t* &pix, uint32_t &t, int axcTime)
mjr 87:8d35c74403af 154 {
mjr 86:e30a1f60f783 155 // start reading the next pixel array (this waits for any DMA
mjr 86:e30a1f60f783 156 // transfer in progress to finish, ensuring a stable pixel buffer)
mjr 86:e30a1f60f783 157 sensor.startCapture(axcTime);
mjr 86:e30a1f60f783 158
mjr 86:e30a1f60f783 159 // get the image array from the last capture
mjr 87:8d35c74403af 160 sensor.getPix(pix, t);
mjr 86:e30a1f60f783 161
mjr 86:e30a1f60f783 162 }
mjr 86:e30a1f60f783 163 };
mjr 86:e30a1f60f783 164
mjr 86:e30a1f60f783 165 // ---------------------------------------------------------------------
mjr 86:e30a1f60f783 166 //
mjr 86:e30a1f60f783 167 // Subclass for the small sensors, such as TSL1401CL (128 pixels).
mjr 86:e30a1f60f783 168 //
mjr 86:e30a1f60f783 169 // For the small sensors, we can't use the asynchronous transfer
mjr 86:e30a1f60f783 170 // scheme we use for the large sensors, because the transfer times
mjr 86:e30a1f60f783 171 // are so short that the main loop can't poll frequently enough to
mjr 86:e30a1f60f783 172 // maintain consistent exposure times. With the short transfer
mjr 86:e30a1f60f783 173 // times, though, we don't need to do them asynchronously.
mjr 86:e30a1f60f783 174 //
mjr 86:e30a1f60f783 175 // Instead, each time we want to read the sensor, we do the whole
mjr 86:e30a1f60f783 176 // integration and transfer synchronously, so that we can precisly
mjr 86:e30a1f60f783 177 // control the total time. This requires two transfers. First,
mjr 86:e30a1f60f783 178 // we start a transfer in order to set the exact starting time of
mjr 86:e30a1f60f783 179 // an integration period: call it period A. We wait for the
mjr 86:e30a1f60f783 180 // transfer to complete, which fills a buffer with the prior
mjr 86:e30a1f60f783 181 // integration period's pixels. We don't want those pixels,
mjr 86:e30a1f60f783 182 // because they started before we got here and thus we can't
mjr 86:e30a1f60f783 183 // control how long they were integrating. So we discard that
mjr 86:e30a1f60f783 184 // buffer and start a new transfer. This starts period B while
mjr 86:e30a1f60f783 185 // transferring period A's pixels into a DMA buffer. We want
mjr 86:e30a1f60f783 186 // those period A pixels, so we wait for this transfer to finish.
mjr 86:e30a1f60f783 187 //
mjr 87:8d35c74403af 188 class PlungerSensorTSL14xxSmall: public PlungerSensorImageInterfaceTSL14xx
mjr 86:e30a1f60f783 189 {
mjr 86:e30a1f60f783 190 public:
mjr 87:8d35c74403af 191 PlungerSensorTSL14xxSmall(int nativePix, PinName si, PinName clock, PinName ao)
mjr 87:8d35c74403af 192 : PlungerSensorImageInterfaceTSL14xx(nativePix, si, clock, ao)
mjr 86:e30a1f60f783 193 {
mjr 86:e30a1f60f783 194 }
mjr 86:e30a1f60f783 195
mjr 87:8d35c74403af 196 // read the image
mjr 87:8d35c74403af 197 virtual void readPix(uint8_t* &pix, uint32_t &t, int axcTime)
mjr 86:e30a1f60f783 198 {
mjr 86:e30a1f60f783 199 // Clear the sensor. This sends a HOLD/SI pulse to the sensor,
mjr 86:e30a1f60f783 200 // which ends the current integration period, starts a new one
mjr 86:e30a1f60f783 201 // (call the new one period A) right now, and clocks out all
mjr 86:e30a1f60f783 202 // of the pixels from the old cycle. We want to discard these
mjr 86:e30a1f60f783 203 // pixels because they've been integrating from some time in
mjr 86:e30a1f60f783 204 // the past, so we can't control the exact timing of that cycle.
mjr 86:e30a1f60f783 205 // Clearing the sensor clocks the pixels out without waiting to
mjr 86:e30a1f60f783 206 // read them on DMA, so it's much faster than a regular transfer
mjr 86:e30a1f60f783 207 // and thus gives us the shortest possible base integration time
mjr 86:e30a1f60f783 208 // for period A.
mjr 86:e30a1f60f783 209 sensor.clear();
mjr 86:e30a1f60f783 210
mjr 86:e30a1f60f783 211 // Start a real transfer. This ends integration period A (the
mjr 86:e30a1f60f783 212 // one we just started), starts a new integration period B, and
mjr 86:e30a1f60f783 213 // begins transferring period A's pixels to memory via DMA. We
mjr 86:e30a1f60f783 214 // use the auto-exposure time to get the optimal exposure.
mjr 86:e30a1f60f783 215 sensor.startCapture(axcTime);
mjr 86:e30a1f60f783 216
mjr 86:e30a1f60f783 217 // wait for the period A pixel transfer to finish, and grab
mjr 86:e30a1f60f783 218 // its pixels
mjr 87:8d35c74403af 219 sensor.waitPix(pix, t);
mjr 86:e30a1f60f783 220 }
mjr 86:e30a1f60f783 221 };
mjr 86:e30a1f60f783 222
mjr 86:e30a1f60f783 223
mjr 87:8d35c74403af 224 // -------------------------------------------------------------------------
mjr 87:8d35c74403af 225 //
mjr 87:8d35c74403af 226 // Concrete TSL14xx sensor types
mjr 87:8d35c74403af 227 //
mjr 87:8d35c74403af 228
mjr 87:8d35c74403af 229
mjr 87:8d35c74403af 230 // TSL1410R sensor - edge detection sensor
mjr 87:8d35c74403af 231 class PlungerSensorTSL1410R: public PlungerSensorEdgePos
mjr 87:8d35c74403af 232 {
mjr 87:8d35c74403af 233 public:
mjr 87:8d35c74403af 234 PlungerSensorTSL1410R(PinName si, PinName clock, PinName ao)
mjr 87:8d35c74403af 235 : PlungerSensorEdgePos(sensor, 1280), sensor(1280, si, clock, ao)
mjr 87:8d35c74403af 236 {
mjr 87:8d35c74403af 237 }
mjr 87:8d35c74403af 238
mjr 87:8d35c74403af 239 protected:
mjr 87:8d35c74403af 240 PlungerSensorTSL14xxLarge sensor;
mjr 87:8d35c74403af 241 };
mjr 87:8d35c74403af 242
mjr 87:8d35c74403af 243 // TSL1412R - edge detection sensor
mjr 87:8d35c74403af 244 class PlungerSensorTSL1412R: public PlungerSensorEdgePos
mjr 87:8d35c74403af 245 {
mjr 87:8d35c74403af 246 public:
mjr 87:8d35c74403af 247 PlungerSensorTSL1412R(PinName si, PinName clock, PinName ao)
mjr 87:8d35c74403af 248 : PlungerSensorEdgePos(sensor, 1536), sensor(1536, si, clock, ao)
mjr 87:8d35c74403af 249 {
mjr 87:8d35c74403af 250 }
mjr 87:8d35c74403af 251
mjr 87:8d35c74403af 252 protected:
mjr 87:8d35c74403af 253 PlungerSensorTSL14xxLarge sensor;
mjr 87:8d35c74403af 254 };
mjr 87:8d35c74403af 255
mjr 87:8d35c74403af 256 // TSL1401CL - bar code sensor
mjr 87:8d35c74403af 257 class PlungerSensorTSL1401CL: public PlungerSensorBarCode<7, 0, 1, 16>
mjr 87:8d35c74403af 258 {
mjr 87:8d35c74403af 259 public:
mjr 87:8d35c74403af 260 PlungerSensorTSL1401CL(PinName si, PinName clock, PinName ao)
mjr 87:8d35c74403af 261 : PlungerSensorBarCode(sensor, 128), sensor(128, si, clock, ao)
mjr 87:8d35c74403af 262 {
mjr 87:8d35c74403af 263 }
mjr 87:8d35c74403af 264
mjr 87:8d35c74403af 265 protected:
mjr 87:8d35c74403af 266 PlungerSensorTSL14xxSmall sensor;
mjr 87:8d35c74403af 267 };
mjr 87:8d35c74403af 268
mjr 87:8d35c74403af 269
mjr 82:4f6209cb5c33 270 #endif