ESP8266 Интеллектуальная розетка WiFi IoT — измерение энергии
ESP8266 Интеллектуальная розетка WiFi IoT — измерение энергии

Основное внимание при проектировании оборудования интеллектуальных розеток WiFi IoT уделяется измерению мощности. По этой причине я напишу отдельный пост в блоге, чтобы объяснить схему проектирования и принцип реализации измерения мощности.

Для измерения мощности был выбран чип BL0942 компании Shanghai Belling. Основные причины: простая конструкция аппаратного решения, хорошая точность измерения и отсутствие необходимости в калибровке, низкая цена и простой метод программного драйвера.

1. Функция чипа

BL0942 может измерять такие параметры, как ток, эффективное значение напряжения, активная мощность, активная электрическая энергия и т. д. Он может выводить эффективное значение быстрого тока (для защиты от перегрузки по току), а также выходной сигнал и другие функции. Могут быть периферийные компоненты. калибруются, если они соответствуют определенным условиям. Конечно, калибровка BL0942 также поддерживается.

Характеристики чипа следующие:

  • Два независимых сигма-дельта АЦП, один по току, другой по напряжению. 
  • Диапазон эффективных значений тока (10 м А~30 А) при 1 МОм.
  • Активная электрическая энергия (1 Вт~6600 Вт) при 1 МОм при 220 В.
  • Он может выводить эффективные значения тока и напряжения, эффективные значения быстрого тока и активную мощность. 
  • Заводская погрешность усиления партии составляет менее 1%, а периферийные компоненты могут быть освобождены от калибровки, если они соответствуют определенным условиям. 
  • Канал тока имеет функцию контроля перегрузки по току, при этом можно установить порог контроля и время отклика. 
  • Выходной сигнал перехода напряжения/тока через ноль. 
  • встроенный регистр формы сигнала, который может выводить данные формы сигнала для анализа типа нагрузки. 
  • Метод связи SPI (самая высокая скорость поддерживает 900 к Гц)/UART (4800–38400 бит/с) (пакет TSSOP14L поддерживает до 4-х чипов каскадной связи UART). 
  • Мониторинг сбоя питания, ниже 2.7V Когда чип переходит в состояние сброса. 
  • Встроенный источник опорного напряжения 1,218 В.
  • Встроенный колебательный контур, тактовая частота составляет около 4 МГц.
  • чип Один рабочий источник питания 3,3 В, низкое энергопотребление 10 м Вт (тип.) 。
  • Пакет SSOP10L/TSSOP14L.

В этом проекте используется пакет SSOP10L и драйвер UART.

2. Показатели эффективности

3. Описание регистра

Этот проект считывает или устанавливает регистр микросхемы BL0942 через шину UART. Описание регистра показано на рисунке ниже:

4. Протокол связи UART

Характеристики связи UART чипа BL0942 следующие:

  • Выбирается через вывод SEL, мультиплексируется с SPI, режим UART SEL=0.
  • чип работает в подчиненном режиме.
  • Полудуплексная связь, скорость передачи данных может быть настроена программно и аппаратно на 4800 бит/с, 9600 бит/с, 19200 бит/с, 38400 бит/с.
  • 8-bit передача данных, без проверочного бита, стоповый бит 1 。
  • поддерживатьданные Читать включено Выбирать。

Пакет TSSOP14L может поддерживать функцию выбора чипа устройства. Адресные контакты выбора аппаратного чипа — [A2_NCS, A1], а дополнительные устройства — 0–3. Он может поддерживать 4 штуки BL0942, подвешенных на шине UART для передачи данных, занимая только один интерфейс UART MCU.

В режиме связи UART сначала отправьте 8-битный идентификационный байт (0x58) или (0xA8), (0x58) — байт идентификации операции чтения, (0xA8) — байт идентификации операции записи, а затем отправьте байт адреса регистра для определения Доступ Адрес регистра (см. список регистров BL0942), один кадр передачи данных завершен, и BL0942 снова входит в режим связи.

4.1. Формат и время кадра операции записи.

Существует два типа структур кадров: кадры операций записи и кадры операций чтения.

Формат кадра операции записи следующий:

