Arnaud VALLEY / Mbed 2 deprecated Pinscape_Controller_V2_arnoz

Dependencies:   mbed FastIO FastPWM USBDevice

Committer:
mjr
Date:
Fri Apr 21 18:50:37 2017 +0000
Revision:
86:e30a1f60f783
Parent:
82:4f6209cb5c33
Child:
87:8d35c74403af
Capture a bunch of alternative bar code decoder tests, mostly unsuccessful

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 82:4f6209cb5c33 18 #include "TSL14xx.h"
mjr 82:4f6209cb5c33 19
mjr 82:4f6209cb5c33 20 class PlungerSensorTSL14xx: public PlungerSensor
mjr 82:4f6209cb5c33 21 {
mjr 82:4f6209cb5c33 22 public:
mjr 86:e30a1f60f783 23 PlungerSensorTSL14xx(int nativePix, int nativeScale,
mjr 86:e30a1f60f783 24 PinName si, PinName clock, PinName ao)
mjr 86:e30a1f60f783 25 : PlungerSensor(nativeScale),
mjr 86:e30a1f60f783 26 sensor(nativePix, si, clock, ao)
mjr 82:4f6209cb5c33 27 {
mjr 86:e30a1f60f783 28 // remember the native pixel size
mjr 82:4f6209cb5c33 29 native_npix = nativePix;
mjr 82:4f6209cb5c33 30
mjr 82:4f6209cb5c33 31 // start with no additional integration time for automatic
mjr 82:4f6209cb5c33 32 // exposure control
mjr 82:4f6209cb5c33 33 axcTime = 0;
mjr 82:4f6209cb5c33 34 }
mjr 82:4f6209cb5c33 35
mjr 82:4f6209cb5c33 36 // is the sensor ready?
mjr 82:4f6209cb5c33 37 virtual bool ready() { return sensor.ready(); }
mjr 82:4f6209cb5c33 38
mjr 82:4f6209cb5c33 39 virtual void init()
mjr 82:4f6209cb5c33 40 {
mjr 82:4f6209cb5c33 41 sensor.clear();
mjr 82:4f6209cb5c33 42 }
mjr 82:4f6209cb5c33 43
mjr 82:4f6209cb5c33 44 // Send a status report to the joystick interface.
mjr 82:4f6209cb5c33 45 // See plunger.h for details on the arguments.
mjr 82:4f6209cb5c33 46 virtual void sendStatusReport(USBJoystick &js, uint8_t flags, uint8_t 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 82:4f6209cb5c33 93 uint8_t *pix;
mjr 82:4f6209cb5c33 94 uint32_t t;
mjr 86:e30a1f60f783 95 sensor.waitPix(pix, t);
mjr 82:4f6209cb5c33 96
mjr 82:4f6209cb5c33 97 // start a timer to measure the processing time
mjr 82:4f6209cb5c33 98 Timer pt;
mjr 82:4f6209cb5c33 99 pt.start();
mjr 82:4f6209cb5c33 100
mjr 82:4f6209cb5c33 101 // process the pixels and read the position
mjr 86:e30a1f60f783 102 int pos, rawPos;
mjr 82:4f6209cb5c33 103 int n = native_npix;
mjr 86:e30a1f60f783 104 if (process(pix, n, rawPos))
mjr 86:e30a1f60f783 105 {
mjr 86:e30a1f60f783 106 // success - apply the jitter filter
mjr 86:e30a1f60f783 107 pos = jitterFilter(rawPos);
mjr 86:e30a1f60f783 108 }
mjr 86:e30a1f60f783 109 else
mjr 86:e30a1f60f783 110 {
mjr 86:e30a1f60f783 111 // report 0xFFFF to indicate that the position wasn't read
mjr 82:4f6209cb5c33 112 pos = 0xFFFF;
mjr 86:e30a1f60f783 113 rawPos = 0xFFFF;
mjr 86:e30a1f60f783 114 }
mjr 82:4f6209cb5c33 115
mjr 82:4f6209cb5c33 116 // note the processing time
mjr 82:4f6209cb5c33 117 uint32_t processTime = pt.read_us();
mjr 82:4f6209cb5c33 118
mjr 86:e30a1f60f783 119 // If a low-res scan is desired, reduce to a subset of pixels. Ignore
mjr 86:e30a1f60f783 120 // this for smaller sensors (below 512 pixels)
mjr 86:e30a1f60f783 121 if ((flags & 0x01) && n >= 512)
mjr 82:4f6209cb5c33 122 {
mjr 82:4f6209cb5c33 123 // figure how many sensor pixels we combine into each low-res pixel
mjr 82:4f6209cb5c33 124 const int group = 8;
mjr 82:4f6209cb5c33 125 int lowResPix = n / group;
mjr 82:4f6209cb5c33 126
mjr 82:4f6209cb5c33 127 // combine the pixels
mjr 82:4f6209cb5c33 128 int src, dst;
mjr 82:4f6209cb5c33 129 for (src = dst = 0 ; dst < lowResPix ; ++dst)
mjr 82:4f6209cb5c33 130 {
mjr 82:4f6209cb5c33 131 // average this block of pixels
mjr 82:4f6209cb5c33 132 int a = 0;
mjr 82:4f6209cb5c33 133 for (int j = 0 ; j < group ; ++j)
mjr 82:4f6209cb5c33 134 a += pix[src++];
mjr 82:4f6209cb5c33 135
mjr 82:4f6209cb5c33 136 // we have the sum, so get the average
mjr 82:4f6209cb5c33 137 a /= group;
mjr 82:4f6209cb5c33 138
mjr 82:4f6209cb5c33 139 // store the down-res'd pixel in the array
mjr 82:4f6209cb5c33 140 pix[dst] = uint8_t(a);
mjr 82:4f6209cb5c33 141 }
mjr 82:4f6209cb5c33 142
mjr 82:4f6209cb5c33 143 // update the pixel count to the reduced array size
mjr 82:4f6209cb5c33 144 n = lowResPix;
mjr 82:4f6209cb5c33 145 }
mjr 82:4f6209cb5c33 146
mjr 86:e30a1f60f783 147 // figure the report flags
mjr 86:e30a1f60f783 148 int jsflags = 0;
mjr 86:e30a1f60f783 149
mjr 86:e30a1f60f783 150 // add flags for the detected orientation: 0x01 for normal orientation,
mjr 86:e30a1f60f783 151 // 0x02 for reversed orientation; no flags if orientation is unknown
mjr 86:e30a1f60f783 152 int dir = getOrientation();
mjr 86:e30a1f60f783 153 if (dir == 1)
mjr 86:e30a1f60f783 154 jsflags |= 0x01;
mjr 86:e30a1f60f783 155 else if (dir == -1)
mjr 86:e30a1f60f783 156 jsflags |= 0x02;
mjr 86:e30a1f60f783 157
mjr 86:e30a1f60f783 158 // send the sensor status report headers
mjr 86:e30a1f60f783 159 js.sendPlungerStatus(n, pos, jsflags, sensor.getAvgScanTime(), processTime);
mjr 86:e30a1f60f783 160 js.sendPlungerStatus2(nativeScale, jfLo, jfHi, rawPos, axcTime);
mjr 82:4f6209cb5c33 161
mjr 82:4f6209cb5c33 162 // If we're not in calibration mode, send the pixels
mjr 82:4f6209cb5c33 163 extern bool plungerCalMode;
mjr 82:4f6209cb5c33 164 if (!plungerCalMode)
mjr 82:4f6209cb5c33 165 {
mjr 82:4f6209cb5c33 166 // send the pixels in report-sized chunks until we get them all
mjr 82:4f6209cb5c33 167 int idx = 0;
mjr 82:4f6209cb5c33 168 while (idx < n)
mjr 82:4f6209cb5c33 169 js.sendPlungerPix(idx, n, pix);
mjr 82:4f6209cb5c33 170 }
mjr 82:4f6209cb5c33 171
mjr 82:4f6209cb5c33 172 // It takes us a while to send all of the pixels, since we have
mjr 82:4f6209cb5c33 173 // to break them up into many USB reports. This delay means that
mjr 82:4f6209cb5c33 174 // the sensor has been sitting there integrating for much longer
mjr 82:4f6209cb5c33 175 // than usual, so the next frame read will be overexposed. To
mjr 82:4f6209cb5c33 176 // mitigate this, make sure we don't have a capture running,
mjr 82:4f6209cb5c33 177 // then clear the sensor and start a new capture.
mjr 82:4f6209cb5c33 178 sensor.wait();
mjr 82:4f6209cb5c33 179 sensor.clear();
mjr 82:4f6209cb5c33 180 sensor.startCapture(axcTime);
mjr 82:4f6209cb5c33 181 }
mjr 82:4f6209cb5c33 182
mjr 82:4f6209cb5c33 183 // get the average sensor scan time
mjr 82:4f6209cb5c33 184 virtual uint32_t getAvgScanTime() { return sensor.getAvgScanTime(); }
mjr 82:4f6209cb5c33 185
mjr 82:4f6209cb5c33 186 protected:
mjr 82:4f6209cb5c33 187 // Analyze the image and find the plunger position. If successful,
mjr 82:4f6209cb5c33 188 // fills in 'pixpos' with the plunger position using the 0..65535
mjr 82:4f6209cb5c33 189 // scale and returns true. If no position can be detected from the
mjr 82:4f6209cb5c33 190 // image data, returns false.
mjr 82:4f6209cb5c33 191 virtual bool process(const uint8_t *pix, int npix, int &pixpos) = 0;
mjr 82:4f6209cb5c33 192
mjr 82:4f6209cb5c33 193 // Get the currently detected sensor orientation, if applicable.
mjr 82:4f6209cb5c33 194 // Returns 1 for standard orientation, -1 for reversed orientation,
mjr 82:4f6209cb5c33 195 // or 0 for orientation unknown or not applicable. Edge sensors can
mjr 82:4f6209cb5c33 196 // automatically detect orientation by observing which side of the
mjr 82:4f6209cb5c33 197 // image is in shadow. Bar code sensors generally can't detect
mjr 82:4f6209cb5c33 198 // orientation.
mjr 82:4f6209cb5c33 199 virtual int getOrientation() const { return 0; }
mjr 82:4f6209cb5c33 200
mjr 82:4f6209cb5c33 201 // the low-level interface to the TSL14xx sensor
mjr 82:4f6209cb5c33 202 TSL14xx sensor;
mjr 82:4f6209cb5c33 203
mjr 82:4f6209cb5c33 204 // number of pixels
mjr 82:4f6209cb5c33 205 int native_npix;
mjr 82:4f6209cb5c33 206
mjr 82:4f6209cb5c33 207 // Automatic exposure control time, in microseconds. This is an amount
mjr 82:4f6209cb5c33 208 // of time we add to each integration cycle to compensate for low light
mjr 82:4f6209cb5c33 209 // levels. By default, this is always zero; the base class doesn't have
mjr 82:4f6209cb5c33 210 // any logic for determining proper exposure, because that's a function
mjr 82:4f6209cb5c33 211 // of the type of image we're looking for. Subclasses can add logic in
mjr 82:4f6209cb5c33 212 // the process() function to check exposure level and adjust this value
mjr 82:4f6209cb5c33 213 // if the image looks over- or under-exposed.
mjr 82:4f6209cb5c33 214 uint32_t axcTime;
mjr 82:4f6209cb5c33 215 };
mjr 82:4f6209cb5c33 216
mjr 86:e30a1f60f783 217 // ---------------------------------------------------------------------
mjr 86:e30a1f60f783 218 //
mjr 86:e30a1f60f783 219 // Subclass for the large sensors, such as TSL1410R (1280 pixels)
mjr 86:e30a1f60f783 220 // and TSL1412S (1536 pixels).
mjr 86:e30a1f60f783 221 //
mjr 86:e30a1f60f783 222 // For the large sensors, pixel transfers take a long time: about
mjr 86:e30a1f60f783 223 // 2.5ms on the 1410R and 1412S. This is much longer than our main
mjr 86:e30a1f60f783 224 // loop time, so we don't want to block other work to do a transfer.
mjr 86:e30a1f60f783 225 // Instead, we want to do our transfers asynchronously, so that the
mjr 86:e30a1f60f783 226 // main loop can keep going while a transfer proceeds. This is
mjr 86:e30a1f60f783 227 // possible via our DMA double buffering.
mjr 86:e30a1f60f783 228 //
mjr 86:e30a1f60f783 229 // This scheme gives us three images in our pipeline at any given time:
mjr 86:e30a1f60f783 230 //
mjr 86:e30a1f60f783 231 // - a live image integrating light on the photo receptors on the sensor
mjr 86:e30a1f60f783 232 // - the prior image being held in the sensor's shift register and being
mjr 86:e30a1f60f783 233 // transferred via DMA into one of our buffers
mjr 86:e30a1f60f783 234 // - the image before that in our other buffer
mjr 86:e30a1f60f783 235 //
mjr 86:e30a1f60f783 236 // Integration of a live image starts when we begin the transfer of the
mjr 86:e30a1f60f783 237 // prior image. Integration ends when we start the next transfer after
mjr 86:e30a1f60f783 238 // that. So the total integration time, which is to say the exposure
mjr 86:e30a1f60f783 239 // time, is the time between consecutive transfer starts. It's important
mjr 86:e30a1f60f783 240 // for this time to be consistent from image to image, because that
mjr 86:e30a1f60f783 241 // determines the exposure level. We use polling from the main loop
mjr 86:e30a1f60f783 242 // to initiate new transfers, so the main loop is responsible for
mjr 86:e30a1f60f783 243 // polling frequently during the 2.5ms transfer period. It would be
mjr 86:e30a1f60f783 244 // more consistent if we did this in an interrupt handler instead,
mjr 86:e30a1f60f783 245 // but that would complicate things considerably since our image
mjr 86:e30a1f60f783 246 // analysis is too time-consuming to do in interrupt context.
mjr 86:e30a1f60f783 247 //
mjr 86:e30a1f60f783 248 class PlungerSensorTSL14xxLarge: public PlungerSensorTSL14xx
mjr 86:e30a1f60f783 249 {
mjr 86:e30a1f60f783 250 public:
mjr 86:e30a1f60f783 251 PlungerSensorTSL14xxLarge(int nativePix, int nativeScale,
mjr 86:e30a1f60f783 252 PinName si, PinName clock, PinName ao)
mjr 86:e30a1f60f783 253 : PlungerSensorTSL14xx(nativePix, nativeScale, si, clock, ao)
mjr 86:e30a1f60f783 254 {
mjr 86:e30a1f60f783 255 }
mjr 86:e30a1f60f783 256
mjr 86:e30a1f60f783 257 // read the plunger position
mjr 86:e30a1f60f783 258 virtual bool readRaw(PlungerReading &r)
mjr 86:e30a1f60f783 259 {
mjr 86:e30a1f60f783 260 // start reading the next pixel array (this waits for any DMA
mjr 86:e30a1f60f783 261 // transfer in progress to finish, ensuring a stable pixel buffer)
mjr 86:e30a1f60f783 262 sensor.startCapture(axcTime);
mjr 86:e30a1f60f783 263
mjr 86:e30a1f60f783 264 // get the image array from the last capture
mjr 86:e30a1f60f783 265 uint8_t *pix;
mjr 86:e30a1f60f783 266 uint32_t tpix;
mjr 86:e30a1f60f783 267 sensor.getPix(pix, tpix);
mjr 86:e30a1f60f783 268
mjr 86:e30a1f60f783 269 // process the pixels
mjr 86:e30a1f60f783 270 int pixpos;
mjr 86:e30a1f60f783 271 if (process(pix, native_npix, pixpos))
mjr 86:e30a1f60f783 272 {
mjr 86:e30a1f60f783 273 r.pos = pixpos;
mjr 86:e30a1f60f783 274 r.t = tpix;
mjr 86:e30a1f60f783 275
mjr 86:e30a1f60f783 276 // success
mjr 86:e30a1f60f783 277 return true;
mjr 86:e30a1f60f783 278 }
mjr 86:e30a1f60f783 279 else
mjr 86:e30a1f60f783 280 {
mjr 86:e30a1f60f783 281 // no position found
mjr 86:e30a1f60f783 282 return false;
mjr 86:e30a1f60f783 283 }
mjr 86:e30a1f60f783 284 }
mjr 86:e30a1f60f783 285 };
mjr 86:e30a1f60f783 286
mjr 86:e30a1f60f783 287 // ---------------------------------------------------------------------
mjr 86:e30a1f60f783 288 //
mjr 86:e30a1f60f783 289 // Subclass for the small sensors, such as TSL1401CL (128 pixels).
mjr 86:e30a1f60f783 290 //
mjr 86:e30a1f60f783 291 // For the small sensors, we can't use the asynchronous transfer
mjr 86:e30a1f60f783 292 // scheme we use for the large sensors, because the transfer times
mjr 86:e30a1f60f783 293 // are so short that the main loop can't poll frequently enough to
mjr 86:e30a1f60f783 294 // maintain consistent exposure times. With the short transfer
mjr 86:e30a1f60f783 295 // times, though, we don't need to do them asynchronously.
mjr 86:e30a1f60f783 296 //
mjr 86:e30a1f60f783 297 // Instead, each time we want to read the sensor, we do the whole
mjr 86:e30a1f60f783 298 // integration and transfer synchronously, so that we can precisly
mjr 86:e30a1f60f783 299 // control the total time. This requires two transfers. First,
mjr 86:e30a1f60f783 300 // we start a transfer in order to set the exact starting time of
mjr 86:e30a1f60f783 301 // an integration period: call it period A. We wait for the
mjr 86:e30a1f60f783 302 // transfer to complete, which fills a buffer with the prior
mjr 86:e30a1f60f783 303 // integration period's pixels. We don't want those pixels,
mjr 86:e30a1f60f783 304 // because they started before we got here and thus we can't
mjr 86:e30a1f60f783 305 // control how long they were integrating. So we discard that
mjr 86:e30a1f60f783 306 // buffer and start a new transfer. This starts period B while
mjr 86:e30a1f60f783 307 // transferring period A's pixels into a DMA buffer. We want
mjr 86:e30a1f60f783 308 // those period A pixels, so we wait for this transfer to finish.
mjr 86:e30a1f60f783 309 //
mjr 86:e30a1f60f783 310 class PlungerSensorTSL14xxSmall: public PlungerSensorTSL14xx
mjr 86:e30a1f60f783 311 {
mjr 86:e30a1f60f783 312 public:
mjr 86:e30a1f60f783 313 PlungerSensorTSL14xxSmall(int nativePix, int nativeScale,
mjr 86:e30a1f60f783 314 PinName si, PinName clock, PinName ao)
mjr 86:e30a1f60f783 315 : PlungerSensorTSL14xx(nativePix, nativeScale, si, clock, ao)
mjr 86:e30a1f60f783 316 {
mjr 86:e30a1f60f783 317 }
mjr 86:e30a1f60f783 318
mjr 86:e30a1f60f783 319 // read the plunger position
mjr 86:e30a1f60f783 320 virtual bool readRaw(PlungerReading &r)
mjr 86:e30a1f60f783 321 {
mjr 86:e30a1f60f783 322 // Clear the sensor. This sends a HOLD/SI pulse to the sensor,
mjr 86:e30a1f60f783 323 // which ends the current integration period, starts a new one
mjr 86:e30a1f60f783 324 // (call the new one period A) right now, and clocks out all
mjr 86:e30a1f60f783 325 // of the pixels from the old cycle. We want to discard these
mjr 86:e30a1f60f783 326 // pixels because they've been integrating from some time in
mjr 86:e30a1f60f783 327 // the past, so we can't control the exact timing of that cycle.
mjr 86:e30a1f60f783 328 // Clearing the sensor clocks the pixels out without waiting to
mjr 86:e30a1f60f783 329 // read them on DMA, so it's much faster than a regular transfer
mjr 86:e30a1f60f783 330 // and thus gives us the shortest possible base integration time
mjr 86:e30a1f60f783 331 // for period A.
mjr 86:e30a1f60f783 332 sensor.clear();
mjr 86:e30a1f60f783 333
mjr 86:e30a1f60f783 334 // Start a real transfer. This ends integration period A (the
mjr 86:e30a1f60f783 335 // one we just started), starts a new integration period B, and
mjr 86:e30a1f60f783 336 // begins transferring period A's pixels to memory via DMA. We
mjr 86:e30a1f60f783 337 // use the auto-exposure time to get the optimal exposure.
mjr 86:e30a1f60f783 338 sensor.startCapture(axcTime);
mjr 86:e30a1f60f783 339
mjr 86:e30a1f60f783 340 // wait for the period A pixel transfer to finish, and grab
mjr 86:e30a1f60f783 341 // its pixels
mjr 86:e30a1f60f783 342 uint8_t *pix;
mjr 86:e30a1f60f783 343 uint32_t tpix;
mjr 86:e30a1f60f783 344 sensor.waitPix(pix, tpix);
mjr 86:e30a1f60f783 345
mjr 86:e30a1f60f783 346 // process the pixels
mjr 86:e30a1f60f783 347 int pixpos;
mjr 86:e30a1f60f783 348 if (process(pix, native_npix, pixpos))
mjr 86:e30a1f60f783 349 {
mjr 86:e30a1f60f783 350 r.pos = pixpos;
mjr 86:e30a1f60f783 351 r.t = tpix;
mjr 86:e30a1f60f783 352
mjr 86:e30a1f60f783 353 // success
mjr 86:e30a1f60f783 354 return true;
mjr 86:e30a1f60f783 355 }
mjr 86:e30a1f60f783 356 else
mjr 86:e30a1f60f783 357 {
mjr 86:e30a1f60f783 358 // no position found
mjr 86:e30a1f60f783 359 return false;
mjr 86:e30a1f60f783 360 }
mjr 86:e30a1f60f783 361 }
mjr 86:e30a1f60f783 362 };
mjr 86:e30a1f60f783 363
mjr 86:e30a1f60f783 364
mjr 82:4f6209cb5c33 365 #endif