Unvarnished internal UART under RUI3 (on RAK4631)

I have a RAK12500 GNSS in slot-A of a RAK4631(RUI3).

I can talk to it successfully over the I2C using the UBX protocol. One of reasons for the I2C usage is that I will have another external device sitting on the RX1/TX1 pins that are on the baseboard J10 connector and I want to make sure that the RAK12500 does not get involved in that conversation in any way.

Now I’m trying to test that I really have the ZOE-M8Q UART disabled but that first requires that I have a reference of what it looks like enabled. But I can’t get anything at all on the Serial1 API. I wonder if there is an AT parser sitting in the way. In this case the AT parser would be in the way of the other external device as well.

In setup() I select the baud with “Serial1.begin(9600)” and wait with “while(!Serial1);”. I assume 1 stop, no parity is used, but I have no way to ensure this.

By default the GGA GLL GSA GSV RMC VTG and TXT messages should be enabled on that port, but “Serial1.available()” always returns 0.

Is Serial1 the correct API handle for RX1/TX1 on RAK4631-RUI3?
Is there something special I have to do to ensure the Serial1 port is waking up unvarnished?

Thanks

[Edit]
BTW I can see the activity on the RX pin (J10-4), so I know that the problem isn’t the GNSS
[Edit2]
And I can issue Serial1.print(“Hello”); and see activity on TX1 (J10-3), so Serial1 is the right mapping for the RX1/TX1 pins. And the bit clocking timing I see on the both pins correspond to 9600 baud, so that’s right too.
I also initialise the Serial1 port with RAK_CUSTOM_MODE in case the default was AT. The issue remains that Serial1.available() returns 0.

Hi @psupine ,

You are correct that Serial1 is for RX1/TX1. It is in Custom Mode by default so it should work fine.

If you are testing it with RAK4631-R + RAK12500, I can try to run your sketch and duplicate the issue you have. You can send me the code in private message or email to [email protected] :+1:

@carlrowan
Have emailed sketch. Thanks for looking.

I have similar issue with you.

  1. Sometimes the internal AT phaser remain active even if I set Serial (USB) to RAK_CUSTOM_MODE, I have no solutuion on that, it just sometimes work or not working.
  2. Serial0 and Serial1 will fail to be functional sometimes when connected to external UART devices, I have checked with logic analyzers and oscilloscope and can confirm the external device is functionaing and all data are valid. I suspend the issue is with NRF’s softdevice.

