Переделка китайского четырёхразрядного ампервольтметра на STM8S103F3 и INA226
После написания прошлой статьи про ампервольтметр на STM8S103F3 и INA226, захотелось попробовать переделать и китайский 4-х разрядный ампервольтметр добавлением в него китайской же платы с INA226, чтобы сделать его точнее и быстрее. Всё оказалось довольно просто. Обошлось заменой и прошивкой китайского клона Nuvoton N76E003 на оригинальный STM8S103F3, добавлением платы с INA226 и выкидываем лишних деталей с платы. Ну и несколько дорожек пришлось перерезать и пробросить проводами, т.к. по распиновке Nuvoton N76E003 всё же немного отличается от STM8S103F3. Причём N76E003 по цоколёвке может заменять напрямую STM8S103F3. А вот наоборот не всегда из-за того, что у N76E003 на два GPIO больше (у STM8S103F3 ножки 4 и 8 заняты под NRST и Vcap и не являются GPIO).
Первым делом выкидываем с платы лишние операционники и подстроечные резисторы. А также убираем шунт.
После этого правим немного схему из предыдущей статьи про ампервольтметр, т.к. у китайца несколько другая схема подключения выходов к сдвиговому регистру и индикаторам, чем я использовал в прошлый раз.
После этого правим скетч, чтобы назначить правильные ножки подключения к индикатору и регистру в соответствие с подправленной схемой.
Добавляем в параллель два резистора по 0,01 Ом к шунту 0,1 Ом, который уже стоит на плате INA226. И измеряем получившееся сопротивление шунта, замерив в милливольтах падение напряжение на нём при протекании тока в 1 А. У меня получилось 5,86 мОм.
Т.к. максимальный расчётный ток для такого шунта составляет до 14 ампер, а дорожки на плате INA226 мне показались недостаточно мощными, то я припаял толстые провода, через которые будет идти измерение тока, прямо к резисторам шунта. Это также обеспечит дополнительный теплоотвод для шунта. Хотя при токе 14 ампер, мощность, рассеиваемая на шунте, составит 1,14688 Ватт. Учитывая, что там стоят три одноваттных СМД резистора, нагрева шунта быть практически не должно даже при максимальном токе.
Рассчитываем значение регистра калибровки, как я ранее описывал в статье и прописываем его в скетче. В самом скетче также есть комментарии по работе с регистрами конфигурации и калибровки.
Конфигурационный регистр прописан таким же значением, как и в прошлый раз 0x456F. Что означает — время преобразования 8,24 миллисекунды и 16 повторов измерений с усреднением. Что даёт время обновления индикатора примерно 5 раз в секунду.
В коде программы есть закомментированные строки с несколькими вариантами значений для регистров с пояснениями к ним. Эти строки можно раскомментировать, если они Вам больше подходят (и не забыть тогда закомментировать первоначальные варианты). Если хочется почитать про расчёт регистров подробнее, то смотрим мою предыдущую статью или читаем документацию к INA226.
Снимаем с платы старый микроконтроллер N76E003. И запаиваем на его место STM8S103F3.
На плате уже есть отверстия под контакты для программирования контроллера. Поэтому просто впаиваем туда ножки для подключения программатора:
— Vdd – питание +3,3 В – идёт к ножке 9 контроллера
— GND – идёт к ножке 7 контроллера
— RST – идёт к ножке 4 контроллера
— SWIM – идёт к ножке 18 контроллера
— TX – – идёт к ножке 2 контроллера — на случай, если нужно будет при отладке выводить на терминал какие-то данные
В коде также есть строки для вывода на терминал данных из регистров INA226. Их нужно раскомментировать, если вы собираетесь мониторить состояние регистров INA226 при отладке.
Теперь прошиваем контроллер с помощью ST-Link V2.
У кого возникает ошибка при прошивке STM8S103F3, тоже смотрим предыдущую статью. Там описано решение проблемы.
Скетч я загружал из Arduino IDE версии 1.8.19 через китайский ST-Link V2.
ВНИМАНИЕ!
Как подсказал пользователь kvarkk, в Arduino IDE 2.х предлагаемое ядро для STM8 не устанавливается. Поэтому для прошивки приведённого скетча Arduino IDE 2.х не подойдёт.
Повторю здесь ещё раз (для тех, кто первый раз их шьёт) как прошивать STM8.
Для работы с STM8S103F3 нужно добавить соответствующие платы в менеджер плат. Для этого сначала нужно, чтобы в настройках в разделе «Дополнительные ссылки для менеджера плат» была добавлена ссылка для STM8 href=«https://github.com/tenbaht/sduino/raw/master/package_sduino_stm8_index.json

Тогда в менеджере плат можно будет выбрать контроллер STM8S103F3.

Напоминаю, что библиотека Wire.h не имеет функций, которые умеют писать по два байта в регистры INA226. В коде есть функции, которые решают эту проблему. Кто будет делать какие-то свои решения с использованием для INA226 библиотеки Wire.h, имейте это ввиду.
Ниже для любителей поковырять код и схему своими руками, приложены схема оригинального китайского ампервольтметра, схема переделанного на STM8S103 ампервольтметра и ссылка на архив со схемами в формате .spl7, а также код программы.
Схема переделанного ампервольтметра:

Схема оригинального китайского 4-разррядного ампервольтметра:

Ссылка на архив с файлпми .spl7 — https://www.dropbox.com/scl/fi/2y24mv7glzy8nadlw0zf1/SPL.rar?rlkey=eobd7e5y16oez4tky1mi4xxyy&dl=0
При проверке работы прибора и сравнении его показаний с четырёхразрядным вольтметром и пятиразрядным амперметром блока питания KORAD U203, расхождение не превысило единички в младшем разряде и по току, и по напряжению.
А это фото результата.


Желаю удачи всем, кто решит попробовать переделать свои китайские ампервольтметры!
Первым делом выкидываем с платы лишние операционники и подстроечные резисторы. А также убираем шунт.
После этого правим немного схему из предыдущей статьи про ампервольтметр, т.к. у китайца несколько другая схема подключения выходов к сдвиговому регистру и индикаторам, чем я использовал в прошлый раз.
После этого правим скетч, чтобы назначить правильные ножки подключения к индикатору и регистру в соответствие с подправленной схемой.
Добавляем в параллель два резистора по 0,01 Ом к шунту 0,1 Ом, который уже стоит на плате INA226. И измеряем получившееся сопротивление шунта, замерив в милливольтах падение напряжение на нём при протекании тока в 1 А. У меня получилось 5,86 мОм.
Т.к. максимальный расчётный ток для такого шунта составляет до 14 ампер, а дорожки на плате INA226 мне показались недостаточно мощными, то я припаял толстые провода, через которые будет идти измерение тока, прямо к резисторам шунта. Это также обеспечит дополнительный теплоотвод для шунта. Хотя при токе 14 ампер, мощность, рассеиваемая на шунте, составит 1,14688 Ватт. Учитывая, что там стоят три одноваттных СМД резистора, нагрева шунта быть практически не должно даже при максимальном токе.
Рассчитываем значение регистра калибровки, как я ранее описывал в статье и прописываем его в скетче. В самом скетче также есть комментарии по работе с регистрами конфигурации и калибровки.
Конфигурационный регистр прописан таким же значением, как и в прошлый раз 0x456F. Что означает — время преобразования 8,24 миллисекунды и 16 повторов измерений с усреднением. Что даёт время обновления индикатора примерно 5 раз в секунду.
В коде программы есть закомментированные строки с несколькими вариантами значений для регистров с пояснениями к ним. Эти строки можно раскомментировать, если они Вам больше подходят (и не забыть тогда закомментировать первоначальные варианты). Если хочется почитать про расчёт регистров подробнее, то смотрим мою предыдущую статью или читаем документацию к INA226.
Снимаем с платы старый микроконтроллер N76E003. И запаиваем на его место STM8S103F3.
На плате уже есть отверстия под контакты для программирования контроллера. Поэтому просто впаиваем туда ножки для подключения программатора:
— Vdd – питание +3,3 В – идёт к ножке 9 контроллера
— GND – идёт к ножке 7 контроллера
— RST – идёт к ножке 4 контроллера
— SWIM – идёт к ножке 18 контроллера
— TX – – идёт к ножке 2 контроллера — на случай, если нужно будет при отладке выводить на терминал какие-то данные
В коде также есть строки для вывода на терминал данных из регистров INA226. Их нужно раскомментировать, если вы собираетесь мониторить состояние регистров INA226 при отладке.
Теперь прошиваем контроллер с помощью ST-Link V2.
У кого возникает ошибка при прошивке STM8S103F3, тоже смотрим предыдущую статью. Там описано решение проблемы.
Скетч я загружал из Arduino IDE версии 1.8.19 через китайский ST-Link V2.
ВНИМАНИЕ!
Как подсказал пользователь kvarkk, в Arduino IDE 2.х предлагаемое ядро для STM8 не устанавливается. Поэтому для прошивки приведённого скетча Arduino IDE 2.х не подойдёт.
Повторю здесь ещё раз (для тех, кто первый раз их шьёт) как прошивать STM8.
Для работы с STM8S103F3 нужно добавить соответствующие платы в менеджер плат. Для этого сначала нужно, чтобы в настройках в разделе «Дополнительные ссылки для менеджера плат» была добавлена ссылка для STM8 href=«https://github.com/tenbaht/sduino/raw/master/package_sduino_stm8_index.json

Тогда в менеджере плат можно будет выбрать контроллер STM8S103F3.

Напоминаю, что библиотека Wire.h не имеет функций, которые умеют писать по два байта в регистры INA226. В коде есть функции, которые решают эту проблему. Кто будет делать какие-то свои решения с использованием для INA226 библиотеки Wire.h, имейте это ввиду.
Ниже для любителей поковырять код и схему своими руками, приложены схема оригинального китайского ампервольтметра, схема переделанного на STM8S103 ампервольтметра и ссылка на архив со схемами в формате .spl7, а также код программы.
Схема переделанного ампервольтметра:

Схема оригинального китайского 4-разррядного ампервольтметра:

Ссылка на архив с файлпми .spl7 — https://www.dropbox.com/scl/fi/2y24mv7glzy8nadlw0zf1/SPL.rar?rlkey=eobd7e5y16oez4tky1mi4xxyy&dl=0
Код программы:
/************************************************************************
* Скетч для вольтметра на STM8S103F3 + INA226 + семисегментнтный LED на 4 разряда с ОА
* (переделка китайского 4-разрядного ампервольтметра)
* Через стандартную библиотеку I2C для STM8S103F3 обмен корректно с INA226 не проходит
* В библиотеке Wire.h для STM8S103F3 нет функции записи двух байт в выбранный регстр.
* Есть только для одного байта.
* Пришлось брать функцию из этой библиотеки и созда на её основе свои, которые могут писать и читать двухбайтовые регистры INA226
*
* Регистры INA226:
* 00h: Регистр конфигурации
* 01h: Регистр напряжения шунта
* 02h: Регистр напряжения шины (это откуда мы читае напряжение для вольтметра)
* 03h: Регистр мощности
* 04h: Регистр тока - содержит в битах значение напряжение на шунте, делённое на 2,5 мкВ
* 05h: Регистр калибровки
* Коэф. пересчёта напряжения по данным из регистра 1.25mV
* Коэф. пересчёта напряжения на шунте по данным из регистра 2.5μV
* Регистр тока хранит данные в милиамперах
* Коэф. пересчёта мощности по данным из регистра 25mW
* Шунт - 0,005 (два в параллель по 0,01)
* Максимальный ток - 16,384 А
* Current_LSB (Current Least Significant Bit)
* — это разрешающая способность датчика тока (например у INA226, INA219) в Амперах на бит.
* Определяется как значение равное или большее (для удобства расчётов в программе)
* значения максимального допустимого измеряемого тока, разделённое на 32768
* часто выбирается из вариантов (0,5 мА; 1мА; 0,1мА; ... )
*
* Формула пересчёта - коэффициент калибровки CAL = 0,00512 / (Current_LSB * Rшунта)
* Current_LSB = Максимальный_ожидаемый_ток / 32768
* Максимальный ожидаемый ток определяется как такой ток,
*при котором на выбранном шунте падение напрядения не превысит значения 0,08192 вольт (предельного для INA226)
*
* Значение регистра калибровки зависит только от сопротивления шунта и выбранного Current_LSB
* Current_LSB лучше выбирать в 1 мА для шунтов меньше 0,05 Ом - тогда в регистре тока будет уже готовое значение в миллиамперах для только
* Если Current_LSB выбрать 0,5 мА, то значение из регистра тока нужно делить на 2. Но точность измерения будет выше. Поглешность около 0,5 мА.
* Для шунтов от 0,05 Ома и больше, можно выбрать Current_LSB = 0,1 мА. Тогда значение из регистра тока нужно будет поделить на 10 для получения
* реального значения тока.
*
* Примеры значений данных для регистра калибровки при Current_LSB = 0,5 мА (CAL = 0,00512 / (Rш * Current_LSB)):
* - сопротивление шунта - 0,005 Ом - > CAL = 0x800 --> 0,00512 / (0,005 Ом * 0,0005 A) = 2048 --> 0x800
* - сопротивление шунта - 0,00544 Ом - > CAL = 0x75A --> 0,00512 / (0,00544 Ом * 0,0005 A) = 1882,35 --> 0x75A
* - сопротивление шунта - 0,0056 Ом - > CAL = 0x725 --> 0,00512 / (0,0056 Ом * 0,0005 A) = 1828,57 --> 0x725
* - сопротивление шунта - 0,00541 Ом - > CAL = 0x765 --> 0,00512 / (0,00541 Ом * 0,0005 A) = 1892,791 --> 0x765
* --- в моём случае полученное из регистра тока значение не забыть разделить на 2 (К = 0,001 / Current_LSB)
* для получение реального значения тока в миллиамперах.
*
* LED индикаторы с общим анодом
* - для включения на регистры подаём 1, на сегменты 0
* - токоограничивающие резисторы с контроллера на сегменты - по 150 Ом
* Максимальный ток контроллера - когда на индикаторе светятся все 7 сегментов + точка на одном разряде касного индикатора
* с током 9 мА на сегмент = 9 х 8 = 72 мА - вполне допустимый ток контроллера
*
* Константин Трыков 12.2025
* Версия 110163_01
************************************************************************/
#include <I2C.h>
#include <stdio.h>
#include <Wire.h>
// Задаём адрес доступа к INA226
#define INA226adress 0x40
//-------------------------------------------------------------------------------------------------------------
// Задать значение для регистров INA226
//#define configData 0x4327 // Значение для регистра конфигурации
// Постоянный режим, время преобразования тока и напряжения - 1,1 мс,
// устедняемое число отсчётов - 4
//#define configData 0x456F // Значение для регистра конфигурации
// Постоянный режим, время преобразования тока и напряжения - 2,116 мс,
// устедняемое число отсчётов - 16
//#define configData 0x45B7 // Значение для регистра конфигурации
// Постоянный режим, время преобразования тока и напряжения - 4,156 мс,
// устедняемое число отсчётов - 16
#define configData 0x45FF // Значение для регистра конфигурации
// Постоянный режим, время преобразования тока и напряжения - 8,244 мс,
// устедняемое число отсчётов - 16
//--------------------------------- Настройка регистра калибровки ------------------------------------------
//#define calibrationData 0x800 // Значение для регистра калибровки при Rш = 5 милиом и Current_LSB = 0,5 мА
#define calibrationData 0x6D3 // Значение для регистра калибровки при Rш = 5,86 милиом и Current_LSB = 0,5 мА
//#define calibrationData 0x6AB // Значение для регистра калибровки при Rш = 6 милkиом и Current_LSB = 0,5 мА
//#define calibrationData 0x725 // Значение для регистра калибровки при Rш = 5,6 милkиом и Current_LSB = 0,5 мА
//#define calibrationData 0x669 // Значение для регистра калибровки при Rш = 6,24 милkиом и Current_LSB = 0,5 мА
//#define calibrationData 0x75A // Значение для регистра калибровки при Rш = 5,44 милkиом и Current_LSB = 0,5 мА
//#define calibrationData 0x765 // Значение для регистра калибровки при Rш = 5,41 милkиом и Current_LSB = 0,5 мА
//--------------------------------------------------------------------------------------------------
// Назначаем пины сегментам LED индикатора
#define SEG_A PD1
#define SEG_B PC6
#define SEG_C PA1
#define SEG_D PC4
#define SEG_E PC7
#define SEG_F PD2
#define SEG_G PA2
#define SEG_P PD3
// Назначаем пины ножкам регистра
#define ST_CP PC5 // PIN защёлки - ножка 12
#define SH_CP PD4 // PIN синхронизации - ножка 11
#define DS PC3 // PIN данных
// Установка значений переменных
uint16_t voltage_mV = 0; // Переменная для значения напряжения
uint16_t current_mA = 0; // Переменная для значения тока
uint8_t cyfra5 = 0; // Переменная для вывода цифры старшего 5-го разряда на индикатор
uint8_t cyfra4 = 0; // Переменная для вывода цифры 4-го разряда на индикатор
uint8_t cyfra3 = 0; // Переменная для вывода цифры 3-го разряда на индикатор
uint8_t cyfra2 = 0; // Переменная для вывода цифры 1-го разряда на индикатор
uint8_t cyfra1 = 0; // Переменная для вывода цифры младшего 1-го разряда на индикатор
// Переменные для считывания данных регистров INA226 - только для отладки
//uint16_t configDataDo = 0;
//uint16_t configDataPosle = 0;
//uint16_t calibrationDo = 0;
//uint16_t calibrationPosle = 0;
//----------------------------------------------------------------------------------------------------
// Массив байтов для отображения сегментов по полученной цифредля LED с ОА
uint8_t numberCode[] = // В этом массиве задаются цифры на семисегментном индикаторе
{ 0xC0, //0
0xF9, //1
0xA4, //2
0xB0, //3
0x99, //4
0x92, //5
0x82, //6
0xF8, //7
0x80, //8
0x90 //9
};
////////////////////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////// Функции //////////////////////////////////////////////////////////////////
// Вкючение сегментов в зависимости от полученного байта
void SendDig(uint8_t byteCode) // Запись сегментов в индикатор
{
digitalWrite(SEG_A, (byteCode & 0x01));
digitalWrite(SEG_B, ((byteCode & 0x02)>>1));
digitalWrite(SEG_C, ((byteCode & 0x04)>>2));
digitalWrite(SEG_D, ((byteCode & 0x08)>>3));
digitalWrite(SEG_E, ((byteCode & 0x10)>>4));
digitalWrite(SEG_F, ((byteCode & 0x20)>>5));
digitalWrite(SEG_G, ((byteCode & 0x40)>>6));
digitalWrite(SEG_P, HIGH); // Выключить точку
}
// Запись байта в регистр 74НС595
void cyfraOut(uint8_t x)
{
delay (1);
digitalWrite(ST_CP, LOW); // начинаем передачу данных
shiftOut(DS, SH_CP, LSBFIRST, x); // устанавливаем нужный байт
digitalWrite(ST_CP, HIGH); // прекращаем передачу данных
}
// Объявление функций записи и чтения INA225
uint16_t readRegisterTK(uint8_t, uint8_t);
void writeRegisterTK(uint8_t, uint8_t, uint16_t);
/////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////// Начальная установка //////////////////////////////////////////////////////////////////
void setup()
{
I2C_begin(); // Инициализируем шину I2C - в библиотеке I2C эта функция выглядит так:
// void I2C_begin()
// {
// bytesAvailable = 0;
// bufferIndex = 0;
// totalBytes = 0;
// timeOutDelay = 10; // set default time out
// I2C_setSpeed(0); // initialize for standard speed (100kHz)
// }
// Считываем данные из регистра конфигурации
// configDataDo = readRegisterTK (INA226adress,0x00); // Читаем 2 байта из регистра 0х00
// Считываем данные из регистра калибровки
// calibrationDo = readRegisterTK (INA226adress,0x05); // Читаем 2 байта из регистра 0х05
writeRegisterTK(INA226adress, 0x00, configData); // Инициализируем INA226 (17191 в десятичной или 0x4327 в шестнадцатиричной)
// Пишем в I2C устройство по адресу 0x40 в регистр 0x00 значение 0x4327
// Что означает:
// Режим работы - "continuous"
// Время выборки и для напряжения и для шунта - 1,1 мс
// Усредненее по 4 измерениям
// По умолчанию значение 0x4127 в шестнадцатиричной или 16679 в десятичной
writeRegisterTK(INA226adress, 0x05, calibrationData); // Инициализируем регистр калибровки INA226 под ток 16,384 А
// ... и сопротивление шунта 5 милиом (два по 0,005) - десятичное значение 2048 или 0x800 в шестнадцатиричной
// Считываем данные из регистра конфигурации
// configDataPosle = readRegisterTK (INA226adress,0x00); // Читаем 2 байта из регистра 0х00 - только для отладки
// Считываем данные из регистра калибровки
// calibrationPosle = readRegisterTK (INA226adress,0x05); // Читаем 2 байта из регистра 0х05 - только для отладки
// Задаём режимы пинов
pinMode(ST_CP, OUTPUT);
pinMode(SH_CP, OUTPUT);
pinMode(DS, OUTPUT);
pinMode(SEG_A, OUTPUT);
pinMode(SEG_B, OUTPUT);
pinMode(SEG_C, OUTPUT);
pinMode(SEG_D, OUTPUT);
pinMode(SEG_E, OUTPUT);
pinMode(SEG_F, OUTPUT);
pinMode(SEG_G, OUTPUT);
pinMode(SEG_P, OUTPUT);
//=========================================================================
//-------------- Только для отладки ----------------------
// Инициализация последовательного порта на скоости 9600 bps:
// Serial_begin(9600);
//-----------------------------------------------------------
//===========================================================================
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////// Начало основного цикла //////////////////////////////////////////////////////////////////
void loop()
{
// Считываем данные из регистра напряжения
voltage_mV = readRegisterTK (INA226adress,0x02); // Читаем 2 байта из регистра напяжения 0х02
voltage_mV = voltage_mV + (voltage_mV / 4); // Получаем данные в миливольтах - увеличиваем на четверть
// Считываем данные из регистра тока
current_mA = readRegisterTK (INA226adress,0x04); // Читаем 2 байта из регистра 0х04 - ток в милиамперах
current_mA = current_mA / 2; // Умножаем на 0,5 - коэффициент для тока = Current_LSB / 0,001
// Считываем данные из регистра конфигурации
// configDataPosle = readRegisterTK (INA226adress,0x00); // Читаем 2 байта из регистра 0х00 - только для отладки
// Считываем данные из регистра калибровки
// calibrationPosle = readRegisterTK (INA226adress,0x05);// Читаем 2 байта из регистра 0х05 - только для отладки
/*
//======================================================================================================
//-------------- Только для отладки - вывод на терминал -------------------------------------------
Serial_print_s("Напряжение - "); // Вывод текста без перевода строки
Serial_println_u(voltage_mV); // Вывод переменной напряжения с переводом строки
Serial_print_s("Ток - "); // Вывод текста с переводом строки
Serial_println_u(current_mA); // Вывод переменной с переводом строки
Serial_print_s("calibrationDo - ");
Serial_println_u(calibrationDo);
Serial_print_s("calibrationPosle - ");
Serial_println_u(calibrationPosle);
Serial_print_s("configDataDo - ");
Serial_println_u(configDataDo);
Serial_print_s("configDataPosle - ");
Serial_println_u(configDataPosle);
Serial_print_s("\n\r"); // Перевод строки
//-----------------------------------------------------------------------------------------------
//========================================================================================================
*/
// Если старший разряд не нулевой, то выводим старшие четыре разряда из пяти на индикатор напряжения
if (voltage_mV > 9999)
{
cyfraOut(0b10000000); // Выбрать разряд 4 вольтметра (1-й с конца - младший - крайний правый)
SendDig(numberCode[voltage_mV/10%10]); // Вывести 4-й из 5-и разряд напряжения
cyfraOut(0b01000000); // Выбрать разряд 3 вольтметра (второй справа)
SendDig(numberCode[voltage_mV/100%10]); // Вывести 3-й из 5-и разряд напряжения
cyfraOut(0b00100000); // Выбрать разряд 2 вольтметра (третий справа)
SendDig(numberCode[voltage_mV/1000%10]); // Вывести 2-й из 5-и разряд напряжения
digitalWrite(SEG_P, LOW); // Включить точку
cyfraOut(0b00010000); // Выбрать разряд 1 вольтметра (крайний левый)
SendDig(numberCode[voltage_mV/10000%10]); // Вывести 1-й из 5-и разряд напряжения
}
// Иначе выводим младщие четыре разряда из пяти на индикатор напряжения
else
{
cyfraOut(0b10000000); // Выбрать разряд 4 вольтметра (1-й с конца - младший - крайний правый)
SendDig(numberCode[voltage_mV%10]); // Вывести 5-й из 5-и разряд напряжения
cyfraOut(0b01000000); // Выбрать разряд 3 вольтметра (второй справа)
SendDig(numberCode[voltage_mV/10%10]); // Вывести 4-й из 5-и разряд напряжения
cyfraOut(0b00100000); // Выбрать разряд 2 вольтметра (третий справа)
SendDig(numberCode[voltage_mV/100%10]); // Вывести 3-й из 5-и разряд напряжения
cyfraOut(0b00010000); // Выбрать разряд 1 вольтметра (крайний левый)
SendDig(numberCode[voltage_mV/1000%10]); // Вывести 2-й из 5-и разряд напряжения
digitalWrite(SEG_P, LOW); // Включить точку
}
// Если старший разряд не нулевой, то выводим старшие четыре разряда на индикатор тока
if (current_mA > 9999)
{
cyfraOut(0b00000001); // Выбрать разряд 4 амперметра (1-й с конца - младший - крайний правый)
SendDig(numberCode[current_mA/10%10]); // Вывести 4-й из 5-и разряд тока
cyfraOut(0b00000010); // Выбрать разряд 3 амперметра (второй справа)
SendDig(numberCode[current_mA/100%10]); // Вывести 3-й из 5-и разряд тока
cyfraOut(0b00000100); // Выбрать разряд 2 амперметра (третий справа)
SendDig(numberCode[current_mA/1000%10]); // Вывести 2-й из 5-и разряд тока
digitalWrite(SEG_P, LOW); // Включить точку
cyfraOut(0b00001000); // Выбрать разряд 1 амперметра (крайний левый)
SendDig(numberCode[current_mA/10000%10]); // Вывести 1-й из 5-и разряд тока
}
// Иначе выводим младщие четыре разряда на индикатор тока
else
{
cyfraOut(0b00000001); // Выбрать разряд 4 амперметра (1-й с конца - младший - крайний правый)
SendDig(numberCode[current_mA%10]); // Вывести 5-й из 5-и разряд тока
cyfraOut(0b00000010); // Выбрать разряд 3 амперметра (второй справа)
SendDig(numberCode[current_mA/10%10]); // Вывести 4-й из 5-и разряд тока
cyfraOut(0b00000100); // Выбрать разряд 2 амперметра (третий справа)
SendDig(numberCode[current_mA/100%10]); // Вывести 3-й из 5-и разряд тока
cyfraOut(0b00001000); // Выбрать разряд 1 амперметра (крайний левый)
SendDig(numberCode[current_mA/1000%10]); // Вывести 2-й из 5-и разряд тока
digitalWrite(SEG_P, LOW); // Включить точку
}
}
/////////////// Конец основного цикла //////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////
// Запись 16-ти битного регистра INA226
void writeRegisterTK(uint8_t i2cAdress, uint8_t address, uint16_t dataTK)
{
Wire_beginTransmission(i2cAdress); // Начинаем передачу
Wire_write(address); // Отправляем адрес
Wire_write(highByte(dataTK)); // Отправляем старший байт
Wire_write(lowByte(dataTK)); // Отправляем младший байт
Wire_endTransmission(); // Заканчиваем передачу
}
// Чтение 16-ти битного регистра INA226
uint16_t readRegisterTK(uint8_t i2cAdress, uint8_t address)
{
Wire_beginTransmission(i2cAdress); // Начинаем передачу
Wire_write(address); // Отправляем адрес
Wire_endTransmission(); // Заканчиваем передачу
Wire_requestFrom2(i2cAdress, (uint8_t)2); // Запрашиваем 2 байта
return Wire_read() << 8 | Wire_read(); // Клеим и возвращаем результат
}
При проверке работы прибора и сравнении его показаний с четырёхразрядным вольтметром и пятиразрядным амперметром блока питания KORAD U203, расхождение не превысило единички в младшем разряде и по току, и по напряжению.
А это фото результата.


Желаю удачи всем, кто решит попробовать переделать свои китайские ампервольтметры!
Самые обсуждаемые обзоры
| +83 |
5271
209
|
| +56 |
2199
52
|
Я подробно всё это описал в предыдущей статье, на которую дал ссылку.
Там, вроде, ясно написано — если будете пробовать переделывать — я вам желаю удачи.
А вы как то интересно почитали — если хочешь удачу — начинай переделывать. ))
А теперь я своим объяснением её убил(
Вы пробовали точно и быстро установить напряжение или ток на ЛБП, когда у вас показания на индикаторе меняются 1, максимум два раза в секунду? Удобно?
Вот меня это ну очень не устраивало. Думаю и не только меня.
а вольтметры и герц 15 бывают.
А вы мне в ответ — видео с частотой изменения показаний в 15 герц.
p.s. и про некоторые вариации a/v до кучи mysku.club/blog/aliexpress/102768.html
А вот ампервольтметры — как я и писал — скорость обновления около 1 раза в секунду. Это дико медленно и неудобно.
НУ и с измерением тока там беда. ((
там в конце еще несколько a/v кратко описаны. и 4хразрядный из них выделяется в лучшую сторону.
Он вообще какой-то особенный. Контроллер совсем не стандартный Ток меряет без операционника и довольно точно. При 0,56 А погрешность 9 мА. При 1,1А — 26 мА и при 1,7 А — 48 мА.
По напряжению погрешность при 5 В — 1 мВ. При 10 В — 12 мВ. При 15В — 30 мВ. И при 20 В — 40 мВ.
Покупал вот тут — https://www.aliexpress.com/item/1005006212276117.html
Ток потребления 5,6 мА.
Заявлено питание до 24 В. Хотя стоит отличный стабилизатор 5433 с входным до 35 вольт.
Но такой вариант скорее исключение у китайцев, чем правило.
И ещё один нюанс — даже ваши купленные 5 лет назад, показывают напряжение до двух знаков после запятой. А на доработанном можно получить три знака с хорошей точностью.
Там 100 / 1024 = 0,0977 вольт на бит. Вот такая получается точность.
а как именно и прозвонить можно.
а сегментов у 4*2 *8(7 сегментов и точка) всего 64.
вот на 5*2 уже нужен 10ый.
Спасибо за подсказку!
всякая же мелочь в sot23/sot89 стоящая в готовых вольтметрах не вывозит не по напряжению, а именно по мощности. особенно у экземпляров которые по 20мА жрут — там вольт 20, не более (но встречаются и с потреблением меньше 10мА, там диапазон пошире).
Тот, что я описывал в первой статье — с бело-красными индикаторами — 22,5 мА. То есть в самом худшем варианте получается 0,7 Ватт рассеиваемой мощности при питании от 34 вольт.
от которых sot23 рискует отпаятся, а sot89 будет раскаленный.
не надо туда 34.
если в лбп — там наверняка есть какой-нить отдельный источник, от него и питать.
Дорожки резать всё равно нужно было бы — там ножки, на которые INA цепляется, заняты под выходы на индикатор. А если без INA, то зачем же мне замена недостаточно точного 10 разрядного АЦП на другой, тоже 10 разрядный?
И с чего Вы взяли, что я добавлял hc595. Она там изначально была. На фото же видно.
Ну и на счёт перспективности 32 битного процессора с пямятью 16К Вы, по моему, погорячились. ))
Где мне не хвати STM8, можно использовать недорогие STM32F. Там функционала за глаза и АЦП 12 битный.
Я так понимаю, что скорость поднять внешним генератором, но вот точность? Поставить малошумящий ОУ, сделать ревизию монтажу?
Где решение для контроллера с 10 или 12 разрядным АЦП?
Теперь Вы знаете, как при помощи простых компонентов можно усилить микровольты до считываемого уровня. Хотя Вы правы: постоянный ток вводить с помощью АЦП — так себе идея, проще таки через демодуляцию/ДСП. Ведь там точность даже 12бит — это на переменном токе или на постоянке тоже?
А что не так с измерением постоянного тока с помощью АЦП?
Поэтому работать удобнее на переменке и уж потом конвертировать в постоянное.
Что конкретно меняем, куда что подключаем, что принципиально делаем в коде.
Вот у меня в одном ампервольтметре, похоже, есть такой, но маркировка там затёрта.
Спасибо за подсказку.
Ещё бы они чуть быстрее его сделали и цвета индикатора местами поменяли — цены бы ему не было.
Ну а про малошумящие ОУ — можете показать решение, которое может сравниться с точностью 16 битного АЦП в INA226?
Практически любой ОУ — с шумом 1мкВ даст ДД под 100дБ/17бит, если там МДМ (зависит от реализации ключа и софта). Если же там дин. подстройка нуля — то хз, я не настоящий сварщик.
Одним из основополагающих принципов дельта-модуляции является превышение частоты Котельникова в K раз. При такой передискретизации эффективная разрядность, а соответственно, и отношение сигнал/шум, увеличивается согласно формуле {\displaystyle K=2^{N}}{\displaystyle K=2^{N}}, где K — коэффициент передискретизации, а N — количество дополнительных битов. Обычно применяется K = 64, и в этом случае эффективная разрядность будет 7 бит, а отношение сигнал/шум будет равно 42 дБ.
ru.wikipedia.org/wiki/Сигма-дельта-модуляция
Вы точно уверены, что такие АЦП есть у STM8S103А3 или N76E003?
Или Вы предлагаете их реализовывать в виде программно-аппаратных методов с использованием встроенного аналогового компаратора и RC-цепи?
Это решение требует внешней обвязки и сложной программной обработки (цифровой фильтр нижних частот).
Я так понял Вы именно это считаете методом упрощения предлагаемого в статье решения?..
Какие? Любой цифровой поток можно «замедлить» с увеличением разрядности.
Нет, даже я понимаю, так точно не получить сколь-либо приличного разрешения)
Внешней обвязки — нет, а вот ДСП может потребоваться достаточно мощный — там схема поддаётся оптимизации очень хорошо, но на аналоге МК 45-летней давности почти наверняка не взлетит.
Нет, это я потакаю Вашему любопытству) а так — предполагал, что апгрейд аналоговой части позволит устройству видеть микровольты (впрочем, МДМ схема даже с самым примитивным ОУ это уже делает, как видно их Ваших картинок «До»).
При заявленных 10 амперах — это 0,01 ампер на бит.
Плюс у АЦП контроллера есть ещё и нелинейность характеристики.
И где тут точность при любом самом точном ОУ?
Сам по себе АЦП лишь звено в ДСП.
Я правильно Вас понял?
Вот Вам всё хорошо разжёвано про Д-С, если интересно: ссылка
То есть получить точные данные о единицах миллиампер и десятках и единицах милливольт мы не можем.
Поэтому у большинства китайцев (и, в том числе у того, который я переделывал) даже при напряжениях меньше 10 вольт отображение на четырёхразрядном индикаторе будет в формате Х.ХХ, а не Х.ХХХ. Потому что там при всём желании нечего отображать. Тут и второму-то знаку после запятой в напряжении веры нету.
А не думали переделать разводку и измерять ток по плюсу, INA226 вроде такое позволяет? для ЛБП это часто удобнее.
Сравнения не делал, т.к. написать статью решил уже после переделки показометра.и варианта снять данные с недоработанной версии уже не было.
К сожалению идея написать статью пришла уже после переделки и варианта снять показания с не доработанного варианта уже не было.
Вот с ним сделал сравнение. Подключал к блоку питания параллельно парой.
Кстати, ошибка измерения тока — 1МЗР, это внутренняя погрешность цифровой индикации считай.
А напряжения — постоянная по диапазону, то есть решается
калибровкойподстройкой усиления…Для сравнения вот подключенные так же в параллель два ампервольтметра с INA226 (из первой и из второй статьи).
В миллиамперах периодически единичка выскакивает на переделанном.
Но это не страшно.
Имелось ввиду, что китайцы с некоторых пор стали заменять в показометрах STM8 на N76E003. И, как правило, с ухудшением скорости работы.
А сделать такую замену смогли потому, что по распиновке N76E003 прекрасно заменяет STM8S103F3. К сожалению наоборот не заменяется.
А вы пробовали перепрошить N76E003?
А вообще под него писать код пробовали?
Какое там ядро знаете?
— для программирования N76E003 используется специальный программатор Nu-Link-Me V3.0 (картинка ниже) или Nu-Link ICP которые не являются универсальными (в отличие от например ST-Link) — стоимость смотрим на алике и радуемся дополнительно
— Протокол ICP обмена между программатором и программируемым контроллером фирмой Nuvoton не раскрывается — большой привет Вашему ИИ
— ни в VC, ни в Keil, ни в ардуино ИДЕ работа без танцев с бубнами с камнем N76E003 не возможна
А Вы мне предлагаете изучить новую среду и купить новый программатор за дорого, когда я могу получить нужный мне результат быстро и за не дорого.
И речь не о быстрых токах, а о том, что при вращении ручки ЛБП не удобно пользоваться медленным показометром. Просто сравните.
Интересно было бы менять пределы измерений. Мне хотелось бы 300в постоянки, 200 мА, но китайцы таких не делают.
И интересно, почему никто не выложил переделку четырёхразрядного вольтметра в амперметр, неужели никто не пробовал?
Вот это я бы точно переделал бы.
просто — только если шунт слоновий поставить. но зачем?
а если у вольтметра менять мк — что от него останется, платка с индикатором? так они и отдельные бывают.
Тот, что у меня меняет показания раз в секунду тоже заявлялся с временем обновления 300 мс.
Чуть медленнее. Но заявленные три раза в секунду честно отрабатывает. И на борту крутой контроллер с 18 битным АЦП. Не много неточность есть по току. Но это может быть связано с отклонением реального сопротивления шунта от расчётного и почти компенсируется регулировкой и подстройкой шунта.
Сам не ожидал, что есть такие в продаже у китайцев.
Главное, чтобы не начали вместо него отправлять левые приборы.
А такая — если скопировать и убрать подчёркивание _https://www.aliexpress.com/item/1005006212276117.html?spm=a2g0o.order_list.order_list_main.10.3ba11802piP87r
А вольтметр если переделывать, то всё равно нужен внешний АЦП.
Иначе для диапазона 100 вольт цена одного бита равна 100 / 1024 = .0,098 вольт.
Поганая точность получается.
На моей схеме оригинального китайца в приведённой статье есть аналогичная приблуда.
Контроллер из серии аналогов STM8S103F3.
Есть у меня и такой. Там ещё интересно, что нет ограничительных резисторов на сегменты индикаторов.