Время записи данных UART хоста показано на рисунке ниже. Хост сначала отправляет командный байт {1,0,1,0,1,0,A2,A1}, затем отправляет необходимый регистровый байт (ADDR). записываются, а затем последовательно отправляются байты данных (сначала младший байт, последним старший байт, если действительные байты данных меньше 3 байтов, недопустимые биты заполняются 0) и, наконец, байт контрольной суммы.

{1,0,1,0,1,0,A2,A1} — это байт идентификации кадра для операции записи. Предположим, {A2,A1}=10, адрес устройства 2, байт идентификации кадра равен 0xAA. 

ADDR — это внутренний адрес регистра BL0942, соответствующий операции записи. 

CHECKSUM байтдля({1,0,1,0,1,0,A2,A1}+ADDR+DATA[7:0]+DATA[15:8]+DATA[23:16])&0xFF Отрицать.

4.2. Чтение формата и времени кадра операции.

Формат кадра операции чтения следующий:

Время чтения данных UART хоста показано на рисунке ниже. Хост сначала отправляет командный байт {0,1,0,1,1,0,A2,A1}, затем отправляет необходимый байт адреса регистра (ADDR). быть прочитан, а затем BL0942 отправляет байты данных последовательно (сначала младший байт, последний старший байт, если действительные байты данных меньше 3 байтов, недопустимые биты заполняются 0) и, наконец, байт контрольной суммы. 

{0,1,0,1,1,0,A2,A1} — байт идентификации кадра для операции чтения. Предположим, что {A2,A1}=10, адрес устройства равен 2, а байт идентификации кадра — 0x5A. 

ADDR — это внутренний адрес регистра BL0942, соответствующий операции чтения. 

CHECKSUM байтдля({0,1,0,1,1,0,A2,A1}+ADDR+DATA[7:0]+DATA[15:8]+DATA[23:16])&0xFF Отрицать. 

Примечание. Адрес устройства пакета SSOP10L равен 0, то есть {A2,A1}=00.

Требования к времени показаны на рисунке ниже:

4.3. Прочтите полный пакет данных по электрическим параметрам.

Этот проект считывает параметры измерения электрической энергии BL0942, которые предназначены для чтения полного пакета данных электрических параметров.

С помощью команды «{0,1,0,1,1,0,A2,A1}+ 0xAA» BL0942 вернет полный пакет данных электрических параметров. Возвращенный пакет данных имеет общий размер 22 байта и занимает около 48 мс при использовании скорости 4800 бит/с. 

Формат пакета полностью электрических параметров следующий:

checksum=(({0,1,0,1,1,0,A2,A1} + 0x55 + data1_l + data1_m + data1_h +…….)& 0xff), а затем нажмите Отрицать.

4.4. Настройка скорости передачи данных.

Скорость передачи данных можно настроить с помощью регистра режима UART_RATE_SEL (MODE[9:8]) и вывода SCLK_BPS. Каждый раз, когда микросхема включается, значение сброса RATE_SEL равно 0x0. В это время скорость передачи данных определяется на основе вывода SCLK_BPS. 

4.5. Механизм защиты UART.

Чип BL0942 имеет некоторые встроенные механизмы защиты, а именно:

  • Сброс таймаута кадра, если интервал между байтами превышает 20мс, интерфейс UART сбрасывается. 
  • Ручной сброс, UART получает более 32 «0» подряд, и интерфейс UART сбрасывается. 
  • байт идентификации кадра или checksum Байтовая ошибка, кадр потерян. 
  • При обмене данными с несколькими чипами в режиме UART каждый отправленный кадр должен дождаться тайм-аута кадра или отправить ручной сброс перед отправкой следующего кадра. 

5. Описание функции

BL0942 в основном разделен на две части: аналоговая обработка сигналов и обработка цифровых сигналов. Аналоговая часть в основном включает в себя двухканальный PGA, двухканальный сигма-дельта АЦП, встроенные часы (внутренние часы), включение/сброс (включение питания). /reset), LDO и другие соответствующие аналоговые модули, цифровая часть — это модуль цифровой обработки сигналов (DSP).

5.1. Измерение переходных сигналов тока и напряжения.

Ток и напряжение пропускаются через аналоговый модуль усилителя (PGA) и высокоточное аналого-цифровое преобразование (АЦП) для получения двух каналов 1-битного ШИМ в цифровой модуль. Цифровой модуль проходит через понижающий преобразователь. фильтр выборки (SINC3), фильтр верхних частот (HPF), смещение канала. Настройте калибровку и другие модули для получения необходимых данных о форме сигнала тока и данных о форме сигнала напряжения (I_WAVE, V_WAVE). 

