Problems with Single Wire UART

Status
Not open for further replies.

TheNetStriker

New member
I'am trying to communicate with two device from the same manufacturer that seams to use a single wire UART serial port. (Sadly I don't have any documentation of the devices because the manufacturer does not release it)

I'am using a Teensy 3.2 and I've implemented this code to add the single wire serial port function. I setup the serial port with 1200 baud, two stop bits and no partity.

The first device works perfectly using only one pin for TX and RX. (note that the UART decoder of my oscillator is not perfect and does not recognize all bytes)
Here is a graph how the communication with this device looks like:
LabNation_Screenshot2.jpg
The first two bytes are sent from the Teensy, then there is a pause and then two bytes from the remote device are coming back. (The bytes from the remote device are also on a higher voltage)
As said this works perfectly and I can receive both bytes every time on the Teensy.

But on the second device the pause is much shorter and the Teensy often gets confused when reading this and reads only one or zero bytes. (And most of the time completely wrong one's)
Here is a graph how this looks like:
LabNation_Screenshot3.jpg
The first two bytes here are also from the Teensy and the second two bytes are from the remote device.

Is there any way to get such a communication to work on the Teensy reliable?
 
Don't see the code you are actually running... Yes there is the old Pull request for the changes to system code...

You might try raising the priority of the Uarts interrupt handler (like set to 0) and see if that helps or not.

Again don't know which Serial object you are using... But lets assume Serial1...

Maybe something like: NVIC_SetPriority(IRQ_UART0_STATUS, 0);
 
Thanks for the quick reply. I'am currently using Serial2 to send and receive data. I just tested this by setting the priority in the application itself (by including kinetis.h and setting NVIC_SET_PRIORITY(IRQ_UART1_STATUS, 0) in the setup method) and I also tried it by setting the IRQ_PRIORITY directly in the serial2.c file, but the bytes are still not read correctly. Here is the code I'am currently using:

Code:
buffer[2];

void setup() {
  Serial.begin(57600);
  Serial.println("START");

  Serial2.begin(1200, SERIAL_8N2_SINGLEWIRE);
}

void loop() {
  buffer[0] = 0;
  buffer[1] = 0;

  serialDevice1.write(myTwoBytes, 2);
    
  int countRead = serialDevice1.readBytes(buffer, 2);
  
  if (countRead != 2)
  {
    serialUsb.println(String(countRead));
  }

  delay(1000);
}

Do you have another idea what could cause this problem? Is there maybe a way to debug such problems?
 
I don't know why it's not working, but I do know I get these errors if I try to compile the code you posted.

Code:
sketch_apr03b:1: error: 'buffer' does not name a type
 buffer[2];
 ^
sketch_apr03b: In function 'void setup()':
sketch_apr03b:7: error: 'SERIAL_8N2_SINGLEWIRE' was not declared in this scope
   Serial2.begin(1200, SERIAL_8N2_SINGLEWIRE);
                       ^
sketch_apr03b: In function 'void loop()':
sketch_apr03b:11: error: 'buffer' was not declared in this scope
   buffer[0] = 0;
   ^
sketch_apr03b:14: error: 'serialDevice1' was not declared in this scope
   serialDevice1.write(myTwoBytes, 2);
   ^
sketch_apr03b:14: error: 'myTwoBytes' was not declared in this scope
   serialDevice1.write(myTwoBytes, 2);
                       ^
sketch_apr03b:20: error: 'serialUsb' was not declared in this scope
     serialUsb.println(String(countRead));
     ^
'buffer' does not name a type
 
I don't know why it's not working, but I do know I get these errors if I try to compile the code you posted.

Code:
sketch_apr03b:1: error: 'buffer' does not name a type
 buffer[2];
 ^
sketch_apr03b: In function 'void setup()':
sketch_apr03b:7: error: 'SERIAL_8N2_SINGLEWIRE' was not declared in this scope
   Serial2.begin(1200, SERIAL_8N2_SINGLEWIRE);
                       ^
sketch_apr03b: In function 'void loop()':
sketch_apr03b:11: error: 'buffer' was not declared in this scope
   buffer[0] = 0;
   ^
sketch_apr03b:14: error: 'serialDevice1' was not declared in this scope
   serialDevice1.write(myTwoBytes, 2);
   ^
sketch_apr03b:14: error: 'myTwoBytes' was not declared in this scope
   serialDevice1.write(myTwoBytes, 2);
                       ^
sketch_apr03b:20: error: 'serialUsb' was not declared in this scope
     serialUsb.println(String(countRead));
     ^
'buffer' does not name a type

Sorry, i forgot to rename some variables. I guess I was working too long on this today. :) Here is the corrected code.

Code:
byte buffer[2];
byte myTwoBytes[] = {0x00, 0xE9};

void setup() {
  Serial.begin(57600);
  Serial.println("START");

  Serial2.begin(1200, SERIAL_8N2_SINGLEWIRE);
}

void loop() {
  buffer[0] = 0;
  buffer[1] = 0;

  Serial2.write(myTwoBytes, 2);
    
  int countRead = Serial2.readBytes(buffer, 2);
  
  if (countRead != 2)
  {
    Serial.println(String(countRead));
  }

  delay(1000);
}

To get the _SINGLEWIRE setting to work this code must be implemented:
https://github.com/PaulStoffregen/cores/pull/57

Because this cannot be merged in the current version I merged this into my own fork:
https://github.com/TheNetStriker/cores/commit/82d762ba9ccf741c450eff08eb6beaa19567e7b8

Just copy the MySoftwareSerial.h, serial1.c, serial2.c and serial3.c from my fork over the existing files in the teensy folder.
 
You might try adding Serial2.flush(), after wite to see if that helps...

Sending a flush after writing both bytes does not seam to help, but if I send the two bytes separately with a flush in between it seams to work!

Maybe the second device is not as fast as the first one. Thanks for the hint.
 
Status
Not open for further replies.
Back
Top