So you're a Noob? Post your questions here until you graduate! Don't be shy.

User avatar
By thales_liu1990
#79660 Hi, all,

I recently got stuck with ESP8266's serial communication with a power measure device, using ESP8266/Arduino platform. Everything seems to be so straightforward and yet nothing was received. I'd very much appreciate any help or advice. Here are some descriptions to my setup.

I have a small device (IM1281B module) measuring voltage, power, etc. It receives a certain command from the serial communication channel, and replies the measured results back, at a very low baudrate (4800).

To illustrate how it works, here are some codes using Python's serial module.
Code: Select all>>> from serial import Serial
>>> ser = Serial('/dev/ttyUSB0', 4800)
>>> b_command = b'\x01\x03\x00\x48\x00\x08\xc4\x1a'   # the command bytes
>>> ser.write(b_command)
8
>>> ser.read_all()
b'\x01\x03 \x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x04\xd8\x00\x00\x03\xe7\x00\x00\x04\xd4\x00\x00\x0c\xe4\x00\x00\x13\x88\xec\t'
>>> len(_)
37


As one can see, the command is a 8-byte array, translating to "{0x01, 0x03, 0x00, 0x48, 0x00, 0x08, 0xC4, 0x1A}" in C language. One sends this command to the device, and the device returns a bytes array of length 37. The response time is less than 1 sec.

With this information, I tried to implement this communication using ESP8266 on the Arduino platform. Here is my hardware setup(my devKit is a generic ESP8266 board):

1. ESP8266 is powered by a USB cable, connected to an adapter.
2. TX, RX GPIOs connected to the RX, TX of the devices. (defaults GPIOs for TX, RX, baudrate=4800).
3. GPIO2 connected to computer via a UART/USB converter. This is the Serial1 transmit-only channel, used for displaying debug information. baudrate=115200

The codes, shown below, are also pretty straightforward.
Code: Select alluint8_t command[8] = {0x01, 0x03, 0x00, 0x48, 0x00, 0x08, 0xC4, 0x1A};
void setup()
{
  delay(1000);
  Serial.begin(4800);
  Serial1.begin(115200);
  Serial1.println("\nReady to work!");
  delay(5000); // give enough time separation to the gibberish when chip starts working
}

void loop()
{
  Serial.write(command, 8);
  Serial.flush(); // tried with and without this line
  delay(500);
  Serial1.print("Waiting for data");
  while(!Serial.available())  // wait for data from the device to Serial's buffer
  {
    Serial1.print(".");  // codes always stuck in this loop
    delay(500);
  }
  Serial1.println("\nData received!");
  while(Serial.available())
    Serial1.print(Serial.read(), HEX); Serial1.print('\t');
  delay(10000);
}


Serial monitor's display info:
Code: Select all⸮⸮ng⸮$gn⸮⸮⸮p⸮⸮ds$sdp⸮g⸮c⸮⸮o'⸮
Ready to work!
Waiting for data............................. (keep going forever)


The codes got stuck in the `while (!Serial.available())` loop and just printed dots forever.

The first line in the display is the gibberish which always appears when the chip starts working (any idea how to avoid this start-up gibberish?) The measuring device can safely ignore this gibberish and get ready to receive the next command. (Note at the end of the 'setup' function, I made a 5 secs delay just to make sure the device can ignore the gibberish and wait for the next input. 5 secs is much more than enough.)

The following Python codes demonstrate this point:

Code: Select all>>> b_gibberish = '⸮⸮ng⸮$gn⸮⸮⸮p⸮⸮ds$sdp⸮g⸮c⸮⸮o\'⸮'.encode()
>>> b_command = b'\x01\x03\x00\x48\x00\x08\xc4\x1a'
>>> ser.read_all()
b''
>>> ser.write(b_gibberish)
55
>>> ser.write(b_command)
8
>>> ser.read_all()
b'\x01\x03 \x00%?(\x00\x00\x01>\x00\x00\x84\xd0\x00\x00\x04\xec\x00\x00\x02\xa8\x00\x00\x04\xe8\x00\x00\r\xac\x00\x00\x13\x8bR\xdb'
>>> len(_)
37


The last 3 lines were pre-typed and run one after another very rapidly. One can see that the gibberish string was ignored by the device, and the command processed.

I've checked everything I could think of, and yet the codes kept being stuck in that while loop, waiting for the device's response. Any idea what is wrong through this communication? To me, this piece of codes is just a re-implementation of my Python codes, yet it does not work as the Python codes.

Any idea or advice is appreciated!
User avatar
By thales_liu1990
#79783 Update:

1. I think it's not the TTL voltage 5V-3.3V compatibility problem. As long as I provide 3.3V to the measuring device, multimeter showed that both TX and RX are close to 3.3V, within the working range of ESP8266 pins.

2. After I used the software serial instead of the default Serial, the code began to work! That was very surprising to me, because I expected the hardware serial to be more reliable than the software serial. What's the difference between the hardware and software serial may be responsible in this situation?