The best solution is a SC16IS740 SPI or I2C UART. This library works very well on the B Series SoM. There are several models with different capabilities like the SC16IS750 and SC16IS760 that also work with that library.
Software serial doesn't work very well because of limited hardware timers and unpredictable interrupt latency on the nRF52.
As far I would need 2xUARTs I would prefer SC16IS760. Does library support 2xUARTs of single SC16IS760?
For highest performance/speed with the library you would recommend stick to I2C or SPI?
You can connect two SC16IS740 or 750 to the same SPI bus and that works right now.
The SC16IS752/762 dual UART is almost two of the other chips in a single package. The library doesn't currently work with it, but I looked at it several years ago and it didn't seem like it would be difficult but I never got a chance to implement it.
@PoCLab, what is the maximum baud rate you expect? These devices have 64 byte receive and transmit FIFOs and will generate an interrupt when they read a preset level. Using SPI is best so you can move the data on or off the device as quickly as possible. However, at high baud rates, servicing the interrupts can be problematic.
In my Application sometimes I get burst of data up to 4KB on 38400
And would like to have a large buffer to be safer about potential overflows and data loss
And as far current implementation of @rickkas7 lib not using interrupts/they are tricky on nRF52. I think unless I am fastly start reading after first byte comes I will lost the data with such a small FIFO.
Anyway it's good starting point and I can handle it somehow in software unless somebody would come up with better solution.
In General it's a shame that such a good module has only 1 free UART to use.
@rickkas7 We have an HW setup with 2xSC16IS740 shared SPI lanes and dedicated CS for each IC.
Can you help me understand the proper initialization for 2 UARTs? My understanding that it's should be somehow similar to a dual port IC example. A short example would be highly appreciated.
We are testing with B524.
How can I use 2xSC16IS740 with shared SPI lines and a dedicated CS for each IC to switch between them on the fly instead of changing the CS pin status every time I want to send data to one of the two SC16IS740
Here's the code I use, when sending a sentence through serialA (with SC16IS740 channel A turned on and SC16IS740 channel B turned off), everything works. When uncommenting println from serialB,the sentence is sent to serialB regardless of the status of the CS pin- LOW
#include <SC16IS7xxRK.h>
// Pick a debug level from one of these two:
SerialLogHandler logHandler;
// SerialLogHandler logHandler(LOG_LEVEL_TRACE);
SYSTEM_THREAD(ENABLED);
SC16IS7x0 SerialA; // First SC16IS7xx module
SC16IS7x0 SerialB; // Second SC16IS7xx module
char out = ' ';
void setup() {
// Set CS pin D5 LOW for extSerial1
pinMode(D5, OUTPUT);
digitalWrite(D5, LOW);
// Set CS pin D6 HIGH for extSerial2
pinMode(D6, OUTPUT);
digitalWrite(D6, HIGH);
// If you want to see the log messages at startup, uncomment the following line
waitFor(Serial.isConnected, 100);
// Set the baud rate of the USB serial port to 115200
// Serial.begin(9600);
Log.info("This is info message1");
// Initialize the first SC16IS7xx module
SerialA
.withSPI(&SPI, D5, 4) // SPI port, CS line (D5), speed in MHz
.begin(9600); // Set the baud rate for extSerial1 to 9600 (or your desired rate)*/
// Initialize the second SC16IS7xx module with a different CS line (D6)
SerialB
.withSPI(&SPI, D6, 4) // SPI port, second CS line (D6), speed in MHz
.begin(9600);
}
void loop() {
// Rest of your loop code
SerialA.println("UART A working");
delay(1000);
/*SerialB.println("UART B working");
delay(1000);*/
}
I will be very grateful if you help me with an example to understand how to manage two chips quickly without rewriting the code every time and without changing the pin statuses.
Could you please explain how to solve the problem with the appearance of an unknown character at the end of each line that is written to the serial port monitor (screenshot below) and whether the baudrate affects it?
There is also a problem with the function of reading channels, as indicated in this piece of code, no output to the log occurs
while(extSerial.available()) {
int c = extSerial.read();
Log.info("received %d", c);
}
I am adding my code that I adapted to my tasks, maybe I made a mistake in it, I will be very grateful if you indicate its availability
#include <SC16IS7xxRK.h>
// Pick a debug level from one of these two:
SerialLogHandler logHandler;
SYSTEM_THREAD(ENABLED);
SC16IS7x0 SerialA; // First SC16IS7xx module
SC16IS7x0 SerialB; // Second SC16IS7xx module
void setup() {
// If you want to see the log messages at startup, uncomment the following line
waitFor(Serial.isConnected, 10000);
// Initialize the first SC16IS7xx module
SerialA
.withSPI(&SPI, D5, 4) // SPI port, CS line (D5), speed in MHz
.begin(115200); // Set the baud rate for extSerial1 to 9600 (or your desired rate)
// Initialize the second SC16IS7xx module with a different CS line (D6)
SerialB
.withSPI(&SPI, D6, 4) // SPI port, second CS line (D6), speed in MHz
.begin(115200);
}
void loop() {
Print *port = &SerialA;
port->println("UART A working");
delay(1000);
port = &SerialB;
port->println("UART B working");
delay(1000);
while(SerialB.available()) {
int c = SerialB.read();
Log.info("received %d", c);
}
}
println adds a CR and LF at the end of each line. You probably need to change the setting of the popup that's currently set to Both NL and CR (next to the baud rate) to some other setting.