Собранные данные о форме тока и напряжения нагрузки обновляются со скоростью 7,8 тыс. Каждые выборочные данные представляют собой 20-битное число со знаком и сохраняются в регистре формы сигнала (I_WAVE, V_WAVE) соответственно. Конфигурация скорости SPI превышает 375 Кбит/с. значение формы сигнала одного канала можно считывать непрерывно.

Примечание. Регистр имеет длину 24 бита. Если цифр недостаточно, старшие биты заполняются нулями. 

5.2. Активная мощность.

Формула расчета активной мощности:

Среди них 𝐼(𝐴), 𝑉(𝑉) — эффективное значение (м В) входного сигнала канала, φ — фазовый угол сигнала переменного тока I(A), V(V), Vref — встроенный при опорном напряжении типичное значение составляет 1,218 В.

Этот регистр указывает, является ли текущая активная мощность положительной или отрицательной мощностью. Бит[23] — это знаковый бит. Бит[23]=0, текущая мощность положительная, Бит[23]=1, текущая мощность отрицательная. сила, дополнение формы. 

5.3. Активное силовое движение против скрытности.

BL0942 имеет запатентованную функцию защиты от подводных лодок, гарантирующую, что мощность шума на уровне платы не будет накапливать мощность при отсутствии входного тока. 

Регистр порогового значения противодействия постепенному увеличению активной мощности (WA_CREEP) представляет собой 8-битное беззнаковое число, значение по умолчанию — 0BH. Соответствующее соотношение между этим значением и значением регистра активной мощности показано в следующей формуле. Когда абсолютное значение входного сигнала активной мощности меньше этого значения, выходная активная мощность устанавливается на 0. Это позволяет в условиях холостого хода, даже при наличии небольшого шумового сигнала, значение, выводимое в регистр активной мощности, равно 0, и электрическая энергия не накапливается.

WA_CREEP может быть установлен в соответствии со значением регистра мощности WATT. Их соответствующее соотношение следующее:

Примечание. Когда текущий канал находится в противолодочном состоянии, действующее значение тока канала не измеряется и также обрезается до 0.

5.4. Измерение электрической энергии.

BL0942 обеспечивает измерение импульса электрической энергии. Активная мгновенная мощность интегрируется в зависимости от времени для получения активной энергии и дальнейшего вывода калибровочного импульса CF. Регистр CF_CNT хранит количество импульсов выходной мощности CF, как показано на рисунке ниже:

Потребляемая мощность может быть считана непосредственно из регистра подсчета импульсов активной энергии CF_CNT, или количество импульсов может быть подсчитано напрямую с вывода CF1/CF2/ZX с помощью прерывания ввода-вывода после настройки регистра OT_FUNX, когда период CF. меньше 160 мс, импульс с рабочим циклом 50 %, если длительность больше или равна 160 мс, фиксированная длительность импульса высокого уровня составляет 80 мс. 

CF_EN — главный переключатель для вывода импульсов энергии. После выключения CF_CNT прекращает подсчет, а вывод CF1/CF2/ZX прекращает выводить подсчет импульсов энергии. 

Вы можете использовать регистр CF_CNT_CLR_SEL, чтобы выбрать, следует ли очищать регистр счетчика CF (CF_CNT) после чтения. Режим накопления энергии импульса можно выбрать через CF_CNT_ADD_SEL. 

Примечание. Регистр CF_CNT по умолчанию настроен на режим накопления абсолютного значения импульсов энергии. 

Время накопления каждого импульса CF следующее:

Где WATT — соответствующее значение регистра активной мощности (WATT).

5.5. Действующее значение тока и напряжения.

Действующие значения каналов тока и напряжения показаны на рисунке ниже. После прохождения через квадратную цепь (X 2), фильтр нижних частот (LPF_RMS) и корневую цепь (ROOT) мгновенное значение. получают эффективное значение RMS_t, а затем получают среднее значение для двух каналов (I_RMS и V_RMS). 

Установите MODE[3].RMS_UPDAT_SEL, вы можете выбрать среднее время обновления эффективного значения 400 мс или 800 мс, значение по умолчанию — 400 мс. 

