Four-channel voltmeter 0-50V based on the set of "Digital Lab" NR05

    Often there is a need to simultaneously control several voltages, for example, the output voltages of a computer power supply unit, several batteries, etc. In the last publication, we reviewed the principle of operation of a code lock, and now, based on the Digital Lab NR05 expansion board , we assemble a four-channel digital voltmeter with indication of results on the built-in board display. The range of measured voltages can be changed by using an external divider, and the measurement step is determined by the width of the Atmega 328 microcontroller’s analog-to-digital converter (ADC) used in the Arduino board and amounts to 1024 values. Then, in the voltage range of 0-50V, the voltage measurement step will be about 50 mV, which is quite enough for domestic use.



    The measured voltages will be connected to the free analog inputs of the board. These are the A0, A4, A5 and A7 inputs located in the lower right of the board. To use the A0 input, you should temporarily evaporate the resistor R4 located near the XP3 connector in the right bottom of the board.



    An external divider with connectors for connecting measured voltages and expansion boards will be manufactured using the LUT method (the so-called “laser-iron technology”) and weed the board in a solution of ferric chloride. We used SMD resistors, but if you do not have a laser printer, you can make a divider by drawing the conductors with a waterproof felt-tip pen. In this case, it is better to use output resistors, since the dimensional accuracy of the resulting conductors will be lower. In detail, the manufacturing technology of printed circuit boards by the method of etching in ferric chloride can be studied by purchasing the Master Kit production set NN201 .

    The finished divider board is presented in the photo below.



    The expansion board has a 2-line LCD display with 16 characters in each line. On this indicator, four readings from 0 to 50 volts with one decimal place and channel IDs will be quite comfortable.

    The measurements themselves should be carried out several times over a short period of time, averaging their values. So we will reduce random measurement errors.
    We also realize in the program “freezing” the results by clicking on one of the buttons built into the board, for example, the middle one. With a second press, continuous measurements will resume.

    We activate the LED connected to the 13th digital output of Arduino to indicate the measurement process.

    In view of the above, we will create a program for Arduino:

    Spoiler
    /*--------------------------------------------------------------
    Четырехканальный вольтметр 0-50В, с усреднением,
    одна цифра после запятой, с отображением на LCD-индикаторе
    16 символов, 2 строки,

    Используется плата расширения из набора Мастер Кит
    NR05 «Цифровая лаборатория»; 4 делителя на 10 на резисторах
    1М, 100к, подключенных с аналоговым входам A0,A4,A5,A7

    Калибровка опорного напряжения
    Измерьте напряжение 5В и измените значения константы V_REF
    в соответствии с измеренным значением.
    Измеряйте напряжение с подключенным ЖК-дисплеем
    и при запущенном скетче.

    Определение калибровочных значений делителей (проводится
    для каждого делителя)
    Подключите стабильное напряжение Vin к входу делителя и
    измерьте его.
    Измерьте напряжение Vout на выходе делителя.
    Калибровочное значение DIV_* будет равно Vin/Vout.

    За основу взят проект с сайта startingelectronics.com
    --------------------------------------------------------------*/
    #include <LiquidCrystal.h>

    // встроенный светодиод (используем для индикации процесса измерения)
    #define LED 13
    // число выборок на одно измерение
    #define NUM_SAMPLES 20
    // калибровочные значения делителя
    #define DIV_1 11.186
    #define DIV_2 11.186
    #define DIV_3 11.186
    #define DIV_4 11.186
    // калибровочное значение опорного напряжения
    #define V_REF 4.575
    // число кнопок на плате
    #define NUM_KEYS 5
    // калибровочные значения для каждой кнопки (выведены экспериментально)
    int adcKeyVal[NUM_KEYS] = {30, 150, 360, 535, 760};

    LiquidCrystal lcd(A1, A2, A3, 2, 4, 7);
    unsigned long sum[4] = {0}; // сумма выборок в каждом канале
    unsigned char sample_count = 0; // номер текущей выборки
    float voltage[4] = {0.0}; // расчитанное напряжениен
    int cnt = 0; // служебная переменная
    int keyIsPressed = 0; // флаг нажатия кнопки «заморозки» измерений

    void setup()
    {
    lcd.begin(16, 2);
    pinMode(LED, OUTPUT);
    digitalWrite(LED, LOW);
    }

    void loop()
    {
    // если кнопка 3 нажата, инвертируем флаг нажатия кнопки «заморозки»
    if (get_key() == 3){
    keyIsPressed = !keyIsPressed;
    delay(500);
    }
    // если флаг установлен (1), информация на дисплее не обновляется
    if (keyIsPressed == 0){
    digitalWrite(LED, LOW);
    // берем выборки в каждом канале и суммируем их
    while (sample_count < NUM_SAMPLES) {
    // sample channel A0, A4, A5, A7
    sum[0] += analogRead(A0);
    sum[1] += analogRead(A4);
    sum[2] += analogRead(A5);
    sum[3] += analogRead(A7);
    sample_count++;
    delay(10);
    }
    digitalWrite(LED, HIGH);
    // рассчитываем напряжения в каждом канале путем усреднения по выборкам
    for (cnt = 0; cnt < 4; cnt++) {
    voltage[cnt] = ((float)sum[cnt] / (float)NUM_SAMPLES * V_REF) / 1024.0;
    }
    // отображаем значения на идикаторе
    lcd.setCursor(0, 0);
    lcd.print(«A „);
    lcd.print(voltage[0] * DIV_1, 1);
    lcd.print(“V „);
    // voltage 2 — B (pin A4)
    lcd.setCursor(8, 0);
    lcd.print(“B „);
    lcd.print(voltage[1] * DIV_2, 1);
    lcd.print(“V „);
    // voltge 3 — C (pin A5)
    lcd.setCursor(0, 1);
    lcd.print(“C „);
    lcd.print(voltage[2] * DIV_3, 1);
    lcd.print(“V „);
    // voltage 4 — D (pin A7)
    lcd.setCursor(8, 1);
    lcd.print(“D „);
    lcd.print(voltage[3] * DIV_4, 1);
    lcd.print(“V „);

    // сбрасываем счетчик и суммы
    sample_count = 0;
    for (cnt = 0; cnt < 4; cnt++) sum[cnt] = 0;
    delay(20);
    }
    }

    // функция возвращает номер нажатой кнопки
    int get_key()
    {
    int input = analogRead(A6);
    int k;
    for (k = 0; k < NUM_KEYS; k++)
    if (input < adcKeyVal[k])
    return k + 1;
    return 0;
    }


    The program is provided with sufficiently detailed comments explaining the features of the implementation of the algorithm.

    Perhaps the most important feature is the process of calibration of the constants described in the comments, which are involved in the calculation of the measured voltages. To calibrate the divider (made once), you should use a stable constant voltage source. Taking into account that the calibration takes a short time, you can successfully use a 9V battery of the “Krona” type and a digital multimeter. A multimeter from the "Set of the young electronics engineer" NR02 is quite suitable. This kit is also perfect for teaching soldering and PCB assembly.

    It should be noted that when changing the supply voltage to the Arduino, it is necessary to change the calibration values ​​of the reference voltage, the relative values ​​of which are measured values.

    To change the measurement range, you must apply a divider with a different division factor of the input voltage.


    Also popular now: