1

I designed my own version of smart socket just like the Sonoff with power metering chip HLW8032. And when I read the data in ESP-12F the data doesn't have a fixed format. To troubleshoot the issue, I bought HLW8032 Breakout Board and analyzed the data sent by HLW8032, and I found the results are the same as the board I designed.

And that made me think that I may be reading the data from the Serial port the wrong way.

HLW8032 sends 24 Bytes on the serial and the format should be like this:

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

The data that I receive is in this format,

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  

We can see that the registers overflows again and again. The code that I use to read the data is:

#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();
  }

  // Display
  for (int i=0;i<24;i++)
  {
    Serial.print(data[i],HEX);
    Serial.print(" ");
  }
  Serial.println();
}

Schematic: enter image description here

I feel that there is no issue in my hardware design, and the issue seems to be in the sketch.


What can be the possible problem with my setup?


How do I make the output of HLW8032 Stable with no overflow of registers?


Is there any library someone can recommend me to read the data from HLW8032 on SoftwareSerial?

Note: After some troubleshooting I found that delay() cause the problem to be more worse. And won't receive a stream of Bytes whose first byte , second nibble is F like F2, F4, as from the datasheet , first four bits are 1s by default.

  • It could be that the data is being sent too rapidly (each byte too close together) for SoftwareSerial to be able to cope with it. The only cure would be to not use software serial, but to use an Arduino with the resources you need to connect the device properly – Majenko Sep 13 '19 at 12:12
  • @Majenko Yes, But as the required Baud rate for HLW8032 is 4800bps, and that is quite low. I searched about better alternatives to SoftwareSerial, and found there is AltSoftSerial and I read someone said as to be better than SoftwareSerial for lower baud rates. I gave it a try and the result is the same. Since the chip I'm using is ESP8266 and it only have one HardwareSerial, and I'm using that for Debug logs. – Khaalidi Sep 13 '19 at 12:26
  • The ESP8266 has two hardware UARTs, not one. Although, you may find that the RX pin isn't exposed on whatever board you have - or if it is, it's not labelled as it. – Majenko Sep 13 '19 at 12:42
  • I would never recommend using any form of SoftwareSerial ever. If you can't do it in hardware on your chosen board / platform, then you are using the wrong board / platform. – Majenko Sep 13 '19 at 12:48
  • Use the Serial1 object in the same way that you would use the Serial object. – Majenko Sep 13 '19 at 12:57
2

First of all I swaped UART0 to GPIO15 (TX) and GPIO13 (RX), (Luckily the Tx of HLW8032 is connected to GPIO13 in my hardware design and This is the UART0 RX pin after swap). Then I analyzed the data coming and the results were the same as of that SoftwareSerial i.e the registers overflows.

Then I used an HLW8032 Library (Which I've forked and will make changes for improvements) which only works on HardwareSerial, and the values are perfect. The way the library reads Serial is quite different.

So in short my issue resolved using two things:

  1. I swaped UART0 to GPIO15 and GPIO13 using Serial.swap()
  2. Used a library for the HLW8032

Thanks to @Juraj who provided the useful link about Serial Swap in ESP8266.

Serial uses UART0, which is mapped to pins GPIO1 (TX) and GPIO3 (RX). Serial may be remapped to GPIO15 (TX) and GPIO13 (RX) by calling Serial.swap() after Serial.begin. Calling swap again maps UART0 back to GPIO1 and 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();
    }
}

With this I can't print and see my debug prints on GPIO1 (TX) and GPIO3 (RX), but at least without changing a bit in the hardware, my design works fine.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.