Когда канал находится в противолодочном состоянии, эффективное значение текущего канала равно нулю. 

Формула преобразования текущей эффективной стоимости:

Формула преобразования действующего значения напряжения:

𝑉𝑟𝑒𝑓 — опорное напряжение, типичное значение — 1,218 В. 

Примечание. I(A) — это входной сигнал (м В) между контактами IP и IN, а V(V) — входной сигнал (м В) контакта VP.

5.6. Обнаружение перегрузки по току.

BL0942 может быстро собирать эффективное значение тока для реализации функции обнаружения перегрузки по току. I_WAVE_F принимает абсолютное значение, накапливает полупериод или время цикла и сохраняет его в регистре I_FAST_RMS. Оно сравнивается с текущим пороговым регистром быстрого эффективного значения I_FAST_RMS_TH, а затем выдает прерывание по току через вывод.

Установите порог быстрого эффективного значения (т. е. порог сверхтока) через регистр порогового значения быстрого эффективного значения I_FAST_RMS_TH. 

Сравните бит[23:8] регистра I_FAST_RMS с порогом перегрузки по току I_FAST_RMS_TH [15:0]. Если он больше или равен установленному порогу, на выводе индикации сигнала перегрузки по току CF1/CF2/ZX выводится высокий уровень. CF1/CF2/ZX устанавливаются регистром конфигурации выхода OT_FUNX. 

Установите цикл быстрого обновления RMS через регистр цикла быстрого обновления RMS I_FAST_RMS_CYC. Среди них частота может быть выбрана как 50H или 60Гц в соответствии с настройкой MODE[5]. Если вы выберете 50 Гц, время обновления по умолчанию составит 1 цикл, то есть 20 мс. Например, при выборе самого быстрого накопления за 0,5 такта ошибка регистра I_FAST_RMS будет относительно большой. 

Следует отметить, что алгоритмы быстрого эффективного значения и эффективного значения различны. Быстрое эффективное значение используется только для оценки больших сигналов. Быстрые измерения среднеквадратичного значения при слабых сигналах будут неточными из-за включения компонентов смещения постоянного тока. Если вам нужно удалить компонент смещения постоянного тока, установите FAST_RMS_SEL(MODE[4])=1 и выберите форму сигнала после HPF для I_WAVE_F. 

Установите частоту переменного тока с помощью MODE[5]. 

5.7. Обнаружение перехода через нуль.

BL0942 обеспечивает обнаружение перехода напряжения и тока через нуль. Сигнал перехода через ноль может выводиться через вывод CF1/CF2/ZX. Ноль на выходе соответствует положительному полупериоду сигнала, а вывод 1 представляет отрицательную половину. цикл формы волны. Задержка фактического входного сигнала составляет 570 мкс.

Настройте выходной контакт через OT_ FUNX (пакет SSOP10L имеет только CF1).

Если эффективное значение напряжения или тока слишком низкое, выходной сигнал обнаружения перехода через ноль будет нестабильным. 

Когда старшие 5 бит действующего значения напряжения V_RMS равны 0, V_ZX_LTH_F равен 1, что указывает на то, что эффективное значение напряжения слишком низкое, менее 1/32 полной шкалы, и индикация перехода напряжения через ноль отключается. и остается 0. 

Когда старшие 6 бит текущего эффективного значения I_RMS равны 0, I_ZX_LTH_F равен 1, что указывает на то, что текущее эффективное значение слишком низкое, менее 1/64 полной шкалы, и текущая индикация перехода через нуль отключается. и остается на уровне 0.

5.8. Обнаружение частоты сетевого напряжения.

BL0942 имеет функцию определения частоты сетевого напряжения, которая обновляется каждые несколько установленных циклов (FREQ_CYC), и обнаруживается полноволновая форма волны напряжения. 

Разрешение измерения линейного напряжения составляет 2 мкс/младший бит (тактовая частота 500 к Гц), что эквивалентно 0,01% при частоте сети 50 Гц или 0,012% при частоте сети 60 Гц. Соотношение преобразования между регистром сетевого напряжения (FREQ) и фактической частотой сетевого напряжения:

В режиме по умолчанию fs=500 к Гц; для сети с частотой 50 Гц измеренное значение FREQ составляет 20000 (десятичное число), а для сети с частотой 60 Гц измеренное значение FREQ составляет 16667 (десятичное число). 

