Kenji Arai
/
NucleoL152_Volt_meter
Simple digital volt meter using internal reference(VREFINT)
main.cpp@0:62a1e3699786, 2016-11-16 (annotated)
- Committer:
- kenjiArai
- Date:
- Wed Nov 16 12:10:42 2016 +0000
- Revision:
- 0:62a1e3699786
- Child:
- 1:2fa5ba8b899f
Simple Digital Volt Meter using internal reference (VREFINT)
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
kenjiArai | 0:62a1e3699786 | 1 | /* |
kenjiArai | 0:62a1e3699786 | 2 | * mbed Application program / Simple Digital Volt-meter |
kenjiArai | 0:62a1e3699786 | 3 | * on Nucleo-L152RE |
kenjiArai | 0:62a1e3699786 | 4 | * |
kenjiArai | 0:62a1e3699786 | 5 | * Copyright (c) 2016 Kenji Arai / JH1PJL |
kenjiArai | 0:62a1e3699786 | 6 | * http://www.page.sannet.ne.jp/kenjia/index.html |
kenjiArai | 0:62a1e3699786 | 7 | * http://mbed.org/users/kenjiArai/ |
kenjiArai | 0:62a1e3699786 | 8 | * Created: Nobember 15th, 2016 |
kenjiArai | 0:62a1e3699786 | 9 | * Revised: Nobember 16th, 2016 |
kenjiArai | 0:62a1e3699786 | 10 | * |
kenjiArai | 0:62a1e3699786 | 11 | * |
kenjiArai | 0:62a1e3699786 | 12 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, |
kenjiArai | 0:62a1e3699786 | 13 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF |
kenjiArai | 0:62a1e3699786 | 14 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. |
kenjiArai | 0:62a1e3699786 | 15 | * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, |
kenjiArai | 0:62a1e3699786 | 16 | * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR |
kenjiArai | 0:62a1e3699786 | 17 | * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR |
kenjiArai | 0:62a1e3699786 | 18 | * THE USE OR OTHER DEALINGS IN THE SOFTWARE. |
kenjiArai | 0:62a1e3699786 | 19 | */ |
kenjiArai | 0:62a1e3699786 | 20 | |
kenjiArai | 0:62a1e3699786 | 21 | #define VOLTMETER |
kenjiArai | 0:62a1e3699786 | 22 | //#define CALC_VDD |
kenjiArai | 0:62a1e3699786 | 23 | //#define READ_VREF_TEMP |
kenjiArai | 0:62a1e3699786 | 24 | |
kenjiArai | 0:62a1e3699786 | 25 | #include "mbed.h" |
kenjiArai | 0:62a1e3699786 | 26 | |
kenjiArai | 0:62a1e3699786 | 27 | #if defined(VOLTMETER) |
kenjiArai | 0:62a1e3699786 | 28 | |
kenjiArai | 0:62a1e3699786 | 29 | /* Use R1 & R2 divider |
kenjiArai | 0:62a1e3699786 | 30 | | Nucleo-L152RE |
kenjiArai | 0:62a1e3699786 | 31 | V_INPUT <-- R1 -.-----| A0(PA_0) |
kenjiArai | 0:62a1e3699786 | 32 | | | |
kenjiArai | 0:62a1e3699786 | 33 | R2 | |
kenjiArai | 0:62a1e3699786 | 34 | |_____| GND |
kenjiArai | 0:62a1e3699786 | 35 | | |
kenjiArai | 0:62a1e3699786 | 36 | */ |
kenjiArai | 0:62a1e3699786 | 37 | #define R1 (3332.4f) // target 3.3K Ohm |
kenjiArai | 0:62a1e3699786 | 38 | #define R2 (987.54f) // target 1K Ohm |
kenjiArai | 0:62a1e3699786 | 39 | |
kenjiArai | 0:62a1e3699786 | 40 | AnalogIn v_input(A0); |
kenjiArai | 0:62a1e3699786 | 41 | AnalogIn vref(ADC_VREF); |
kenjiArai | 0:62a1e3699786 | 42 | DigitalOut myled(LED1); |
kenjiArai | 0:62a1e3699786 | 43 | Timer tmr; |
kenjiArai | 0:62a1e3699786 | 44 | |
kenjiArai | 0:62a1e3699786 | 45 | int main() { |
kenjiArai | 0:62a1e3699786 | 46 | double v_in, vdd; |
kenjiArai | 0:62a1e3699786 | 47 | double v_in_actual; |
kenjiArai | 0:62a1e3699786 | 48 | |
kenjiArai | 0:62a1e3699786 | 49 | while(true) { |
kenjiArai | 0:62a1e3699786 | 50 | tmr.reset(); |
kenjiArai | 0:62a1e3699786 | 51 | tmr.start(); |
kenjiArai | 0:62a1e3699786 | 52 | vdd = (1.224f) / vref.read(); |
kenjiArai | 0:62a1e3699786 | 53 | v_in = v_input.read(); |
kenjiArai | 0:62a1e3699786 | 54 | v_in_actual = v_in * vdd * ( R1 + R2) / R2; |
kenjiArai | 0:62a1e3699786 | 55 | printf("V IN : %5.3f [V]\r\n", v_in_actual); |
kenjiArai | 0:62a1e3699786 | 56 | wait_ms(500 - tmr.read_ms()); // 1sec interval |
kenjiArai | 0:62a1e3699786 | 57 | } |
kenjiArai | 0:62a1e3699786 | 58 | } |
kenjiArai | 0:62a1e3699786 | 59 | #endif |
kenjiArai | 0:62a1e3699786 | 60 | |
kenjiArai | 0:62a1e3699786 | 61 | #if defined(CALC_VDD) |
kenjiArai | 0:62a1e3699786 | 62 | |
kenjiArai | 0:62a1e3699786 | 63 | AnalogIn vref(ADC_VREF); |
kenjiArai | 0:62a1e3699786 | 64 | DigitalOut myled(LED1); |
kenjiArai | 0:62a1e3699786 | 65 | Timer tmr; |
kenjiArai | 0:62a1e3699786 | 66 | |
kenjiArai | 0:62a1e3699786 | 67 | /* |
kenjiArai | 0:62a1e3699786 | 68 | Calculate Voltage data |
kenjiArai | 0:62a1e3699786 | 69 | |
kenjiArai | 0:62a1e3699786 | 70 | Vdd: CPU Vdd line voltage |
kenjiArai | 0:62a1e3699786 | 71 | (If VREF+ connected Vdd and VREF- connected GND) |
kenjiArai | 0:62a1e3699786 | 72 | dt_adc: ADC data (12bit) |
kenjiArai | 0:62a1e3699786 | 73 | VREFINT: Internal bandgap voltage |
kenjiArai | 0:62a1e3699786 | 74 | 1.202V(min), 1.224V(typ), 1.242V(max) |
kenjiArai | 0:62a1e3699786 | 75 | VREFINT_CAL Raw data acquired at temperature of 30 °C, |
kenjiArai | 0:62a1e3699786 | 76 | Vdd = 3 V Addr: 0x1FF80078-0x1FF80079 |
kenjiArai | 0:62a1e3699786 | 77 | |
kenjiArai | 0:62a1e3699786 | 78 | VREFINT_CAL = 3000 * VREF(Factory) / 4096 [V] |
kenjiArai | 0:62a1e3699786 | 79 | Vdd = VREFINT_CAL / VREFINT(ADC float) [V] |
kenjiArai | 0:62a1e3699786 | 80 | |
kenjiArai | 0:62a1e3699786 | 81 | reference: |
kenjiArai | 0:62a1e3699786 | 82 | en.CD00277537.pdf page 56/133 (April 2016 DocID17659 Rev 12) |
kenjiArai | 0:62a1e3699786 | 83 | en.CD00240193.pdf page 287/908 (September 2016 DocID15965 Rev 14) |
kenjiArai | 0:62a1e3699786 | 84 | */ |
kenjiArai | 0:62a1e3699786 | 85 | int main() { |
kenjiArai | 0:62a1e3699786 | 86 | double vdd; |
kenjiArai | 0:62a1e3699786 | 87 | double vdd_calibed; |
kenjiArai | 0:62a1e3699786 | 88 | double vref_calibed; |
kenjiArai | 0:62a1e3699786 | 89 | double vref_f; |
kenjiArai | 0:62a1e3699786 | 90 | uint16_t vref_u16; |
kenjiArai | 0:62a1e3699786 | 91 | uint16_t vref_cal; |
kenjiArai | 0:62a1e3699786 | 92 | |
kenjiArai | 0:62a1e3699786 | 93 | vref_cal = *(__IO uint16_t *)((uint32_t)0x1ff800f8); |
kenjiArai | 0:62a1e3699786 | 94 | while(true) { |
kenjiArai | 0:62a1e3699786 | 95 | tmr.reset(); |
kenjiArai | 0:62a1e3699786 | 96 | tmr.start(); |
kenjiArai | 0:62a1e3699786 | 97 | myled = 1; |
kenjiArai | 0:62a1e3699786 | 98 | wait(0.2f); |
kenjiArai | 0:62a1e3699786 | 99 | myled = 0; |
kenjiArai | 0:62a1e3699786 | 100 | wait(0.6f); |
kenjiArai | 0:62a1e3699786 | 101 | vref_f = vref.read(); |
kenjiArai | 0:62a1e3699786 | 102 | vref_u16 = vref.read_u16(); |
kenjiArai | 0:62a1e3699786 | 103 | printf("Vref(f): %f, Vref : %u, Vref_CAL : %u,", |
kenjiArai | 0:62a1e3699786 | 104 | vref_f, vref_u16, vref_cal); |
kenjiArai | 0:62a1e3699786 | 105 | vref_calibed = 3.0f * (double)vref_cal / 4096.0f; |
kenjiArai | 0:62a1e3699786 | 106 | vdd_calibed = vref_calibed / vref_f; |
kenjiArai | 0:62a1e3699786 | 107 | vdd = 1.224f / vref_f; |
kenjiArai | 0:62a1e3699786 | 108 | printf(" Vref(Calibrated) : %f, VDD(Calibrated) : %f, VDD : %f,", |
kenjiArai | 0:62a1e3699786 | 109 | vref_calibed, vdd_calibed, vdd); |
kenjiArai | 0:62a1e3699786 | 110 | printf(" VDD(measured my Nucleo) : 3.3163\r\n"); |
kenjiArai | 0:62a1e3699786 | 111 | wait_ms(1000 - tmr.read_ms()); // 1sec interval |
kenjiArai | 0:62a1e3699786 | 112 | } |
kenjiArai | 0:62a1e3699786 | 113 | } |
kenjiArai | 0:62a1e3699786 | 114 | #endif |
kenjiArai | 0:62a1e3699786 | 115 | |
kenjiArai | 0:62a1e3699786 | 116 | #if defined(READ_VREF_TEMP) |
kenjiArai | 0:62a1e3699786 | 117 | |
kenjiArai | 0:62a1e3699786 | 118 | AnalogIn vrefint(ADC_VREF); |
kenjiArai | 0:62a1e3699786 | 119 | AnalogIn tempint(ADC_TEMP); |
kenjiArai | 0:62a1e3699786 | 120 | |
kenjiArai | 0:62a1e3699786 | 121 | int main() { |
kenjiArai | 0:62a1e3699786 | 122 | while(true) { |
kenjiArai | 0:62a1e3699786 | 123 | printf("Vref(f): %f, Vref : %u, Temperature : %u\r\n", |
kenjiArai | 0:62a1e3699786 | 124 | vrefint.read(), vrefint.read_u16(), tempint.read_u16()); |
kenjiArai | 0:62a1e3699786 | 125 | wait(1.0f); |
kenjiArai | 0:62a1e3699786 | 126 | } |
kenjiArai | 0:62a1e3699786 | 127 | } |
kenjiArai | 0:62a1e3699786 | 128 | #endif |