Reasons as follow:

  1. I can see a short duration logic 0 (any reason?) on the RAK4630 RX pin (aka. NRF52840’s RX pin) when the external device is transmitting data and this will cause the NRF softdevice’s UART handler to report an internal error and stop functioning (Which the user will not know as RAK has hide the error)
  2. by calling Serial1.begin() again, the port become functioanl again.
  3. By adding a strong pull-up on the UART RX pin (to prevent the pin status going logic 0 randomly, it functions. (d) Take a look at RAK’s Wisblock RS485 module, there is a pull-up resistor on the RX pin to prevent floating/unknown state.

A solution is RAK updated its RUI3 to allow setting stronger/or just enable RX pin internal pull-up resistor.

I am also connecting to a GNSS module.

TLDR: Softdevice state machine report error on RX pin and RAK does not report the error to the user nor provide a way to recover, solution is to add pull-up resistor on RX pin.

Thanks @chansheunglong for sharing your experience. The fact that you are also reporting something that is not right encourages me to think that it’s a RUI3 configuration issue rather than a dry joint.

I just had a look at the TP8485E datasheet; that’s the RS485 transceiver on the RAK5802. When that chip is not enabled, the “R” output on pin 1 is tri-stated. The 10k pullup resistor is to stop that dataline flapping. However the UART_RX line on that board is also driven by the MAX3232’s R1OUT pin which is never tristated. This makes no sense to me, but I’m sure there’s a reason. Anyway, I think the 10k pullup should not be needed, so it’s even more interesting that you say it prevents the dropout problem. :thinking:

Also, the nRF’s UART should also be able to cope with random noise events without locking up. Sure, lose a character, but not lock up. I wonder if the short logic ‘0’ you see is because the firmware is doing some kind of reconfiguration of the nRF pin, dropping back to a GPIO state before setting it up for UART again.

I’ll try out your tricks while we wait for RAK to get back to us.

RAK5802 is soldered only TP8485E, so the pin should be at tri-state (floating that is)

When I discovered the issue, I add 10K pull-up to my custom board and it has since been working. I stop thinking of that because it has taken me a whole week just to find a solution.

One funny things is that, by touching the RX pin with my hand (making it not floating?) It works, when I remove my finder, it fail.

For NRF52, see this: Recover from NRF_UARTE_EVENT_ERROR when UART RX pin pulled low - Nordic Q&A - Nordic DevZone - Nordic DevZone
When RX pin was pulled low for too long (Or I believe it is at floating state for too long) it should generate a NRF_UARTE_EVENT_ERROR, which will cause the UART driver to stop. I came to this conclusion because after I called Serial.begin(), it starts working again. Thus I think the initialzation of UART driver solve the issue.

I did not experience the same problem on RAK3172 (STM32) so I think the logic code of RUI is fine, it should be some pin configuration problem. A weak pull-up by the MCU should also solve the issue by preventing a floating state.

I strapped a 10k resistor between 3V3 (J12-1) and RX (J10-4).

It didn’t work for me. :frowning:

I found a solution !!!

On a whim (I don’t know what inspired this), I initialised Serial1 TWICE. ie:

// Initialise internal UART

Serial1.begin(9600, RAK_CUSTOM_MODE); // default UART baud for ZOE-M8Q
while (!Serial1); // Wait for it to be ready
Serial1.end();

// Initialise internal UART

Serial1.begin(9600, RAK_CUSTOM_MODE); // default UART baud for ZOE-M8Q
while (!Serial1); // Wait for it to be ready
Serial1.end();

This now happily reads NMEA strings from the GNSS over the UART.

I then clipped the 10k resistor … and it still works.

[Edit] The second Serial1.end() is optional. It works either way. Which is another strange thing. I thought end() terminated the function, but clearly it doesn’t.

So from your finding, can I assume, the issue is because you initialize twice? By removing the extra Serial1.begin(), everything works

No. Other way around.

It only works when I initialise twice. Strange, but there it is.

That is really strange, maybe RAK can take a look at that.

In my case, it should be solved by calling nrf_gpio_cfg_input(PIN, NRF_GPIO_PIN_PULLUP), which does not affect power consumption, and UART is now much more reliable. Sorry for hijacking your post in the first place.

No apology needed. I’ll take any help I can get !

If anyone has a similar setup (RAK12500 + RAK 4631-R on a RAK19007) wants to explore this issue, here is the distilled code.

/*

  Demo code to talk to the ZOE M8Q GNSS module on the RAK 12500 via UART and NMEA

*/

void setup()

{

  // Initialize Serial for debug output

  Serial.begin(115200);

  while (!Serial);  // Wait for Serial port to be available, no time out

  delay(100);       // There needs to be some delay here. Not sure how much

  Serial.println("GPS ZOE-M8Q (NMEA over UART)");

  Serial.printf("Firmware Version: %s\r\n", api.system.firmwareVersion.get().c_str());

  delay(1000);    // Window to enter AT+BOOT when it all goes wrong

  // Reset the RAK12500 GNSS sensor, plugged into slot A

  pinMode(WB_IO2, OUTPUT);

  digitalWrite(WB_IO2, 0);

  delay(1000);

  digitalWrite(WB_IO2, 1);

  delay(1000);

  // Initialise internal UART

  Serial1.begin(9600, RAK_CUSTOM_MODE);  // default UART baud for ZOE-M8Q

  while (!Serial1);     // Wait for it to be ready

  Serial1.end();

  // Re-Initialise internal UART

  Serial1.begin(9600, RAK_CUSTOM_MODE);  // default UART baud for ZOE-M8Q

  while (!Serial1);     // Wait for it to be ready

  Serial1.end();

  Serial.println("Starting serial relay");

}

void loop()

{

  // By default the following NMEA strings should be enabled on UART:

  // GGA GLL GSA GSV RMC VTG TXT

  // I can see them on the scope on J10-4

  // Just try echoing

  if( Serial1.available() )

    Serial.print((char) Serial1.read());

}