Trouble settings SODAQ EXPLORER to 300,E,7,1

Hi guys
I am trying to setup a sodaq explorer board to communicate in 300,e,7,1 as described at the section “Parameters” in the Arduino Reference https://www.arduino.cc/reference/en/language/functions/communication/serial/begin/

The board seems to not be responding to such configuration :confounded:.
The same sketch run fine on a Arduino Mega (changind port names obviously).

Sodaq sketch:

    #include "Arduino.h"`

    #define debugSerial SerialUSB
    #define SerialPort Serial

    //#define AL
    #define AC

    #if defined AC
      int BaudRate = 300;
      int BitsParityStop = SERIAL_7E1; // ---->this setup only work in arduino mega sketch, not here in sodaq explorer
    #elif defined AL
      int BaudRate = 1200; 
      int BitsParityStop = SERIAL_8N1;
    #endif
    void setup() {


      while ((!debugSerial) && (millis() < 10000)){
        // wait 10 seconds for serial monitor
      }
      
      debugSerial.begin(115200);
      SerialPort.begin (BaudRate,BitsParityStop);   // Inicializo el puerto serial
    }

    void loop() {  

        //send and receive data with serial
         if (debugSerial.available()){
          while (debugSerial.available()) {
            uint8_t inChar = debugSerial.read();
            SerialPort.write(inChar);
          }
         }

         if (SerialPort.available()){
          while (SerialPort.available()) {
            uint8_t inChar = SerialPort.read();
            debugSerial.write(inChar);
          }
         }
    }

Arduino Mega Sketch (Working fine)

#include "Arduino.h"

#define debugSerial Serial
#define SerialPort Serial1

//#define AL
#define AC 

#if defined AC
  int BaudRate = 300;
  int BitsParityStop = SERIAL_7E1; ---->this setup only work fine here  in the arduino mega sketch
#elif defined AL
  int BaudRate = 1200; 
  int BitsParityStop = SERIAL_8N1; // 
#endif

void setup() {

  while ((!debugSerial) && (millis() < 10000)){
  }
  
  debugSerial.begin(115200); 
  SerialPort.begin (BaudRate,BitsParityStop);   // Inicializo el puerto serial 
}

void loop() {  

    //send and receive data with serial
     if (debugSerial.available()){
      while (debugSerial.available()) {
        uint8_t inChar = debugSerial.read();
        SerialPort.write(inChar);
      }
     }

     if (SerialPort.available()){
      while (SerialPort.available()) {
        uint8_t inChar = SerialPort.read();
        debugSerial.write(inChar);
      }
     }
}

Can tell me how to see the library that process the parameters to check if is correctly implemented?
Or what suggest to solve this issue?

THanks in advance.

I just discovered the problem as it originates, it is actually something much more serious than I thought. SODAQ EXPLORER does not respect timings for 300bps, it sends 9 bits in 32.6 milliseconds instead of 30 milliseconds.

Can anyone tell me why this speed error is due? Is it a bug?

Thanks in advance.

Hi @GiroSinTornillo,

Do you have this issue with both hardware serials?

SerialUSB has a autobaud function, can you try to request this baudrate from your pc?
Serial should respect your requested settings.

Best regards,
Jan