Кроме того, когда эффективное значение напряжения ниже порога определения перехода через ноль, обнаружение частоты сетевого напряжения отключается.

6. Схема применения

7. Водитель

Используйте Arduino IDE для управления ESP8266 для периодического чтения полного пакета данных электрических параметров. Исходный файл выглядит следующим образом:

Язык кода:javascript
копировать
/******************************************************************************
 *
 * File Name : bl0942.cpp
 *
 * Functional Description:
 * файл библиотеки драйверов bl0942
 *
 * Change Logs:
 * Date         Author         Notes        explain
 * 2022-12-6    yangjunjie      V1.0         
 *
*******************************************************************************/

/******************************************************************************
 * Include files
 ******************************************************************************/
#include "bl0942.h"

/******************************************************************************
 * Global variable definitions
 ******************************************************************************/
static char serial_data[SERIAL_RX_MAXLEN];

// Последовательный порт получает дескриптор очереди данных 
extern struct tk_queue serial_receive_dataqueue;

// Этот параметр еще не используется и может использоваться в качестве вторичного калибровочного устройства.
static float adjust_volrate = 1;
static float adjust_currentrate = 1;
static float adjust_powerrate = 1;

/******************************************************************************
 * Local type definitions ('typedef')
 ******************************************************************************/
static void sendCommand(void);
static status_t receiveData(void);

/******************************************************************************
 * function realize
 ******************************************************************************/

 /**
 ******************************************************************************
 ** \brief  Инициализируйте чип BL0942.
 **
 ** \param  никто
 **
 ** \retval никто
 **
 ******************************************************************************/
void Init_BL0942(void)
{
  Serial.begin(4800, SERIAL_8N1);  // 4800bps никто не проверит
  Serial.setTimeout(30);           // настройки Таймаут последовательного порта на 30мс

  memset(serial_data, 0, SERIAL_RX_MAXLEN);  
}

 /**
 ******************************************************************************
 ** \brief  Обновляется раз в секунду, считывается последовательно (напряжение, ток, мощность)
 **
 ** \param  никто
 **
 ** \retval никто
 **
 ******************************************************************************/
void Updata_BL0942(void)
{
  sendCommand();  // Отправить команду
  receiveData();  // Обработка данных приема последовательного порта
}

 /**
 ******************************************************************************
 ** \brief  последовательный порт Отправить командуполучать Выбирать Электрический женьшеньданные
 **
 ** \param  никто
 **
 ** \retval никто
 **
 ******************************************************************************/
static void sendCommand(void)
{
    Serial.write((byte)0X58);
    Serial.write((byte)0XAA);
}

 /**
 ******************************************************************************
 ** \brief  Получайте и анализируйте инструкции электрических параметров, полученные через последовательный порт.
 **
 ** \param  никто
 **
 ** \retval STATUS_SUCCESS:данные校验成功 STATUS_ERROR: проверка данных не удалась.
 **
 ******************************************************************************/
static status_t receiveData(void)
{
	status_t ret = STATUS_SUCCESS;
	bool temp_flag = false, receive_flag = false;
	char temp_data = 0X00;
	uint8_t data_index = 0X00;
	uint8_t checksum = 0X58;
	char temp_serial_data[SERIAL_RX_MAXLEN];
   
	while(Serial.available()) 
	{
		temp_data = (char)Serial.read();

		if(temp_data == 0X55)  // Определить заголовок кадра
		{
			temp_flag = true;
		}

		if(temp_flag == true)
		{
		  temp_serial_data[data_index++] = temp_data;
		}

		if (data_index >= SERIAL_RX_MAXLEN)
		{
		  // tk_queue_push_multi(&serial_receive_dataqueue, temp_serial_data, SERIAL_RX_MAXLEN);  // Загрузить длину данных в кеш
		  
		  data_index = 0;
		  temp_flag = false;
		  receive_flag = true;
		  // memset(temp_serial_data, 0, SERIAL_RX_MAXLEN);  
		}
		else
		{
			receive_flag = false;
		}
	}

	// Прием прерываний не используется, режим кэширования временно не используется, эта функция зарезервирована.
	// if(tk_queue_empty(&serial_receive_dataqueue) == false)  // В кэше есть данные
	// {
		// tk_queue_pop_multi(&serial_receive_dataqueue, temp_serial_data, SERIAL_RX_MAXLEN);  // Получить извлеченные из кэша
	
	if(receive_flag == true)
	{
		for(uint8_t i = 0; i < SERIAL_RX_MAXLEN - 1; i++)  // 校验данные
		{
			checksum += temp_serial_data[i];
		}
		
		checksum = ~(checksum & 0XFF);
		
		if(checksum == temp_serial_data[SERIAL_RX_MAXLEN - 1])
		{
			memcpy(serial_data, temp_serial_data, SERIAL_RX_MAXLEN);

			Log.verboseln("serial receive OK");
		}
		else
		{
			Log.errorln("serial receive ERROR");

			ret = STATUS_ERROR;
		}
	}

    return ret;
}

 /**
 ******************************************************************************
 ** \brief  получать Выбиратьтекущий **
 ** \param  никто
 **
 ** \retval текущийданные **
 ******************************************************************************/
float getCurrent(void)
{
    uint32_t parm = 0;
	  float current = 0.0;
	
    parm = ((uint32_t)serial_data[3] << 16) + ((uint32_t)serial_data[2] << 8) + serial_data[1];
    current = (float)parm * V_REF * adjust_currentrate * 1000 / (305978 * RL_CURRENT);  // mA

    return current;
}

 /**
 ******************************************************************************
 ** \brief  Получить Выбирать напряжение
 **
 ** \param  никто
 **
 ** \retval Напряжениеданные **
 ******************************************************************************/
float getVoltage(void)
{
    uint32_t parm = 0;
	  float voltage = 0.0;
	
    parm = ((uint32_t)serial_data[6] << 16) + ((uint32_t)serial_data[5] << 8) + serial_data[4];
    voltage = (float)parm * V_REF * (R2_VOLTAGE + R1_VOLTAGE) * adjust_volrate / (73989 * R1_VOLTAGE * 1000);

    return voltage;
}

 /**
 ******************************************************************************
 ** \brief  Обнаружение перегрузки по току, быстро собирает эффективное значение тока для реализации функции обнаружения перегрузки по току.
 **
 ** \param  никто
 **
 ** \retval Текущие быстрые эффективные значения
 **
 ******************************************************************************/
float getFastCurrent(void)
{
    uint32_t parm = 0;
    parm = ((uint32_t)serial_data[9] << 16) + ((uint32_t)serial_data[8] << 8) + serial_data[7];
    float fcurrent = (float)parm * V_REF * adjust_currentrate * 1000 / (305978 * RL_CURRENT); // mA

    return fcurrent;
}

 /**
 ******************************************************************************
 ** \brief  Усиление Выбирать активную мощность
 **
 ** \param  никто
 **
 ** \retval Активная мощностьданные
 **
 ******************************************************************************/
