arduino / uno-r4-library-compatibility

25 stars 6 forks source link

SoftwareSerial (FAIL) #12

Open Hsubtnarg opened 1 year ago

Hsubtnarg commented 1 year ago

I have been trying to use the SoftwareSerial library but get errors on the receiver. So I had a look at what it is sending and this is what I found. It looks like the Uno R4 is not sending the stop bit correctly. For 9600baud it should be about 120us, but it is only 62us. image

This is causing the frame to drift and causing errors on the receiver. This is the same code running on a Lenardo. image

Originally posted by @Hsubtnarg in https://github.com/arduino/uno-r4-library-compatibility/issues/3#issuecomment-1661543925

Binary-System commented 2 months ago

Is there any update on this problem with SoftwareSerial?

Hsubtnarg commented 2 months ago

I have been testing it with the latest updates and it is still the same

Hannes7eicher commented 3 weeks ago

Apologies for the late reply! I ran some tests using two UNO R4 WiFi with the following sketches without encountering any issues.

Sender Sketch

#include <SoftwareSerial.h>

// Define the pins for SoftwareSerial
const int TX_PIN = 10;
const int RX_PIN = 11;

// Initialize SoftwareSerial
SoftwareSerial mySerial(RX_PIN, TX_PIN); // RX, TX

void setup() {
  // Start the hardware serial communication at 9600 baud rate
  Serial.begin(9600);
  // Start the software serial communication at 9600 baud rate
  mySerial.begin(9600);
}

void loop() {
  // The message to send
  String message = "Hello, Arduino!";

  // Print the message to the SoftwareSerial
  Serial.println("Sending message: " + message);
  mySerial.println(message);

  // Wait for a second before sending the next message
  delay(1000);
}

Receiver Sketch

#include <SoftwareSerial.h>

// Define the pins for SoftwareSerial
const int TX_PIN = 11;
const int RX_PIN = 12;

// Initialize SoftwareSerial
SoftwareSerial mySerial(RX_PIN, TX_PIN); // RX, TX

void setup() {
  // Start the hardware serial communication at 9600 baud rate
  Serial.begin(9600);
  // Start the software serial communication at 9600 baud rate
  mySerial.begin(9600);

  Serial.println("Receiver ready");
}

void loop() {
  // Check if data is available to read from SoftwareSerial
  if (mySerial.available() > 0) {
    // Read the incoming data
    String incomingMessage = mySerial.readStringUntil('\n');

    // Print the received message to the Serial Monitor
    Serial.println("Received message: " + incomingMessage);
  }

  // Insert a tiny delay to avoid overloading the processor
  delay(100);
}

Let me know if you still encounter issues and I can set aside some time to investigate.

Hsubtnarg commented 3 weeks ago

If you use only Arduino boards then you will not see the issue as they are tolerant of the shorter stop bit, but if you are communicating with something that is not so tolerant, then you will get errors. See the traces above that illustrate that the stop bit is shorter on the Uno R4, but is the correct length with the same code on the Lenardo

iabdalkader commented 4 days ago

If you use only Arduino boards then you will not see the issue

I also tested this library with multiple USB to serial chips and they all work fine. The receiver you're using must have a very low error tolerance. That said, I'll take a look and see if I can improve it.

iabdalkader commented 4 days ago

The reason for the short stop bit is that DMA transfers are triggered by a timer, cycles are bit-time apart. After the last bit, the transfer is complete as soon as the bit is written out, which is not a full timer cycle. A following byte will just pull the GPIO low too soon.

So one possible solution is to delay for half-bit time after the stop bit. Is this accurate/good enough ?

SDS00004

This depends on the micro-seconds resolution, but it seems good enough. I don't think +-16us will cause an issue with your UART receiver. Another solution would be to poll the timer's counter after the transfer is complete, but this may require more changes to the core as those timer fields are currently private.

Hsubtnarg commented 3 days ago

I could try it with your solution but the things I am talking to are a solar inverter and a in line power meter, both of which are not old. Neither work reliably with the short stop bit.

Is it possible to get the DMA to send a dummy bit at the end so it would do one more cycle and make the stop bit the correct length

Thanks

Grant

From: Ibrahim Abdelkader @.> Sent: Wednesday, 11 September 2024 7:13 am To: arduino/uno-r4-library-compatibility @.> Cc: Hsubtnarg @.>; Author @.> Subject: Re: [arduino/uno-r4-library-compatibility] SoftwareSerial (FAIL) (Issue #12)

The reason for the short stop bit is that DMA transfers are triggered by a timer, cycles are bit-time apart. After the last bit, the transfer is complete as soon as the bit is written out, which is not a full timer cycle. A following byte will just pull the GPIO low too soon.

So one possible solution is to delay for half-bit time after the stop bit. Is this accurate/good enough ?

SDS00004.png (view on web)https://github.com/user-attachments/assets/fcd3bbb8-b233-48e9-b19c-336808606d51

- Reply to this email directly, view it on GitHubhttps://github.com/arduino/uno-r4-library-compatibility/issues/12#issuecomment-2341819200, or unsubscribehttps://github.com/notifications/unsubscribe-auth/AYJ3WQ7PHNBEJMI4U75Z6ALZV5AC3AVCNFSM6AAAAABKMCDWEKVHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMZDGNBRHAYTSMRQGA. You are receiving this because you authored the thread.Message ID: @.**@.>>

iabdalkader commented 3 days ago

Is it possible to get the DMA to send a dummy bit at the end so it would do one more cycle and make the stop bit the correct length

That's another solution I've considered, but it adds even more time than the half-bit solution above. You can actually test this without any changes to the code, just use 2 stop bits and on the receiving end, use 1 stop bit (EDIT: this will only work for sending, it will break receiving).

iabdalkader commented 3 days ago

I found a better fix, see the details here: https://github.com/arduino/ArduinoCore-renesas/pull/374

Hsubtnarg commented 2 days ago

I did try 2 stop bits but it was some time ago and all I can remember is that it did not work.

That fix does look promising, I am out of town at the moment, but I will test it when I get back in about 3 weeks

Thanks