HLW8032 UART отправляет случайные данные (регистры часто переполняются)

Я разработал собственную версию смарт-розетки, аналогичную Sonoff, с микросхемой измерения мощности HLW8032. И когда я читаю данные в ESP-12F, данные не имеют фиксированного формата. Чтобы устранить эту проблему, я купил разветвительную плату HLW8032. и проанализировал данные, отправленные HLW8032, и обнаружил, что результаты такие же, как и у платы, которую я разработал.

И это навело меня на мысль, что я могу неправильно читать данные из последовательного порта.

HLW8032 отправляет 24 байта по последовательному порту, и формат должен быть таким:

F2 5A 02 DA 78 07 1A E0 00 3D 3B 03 EC F5 4C C4 58 9C 2A 39 61 00 00 79 
F2 5A 02 DA 78 07 1A E0 00 3D 3B 03 EC F5 4C C4 58 9D C2 9F 61 00 00 78

Данные, которые я получаю, имеют этот формат,

F2 5A 2 D3 70 6 BC D4 0 3D 4F 4 98 B4 4D F2 5A 2 D3 70 6 AA 59 0 
3D 4F 4 98 B4 4D E1 80 FB EC 17 61 0 1 38 0 3D 4F 4 98 B4 4D E1 80 
FD 84 7D 61 0 1 38 F2 5A 2 D3 70 6 AA 59 F2 5A 2 D3 70 6 AA 59 0 
3D 4F 4 98 B4 4D E1 80 FE FF 1 61 0 1 38 2 D3 70 6 AA 59 0 3D 4F 
4 98 B4 4D E1 80 FE FF 1 61 0 1 38 F2 5A 1 61 0 1 38 F2 5A 2 D3 
70 6 AA 59 0 3D 4F 4 98 B4 4D E1 80 FE FF F2 5A 2 D3 70 6 AA 59 0 
3D 4F 4 98 B4 4D E1 80 FE FF 1 61 0 1 38 0 3D 4F 4 98 B4 4D E1 80 
FE FF 1 61 0 1 38 F2 5A 2 D3 70 6 AA 59 38 F2 5A 2 D3 70 6 AA 59 
0 3D 4F 4 98 B4 4D E1 80 FE FF 1 61 0 1 F2 5A 2 D3 70 6 AA 59 0 
3D 4F 4 98 B4 4D E1 80 FE FF 1 61 0 1 38 4F 4 98 B4 4D E1 80 10 1B 
D4 61 0 1 39 F2 5A 2 D3 70 6 AA 59 0 3D F2 5A 2 D3 70 6 AA 59 0 
3D 4F 4 98 B4 4D E1 80 13 4E 9E 61 0 1 39 F2 5A 2 D3 70 6 AA 59 0 
3D 4F 4 98 B4 4D E1 80 14 E8 3 61 0 1 39 E1 80 16 82 67 61 0 1 39 
F2 5A 2 D3 70 6 AA 59 0 3D 4F 4 98 B4 4D F2 5A 2 D3 70 6 AA 59 0  

Мы видим, что регистры снова и снова переполняются. Код, который я использую для чтения данных:

#include <SoftwareSerial.h>
#define BAUD_RATE 4800

SoftwareSerial swSer(13, 12);

void setup() 
{
  Serial.begin(BAUD_RATE);
  swSer.begin(BAUD_RATE);
}

byte data[24];
void loop() 
{
  if (swSer.available() > 0) {
    int a = swSer.readBytes(data, 24);
    yield();
  }

  // Отображать
  for (int i=0;i<24;i++)
  {
    Serial.print(data[i],HEX);
    Serial.print(" ");
  }
  Serial.println();
}

Схема:

Я чувствую, что проблема не в конструкции моего оборудования, а в скетче.


В чем может быть проблема с моей настройкой?


Как сделать вывод HLW8032 стабильным без переполнения регистров?


Есть ли какая-нибудь библиотека, которую кто-нибудь может порекомендовать мне для чтения данных из HLW8032 в SoftwareSerial?

Примечание. После некоторого устранения неполадок я обнаружил, что задержка() усугубляет проблему. И не будет получать поток байтов, первый байт и второй полубайт которого имеют значение F, например F2, F4, как в таблице данных, первые четыре бита по умолчанию равны 1.

, 👍1

Обсуждение

Возможно, данные отправляются слишком быстро (каждый байт слишком близко друг к другу), чтобы SoftwareSerial мог с этим справиться. Единственным решением было бы не использовать software serial, а использовать Arduino с ресурсами, необходимыми для правильного подключения устройства., @Majenko