Hi Jan
Thanks by your fast reply. I have tested this fail on Serial that uses D0/D1,
A fast verification is to setup the port to 300,n,8,1 and send 0x00, then there are 9 bits to zero, counting the StartBit.
@300 bps, each bit must have exactly 3,3333 mSec. so, 9 bits must remain low over 30,0mSec. and i verify on scope that SODAQ EXPLORER remains low for 32,6mSeg, it{s 276 bps, and error of 7,9% in the timming.

Best Regards

Hugo

Hi Jan
Do you need some additional info or proof of concept about the issue?
I suggest to send a byte in 300,n,8,1 and check in an oscilloscope the timming. Bit rate is not 300 bps, is less, about 276 bps from my readings.

Thanks in advance

Hi @GiroSinTornillo,

Looking into the datasheet I don’t know if this can be improved. Look like there is always some small error rate on the baudrate. Datasheet:

Best regards,
Jan

1 Like

Hi Jan
Could you specify the page numbers from where you deduce that the error present in 300bps is acceptable according to the data sheet? and quote the text please, I don’t see anything that supports this theory.

Can you refer to the library section where baud rate is setted after a .begin methoed execution?
To review them.

Regards

Page 463
25.6.2.3
Here is points out that the baudrate is calculated by the used clock.
There will be always an error rate.

.begin is a function from the Arduino SAMD Core.
See their GitHub page: https://github.com/arduino/ArduinoCore-samd

Best regards,
Jan

Can you try transmitting 0xAA and then graph that on the scope.
The alternating bit pattern should make it easy to see the duration of the start bit, the data bits and the stop bit.

This should help figure out where the issue is.

Also, our core uses slightly different code than the main Arduino SAMD core for UARTs running < 600 BAUD.

If you want you can try modifying the following file in the Sodaq SAMD core.

In Uart.cpp remove lines 70-74 leaving only:

sercom->initUART(UART_INT_CLOCK, SAMPLE_RATE_FRACT_x16, baudrate);

If you are using Windows you can normally find that file in:
%localappdata%/Arduino15/packages/SODAQ/hardware/samd/1.6.20/cores/arduino

Yes, Gabriel, i made it.
Bit rate is not 300 bps, is less, about 276 bps from my readings.

SODAQ EXPLORER does not respect timings for 300bps, it sends 9 bits in 32.6 milliseconds instead of 30 milliseconds.

1 bit have 0,0036222 seconds (3,6222 mSeg), so 1/Tbit=276 bps baudrate. Checked on the osciloscope.

That apparent arithmetic rounding, instead of using a fractional factor may be the reason for the error, later I will be testing it, on the sodaq board, after editing that library and recompile.

It is very interesting what you explain to me where the libraries are located, I did not know how to get to that sourcecode.

What was the intended objective for that conditional adjustment for speeds below 600bps?

By the way, the constants SAMPLE_RATE_ARITH_x16 and SAMPLE_RATE_FRACT_x16 where they are defined? To better understand how it works.

I clarify that my knowledge about library management and creation is very basic, especially if we talk about the Arduino core.

I will update the results for the change suggested, later in my lab.

Thanks in advance.

We forked from the Arduino core quite early on in its development.

We need a fix for one of our projects, which is what you see there.
Later the Arduino core applied a difference fix and we have not merged the two.

Almost all developments within the Arduino core are pulled into our core.
I believe we are mostly level with Arduino core release 1.6.20.

SAMPLE_RATE_FRACT_x16 can be found in an enum SERCOM.h.

I’m curious if the just using the fractional mode resolves this.

Hi Gabriel
bad news… fractional mode does not resolve the issue, on the contrary, the error worsens, leaving a baudrate of 1666 bps.

Without library modification, transmiting “U” 0x55 character, at 300n81, the waveform is this


and with the suggested change, the waveform is:

I don’t know if you want me to do another test, you tell me …

Regards

Hugo

I was thinking in to try SoftwareSerial, but i see this post SODAQ not finding SoftwareSerial.h So, I discard the idea of trying it with a serial library by software.

I believe there are a number of things at play here, and ultimately the combination of the clock setup and low baudrates doesn’t seem to mix well.

One thing you could try is changing line 81 of Sercom.cpp to: (Edit: First revert any changes suggested above.)

term1 += (SystemCoreClock / 2);   // Some rounding

This will change the direction of the rounding.

Alternatively, you could try replacing the following files in the Sodaq Core.

  1. Sercom.h
  2. Sercom.cpp
  3. Uart.cpp

You should replace them with the files from the Arduino Core.
This should make the UART behave exactly as in the main Arduino Core (I’m not sure if this will help).

Hi @GabrielNotman
good afternoon, here I am again with the news, which is not good news …
I tried all the changes you indicated to me and the result was not satisfactory, I will document the results here:

Changing sercom line 81 to term1 += (SystemCoreClock /2)


Speed on port is now 322 bps

Commenting sercom line 81 // term1 -= (SystemCoreClock /2)


speed on port is now 277 bps (same as uncommenting line 81)

Comparative changing sign on line 81 of sercom

Replacing the three files with arduino samd21 core files


speed on port is now 1666 bps, a disaster!!! :frowning:

Well, finally I still don’t understand why it is not possible for such hardware to achieve a speed of 300bps when it would have to be very simple.
Unfortunately I do not quite understand the adjustments at the level of records made by the code in the SAMD21, but I think there is the key.
I also don’t understand what clock speed the SODAQ EXPLORER has, in the schematic I only see a crystal of 32,768 Khz … does it perhaps multiply it internally then with a PLL?

It is a pity that the sodaq explorer boards do not allow operating at 300bps, I am with a metering project, and all electrical meters with IEC standard, start dialoging at 300bps.
I am among the options of putting a MAX3100 as UART, but I consider it a waste, the other option is to change to another platform different from SODAQ EXPLORER, which I hope I don’t have to reach that end.

If you suggest any other test, I am happy to do it, but I understand that they are also tests that the SODAQ team should perform, since it is a serious failure.

Sincerely

In the Arduino Core setup, the UARTs use the 48MHz DFLL system clock (on GCLK0). This gives the maximum range with regards to the baud rates, however, this comes at the expense of less fine resolution with regards.

Using a lower frequency source clock (such as the 1MHz source available from GCL1) will give you finer resolution. In this case with a 1MHz vs 48MHz you will have 48x better resolution between each step in the baud rates.

To do this you will need to adjust the clock setup and the math involved with the baud rate.

You can adjust which GCLK the SERCOM sources from in:

void SERCOM::initClockNVIC(void)

And you will need to replace the references to: SystemCoreClock
in: void SERCOM::initUART(SercomUartMode mode, SercomUartSampleRate sampleRate, uint32_t baudrate) to use the value 1000000 instead.

Please note as this code is shared for all SERCOM use, it will mess things up for I2C and SPI.

Another approach would be to leave the existing code intact and set the baud rate to 48 x 300 (14400), then redirct the specific SERCOM for the UART to source from GCLK1.

The mapping for the UARTs on the Sodaq ExpLoRer are:

Serial  = Sercom5
Serial1 = Sercom4
Serial2 = Sercom0
1 Like

Hi Gabriel
I´m interested in to test the second option, due i use SPI and I2C and do not want to mess with them.
GCLK1 is an internal or external clock? I need to put an 1 Mhz clock source externally? Can you explain more in deep the steps to configure for example the Serial or Serial1 port for 300bps with more accuraccy?
THanks in advance.

Regards

Hugo