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?
Примечание. После некоторого устранения неполадок я обнаружил, что delay() усугубляет проблему. И не будет получать поток байтов, первый байт и второй полубайт которого имеют значение F, например F2, F4, как в таблице данных, первые четыре бита по умолчанию равны 1.
@Khaalidi, 👍1
Обсуждение1 ответ
Лучший ответ:
Прежде всего я поменял местами UART0 на GPIO15 (TX) и GPIO13 (RX) (к счастью, Tx HLW8032 подключен к GPIO13 в моей конструкции оборудования, а после замены это вывод UART0 RX). Затем я проанализировал поступающие данные, и результаты оказались такими же, как и у этого SoftwareSerial, т.е. переполнение регистров.
Затем я использовал библиотеку HLW8032 (которую я развил и внес изменения для улучшения), которая работает только на HardwareSerial, и значения идеальные. То, как библиотека читает Serial, совершенно другое.
Итак, моя проблема была решена с помощью двух вещей:
- Я заменил UART0 на GPIO15 и GPIO13 с помощью
Serial.swap()
- Использована библиотека для 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), но, по крайней мере, без каких-либо изменений в оборудовании, моя конструкция работает нормально.
- AT-команда не отвечает на последовательный монитор
- Как связаться с ESP8266 ESP01, отправив данные через программный сериал на Arduino Uno?
- Последовательная связь от Arduino до ESP8266 NodeMCU работает, но от NodeMCU до Arduino не работает
- SIM800L не отвечает на AT-команды
- Проблема последовательной связи с общей землей SIM800L
- Повреждение данных SoftwareSerial - поиск предложений
- Модули HC-12 перестали принимать, не могу понять почему
- Можно ли использовать SoftwareSerial в ESP01
Возможно, данные отправляются слишком быстро (каждый байт слишком близко друг к другу), чтобы 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