UART/Serial connection not interpreting data correctly?

I'm trying to read (and later write) data to my garage door opener with an ESP8266 using the Software Serial library.

The wired garage door opener button uses two wires, 12v and ground. The 12v line is pulled to ground and both RX & TX are done on the same wire. I used a voltage divider to drop the 12v to 3.3v and have this connected to D6 on the ESP.

The chip in the door opener is an STM8S, and the UART is configured to be 9600 baud, 8 bits, no parity, 2 stop bits.

I wrote a data logger which uses an interrupt to record the microseconds of the signal. I manually converted this signal from timestamps to binary, and then loaded it into pulseview.

As we can see, there are three messages, each starting with 0x00, 0x55, 0x01, 0x00, and each one is 20 bytes in length. I repeated my tests several times and compared the interpreted wave form with my scope, so I'm quite confident that its correct.

The problem is that the software serial library is only returning a few random bytes of data. I setup the port with

mySerial.begin(9600, SWSERIAL_8N2, D6, D5, true);

Here's the result after pressing the door opener button 5 times (each line is one message as seen by the Software Serial library)

4 B4 6E 32 CE
DE BA A 11
E6 E 2
9A E 36 6E 6A
8A A6 12

Sketch:

#include <SoftwareSerial.h>
#define RX D6
#define TX D5
#define MSGLEN 20 // number of expected bytes in each message

byte data[MSGLEN]; // hold the data received from the uart
int counter = 0; // counter to keep track of how many bytes were received from the uart
int lastInterrupt = 0; // the last interrupt time from the uart

SoftwareSerial mySerial(D6, D5); // RX, TX


void setup()
{
  // Open serial communication for debugger and wait for port to open:
  Serial.begin(115200);
  while (!Serial) {
    ; // wait for serial port to connect. Needed for Native USB only
  }

  // Open the software serial port and set the data rate
  mySerial.begin(9600, SWSERIAL_8N2, D6, D5, true);
  while (! mySerial) {
    ;
  }

  Serial.println("Setup completed");
}

void loop() // run over and over
{
  if (mySerial.available() > 0) {
    lastInterrupt = millis();

    data[counter] = mySerial.read();
    counter++;
  }

  if (counter == MSGLEN - 1) {
    Serial.println("Message overflow");
    counter = 0;
  }

  if (counter > 0 && millis() > lastInterrupt + 60) {
    //    Serial.print("last interrupt: ");
    //    Serial.print(lastInterrupt);
    //    Serial.print(" counter: ");
    //    Serial.println(counter);

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

}

Does anyone have any idea why it's not reading the data correctly?

Please use the method of autoformatting in the IDE and code tags when pasting here.
No helper wants to be invaded by unknowm cockies.
Schematics works better than words.

Read the forum guidelines to see how to properly post code and some information on how to get the most from this forum.

Use the IDE autoformat tool (ctrl-t or Tools, Auto format) before posting code in code tags.

Here's a diagram of the voltage divider.

But I don't think its a problem with the circuit because I verified the pin logic with my scope. I setup an interrupt to mirror the high/low values to another digital pin and then measured it with my scope.

Comparing the two channels on the scope shows that the ESP is outputting the same exact signal it is being sent.

Looks like 00 is the start and stop message markers. Read the serial port checking for a 0x00 once a 0x00 is received on the next data read, check to see if there is another 0x00 if not start saving the incoming data until a 0X00 is received. then print the data.

here is some code that might help in illustration.

void fReceiveSerial_LIDAR( void * parameters  )
{
  bool BeginSentence = false;
  sSerial.reserve ( StringBufferSize300 );
  char OneChar;
  for ( ;; )
  {
    EventBits_t xbit = xEventGroupWaitBits (eg, evtReceiveSerial_LIDAR, pdTRUE, pdTRUE, portMAX_DELAY);
    if ( LIDARSerial.available() >= 1 )
    {
      while ( LIDARSerial.available() )
      {
        OneChar = LIDARSerial.read();
        if ( BeginSentence )
        {
          if ( OneChar == ‘>’)
          {
            if ( xSemaphoreTake( sema_ParseLIDAR_ReceivedSerial, xSemaphoreTicksToWait10 ) == pdTRUE )
            {
              xQueueOverwrite( xQ_LIDAR_Display_INFO, ( void * ) &sSerial );
              xEventGroupSetBits( eg, evtParseLIDAR_ReceivedSerial );
              //
            }
            BeginSentence = false;
            break;
          }
          sSerial.concat ( OneChar );
        }
        else
        {
          if ( OneChar == ‘<’ )
          {
            sSerial = “”; // clear string buffer
            BeginSentence = true; // found begining of sentence
          }
        }
      } //  while ( LIDARSerial.available() )
    } //if ( LIDARSerial.available() >= 1 )
    xSemaphoreGive( sema_ReceiveSerial_LIDAR );
  }
  vTaskDelete( NULL );
} //void fReceiveSerial_LIDAR( void * parameters  )

I am using a < for the start and a > for the end of sentence markers.

Hi @Idahowalker - I don't think that will work because the library isn't seeing any 0x00 bytes.

My initial approach here is just to buffer 60 milliseconds of data and then print it to the serial monitor. In the 5 cases that I pasted in above, it didn't output a 0x00.

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.