Mirror with some correction
Dependencies: mbed FastIO FastPWM USBDevice
Diff: main.cpp
- Revision:
- 82:4f6209cb5c33
- Parent:
- 80:94dc2946871b
- Child:
- 84:31e926f4f3bc
--- a/main.cpp Fri Mar 24 05:42:01 2017 +0000 +++ b/main.cpp Thu Apr 13 23:20:28 2017 +0000 @@ -219,21 +219,25 @@ #include "NewMalloc.h" #include "USBJoystick.h" #include "MMA8451Q.h" -#include "tsl1410r.h" #include "FreescaleIAP.h" #include "crc32.h" #include "TLC5940.h" #include "74HC595.h" #include "nvm.h" -#include "plunger.h" -#include "ccdSensor.h" -#include "potSensor.h" -#include "nullSensor.h" #include "TinyDigitalIn.h" #include "IRReceiver.h" #include "IRTransmitter.h" #include "NewPwm.h" +// plunger sensors +#include "plunger.h" +#include "edgeSensor.h" +#include "potSensor.h" +#include "quadSensor.h" +#include "nullSensor.h" +#include "barCodeSensor.h" +#include "distanceSensor.h" + #define DECL_EXTERNS #include "config.h" @@ -2418,6 +2422,7 @@ { // presume no shift key shiftButton.index = -1; + shiftButton.state = 0; // Count up how many button slots we'll need to allocate. Start // with assigned buttons from the configuration, noting that we @@ -2854,13 +2859,13 @@ // // Note that the "shift" flag (0x02) has no effect in switch // mode. Shifting only works for toggle mode. - if (cfg.nightMode.flags & 0x01) + if ((cfg.nightMode.flags & 0x01) != 0) { // It's an on/off switch. Night mode simply tracks the // current switch state. setNightMode(bs->logState); } - else + else if (bs->logState) { // It's a momentary toggle switch. Toggle the night mode // state on each distinct press of the button: that is, @@ -4307,52 +4312,60 @@ // create the new sensor object according to the type switch (cfg.plunger.sensorType) { - case PlungerType_TSL1410RS: - // TSL1410R, serial mode (all pixels read in one file) + case PlungerType_TSL1410R: + // TSL1410R, shadow edge detector // pins are: SI, CLOCK, AO plungerSensor = new PlungerSensorTSL1410R( wirePinName(cfg.plunger.sensorPin[0]), wirePinName(cfg.plunger.sensorPin[1]), - wirePinName(cfg.plunger.sensorPin[2]), - NC); + wirePinName(cfg.plunger.sensorPin[2])); break; - case PlungerType_TSL1410RP: - // TSL1410R, parallel mode (each half-sensor's pixels read separately) - // pins are: SI, CLOCK, AO1, AO2 - plungerSensor = new PlungerSensorTSL1410R( - wirePinName(cfg.plunger.sensorPin[0]), - wirePinName(cfg.plunger.sensorPin[1]), - wirePinName(cfg.plunger.sensorPin[2]), - wirePinName(cfg.plunger.sensorPin[3])); - break; - - case PlungerType_TSL1412SS: - // TSL1412S, serial mode - // pins are: SI, CLOCK, AO1, AO2 + case PlungerType_TSL1412S: + // TSL1412S, shadow edge detector + // pins are: SI, CLOCK, AO plungerSensor = new PlungerSensorTSL1412R( wirePinName(cfg.plunger.sensorPin[0]), wirePinName(cfg.plunger.sensorPin[1]), - wirePinName(cfg.plunger.sensorPin[2]), - NC); - break; - - case PlungerType_TSL1412SP: - // TSL1412S, parallel mode - // pins are: SI, CLOCK, AO1, AO2 - plungerSensor = new PlungerSensorTSL1412R( - wirePinName(cfg.plunger.sensorPin[0]), - wirePinName(cfg.plunger.sensorPin[1]), - wirePinName(cfg.plunger.sensorPin[2]), - wirePinName(cfg.plunger.sensorPin[3])); + wirePinName(cfg.plunger.sensorPin[2])); break; case PlungerType_Pot: - // pins are: AO + // Potentiometer (or any other sensor with a linear analog voltage + // reading as the proxy for the position) + // pins are: AO (analog in) plungerSensor = new PlungerSensorPot( wirePinName(cfg.plunger.sensorPin[0])); break; - + + case PlungerType_OptQuad: + // Optical quadrature sensor, AEDR8300-K or similar. The -K is + // designed for a 75 LPI scale, which translates to 300 pulses/inch. + // Pins are: CHA, CHB (quadrature pulse inputs). + plungerSensor = new PlungerSensorQuad( + 300, + wirePinName(cfg.plunger.sensorPin[0]), + wirePinName(cfg.plunger.sensorPin[1])); + break; + + case PlungerType_TSL1401CL: + // TSL1401CL, absolute position encoder with bar code scale + // pins are: SI, CLOCK, AO + plungerSensor = new PlungerSensorTSL1401CL( + wirePinName(cfg.plunger.sensorPin[0]), + wirePinName(cfg.plunger.sensorPin[1]), + wirePinName(cfg.plunger.sensorPin[2])); + break; + + case PlungerType_VL6180X: + // VL6180X time-of-flight IR distance sensor + // pins are: SDL, SCL, GPIO0/CE + plungerSensor = new PlungerSensorVL6180X( + wirePinName(cfg.plunger.sensorPin[0]), + wirePinName(cfg.plunger.sensorPin[1]), + wirePinName(cfg.plunger.sensorPin[2])); + break; + case PlungerType_None: default: plungerSensor = new PlungerSensorNull(); @@ -4456,11 +4469,11 @@ // read, so it will never be affected by this, but other sensor // types don't all have the same hardware cycle time, so we need // to throttle them artificially. E.g., the potentiometer only - // needs one ADC sample per reading, which only takes about 15us. - // We don't need to check which sensor type we have here; we - // just ignore readings until the minimum interval has passed, - // so if the sensor is already slower than this, we'll end up - // using all of its readings. + // needs one ADC sample per reading, which only takes about 15us; + // the quadrature sensor needs no time at all since it keeps + // track of the position continuously via interrupts. We don't + // need to check which sensor type we have here; we just ignore + // readings until the minimum interval has passed. if (uint32_t(r.t - prv.t) < 1000UL) return; @@ -4566,7 +4579,7 @@ // figures will fit nicely into a 32-bit fixed point value with // a 64K scale factor. const PlungerReading &prv2 = nthHist(1); - int v = ((r.pos - prv2.pos) << 16)/(r.t - prv2.t); + int v = ((r.pos - prv2.pos) * 65536L)/int(r.t - prv2.t); // presume we'll report the latest instantaneous reading z = r.pos; @@ -4738,7 +4751,7 @@ { // It's at roughly the same position as the starting point. // Consider it stable if this has been true for 300ms. - if (uint32_t(r.t - f3s.t) > 30000UL) + if (uint32_t(r.t - f3s.t) > 300000UL) { // we're done with the firing event firingMode(0); @@ -4765,11 +4778,36 @@ vprv2 = vprv; vprv = v; + // Check for auto-zeroing, if enabled + if ((cfg.plunger.autoZero.flags & PlungerAutoZeroEnabled) != 0) + { + // If we moved since the last reading, reset and restart the + // auto-zero timer. Otherwise, if the timer has reached the + // auto-zero timeout, it means we've been motionless for that + // long, so auto-zero now. + if (r.pos != prv.pos) + { + // movement detected - reset the timer + autoZeroTimer.reset(); + autoZeroTimer.start(); + } + else if (autoZeroTimer.read_us() > cfg.plunger.autoZero.t * 1000000UL) + { + // auto-zero now + plungerSensor->autoZero(); + + // stop the timer so that we don't keep repeating this + // if the plunger stays still for a long time + autoZeroTimer.stop(); + autoZeroTimer.reset(); + } + } + // add the new reading to the history hist[histIdx] = r; - if (++histIdx > countof(hist)) + if (++histIdx >= countof(hist)) histIdx = 0; - + // apply the post-processing filter zf = applyPostFilter(); } @@ -4801,6 +4839,9 @@ calRlsTimeSum = 0; calRlsTimeN = 0; + // tell the plunger we're starting calibration + plungerSensor->beginCalibration(); + // set the initial zero point to the current position PlungerReading r; if (plungerSensor->read(r)) @@ -4871,6 +4912,8 @@ bool isFiring() { return firing == 3; } private: + // Auto-zeroing timer + Timer autoZeroTimer; // Plunger data filtering mode: optionally apply filtering to the raw // plunger sensor readings to try to reduce noise in the signal. This @@ -5583,6 +5626,7 @@ nvm.valid(), // a config is loaded if the config memory block is valid true, // we support sbx/pbx extensions true, // we support the new accelerometer settings + true, // we support the "flash write ok" status bit in joystick reports mallocBytesFree()); // remaining memory size break; @@ -5835,9 +5879,16 @@ { // say hello to the debug console, in case it's connected printf("\r\nPinscape Controller starting\r\n"); - + // clear the I2C connection clear_i2c(); + + // Elevate GPIO pin interrupt priorities, so that they can preempt + // other interrupts. This is important for some external peripherals, + // particularly the quadrature plunger sensors, which can generate + // high-speed interrupts that need to be serviced quickly to keep + // proper count of the quadrature position. + FastInterruptIn::elevatePriority(); // Load the saved configuration. There are two sources of the // configuration data: @@ -6384,11 +6435,14 @@ { // save the configuration if (saveConfigToFlash()) + { + // report success in the status flags saveConfigSucceededFlag = 0x40; - // if desired, reboot after the specified delay - if (saveConfigPending == SAVE_CONFIG_AND_REBOOT) - saveConfigRebootTimer.start(); + // if desired, reboot after the specified delay + if (saveConfigPending == SAVE_CONFIG_AND_REBOOT) + saveConfigRebootTimer.start(); + } // the save is no longer pending saveConfigPending = 0;