Skip to content

No real-time serial.read() possible #6921

Closed
@OekoSolveMG

Description

@OekoSolveMG

Board

M5 Stack Core 1 / 2

Device Description

M5 Stack Core 1 / 2 with the LAN Module with W5500

Hardware Configuration

Pinmap M5 Core 2
Pinmap Lan module

Version

v2.0.3

IDE Name

PlatformIO

Operating System

Windows 10

Flash frequency

40 MHz

PSRAM enabled

no

Upload speed

115200

Description

Low baudrate (9600) causes the serial.read() command to fail and not read bytes on the Modbus. Might there be some interfering code that runs in timed cycles with a very high priority that could creates issues for the serial.read().

image

The failed read seen above happens every 6th read.

image

Complete message:

The third line is a pin that gets toggled to high before serial.read() and to low after seral.read().

image

Sketch

// Allocate initial receive buffer size: 1 block of BUFBLOCKSIZE bytes
  const uint16_t BUFBLOCKSIZE(512);
  uint8_t *buffer = new uint8_t[BUFBLOCKSIZE];
  ModbusMessage rv;

  // Index into buffer
  register uint16_t bufferPtr = 0;
  // Byte read
  register int b; 

  // State machine states, RTU mode
  enum STATES : uint8_t { WAIT_DATA = 0, IN_PACKET, DATA_READ, FINISHED };

  // State machine states, ASCII mode
  enum ASTATES : uint8_t { A_WAIT_DATA = 0, A_DATA, A_WAIT_LEAD_OUT, A_FINISHED };

  register uint8_t state;

  // Timeout tracker
  unsigned long TimeOut = millis();

  // RTU mode?
  if (!ASCIImode) {
    // Yes.
    state = WAIT_DATA;
    // interval tracker 
    lastMicros = micros();
  
    while (state != FINISHED) {
      switch (state) {
      // WAIT_DATA: await first data byte, but watch timeout
      case WAIT_DATA:
        // Blindly try to read a byte
        b = serial.read();
        // Did we get one?
        if (b >= 0) {
          // Yes. Note the time.
          lastMicros = micros();
          // Do we need to skip it, if it is zero?
          if (b > 0 || !skipLeadingZeroBytes) {
            // No, we can go process it regularly
            state = IN_PACKET;
          } 
        } else {
          // No, we had no byte. Just check the timeout period
          if (millis() - TimeOut >= timeout) {
            rv.push_back(TIMEOUT);
            state = FINISHED;
          }
          delay(1);
        }
        break;
      // IN_PACKET: read data until a gap of at least _interval time passed without another byte arriving
      case IN_PACKET:
        // Are we past the interval gap without another byte?
        if (micros() - lastMicros >= interval) {
          // Yes, terminate reading
          LOG_V("%ldus without data\n", micros() - lastMicros);
          state = DATA_READ;
        } else {
          // No, still in reading sequence
          // Did we get a byte?
          if (b >= 0) {
            // Yes, collect it
            buffer[bufferPtr++] = b;
            // Mark time of last byte
            lastMicros = micros();
            // Buffer full?
            if (bufferPtr >= BUFBLOCKSIZE) {
              // Yes. Something fishy here - bail out!
              rv.push_back(PACKET_LENGTH_ERROR);
              state = FINISHED;
              break;
            }
          }
          // Buffer has space left - try to read another byte
          b = serial.read();
        }
        break;
      // DATA_READ: successfully gathered some data. Prepare return object.
      case DATA_READ:
        // Did we get a sensible buffer length?
        HEXDUMP_D("Raw buffer received", buffer, bufferPtr);
        tmp_copy.assign(buffer, buffer + bufferPtr);

        if (bufferPtr >= 4)
        {
          // Yes. Check CRC
          if (!validCRC(buffer, bufferPtr)) {
            // Ooops. CRC is wrong.
            rv.push_back(CRC_ERROR);
            tmp_failed = true;
          } else {
            // CRC was fine, Now allocate response object without the CRC
            for (uint16_t i = 0; i < bufferPtr - 2; ++i) {
              rv.push_back(buffer[i]);
            }
          }
        } else {
          // No, packet was too short for anything usable. Return error
          rv.push_back(PACKET_LENGTH_ERROR);
          tmp_failed = true;
        }
        state = FINISHED;
        break;
      // FINISHED: we are done, clean up.
      case FINISHED:
        // CLear serial buffer in case something is left trailing
        // May happen with servers too slow!
        while (serial.available()) serial.read();
        break;
      }
    }
  }
  // Deallocate buffer
  delete[] buffer;

  return rv;

Debug Message

[244292][E-MB][DUMP] (.pio/libdeps/m5stack-core-esp32/eModbus/src/RTUutils.cpp:497) - Size: [23], Content: [02 5E EA 06 00 00 08 00 50 0F 71 0C A8 00 01 00 01 00 64 00 03 2B A9 ]
[244300][MB][E] (lib/modbus/ModbusMaster.cpp:304) - Error: (E2) - (CRC check error).