float getActivePower(void)
{
    uint32_t parm = 0;
	  float power = 0.0;
	
    parm = ((uint32_t)serial_data[12] << 16) + ((uint32_t)serial_data[11] << 8) + serial_data[10];

    if (1 == bitRead(serial_data[12], 7))
    {
        parm = 0xFFFFFF - parm + 1;  // Выбирать补码    }
	
    power = (float)parm * adjust_powerrate * V_REF * V_REF * (R2_VOLTAGE + R1_VOLTAGE) / (3537 * RL_CURRENT * R1_VOLTAGE * 1000);

    return power;
}

 /**
 ******************************************************************************
 ** \brief  Получить Выбирать потребление электроэнергии
 **
 ** \param  никто
 **
 ** \retval Потребление электроэнергииданные
 **
 ******************************************************************************/
float getEnergy(void)
{
    uint32_t parm = 0;
	  float energy = 0.0;
	
    parm = ((uint32_t)serial_data[15] << 16) + ((uint32_t)serial_data[14] << 8) + serial_data[13];
    energy = (float)parm * 1638.4 * 256 * V_REF * V_REF * (R2_VOLTAGE + R1_VOLTAGE) / (3600000.0 * 3537 * RL_CURRENT * R1_VOLTAGE * 1000);

    return energy;
}

 /**
 ******************************************************************************
 ** \brief  Функция определения частоты линейного напряжения
 **
 ** \param  никто
 **
 ** \retval Частота сетевого напряженияданные
 **
 ******************************************************************************/
float getFREQ(void)
{
    uint32_t parm = 0;
	  float FREQ = 0.0;
	
    parm = ((uint32_t)serial_data[18] << 16) + ((uint32_t)serial_data[17] << 8) + serial_data[16];
    
    if (parm > 0)
    {
        FREQ = 500 * 1000 * 2 / (float)parm;
    }

    return FREQ;
}

 /**
 ******************************************************************************
 ** \brief  рабочий статус
 **
 ** \param  никто
 **
 ** \retval рабочий статусданные
 **
 ******************************************************************************/
uint8_t getSTATUS(void)
{
    return (uint8_t)serial_data[19];
}

/******************************************************************************/
/* EOF (not truncated)                                                        */
/******************************************************************************/

Заголовочный файл выглядит следующим образом:

Язык кода:javascript
копировать
/******************************************************************************
 *
 * File Name : bl0942.h
 *
 * Functional Description:
 * файл библиотеки драйверов bl0942
 *
 * Change Logs:
 * Date         Author         Notes        explain
 * 2022-12-6    yangjunjie      V1.0         
 *
*******************************************************************************/

#ifndef __BL0942_H__
#define __BL0942_H__

/******************************************************************************/
/* Include files                                                              */
/******************************************************************************/
#include <Arduino.h>
#include "tk_queue.h"

/* C binding of definitions if building with C++ compiler */
#ifdef __cplusplus
extern "C"
{
#endif
 
//@{

/******************************************************************************
 * Local pre-processor symbols/macros ('#define')
 ******************************************************************************/
#define V_REF 1.218
#define RL_CURRENT 1     // 0,001 Ом, единица миллиом
#define R2_VOLTAGE 1950  // 390К*5, ед. для К Евро
#define R1_VOLTAGE 0.51  // 0,51К, ед. для тыс. евро

#define SERIAL_RX_MAXLEN 23

/******************************************************************************
 ** Local type definitions ('typedef')
 ******************************************************************************/

/******************************************************************************
 * Global variable definitions ('extern')
 ******************************************************************************/
// Определить, пуста ли очередь 
extern bool tk_queue_empty(struct tk_queue *queue);

// Поместите (поставьте в очередь) несколько элементов в очередь данных.
extern uint16_t tk_queue_push_multi(struct tk_queue *queue, char *pval, uint16_t len);

// Извлечь (удалить из очереди) несколько элементов из очереди данных
extern uint16_t tk_queue_pop_multi(struct tk_queue *queue, char *pval, uint16_t len);

/*****************************************************************************
 * Function definitions - global ('extern') and local ('static')
 ******************************************************************************/
// Инициализируйте чип BL0942.
void Init_BL0942(void);

// Обновляется раз в секунду, считывается последовательно (напряжение, ток, мощность)
void Updata_BL0942(void);

// получать Выбиратьтекущийfloat getCurrent(void);

// Получить Выбирать напряжение
float getVoltage(void);

// Обнаружение перегрузки по току, быстро собирает эффективное значение тока для реализации функции обнаружения перегрузки по току.
float getFastCurrent(void);

// Усиление Выбирать активную мощность
float getActivePower(void);

// Получить Выбирать потребление электроэнергии
float getEnergy(void);

// Функция определения частоты линейного напряжения
float getFREQ(void);

// рабочий статус
uint8_t getSTATUS(void);

//@}
#ifdef __cplusplus
}
#endif

#endif /* __BL0942_H__ */

/******************************************************************************/
/* EOF (not truncated)                                                        */
/******************************************************************************/

8. Альтернативы

Компания Shanghai Belling также предоставляет микросхему измерения мощности, требующую калибровки: BL0937.

При определении продукта BL0937 учитывает, что производители интеллектуальных розеток не являются профессиональными производителями измерительных приборов, не имеют профессионального и дорогостоящего калибровочного оборудования и имеют относительно низкие требования к точности измерения электрической энергии. Они предоставляют только справочную информацию об электричестве, но не предоставляют ее. используйте его в качестве стандарта выставления счетов. Интеллектуальной розетке необходимо только считывать мощность, напряжение, ток и измерять накопленную мощность на основе мощности. Поэтому нет необходимости в сложном протоколе связи между BL0937 и MCU для считывания регистра измерительного чипа в режиме реального времени. Калибровка точности дозирования также относительно проста, достаточно установить номинальную мощность. Калибровочный коэффициент калибруется под нагрузкой и не требует сложного калибровочного оборудования. 

Схема применения решения BL0937 выглядит следующим образом и после реальных испытаний она стабильна и надежна:

Заинтересованные друзья могут изучить это решение. Поскольку оно не используется в этом проекте, я не буду вдаваться в подробности.

boy illustration
Неразрушающее увеличение изображений одним щелчком мыши, чтобы сделать их более четкими артефактами искусственного интеллекта, включая руководства по установке и использованию.
boy illustration
Копикодер: этот инструмент отлично работает с Cursor, Bolt и V0! Предоставьте более качественные подсказки для разработки интерфейса (создание навигационного веб-сайта с использованием искусственного интеллекта).
boy illustration
Новый бесплатный RooCline превосходит Cline v3.1? ! Быстрее, умнее и лучше вилка Cline! (Независимое программирование AI, порог 0)
boy illustration
Разработав более 10 проектов с помощью Cursor, я собрал 10 примеров и 60 подсказок.
boy illustration
Я потратил 72 часа на изучение курсорных агентов, и вот неоспоримые факты, которыми я должен поделиться!
boy illustration
Идеальная интеграция Cursor и DeepSeek API
boy illustration
DeepSeek V3 снижает затраты на обучение больших моделей
boy illustration
Артефакт, увеличивающий количество очков: на основе улучшения характеристик препятствия малым целям Yolov8 (SEAM, MultiSEAM).
boy illustration
DeepSeek V3 раскручивался уже три дня. Сегодня я попробовал самопровозглашенную модель «ChatGPT».
boy illustration
Open Devin — инженер-программист искусственного интеллекта с открытым исходным кодом, который меньше программирует и больше создает.
boy illustration
Эксклюзивное оригинальное улучшение YOLOv8: собственная разработка SPPF | SPPF сочетается с воспринимаемой большой сверткой ядра UniRepLK, а свертка с большим ядром + без расширения улучшает восприимчивое поле
boy illustration
Популярное и подробное объяснение DeepSeek-V3: от его появления до преимуществ и сравнения с GPT-4o.
boy illustration
9 основных словесных инструкций по доработке академических работ с помощью ChatGPT, эффективных и практичных, которые стоит собрать
boy illustration
Вызовите deepseek в vscode для реализации программирования с помощью искусственного интеллекта.
boy illustration
Познакомьтесь с принципами сверточных нейронных сетей (CNN) в одной статье (суперподробно)
boy illustration
50,3 тыс. звезд! Immich: автономное решение для резервного копирования фотографий и видео, которое экономит деньги и избавляет от беспокойства.
boy illustration
Cloud Native|Практика: установка Dashbaord для K8s, графика неплохая
boy illustration
Краткий обзор статьи — использование синтетических данных при обучении больших моделей и оптимизации производительности
boy illustration
MiniPerplx: новая поисковая система искусственного интеллекта с открытым исходным кодом, спонсируемая xAI и Vercel.
boy illustration
Конструкция сервиса Synology Drive сочетает проникновение в интрасеть и синхронизацию папок заметок Obsidian в облаке.
boy illustration
Центр конфигурации————Накос
boy illustration
Начинаем с нуля при разработке в облаке Copilot: начать разработку с минимальным использованием кода стало проще
boy illustration
[Серия Docker] Docker создает мультиплатформенные образы: практика архитектуры Arm64
boy illustration
Обновление новых возможностей coze | Я использовал coze для создания апплета помощника по исправлению домашних заданий по математике
boy illustration
Советы по развертыванию Nginx: практическое создание статических веб-сайтов на облачных серверах
boy illustration
Feiniu fnos использует Docker для развертывания личного блокнота Notepad
boy illustration
Сверточная нейронная сеть VGG реализует классификацию изображений Cifar10 — практический опыт Pytorch
boy illustration
Начало работы с EdgeonePages — новым недорогим решением для хостинга веб-сайтов
boy illustration
[Зона легкого облачного игрового сервера] Управление игровыми архивами
boy illustration
Развертывание SpringCloud-проекта на базе Docker и Docker-Compose