Kenji Arai
/
NucleoL152_Volt_meter
Simple digital volt meter using internal reference(VREFINT)
Diff: main.cpp
- Revision:
- 0:62a1e3699786
- Child:
- 1:2fa5ba8b899f
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/main.cpp Wed Nov 16 12:10:42 2016 +0000 @@ -0,0 +1,128 @@ +/* + * mbed Application program / Simple Digital Volt-meter + * on Nucleo-L152RE + * + * Copyright (c) 2016 Kenji Arai / JH1PJL + * http://www.page.sannet.ne.jp/kenjia/index.html + * http://mbed.org/users/kenjiArai/ + * Created: Nobember 15th, 2016 + * Revised: Nobember 16th, 2016 + * + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, + * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR + * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR + * THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +#define VOLTMETER +//#define CALC_VDD +//#define READ_VREF_TEMP + +#include "mbed.h" + +#if defined(VOLTMETER) + +/* Use R1 & R2 divider + | Nucleo-L152RE + V_INPUT <-- R1 -.-----| A0(PA_0) + | | + R2 | + |_____| GND + | + */ +#define R1 (3332.4f) // target 3.3K Ohm +#define R2 (987.54f) // target 1K Ohm + +AnalogIn v_input(A0); +AnalogIn vref(ADC_VREF); +DigitalOut myled(LED1); +Timer tmr; + +int main() { + double v_in, vdd; + double v_in_actual; + + while(true) { + tmr.reset(); + tmr.start(); + vdd = (1.224f) / vref.read(); + v_in = v_input.read(); + v_in_actual = v_in * vdd * ( R1 + R2) / R2; + printf("V IN : %5.3f [V]\r\n", v_in_actual); + wait_ms(500 - tmr.read_ms()); // 1sec interval + } +} +#endif + +#if defined(CALC_VDD) + +AnalogIn vref(ADC_VREF); +DigitalOut myled(LED1); +Timer tmr; + +/* + Calculate Voltage data + + Vdd: CPU Vdd line voltage + (If VREF+ connected Vdd and VREF- connected GND) + dt_adc: ADC data (12bit) + VREFINT: Internal bandgap voltage + 1.202V(min), 1.224V(typ), 1.242V(max) + VREFINT_CAL Raw data acquired at temperature of 30 °C, + Vdd = 3 V Addr: 0x1FF80078-0x1FF80079 + + VREFINT_CAL = 3000 * VREF(Factory) / 4096 [V] + Vdd = VREFINT_CAL / VREFINT(ADC float) [V] + + reference: + en.CD00277537.pdf page 56/133 (April 2016 DocID17659 Rev 12) + en.CD00240193.pdf page 287/908 (September 2016 DocID15965 Rev 14) +*/ +int main() { + double vdd; + double vdd_calibed; + double vref_calibed; + double vref_f; + uint16_t vref_u16; + uint16_t vref_cal; + + vref_cal = *(__IO uint16_t *)((uint32_t)0x1ff800f8); + while(true) { + tmr.reset(); + tmr.start(); + myled = 1; + wait(0.2f); + myled = 0; + wait(0.6f); + vref_f = vref.read(); + vref_u16 = vref.read_u16(); + printf("Vref(f): %f, Vref : %u, Vref_CAL : %u,", + vref_f, vref_u16, vref_cal); + vref_calibed = 3.0f * (double)vref_cal / 4096.0f; + vdd_calibed = vref_calibed / vref_f; + vdd = 1.224f / vref_f; + printf(" Vref(Calibrated) : %f, VDD(Calibrated) : %f, VDD : %f,", + vref_calibed, vdd_calibed, vdd); + printf(" VDD(measured my Nucleo) : 3.3163\r\n"); + wait_ms(1000 - tmr.read_ms()); // 1sec interval + } +} +#endif + +#if defined(READ_VREF_TEMP) + +AnalogIn vrefint(ADC_VREF); +AnalogIn tempint(ADC_TEMP); + +int main() { + while(true) { + printf("Vref(f): %f, Vref : %u, Temperature : %u\r\n", + vrefint.read(), vrefint.read_u16(), tempint.read_u16()); + wait(1.0f); + } +} +#endif \ No newline at end of file