[269243][E-MB][DUMP] (.pio/libdeps/m5stack-core-esp32/eModbus/src/RTUutils.cpp:497) - Size: [18], Content: [01 03 3E 00 71 02 7B 00 04 01 3C 00 00 00 00 02 79 01 ]
[269248][MB][E] (lib/modbus/ModbusMaster.cpp:304) - Error: (E2) - (CRC check error).

[269292][E-MB][DUMP] (.pio/libdeps/m5stack-core-esp32/eModbus/src/RTUutils.cpp:497) - Size: [23], Content: [F9 4C 9F 00 00 00 08 00 50 0F 71 0C A8 00 01 00 01 00 64 00 03 33 EA ]
[269298][MB][E] (lib/modbus/ModbusMaster.cpp:304) - Error: (E2) - (CRC check error).

[294243][E-MB][DUMP] (.pio/libdeps/m5stack-core-esp32/eModbus/src/RTUutils.cpp:497) - Size: [18], Content: [01 03 3E 00 71 02 7C 00 04 01 3C 00 00 00 00 02 79 01 ]
[294248][MB][E] (lib/modbus/ModbusMaster.cpp:304) - Error: (E2) - (CRC check error).

[294293][E-MB][DUMP] (.pio/libdeps/m5stack-core-esp32/eModbus/src/RTUutils.cpp:497) - Size: [22], Content: [01 EA 06 00 00 08 00 50 0F 71 0C A8 00 01 00 01 00 64 00 03 49 01 ]
[294299][MB][E] (lib/modbus/ModbusMaster.cpp:304) - Error: (E2) - (CRC check error).

[319242][E-MB][DUMP] (.pio/libdeps/m5stack-core-esp32/eModbus/src/RTUutils.cpp:497) - Size: [18], Content: [01 03 3E 00 71 02 7C 00 04 01 3C 00 00 00 00 02 79 00 ]
[319247][MB][E] (lib/modbus/ModbusMaster.cpp:304) - Error: (E2) - (CRC check error).

[319292][E-MB][DUMP] (.pio/libdeps/m5stack-core-esp32/eModbus/src/RTUutils.cpp:497) - Size: [23], Content: [FF 4C 9F 00 00 00 08 00 50 0F 71 0C A8 00 01 00 01 00 64 00 03 8C 91 ]
[319297][MB][E] (lib/modbus/ModbusMaster.cpp:304) - Error: (E2) - (CRC check error).

[339351][E-MB][DUMP] (.pio/libdeps/m5stack-core-esp32/eModbus/src/RTUutils.cpp:497) - Size: [3], Content: [D3 12 FF ]
[339353][MB][E] (lib/modbus/ModbusMaster.cpp:304) - Error: (E5) - (Packet length error).

[344233][E-MB][DUMP] (.pio/libdeps/m5stack-core-esp32/eModbus/src/RTUutils.cpp:497) - Size: [7], Content: [01 03 3E 00 71 02 7C ]
[344235][MB][E] (lib/modbus/ModbusMaster.cpp:304) - Error: (E2) - (CRC check error).

[344294][E-MB][DUMP] (.pio/libdeps/m5stack-core-esp32/eModbus/src/RTUutils.cpp:497) - Size: [35], Content: [7A 00 00 02 B9 00 00 0B D6 27 28 02 79 4C 9F 00 00 00 08 00 50 0F 71 0C A8 00 01 00 01 
00 64 00 03 A2 09 ]
[344303][MB][E] (lib/modbus/ModbusMaster.cpp:304) - Error: (E2) - (CRC check error).

[364269][E-MB][DUMP] (.pio/libdeps/m5stack-core-esp32/eModbus/src/RTUutils.cpp:497) - Size: [42], Content: [01 03 3E 00 71 02 7B 00 04 01 3D 00 00 00 00 02 79 01 01 00 78 FF FF 00 00 02 72 00 01 
00 01 01 84 00 00 02 B9 00 00 0B D6 27 ]
[364281][MB][E] (lib/modbus/ModbusMaster.cpp:304) - Error: (E2) - (CRC check error).

[389244][E-MB][DUMP] (.pio/libdeps/m5stack-core-esp32/eModbus/src/RTUutils.cpp:497) - Size: [19], Content: [01 03 3E 00 71 02 7C 00 04 01 3C 00 00 00 00 02 79 01 00 ]
[389249][MB][E] (lib/modbus/ModbusMaster.cpp:304) - Error: (E2) - (CRC check error).

[389295][E-MB][DUMP] (.pio/libdeps/m5stack-core-esp32/eModbus/src/RTUutils.cpp:497) - Size: [20], Content: [06 00 00 08 00 50 0F 71 0C A8 00 01 00 01 00 64 00 03 D2 F8 ]
[389300][MB][E] (lib/modbus/ModbusMaster.cpp:304) - Error: (E2) - (CRC check error).

Other Steps to Reproduce

See issue on the eModbus library about the same problem. Conclusion was that it might be a problem with the Base library. (eModbus/eModbus#198)

The same issue happens on both Core 1 and Core 2 as well as with a custom adapter for modbus or the WAN 5500 module.

I have checked existing issues, online documentation and the Troubleshooting Guide

  • I confirm I have checked existing issues, online documentation and Troubleshooting guide.

Metadata

Metadata

Assignees

Type

No type

Projects

Status

Done

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions