24 KiB
@page phase_comparison_balsam Сравнение фазовой части Balsam 165 и Balsam 167
Сравнение фазовой части Balsam 165 и Balsam 167
Область сравнения
Сравнивались:
- захват фазных сигналов АЦП;
- удаление нулевого смещения;
- масштабирование в физические единицы;
- расчёт общего действующего значения;
- расчёт уровней отдельных фаз A, B и C;
- диагностика перекоса и обрыва фаз;
- диагностические биты и регистры Modbus;
- пороги напряжения и выдержки времени.
Исходные проекты:
K:/git_project/Balsam_165_periph;K:/git_project/Balsam_167_periph.
Основные файлы:
| Проект | Файл |
|---|---|
| Balsam 165 | K:/git_project/Balsam_165_periph/Source/Internal/measure.c |
| Balsam 165 | K:/git_project/Balsam_165_periph/Source/Internal/ADC.c |
| Balsam 165 | K:/git_project/Balsam_165_periph/Source/Internal/Include/measure.h |
| Balsam 165 | K:/git_project/Balsam_165_periph/Doc/Balsam 165 data stru.xls |
| Balsam 167 | Source/Internal/measure.c |
| Balsam 167 | Source/Internal/ADC.c |
| Balsam 167 | Source/Internal/Include/measure.h |
| Balsam 167 | Doc/Balsam 167 data stru.xls |
Вывод
Balsam 167 использует более правильный способ расчёта действующих значений отдельных фаз: усреднение квадрата с последующим извлечением корня. Balsam 165 сглаживает модуль сигнала, что не является настоящим RMS.
При этом в Balsam 167 появились две ошибки индексации:
- Парный канал записывается по абсолютному индексу, но читается по относительному.
- Бит
Ignorустанавливается у абсолютного номера датчика, но проверяется у относительногоchan.
Для УМП, где pow_addr == 0, первая ошибка не проявляется. Для силового блока
она может приводить к дублированию фазных уровней и ложному Wry + Stop.
Рекомендуемый вариант: сохранить RMS-алгоритм Balsam 167, исправить индексацию и выполнять диагностику трёх фаз один раз после обработки всей пары каналов.
Сводная таблица
| Параметр | Balsam 165 | Balsam 167 | Оценка |
|---|---|---|---|
| Частота АЦП | 5000 Гц | 3750 Гц | Изменена |
| Выбор фазных входов АЦП | CONV02…CONV05 |
CONV02…CONV05 |
Одинаковый |
Формула im_calc() |
Одинаковая | Одинаковая | Без изменений |
| Фаза B | -A-C, для dsk_COMM эквивалентная разность |
-A-C после смены знака A |
По модулю эквивалентно |
| Уровень отдельной фазы | EMA от abs(x) |
sqrt(EMA(x²)) |
167 корректнее |
| Частота фильтра результата | 5 Гц | 3 Гц | 167 медленнее |
Тип lev_count[] |
float |
int |
В 167 раньше теряется дробная часть |
| Порог перекоса | 20% | 30% | 167 менее чувствителен |
| Выдержка измеряемой фазы | около 1,5 с | около 3 с | 167 медленнее |
| Выдержка восстановленной фазы | около 0,75 с | около 1,5 с | В обеих версиях вдвое короче |
Curr_Edge, УМП |
100 | 300 | Порог существенно повышен |
Curr_Edge, силовой блок |
40 | 200 | Порог существенно повышен |
Низкое Utr |
без выдержки | счётчик около 3 с | Улучшено, но блокируется Ignor |
Верхнее Utr |
без выдержки | без выдержки | Без улучшения |
| Калибровка входов | жёсткий curK[] |
Modbus/EEPROM Caliber[] |
167 гибче |
| Пары каналов силового блока | корректные относительные индексы | несогласованные индексы | Регрессия 167 |
Обработка Ignor |
правильный абсолютный датчик | проверяется chan |
Регрессия 167 |
| Отдельные биты фаз A/B/C | нет | нет | Общий недостаток |
| Контроль пределов АЦП U/I | нет | нет | Общий недостаток |
1. Захват сигналов АЦП
Для УМП обе версии используют одинаковые входы:
CONV02 = 0x5; // напряжение 1
CONV03 = 0x4; // напряжение 2
CONV04 = 0x7; // ток 1
CONV05 = 0x2; // ток 2
Данные читаются из результатов ADCRESULT2…ADCRESULT5, после чего вызывается
Current_count(i).
Различается частота обработки:
Balsam 165: ADC_FREQ = 5000 Гц
Balsam 167: ADC_FREQ = 3750 Гц
Назначение входов УМП:
chan |
Сигнал |
|---|---|
| 0 | Utr A |
| 1 | Utr C |
| 2 | Itr A |
| 3 | Itr C |
Фаза B физически не измеряется.
2. Нулевое смещение
В обеих версиях используется медленное усреднение:
zero[n] = zero[n-1] + (ADC-zero[n-1]) / (5 * ADC_FREQ)
Balsam 165
Ноль записывается постоянно:
Zero_lev[chan] = filterbat(&out_filter[chan], zer_count[chan]);
Для подстройки используются те же out_filter[], которые участвуют в другой
обработке сигналов.
Balsam 167
Добавлены отдельные фильтры zer_filter[]:
Zer = filterbat(&zer_filter[chan], zer_count[chan]);
if (WAKE < (WAKE_TIME / 2)) Zero_lev[chan] = Zer;
Разделение фильтров является улучшением. Однако после того как WAKE достиг
нуля, условие остаётся истинным. Подстройка нуля фактически продолжается во
время всей работы.
Если подстройка нужна только при запуске, должно проверяться также WAKE > 0.
3. Масштабирование
Balsam 165
Используются жёстко заданные коэффициенты curK[]:
| Устройство | Напряжение | Ток |
|---|---|---|
| УМП 1/2 | 0.386 |
4.82 |
| Силовой блок | 0.402 |
— |
Коэффициенты одинаковы для однотипных каналов и не берутся из EEPROM.
Balsam 167
Коэффициенты вычисляются из Caliber[0…3]:
напряжение: powK = Caliber / 10000
ток: powK = Caliber / 1000
Преимущества:
- индивидуальная калибровка каждого входа;
- отдельные значения для экземпляров устройств;
- сохранение и загрузка через EEPROM.
Значения тока заметно отличаются от Balsam 165. Например, для УМП 1 в
Balsam 167 используются 3.505 и 3.380 вместо 4.82. Это может быть связано
с изменением аппаратной части или новой калибровкой и требует стендовой сверки.
4. Общий уровень трёхфазного сигнала
Функция im_calc() в проектах совпадает:
isA = -1.5 * (a + b)
isB = cos(π/6) * (a - b)
Amplitude = 2/3 * sqrt(isA² + isB²)
Level = Amplitude / sqrt(2)
Эквивалентная формула амплитуды:
Amplitude = 2/sqrt(3) * sqrt(a² + a*b + b²)
Фильтрация общего уровня
Balsam 165 сначала делит амплитуду на sqrt(2), затем фильтрует Level
фильтром 5 Гц. Для тока и всех каналов dsk_COMM используется дополнительная
статическая переменная ffLev.
ffLev одна на все вызовы функции. На силовом блоке результаты разных пар
могут влиять друг на друга.
Balsam 167 фильтрует амплитуду отдельным фильтром текущего датчика:
Amplitude = filterbat(&out_filter[sens], im_calc(Current, aCurrent));
Level = Amplitude / RADIX2;
Это устраняет общий ffLev и разделяет состояния фильтров разных пар.
Зона нечувствительности
Balsam 165:
Level < Curr_Edge -> Level = 0
Для УМП порог равен 100 единицам RMS.
Balsam 167:
напряжение: Amplitude < 20 -> 0
ток: Amplitude < 75 -> 0
В пересчёте на RMS это примерно 14,1 для напряжения и 53,0 для тока. Поэтому Balsam 167 публикует слабые сигналы, которые Balsam 165 обнулял.
5. Уровни отдельных фаз
Balsam 165: среднее модуля
lev_count[chan] +=
(fabs(Current) - lev_count[chan]) / (ADC_FREQ / 5);
Для синусоиды установившееся значение соответствует среднему модулю:
MeanAbs = 2/π * Amplitude ≈ 0.6366 * Amplitude
Balsam 167: настоящий RMS
lev_quadr[chan] +=
(Current * Current - lev_quadr[chan]) / ADC_FREQ;
lev_count[chan] = sqrt(lev_quadr[chan]);
Для синусоиды:
RMS = 1/sqrt(2) * Amplitude ≈ 0.7071 * Amplitude
При одинаковом входном масштабе Balsam 167 показывает примерно в 1,1107 раза, или на 11,1%, больше Balsam 165.
Это изменение влияет на абсолютные фазные уровни, но почти не влияет на
отношение минимальной фазы к максимальной, используемое для Wry.
Скорость сглаживания
Balsam 165 использует коэффициент 5/ADC_FREQ, что соответствует постоянной
времени около 0,2 с.
Balsam 167 использует коэффициент 1/ADC_FREQ, что соответствует постоянной
времени около 1 с. Фазные уровни Balsam 167 изменяются медленнее и стабильнее.
6. Восстановление фазы B
Для УМП в обеих версиях:
B = -A - C
Для силового блока в Balsam 165 используется:
third = current_channel - first_channel
В Balsam 167 сначала меняется знак сохранённого первого канала, затем
применяется общая формула -Current-aCurrent. Результат отличается знаком, но
для RMS знак не имеет значения.
Основной недостаток общий: фаза B не измеряется. Неисправность B определяется только через математическую связь с A и C.
7. Карта фазных регистров
В Balsam 165 код записывает:
0x68 + n*3 + 0 = текущий нечётный канал, для УМП фаза C
0x68 + n*3 + 1 = парный канал, для УМП фаза A
0x68 + n*3 + 2 = восстановленная фаза B
То есть фактический порядок для УМП:
C, A, B
В Balsam 167 первые две записи переставлены:
0x68 + n*3 + 0 = парный канал A
0x68 + n*3 + 1 = текущий канал C
0x68 + n*3 + 2 = восстановленная фаза B
Порядок соответствует карте Balsam 167:
| Регистр | УМП |
|---|---|
0x68 |
Utr A |
0x69 |
Utr C |
0x6A |
Utr B |
0x6B |
Itr A |
0x6C |
Itr C |
0x6D |
Itr B |
В карте Balsam 165 эти регистры не описаны как фазные. Адрес 0x68 обозначен
как яркость ламп, хотя исходный код записывает туда фазный уровень. Это риск
несовместимости прошивки с внешним ПО и документацией.
8. Диагностика Wry
В обеих версиях используется отношение:
Max = max(phase_A, phase_C, phase_B)
deviation = (Max - phase) / Max
Balsam 165
deviation > 20%
Max > Curr_Edge
выдержка измеряемой фазы ≈ 1,5 с
Curr_Edge:
| Режим | Значение |
|---|---|
| УМП | 100 |
| Силовой блок | 40 |
Balsam 167
deviation > 30%
Max > Curr_Edge
выдержка измеряемой фазы ≈ 3 с
Curr_Edge:
| Режим | Значение |
|---|---|
| УМП | 300 |
| Силовой блок | 200 |
Balsam 167 значительно менее чувствителен к перекосу и реагирует медленнее.
Ошибка выдержки восстановленной фазы
Один счётчик err_count[thrd] вызывается при обработке обоих каналов пары.
Поэтому он увеличивается дважды за цикл АЦП.
Фактическая выдержка постоянного дефекта фазы B:
| Проект | Заданная | Фактическая для B |
|---|---|---|
| Balsam 165 | 1,5 с | около 0,75 с |
| Balsam 167 | 3 с | около 1,5 с |
Проблема присутствует в обеих версиях.
Деление на ноль
Обе версии сначала вычисляют отношение с делением на Max, а затем проверяют
нижний порог:
((Max - phase) / Max > limit) && (Max > Curr_Edge)
При Max == 0 выполняется 0/0. Безопасный порядок:
(Max > Curr_Edge) && (((Max - phase) / Max) > limit)
9. Различия обработки Ignor
Balsam 165
Используется правильный абсолютный номер датчика:
sens = tpl_cans + chan;
ignor = sens_error[sens].bit.Ignor;
Ошибки Wry, Out и Hyper продолжают вычисляться и передаваться, но
Stop не устанавливается для игнорируемого канала.
Balsam 167
Проверяется относительный индекс:
sens = pow_addr + chan;
if (WAKE || sens_error[chan].bit.Ignor) goto fin;
Последствия различаются по типу устройства.
УМП
Для УМП pow_addr == 0, поэтому индекс формально совпадает. Каналам напряжения
0x00 и 0x01 по умолчанию устанавливается Ignor. В результате Balsam 167
полностью пропускает для напряжения:
Wry;OutприUtr < 300 В;HyperприUtr > 420 В;Stop.
В Balsam 165 эти информационные биты вычислялись, но Stop блокировался.
Силовой блок
На силовом блоке pow_addr != 0. Ignor устанавливается в
sens_error[pow_addr+chan], но проверяется sens_error[chan].
Из-за этого игнорирование может не сработать, а Wry + Stop сформироваться для
канала, который должен быть исключён из диагностики.
10. Регрессия sens_pair в Balsam 167
В Balsam 165 пары хранятся относительно chan:
sens_pair[0] = 1;
sens_pair[1] = 0;
sens_pair[2] = 3;
sens_pair[3] = 2;
pair = sens_pair[chan];
В Balsam 167 пары записываются по абсолютному индексу:
sens_pair[pow_addr+i] = pow_addr+(i^1);
Но чтение осталось старым:
pair = sens_pair[chan];
Для силового блока элементы sens_pair[0…3] после общей инициализации равны
0, 1, 2, 3. Следовательно, pair указывает на текущий канал, а не на
соседний.
Последствия:
- один фазный уровень может записываться дважды;
- максимальная фаза выбирается из неполного набора;
Wryможет быть пропущен или сформирован ошибочно;- карта
0x68…0x6Dдля силового блока не соответствует ожидаемой.
Вероятное исправление:
pair = sens_pair[sens] - pow_addr;
Окончательный вариант следует подтвердить стендовым тестом и ожидаемым порядком фаз в регистрах.
11. Пороговые уровни УМП
Заводские уставки в проектах совпадают:
| Сигнал | Нижний порог | Верхний порог |
|---|---|---|
Utr |
300 В | 420 В |
Itr |
800 А, предупреждение | 900 А, авария |
Различается обработка нижнего напряжения:
| Проект | Реакция Utr < 300 В |
|---|---|
| Balsam 165 | Out сразу; Stop блокируется при штатном Ignor |
| Balsam 167 | счётчик около 3 с, но при штатном Ignor проверка не выполняется |
Верхний порог Utr > 420 В в обеих версиях не имеет отдельной выдержки и
гистерезиса.
12. Диагностические биты
Расположение основных битов не изменилось:
| Бит | Маска | Имя | Назначение |
|---|---|---|---|
| 0 | 0x0001 |
Tear |
обрыв датчика/предельное значение АЦП |
| 2 | 0x0004 |
Wry |
перекос фаз |
| 3 | 0x0008 |
Out |
ниже нижнего порога |
| 4 | 0x0010 |
Over |
выше предупредительного порога |
| 5 | 0x0020 |
Hyper |
выше аварийного порога |
| 8 | 0x0100 |
Stop |
авария |
| 9 | 0x0200 |
Ready |
готовность |
| 14 | 0x4000 |
Ignor |
игнорировать аварию |
| 15 | 0x8000 |
Bypas |
отключить канал |
В обеих версиях Current_count() не формирует Tear для фазных входов U/I.
Поэтому неисправность измерительного тракта нельзя надёжно отличить от
пропадания напряжения или тока.
13. Что следует перенести из Balsam 165
В Balsam 167 полезно вернуть следующие свойства реализации 165:
- Согласованную систему индексов
sens_pair. - Проверку
Ignorчерез абсолютный индексsens_error[sens]. - Использование
floatдля внутренних фазных уровней до момента публикации.
Не следует возвращать:
- усреднение
fabs()вместо RMS; - общий статический фильтр
ffLev; - немедленное срабатывание нижнего напряжения;
- жёсткие коэффициенты
curK[].
14. Рекомендуемая итоговая реализация
-
Считать все абсолютные номера датчиков один раз:
sens = pow_addr + chan; -
Хранить
sens_pair[]либо полностью в относительных, либо полностью в абсолютных индексах. Не смешивать системы адресации. -
Сохранить RMS Balsam 167, но хранить
lev_count[]какfloat. -
После поступления обоих отсчётов пары вычислять A, C и B в одном месте.
-
Один раз за цикл обновлять три RMS и три диагностических счётчика.
-
Проверять
Max > Curr_Edgeдо деления. -
Проверять
Ignorчерезsens_error[sens]. -
Разделить понятия:
- информационная ошибка присутствует;
- ошибка участвует в формировании
Stop.
-
Добавить отдельную маску фаз A/B/C.
-
Добавить
Tearпо сырому значению АЦП. -
Добавить выдержку и гистерезис для 300/420 В.
-
Явно определить, должна ли подстройка нуля работать после запуска.
15. Минимальные сравнительные тесты
| Тест | Что проверить |
|---|---|
| Одинаковая синусоида на обеих версиях | Разницу MeanAbs и RMS около 11,1% |
| Номинальные A и C | Правильный порядок A/C/B в 0x68…0x6D |
| Обрыв A | RMS A, Wry, выдержку |
| Обрыв C | RMS C, Wry, выдержку |
| Нарушение вычисленной B | Отсутствие двойной скорости счётчика |
| Перекос 20%, 25%, 30%, 35% | Различия порогов 165 и 167 |
Max == 0 |
Отсутствие деления на ноль |
Utr = 299 В |
Out и выдержку |
Utr = 421 В |
Hyper и отсутствие дребезга |
Ignor = 1 |
Ошибка видна, но не создаёт Stop, если это требуемая семантика |
| Силовой блок, две пары | Отсутствие дублирования фазных RMS |
| АЦП около 0 и 4095 | Формирование Tear |
Заключение
Фазовый расчёт Balsam 167 является хорошей основой благодаря настоящему RMS, раздельным фильтрам и калибровке из регистров. Главный риск версии 167 находится не в математике RMS, а в адресации состояния каналов.
До исправления sens_pair и Ignor фазные регистры и Wry силового блока
нельзя считать надёжными. Для УМП необходимо отдельно решить, должны ли
напряжения с установленным Ignor продолжать формировать информационные
Wry, Out и Hyper, как это происходило в Balsam 165.