@Majenko Да, но поскольку требуемая скорость передачи данных для HLW8032 составляет 4800 бит/с, а это довольно мало. Я искал лучшие альтернативы SoftwareSerial и обнаружил, что есть **AltSoftSerial**, и я читал, что кто-то сказал, что он лучше, чем SoftwareSerial, для более низкой скорости передачи данных. Я попробовал, и результат тот же. Поскольку я использую чип ESP8266, и у него есть только один HardwareSerial, я использую его для журналов отладки., @Khaalidi

ESP8266 имеет два аппаратных UART, а не один. Хотя вы можете обнаружить, что контакт RX не отображается на любой плате, которая у вас есть, или если он есть, он не помечен как таковой., @Majenko

Я бы никогда не рекомендовал использовать какую-либо форму SoftwareSerial. Если вы не можете сделать это аппаратно на выбранной вами плате/платформе, значит, вы используете не ту плату/платформу., @Majenko

Используйте объект Serial1 так же, как вы использовали бы объект Serial., @Majenko

ошибка: «Serial1» не был объявлен в этой области. (Платформа ИО), @Khaalidi

@Majenko, и из-за ограничений ESP8266 только UART 0 может получать данные., @Khaalidi

Ну, это [ругательство удалено], не так ли? Обновите до ESP32 тогда. Периферийных предложений ESP8266 всегда не хватало., @Majenko

какую версию пакета плат esp8266 вы используете? какие контакты вы используете для SoftwareSerial? какой у тебя модуль esp8266? Serial1 должен быть доступен. вам не нужно получать данные для отладочной печати, @Juraj

@Juraj Я не использую какую-либо плату (например, NodeMCU, Wesmos D1 и т. д.). Я использую свою собственную плату с модулем ESP-12F. Я использую GPIO13 и GPIO12 для SoftwareSerial. Serial1 недоступен. Мне нужны отладочные отпечатки, так как это первая версия платы, которую я разработал, и я должен отлаживать и все видеть., @Khaalidi

@Juraj Но для понимания и устранения проблемы я получил плату Arduino UNO и плату HLW8032 Breakout, и она дает тот же результат, что и моя плата. Я использовал SoftwareSerial для довольно многих приложений, даже получая данные через порт RS232, у меня никогда не было никаких проблем,, @Khaalidi

@Majenko SoC esp8266 имеет два аппаратных UART, UART 0 и UART 1. UART 1 не может принимать данные. Вот почему Serial1 не определен для плат на базе esp8266. Вот где я последую вашему совету и обновлюсь до ESP32., @Khaalidi

https://arduino-esp8266.readthedocs.io/en/latest/reference.html?highlight=serial1#serial, @Juraj

@Juraj Большое спасибо!! Это слишком исчерпывающая информация. Я попробовал и увидел результаты., @Khaalidi

@Majenko Это не проблема SoftwareSerial. Я протестировал HLW8032 на аппаратном серийном номере Arduino Mega, используя этот код, и результаты такие же, как и при переполнении регистров. Затем я использовал [библиотеку HLW8032](https://github.com/ocrobot/HLW8032), которая работает только на HardwareSerial, и значения идеальны. То, как библиотека читает Serial, совершенно другое. Меня раздражает, почему у меня возникают проблемы с использованием readBytes()., @Khaalidi


1 ответ


Лучший ответ:

2

Прежде всего я поменял местами UART0 на GPIO15 (TX) и GPIO13 (RX) (к счастью, Tx HLW8032 подключен к GPIO13 в моей конструкции оборудования, а после замены это вывод UART0 RX). Затем я проанализировал поступающие данные, и результаты оказались такими же, как и у этого SoftwareSerial, т.е. переполнение регистров.

Затем я использовал библиотеку HLW8032 (которую я развил и внес изменения для улучшения), которая работает только на HardwareSerial, и значения идеальные. То, как библиотека читает Serial, совершенно другое.

Итак, моя проблема была решена с помощью двух вещей:

  1. Я заменил UART0 на GPIO15 и GPIO13 с помощью Serial.swap()
  2. Использована библиотека для HLW8032

Благодарим @Juraj, предоставившего полезную информацию ссылка о Serial Swap в ESP8266.

Serial использует UART0, который сопоставляется с контактами GPIO1 (TX) и GPIO3 (RX). Serial можно переназначить на GPIO15 (TX) и GPIO13 (RX), вызвав Serial.swap() после Serial.begin. Повторный вызов swap сопоставляет UART0 обратно с GPIO1 и GPIO3.

#include "HLW8032.h"

HLW8032 HL;

void setup()
{
    HL.begin(Serial,4);   
    Serial.begin(4800);
    Serial.swap(); 
}

unsigned int V;
void loop()
{
    HL.SerialReadLoop();   

    if(HL.SerialRead == 1)   
    {
    V = HL.GetVol();
    }
}

С этим я не могу печатать и видеть свои отладочные отпечатки на GPIO1 (TX) и GPIO3 (RX), но, по крайней мере, без каких-либо изменений в оборудовании, моя конструкция работает нормально.

,