Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Dependencies: mbed FastIO FastPWM USBDevice
Fork of Pinscape_Controller by
AltAnalogIn/AltAnalogIn.h@43:7a6364d82a41, 2016-02-06 (annotated)
- Committer:
- mjr
- Date:
- Sat Feb 06 20:21:48 2016 +0000
- Revision:
- 43:7a6364d82a41
- Child:
- 45:c42166b2878c
Before floating point plunger ranging
Who changed what in which revision?
| User | Revision | Line number | New contents of line |
|---|---|---|---|
| mjr | 43:7a6364d82a41 | 1 | #ifndef ALTANALOGIN_H |
| mjr | 43:7a6364d82a41 | 2 | #define ALTANALOGIN_H |
| mjr | 43:7a6364d82a41 | 3 | |
| mjr | 43:7a6364d82a41 | 4 | // This is a slightly modified version of Scissors's FastAnalogIn. |
| mjr | 43:7a6364d82a41 | 5 | // |
| mjr | 43:7a6364d82a41 | 6 | // This version is optimized for reading from multiple inputs. The KL25Z has |
| mjr | 43:7a6364d82a41 | 7 | // multiple ADC channels, but the multiplexer hardware only allows sampling one |
| mjr | 43:7a6364d82a41 | 8 | // at a time. The entire sampling process from start to finish is serialized |
| mjr | 43:7a6364d82a41 | 9 | // in the multiplexer, so we unfortunately can't overlap the sampling times |
| mjr | 43:7a6364d82a41 | 10 | // for multiple channels - we have to wait in sequence for the sampling period |
| mjr | 43:7a6364d82a41 | 11 | // on each channel, one after the other. |
| mjr | 43:7a6364d82a41 | 12 | // |
| mjr | 43:7a6364d82a41 | 13 | // The base version of FastAnalogIn uses the hardware's continuous conversion |
| mjr | 43:7a6364d82a41 | 14 | // feature to speed up sampling. When sampling multiple inputs, that feature |
| mjr | 43:7a6364d82a41 | 15 | // becomes useless, and in fact the way FastAnalogIn uses it creates additional |
| mjr | 43:7a6364d82a41 | 16 | // overhead for multiple input sampling. But FastAnalogIn still has some speed |
| mjr | 43:7a6364d82a41 | 17 | // advantages over the base mbed AnalogIn implementation, since it sets all of |
| mjr | 43:7a6364d82a41 | 18 | // the other conversion settings to the fastest options. This version keeps the |
| mjr | 43:7a6364d82a41 | 19 | // other speed-ups from FastAnalogIn, but dispenses with the continuous sampling. |
| mjr | 43:7a6364d82a41 | 20 | |
| mjr | 43:7a6364d82a41 | 21 | /* |
| mjr | 43:7a6364d82a41 | 22 | * Includes |
| mjr | 43:7a6364d82a41 | 23 | */ |
| mjr | 43:7a6364d82a41 | 24 | #include "mbed.h" |
| mjr | 43:7a6364d82a41 | 25 | #include "pinmap.h" |
| mjr | 43:7a6364d82a41 | 26 | |
| mjr | 43:7a6364d82a41 | 27 | #if !defined TARGET_LPC1768 && !defined TARGET_KLXX && !defined TARGET_LPC408X && !defined TARGET_LPC11UXX && !defined TARGET_K20D5M |
| mjr | 43:7a6364d82a41 | 28 | #error "Target not supported" |
| mjr | 43:7a6364d82a41 | 29 | #endif |
| mjr | 43:7a6364d82a41 | 30 | |
| mjr | 43:7a6364d82a41 | 31 | /** A class similar to AnalogIn, only faster, for LPC1768, LPC408X and KLxx |
| mjr | 43:7a6364d82a41 | 32 | * |
| mjr | 43:7a6364d82a41 | 33 | * AnalogIn does a single conversion when you read a value (actually several conversions and it takes the median of that). |
| mjr | 43:7a6364d82a41 | 34 | * This library runns the ADC conversion automatically in the background. |
| mjr | 43:7a6364d82a41 | 35 | * When read is called, it immediatly returns the last sampled value. |
| mjr | 43:7a6364d82a41 | 36 | * |
| mjr | 43:7a6364d82a41 | 37 | * LPC1768 / LPC4088 |
| mjr | 43:7a6364d82a41 | 38 | * Using more ADC pins in continuous mode will decrease the conversion rate (LPC1768:200kHz/LPC4088:400kHz). |
| mjr | 43:7a6364d82a41 | 39 | * If you need to sample one pin very fast and sometimes also need to do AD conversions on another pin, |
| mjr | 43:7a6364d82a41 | 40 | * you can disable the continuous conversion on that ADC channel and still read its value. |
| mjr | 43:7a6364d82a41 | 41 | * |
| mjr | 43:7a6364d82a41 | 42 | * KLXX |
| mjr | 43:7a6364d82a41 | 43 | * Multiple Fast instances can be declared of which only ONE can be continuous (all others must be non-continuous). |
| mjr | 43:7a6364d82a41 | 44 | * |
| mjr | 43:7a6364d82a41 | 45 | * When continuous conversion is disabled, a read will block until the conversion is complete |
| mjr | 43:7a6364d82a41 | 46 | * (much like the regular AnalogIn library does). |
| mjr | 43:7a6364d82a41 | 47 | * Each ADC channel can be enabled/disabled separately. |
| mjr | 43:7a6364d82a41 | 48 | * |
| mjr | 43:7a6364d82a41 | 49 | * IMPORTANT : It does not play nicely with regular AnalogIn objects, so either use this library or AnalogIn, not both at the same time!! |
| mjr | 43:7a6364d82a41 | 50 | * |
| mjr | 43:7a6364d82a41 | 51 | * Example for the KLxx processors: |
| mjr | 43:7a6364d82a41 | 52 | * @code |
| mjr | 43:7a6364d82a41 | 53 | * // Print messages when the AnalogIn is greater than 50% |
| mjr | 43:7a6364d82a41 | 54 | * |
| mjr | 43:7a6364d82a41 | 55 | * #include "mbed.h" |
| mjr | 43:7a6364d82a41 | 56 | * |
| mjr | 43:7a6364d82a41 | 57 | * AltAnalogIn temperature(PTC2); //Fast continuous sampling on PTC2 |
| mjr | 43:7a6364d82a41 | 58 | * AltAnalogIn speed(PTB3, 0); //Fast non-continuous sampling on PTB3 |
| mjr | 43:7a6364d82a41 | 59 | * |
| mjr | 43:7a6364d82a41 | 60 | * int main() { |
| mjr | 43:7a6364d82a41 | 61 | * while(1) { |
| mjr | 43:7a6364d82a41 | 62 | * if(temperature > 0.5) { |
| mjr | 43:7a6364d82a41 | 63 | * printf("Too hot! (%f) at speed %f", temperature.read(), speed.read()); |
| mjr | 43:7a6364d82a41 | 64 | * } |
| mjr | 43:7a6364d82a41 | 65 | * } |
| mjr | 43:7a6364d82a41 | 66 | * } |
| mjr | 43:7a6364d82a41 | 67 | * @endcode |
| mjr | 43:7a6364d82a41 | 68 | * Example for the LPC1768 processor: |
| mjr | 43:7a6364d82a41 | 69 | * @code |
| mjr | 43:7a6364d82a41 | 70 | * // Print messages when the AnalogIn is greater than 50% |
| mjr | 43:7a6364d82a41 | 71 | * |
| mjr | 43:7a6364d82a41 | 72 | * #include "mbed.h" |
| mjr | 43:7a6364d82a41 | 73 | * |
| mjr | 43:7a6364d82a41 | 74 | * AltAnalogIn temperature(p20); |
| mjr | 43:7a6364d82a41 | 75 | * |
| mjr | 43:7a6364d82a41 | 76 | * int main() { |
| mjr | 43:7a6364d82a41 | 77 | * while(1) { |
| mjr | 43:7a6364d82a41 | 78 | * if(temperature > 0.5) { |
| mjr | 43:7a6364d82a41 | 79 | * printf("Too hot! (%f)", temperature.read()); |
| mjr | 43:7a6364d82a41 | 80 | * } |
| mjr | 43:7a6364d82a41 | 81 | * } |
| mjr | 43:7a6364d82a41 | 82 | * } |
| mjr | 43:7a6364d82a41 | 83 | * @endcode |
| mjr | 43:7a6364d82a41 | 84 | */ |
| mjr | 43:7a6364d82a41 | 85 | class AltAnalogIn { |
| mjr | 43:7a6364d82a41 | 86 | |
| mjr | 43:7a6364d82a41 | 87 | public: |
| mjr | 43:7a6364d82a41 | 88 | /** Create an AltAnalogIn, connected to the specified pin |
| mjr | 43:7a6364d82a41 | 89 | * |
| mjr | 43:7a6364d82a41 | 90 | * @param pin AnalogIn pin to connect to |
| mjr | 43:7a6364d82a41 | 91 | * @param enabled Enable the ADC channel (default = true) |
| mjr | 43:7a6364d82a41 | 92 | */ |
| mjr | 43:7a6364d82a41 | 93 | AltAnalogIn( PinName pin, bool enabled = true ); |
| mjr | 43:7a6364d82a41 | 94 | |
| mjr | 43:7a6364d82a41 | 95 | ~AltAnalogIn( void ) |
| mjr | 43:7a6364d82a41 | 96 | { |
| mjr | 43:7a6364d82a41 | 97 | } |
| mjr | 43:7a6364d82a41 | 98 | |
| mjr | 43:7a6364d82a41 | 99 | /** Start a sample. This sets the ADC multiplexer to read from |
| mjr | 43:7a6364d82a41 | 100 | * this input and activates the sampler. |
| mjr | 43:7a6364d82a41 | 101 | */ |
| mjr | 43:7a6364d82a41 | 102 | inline void start() |
| mjr | 43:7a6364d82a41 | 103 | { |
| mjr | 43:7a6364d82a41 | 104 | // update the MUX bit in the CFG2 register only if necessary |
| mjr | 43:7a6364d82a41 | 105 | static int lastMux = -1; |
| mjr | 43:7a6364d82a41 | 106 | if (lastMux != ADCmux) |
| mjr | 43:7a6364d82a41 | 107 | { |
| mjr | 43:7a6364d82a41 | 108 | // remember the new register value |
| mjr | 43:7a6364d82a41 | 109 | lastMux = ADCmux; |
| mjr | 43:7a6364d82a41 | 110 | |
| mjr | 43:7a6364d82a41 | 111 | // select the multiplexer for our ADC channel |
| mjr | 43:7a6364d82a41 | 112 | if (ADCmux) |
| mjr | 43:7a6364d82a41 | 113 | ADC0->CFG2 |= ADC_CFG2_MUXSEL_MASK; |
| mjr | 43:7a6364d82a41 | 114 | else |
| mjr | 43:7a6364d82a41 | 115 | ADC0->CFG2 &= ~ADC_CFG2_MUXSEL_MASK; |
| mjr | 43:7a6364d82a41 | 116 | } |
| mjr | 43:7a6364d82a41 | 117 | |
| mjr | 43:7a6364d82a41 | 118 | // select our ADC channel in the control register - this initiates sampling |
| mjr | 43:7a6364d82a41 | 119 | // on the channel |
| mjr | 43:7a6364d82a41 | 120 | ADC0->SC1[0] = startMask; |
| mjr | 43:7a6364d82a41 | 121 | } |
| mjr | 43:7a6364d82a41 | 122 | |
| mjr | 43:7a6364d82a41 | 123 | |
| mjr | 43:7a6364d82a41 | 124 | |
| mjr | 43:7a6364d82a41 | 125 | /** Returns the raw value |
| mjr | 43:7a6364d82a41 | 126 | * |
| mjr | 43:7a6364d82a41 | 127 | * @param return Unsigned integer with converted value |
| mjr | 43:7a6364d82a41 | 128 | */ |
| mjr | 43:7a6364d82a41 | 129 | inline uint16_t read_u16() |
| mjr | 43:7a6364d82a41 | 130 | { |
| mjr | 43:7a6364d82a41 | 131 | // wait for the hardware to signal that the sample is completed |
| mjr | 43:7a6364d82a41 | 132 | while ((ADC0->SC1[0] & ADC_SC1_COCO_MASK) == 0); |
| mjr | 43:7a6364d82a41 | 133 | |
| mjr | 43:7a6364d82a41 | 134 | // return the result register value |
| mjr | 43:7a6364d82a41 | 135 | return (uint16_t)ADC0->R[0] << 4; // convert 12-bit to 16-bit, padding with zeroes |
| mjr | 43:7a6364d82a41 | 136 | } |
| mjr | 43:7a6364d82a41 | 137 | |
| mjr | 43:7a6364d82a41 | 138 | /** Returns the scaled value |
| mjr | 43:7a6364d82a41 | 139 | * |
| mjr | 43:7a6364d82a41 | 140 | * @param return Float with scaled converted value to 0.0-1.0 |
| mjr | 43:7a6364d82a41 | 141 | */ |
| mjr | 43:7a6364d82a41 | 142 | float read(void) |
| mjr | 43:7a6364d82a41 | 143 | { |
| mjr | 43:7a6364d82a41 | 144 | unsigned short value = read_u16(); |
| mjr | 43:7a6364d82a41 | 145 | return value / 65535.0f; |
| mjr | 43:7a6364d82a41 | 146 | } |
| mjr | 43:7a6364d82a41 | 147 | |
| mjr | 43:7a6364d82a41 | 148 | /** An operator shorthand for read() |
| mjr | 43:7a6364d82a41 | 149 | */ |
| mjr | 43:7a6364d82a41 | 150 | operator float() { return read(); } |
| mjr | 43:7a6364d82a41 | 151 | |
| mjr | 43:7a6364d82a41 | 152 | |
| mjr | 43:7a6364d82a41 | 153 | private: |
| mjr | 43:7a6364d82a41 | 154 | char ADCnumber; // ADC number of our input pin |
| mjr | 43:7a6364d82a41 | 155 | char ADCmux; // multiplexer for our input pin (0=A, 1=B) |
| mjr | 43:7a6364d82a41 | 156 | uint32_t startMask; |
| mjr | 43:7a6364d82a41 | 157 | }; |
| mjr | 43:7a6364d82a41 | 158 | |
| mjr | 43:7a6364d82a41 | 159 | #endif |
