Mike R / Mbed 2 deprecated Pinscape_Controller_V2

Dependencies:   mbed FastIO FastPWM USBDevice

Fork of Pinscape_Controller by Mike R

Committer:
mjr
Date:
Thu Apr 13 23:20:28 2017 +0000
Revision:
82:4f6209cb5c33
Child:
86:e30a1f60f783
Plunger refactoring; AEDR-8300 added; TSL1401CL in progress; VL6180X added

Who changed what in which revision?

UserRevisionLine numberNew contents of line
mjr 82:4f6209cb5c33 1 // Plunger sensor type for bar-code based absolute position encoders.
mjr 82:4f6209cb5c33 2 // This type of sensor uses an optical sensor that moves with the plunger
mjr 82:4f6209cb5c33 3 // along a guide rail with printed bar codes along its length that encode
mjr 82:4f6209cb5c33 4 // the absolute position at each point. We figure the plunger position
mjr 82:4f6209cb5c33 5 // by reading the bar code and decoding it into a position figure.
mjr 82:4f6209cb5c33 6 //
mjr 82:4f6209cb5c33 7 // The bar code has to be encoded in a specific format that we recognize.
mjr 82:4f6209cb5c33 8 // We use a 10-bit reflected Gray code, optically encoded using a Manchester-
mjr 82:4f6209cb5c33 9 // type of coding. Each bit is represented as a fixed-width area on the
mjr 82:4f6209cb5c33 10 // bar, half white and half black. The bit value is encoded in the order
mjr 82:4f6209cb5c33 11 // of the colors: Black/White is '0', and White/Black is '1'.
mjr 82:4f6209cb5c33 12 //
mjr 82:4f6209cb5c33 13 // Gray codes are ideal for this type of application, because they have the
mjr 82:4f6209cb5c33 14 // property that any two adjacent code values differ in exactly one bit.
mjr 82:4f6209cb5c33 15 // This is perfectly suited to an optical sensor scanning a moving target.
mjr 82:4f6209cb5c33 16 // For one thing, if we're halfway between two positions, the single-bit
mjr 82:4f6209cb5c33 17 // difference between adjacent codes means that exactly one bit will be
mjr 82:4f6209cb5c33 18 // ambiguous, so even if we get it wrong because of the ambiguous optical
mjr 82:4f6209cb5c33 19 // data, we'll still be +/- 1 position from the true position. The other
mjr 82:4f6209cb5c33 20 // good feature is that any motion blur in images taken during rapid motion
mjr 82:4f6209cb5c33 21 // will likewise create ambiguity in the least significant bits, so we'll
mjr 82:4f6209cb5c33 22 // gracefully lose precision as motion blur increases but still have the
mjr 82:4f6209cb5c33 23 // correct values for the most significant bits, which is to say that we'll
mjr 82:4f6209cb5c33 24 // know our true position at reduced precision during motion.
mjr 82:4f6209cb5c33 25 //
mjr 82:4f6209cb5c33 26 // We use the Manchester-type optical coding because it has good properties
mjr 82:4f6209cb5c33 27 // for noisy images. In particular, we evaluate each bit based only on
mjr 82:4f6209cb5c33 28 // the light levels of nearby pixels. This insulates us from non-uniformity
mjr 82:4f6209cb5c33 29 // in the light level across the image. We don't have to care if the pixels
mjr 82:4f6209cb5c33 30 // in a bit are above or below the average or median across the whole image;
mjr 82:4f6209cb5c33 31 // we only have to compare them to the immediately adjacent few pixels.
mjr 82:4f6209cb5c33 32 // This gives us highly stable readings even with poor lighting conditions.
mjr 82:4f6209cb5c33 33 // That's desirable because it simplifies the requirements for the physical
mjr 82:4f6209cb5c33 34 // sensor installation.
mjr 82:4f6209cb5c33 35 //
mjr 82:4f6209cb5c33 36
mjr 82:4f6209cb5c33 37 #ifndef _BARCODESENSOR_H_
mjr 82:4f6209cb5c33 38 #define _BARCODESENSOR_H_
mjr 82:4f6209cb5c33 39
mjr 82:4f6209cb5c33 40 #include "plunger.h"
mjr 82:4f6209cb5c33 41 #include "tsl14xxSensor.h"
mjr 82:4f6209cb5c33 42
mjr 82:4f6209cb5c33 43 // Base class for bar-code sensors
mjr 82:4f6209cb5c33 44 class PlungerSensorBarCode
mjr 82:4f6209cb5c33 45 {
mjr 82:4f6209cb5c33 46 public:
mjr 82:4f6209cb5c33 47 bool process(const uint8_t *pix, int npix, int &pos)
mjr 82:4f6209cb5c33 48 {
mjr 82:4f6209cb5c33 49 // $$$ to be written
mjr 82:4f6209cb5c33 50 return false;
mjr 82:4f6209cb5c33 51 }
mjr 82:4f6209cb5c33 52 };
mjr 82:4f6209cb5c33 53
mjr 82:4f6209cb5c33 54 // PlungerSensor interface implementation for edge detection setups
mjr 82:4f6209cb5c33 55 class PlungerSensorBarCodeTSL14xx: public PlungerSensorTSL14xx, public PlungerSensorBarCode
mjr 82:4f6209cb5c33 56 {
mjr 82:4f6209cb5c33 57 public:
mjr 82:4f6209cb5c33 58 PlungerSensorBarCodeTSL14xx(int nativePix, PinName si, PinName clock, PinName ao)
mjr 82:4f6209cb5c33 59 : PlungerSensorTSL14xx(nativePix, si, clock, ao),
mjr 82:4f6209cb5c33 60 PlungerSensorBarCode()
mjr 82:4f6209cb5c33 61 {
mjr 82:4f6209cb5c33 62 }
mjr 82:4f6209cb5c33 63
mjr 82:4f6209cb5c33 64 protected:
mjr 82:4f6209cb5c33 65 // process the image through the bar code reader
mjr 82:4f6209cb5c33 66 virtual bool process(const uint8_t *pix, int npix, int &pos)
mjr 82:4f6209cb5c33 67 {
mjr 82:4f6209cb5c33 68 // adjust the exposure
mjr 82:4f6209cb5c33 69 adjustExposure(pix, npix);
mjr 82:4f6209cb5c33 70
mjr 82:4f6209cb5c33 71 // do the standard bar code processing
mjr 82:4f6209cb5c33 72 return PlungerSensorBarCode::process(pix, npix, pos);
mjr 82:4f6209cb5c33 73 }
mjr 82:4f6209cb5c33 74
mjr 82:4f6209cb5c33 75 // adjust the exposure
mjr 82:4f6209cb5c33 76 void adjustExposure(const uint8_t *pix, int npix)
mjr 82:4f6209cb5c33 77 {
mjr 82:4f6209cb5c33 78 // Count the number of pixels near total darkness and
mjr 82:4f6209cb5c33 79 // total saturation
mjr 82:4f6209cb5c33 80 int nDark = 0, nSat = 0;
mjr 82:4f6209cb5c33 81 for (int i = 0 ; i < npix ; ++i)
mjr 82:4f6209cb5c33 82 {
mjr 82:4f6209cb5c33 83 int pi = pix[i];
mjr 82:4f6209cb5c33 84 if (pi < 10)
mjr 82:4f6209cb5c33 85 ++nDark;
mjr 82:4f6209cb5c33 86 else if (pi > 244)
mjr 82:4f6209cb5c33 87 ++nSat;
mjr 82:4f6209cb5c33 88 }
mjr 82:4f6209cb5c33 89
mjr 82:4f6209cb5c33 90 // If more than 30% of pixels are near total darkness, increase
mjr 82:4f6209cb5c33 91 // the exposure time. If more than 30% are near total saturation,
mjr 82:4f6209cb5c33 92 // decrease the exposure time.
mjr 82:4f6209cb5c33 93 int pct30 = uint32_t(npix * 19661) >> 16;
mjr 82:4f6209cb5c33 94 int pct50 = uint32_t(npix) >> 1;
mjr 82:4f6209cb5c33 95 if (nDark > pct50 && nSat < pct30)
mjr 82:4f6209cb5c33 96 {
mjr 82:4f6209cb5c33 97 // very dark - increase exposure time a lot
mjr 82:4f6209cb5c33 98 if (axcTime < 450)
mjr 82:4f6209cb5c33 99 axcTime += 50;
mjr 82:4f6209cb5c33 100 }
mjr 82:4f6209cb5c33 101 else if (nDark > pct30 && nSat < pct30)
mjr 82:4f6209cb5c33 102 {
mjr 82:4f6209cb5c33 103 // dark - increase exposure time a bit
mjr 82:4f6209cb5c33 104 if (axcTime < 490)
mjr 82:4f6209cb5c33 105 axcTime += 10;
mjr 82:4f6209cb5c33 106 }
mjr 82:4f6209cb5c33 107 else if (nSat > pct50 && nDark < pct30)
mjr 82:4f6209cb5c33 108 {
mjr 82:4f6209cb5c33 109 // very overexposed - decrease exposure time a lot
mjr 82:4f6209cb5c33 110 if (axcTime > 50)
mjr 82:4f6209cb5c33 111 axcTime -= 50;
mjr 82:4f6209cb5c33 112 else
mjr 82:4f6209cb5c33 113 axcTime = 0;
mjr 82:4f6209cb5c33 114 }
mjr 82:4f6209cb5c33 115 else if (nSat > pct30 && nDark < pct30)
mjr 82:4f6209cb5c33 116 {
mjr 82:4f6209cb5c33 117 // overexposed - decrease exposure time a little
mjr 82:4f6209cb5c33 118 if (axcTime > 10)
mjr 82:4f6209cb5c33 119 axcTime -= 10;
mjr 82:4f6209cb5c33 120 else
mjr 82:4f6209cb5c33 121 axcTime = 0;
mjr 82:4f6209cb5c33 122 }
mjr 82:4f6209cb5c33 123 }
mjr 82:4f6209cb5c33 124 };
mjr 82:4f6209cb5c33 125
mjr 82:4f6209cb5c33 126
mjr 82:4f6209cb5c33 127 // TSL1401CL
mjr 82:4f6209cb5c33 128 class PlungerSensorTSL1401CL: public PlungerSensorBarCodeTSL14xx
mjr 82:4f6209cb5c33 129 {
mjr 82:4f6209cb5c33 130 public:
mjr 82:4f6209cb5c33 131 PlungerSensorTSL1401CL(PinName si, PinName clock, PinName a0)
mjr 82:4f6209cb5c33 132 : PlungerSensorBarCodeTSL14xx(128, si, clock, a0)
mjr 82:4f6209cb5c33 133 {
mjr 82:4f6209cb5c33 134 }
mjr 82:4f6209cb5c33 135 };
mjr 82:4f6209cb5c33 136
mjr 82:4f6209cb5c33 137 #endif