UNO R4 WiFi 3rd I2C Bus?

Update: The Arduino source code does support I2C on the SCI hardware. So in theory, it should be possible to create a TwoWire object for a new I2C bus.

Hi @Koepel - how do you create the SCI version and is it only available on D0/D1?

The pins definition has:

/****** UART CORE DEFINES ******/

#define SERIAL_HOWMANY		3
#define UART1_TX_PIN        22
#define UART1_RX_PIN        23
#define UART2_TX_PIN        1
#define UART2_RX_PIN        0
#define UART3_TX_PIN        24
#define UART3_RX_PIN        25

/****** WIRE CORE DEFINES ******/

#define WIRE_HOWMANY      2
#define WIRE_SDA_PIN      18 /* A4 */
#define WIRE_SCL_PIN      19 /* A5 */
#define WIRE1_SDA_PIN     27
#define WIRE1_SCL_PIN     26

Can you retain the Serial Monitor over USB if you change the Serial "HOWMANY" to 1 (pins 22 & 23) while commenting out UART2 & UART3?
Or does that break something not having UART2 and use SERIAL?

And if change the Wire "HOWMANY" to 3 and add WIRE2 for pins 1 & 0, how do you define them as SCI IIC instead if hardware I2C?

Wire.cpp "Version 2022 for Renesas RA4" looks like it has everything for SCI I2C.

And Wire.h

#include "r_sci_i2c.h"

But still can't seem to put it all together to make it work on D0/D1, or how to manually create an SCI I2C bus.
But will keep trying...

I'm thinking in this direction:

#include <Wire.h>

int sda_pin = ...
int scl_pin = ...

// The last parameter "true" is to select the SCI hardware.
TwoWire myWire(scl_pin, sda_pin, SPEED_STANDARD, ADDRESS_MODE_7_BITS, true);

void setup()
{
  myWire.begin();
}

void loop()
{

}

I don't know about the Serial communication to the computer, I forgot what I have read about it in the last days, sorry.

Hi @Koepel - my concern is why the Advanced Section of the full pinout only lists D0 & D1 as being potentially SCI Simple I2C capable?

Is there something 'under the hood' that is required to make it work, which might be present in the Wire library, but not officially supported?

I will try your suggestion.

If only we could ask the person responsible for the 2022 changes...

I didn't notice it before, but funny enough, the Uno R4 Wifi Cheat Sheet I2C section gives the example...

#include <Wire.h>
Wire.begin() //SDA & SDL
Wire1.begin(); //SDA1 & SDL1
Wire2.begin(); //SDA2 & SDL2

However, not matter what I try, I can't seem to communicate with a device on Wire2.

Thanks,

for some reason I never noticed that part.

I created my own cheat sheet, actually the Pin information extracted from their PDF, where I created a page in WIFI order and another in MINIMA order...

Wifi:

WIFI Main Usage Minima I/O ports LQFP64 Power, System, Clock,
Debug, CAC, VBATT
Interrupt AGT GPT_OPS, POEG GPT RTC USBFS,CAN SCI IIC SPI SSIE ADC14 DAC12, OPAMP ACMPLP SLCDC CTSU
0 Serial1 0 P301 31 IRQ6 AGTIO0 GTOULO GTIOC4B RXD2/
MISO2/
SCL2
CTS9_
RTS9/
SS9
SSLB2 SEG01/
COM5
TS09
1 Serial1 1 P302 30 IRQ5 GTOUUP GTIOC4A TXD2/
MOSI2/
SDA2
SSLB3 SEG02/
COM6
TS08
2 3 P104 44 KR04/
IRQ1
GTETRGB GTIOC1B RXD0/
MISO0/
SCL0
SSLA1 COM0 TS13
3 2 P105 43 KR05/
IRQ0
GTETRGA GTIOC1A SSLA2 COM1 TS34
4 6 P106 42 KR06 GTIOC0B SSLA3 COM2
5 7 P107 41 KR07 GTIOC0A COM3
6 13 P111 36 IRQ4 GTIOC3A SCK2
SCK9
RSPCKB CAPH TS12
7 10 P112 37 GTIOC3B TXD2/
MOSI2/
SDA2
SCK1
SSLB0 SSIBCK0 CAPL TSCAP
8 8 P304 28 IRQ9 GTIOC7A SEG20 TS11
9 9 P303 29 GTIOC7B SEG03/
COM7
TS02
10 4 P103 45 KR03 GTOWUP GTIOC2A CTX0 CTS0_
RTS0/
SS0
SSLA0 AN019 CMPREF1 VL4
11 P411 12 IRQ4 AGTOA1 GTOVUP GTIOC6A TXD0/
MOSI0/
SDA0
MOSIA SEG07 TS07
12 P410 13 IRQ5 AGTOB1 GTOVLO GTIOC6B RXD0/
MISO0/
SCL0
MISOA SEG08 TS06
13 5 P102 46 KR02 AGTO0 GTOWLO GTIOC2B CRX0 SCK0
TXD2/
MOSI2/
SDA2
RSPCKA AN020/
ADTRG0
CMPIN1 VL3
14 14(A0) P014 53 AN009 DA0
15 15(A1) P000 64 IRQ6 AN000 AMP0+ TS21
16 16(A2) P001 63 IRQ7 AN001 AMP0- TS22
17 17(A3) P002 62 IRQ2 AN002 AMP0O
18 18(A4/SDA) P101 47 KR01/
IRQ1
AGTEE0 GTETRGB GTIOC5A TXD0/
MOSI0/
SDA0
CTS1_
RTS1/
SS1
SDA1 MOSIA AN021 CMPREF0 VL2
19 19(A5/SCL) P100 48 KR00/
IRQ2
AGTIO0 GTETRGA GTIOC5B RXD0/
MISO0/
SCL0
SCK1
SCL1 MISOA AN022 CMPIN0 VL1
20 20 P500 49 AGTOA0 GTIU GTIOC2A USB_VB
USEN
AN016 CMPREF1 SEG34
22 Serial 11 P109 34 TDO/SWO/
CLKOUT
GTOVUP GTIOC1A CTX0 SCK1
TXD9/
MOSI9/
SDA9
MOSIB SEG23 TS10
23 Serial 12 P110 35 TDI IRQ3 GTOVLO GTIOC1B CRX0 CTS2_
RTS2/
SS2
RXD9/
MISO9/
SCL9
MISOB VCOUT SEG24
24 Serial2 / ESP32 P501 50 IRQ11 AGTOB0 GTIV GTIOC2B USB_OV
RCURA
TXD1/
MOSI1/
SDA1
AN017 CMPIN1 SEG35
25 Serial2 / ESP32 P502 51 IRQ12 GTIW GTIOC3B USB_OV
RCURB
RXD1/
MISO1/
SCL1
AN018 CMPREF0 SEG36
26 P400 1 CACREF IRQ0 AGTIO1 GTIOC6A SCK0
SCK1
SCL0 AUDIO_CL
K
SEG04 TS20
27 P401 2 IRQ5 GTETRGA GTIOC6B CTX0 CTS0_
RTS0/
SS0
TXD1/
MOSI1/
SDA1
SDA0 SEG05 TS19
28 P003 61 AN003 AMP1O
29 P004 60 IRQ3 AN004 AMP2O
30 P011 58 VREFL0 IRQ15 AN006 AMP2+ TS31
31 P012 55 VREFH AN007 AMP1-
32 P013 54 VREFL AN008 AMP1+
33 P015 52 IRQ7 AN010 TS28
34 P204 24 CACREF AGTIO1 GTIW GTIOC4B USB_OV
RCURB
SCK0
SCK9
SCL0 RSPCKB SEG14 TS00
35 P205 23 CLKOUT IRQ1 AGTO1 GTIV GTIOC4A USB_OV
RCURA
TXD0/
MOSI0/
SDA0
CTS9_
RTS9/
SS9
SCL1 SSLB0 SEG13 TSCAP
36 P206 22 IRQ0 GTIU USB_VB
USEN
RXD0/
MISO0/
SCL0
SDA1 SSLB1 SEG12 TS01
37 P212 10 EXTAL IRQ3 AGTEE1 GTETRGB GTIOC0B RXD1/
MISO1/
SCL1
38 P213 9 XTAL IRQ2 GTETRGA GTIOC0A TXD1/
MOSI1/
SDA1
21 (usb Switch) P408 15 IRQ7 GTOWLO GTIOC5B USB_ID CTS1_
RTS1/
SS1
RXD9/
MISO9/
SCL9
SCL0 SEG10 TS04

Again nothing special but file is up at: UNOR4-stuff/arduino_uno_r4.xlsx at main · KurtE/UNOR4-stuff · GitHub

And I did figure out for example how to use the extra Serial port, as I have added to my Serial port test program:

//connect  Serial1 TX -> Serial2 RX, Serial2 TX -> Serial3 RX, Serial3 TX -> Serial4 RX....

#if defined(ARDUINO_UNOR4_WIFI)
UART _UART4_(18, 19);
#else
UART _UART2_(18, 19);
#endif

#define SPD 115200
int loop_count = 0;

void setup() {
  pinMode(2, OUTPUT);
  pinMode(3, OUTPUT);
  pinMode(4, OUTPUT);
  pinMode(5, OUTPUT);
  pinMode(13, OUTPUT);
  while (!Serial && millis() < 4000) ;
  Serial.begin(115200);
  delay(800);
  Serial.println("Test all Serials");
  Serial.print("Baud rate: ");
  Serial.println(SPD, DEC);
  Serial1.begin(SPD);
#if defined(ARDUINO_UNOR4_WIFI)
  Serial3.begin(SPD);
#else
  Serial2.begin(SPD);
#endif
}

#define MIN(a, b) ((a) <= (b)? (a) : (b))
uint8_t buffer[80];

void loop() {

  int available;
  int available_for_write;
  int cb;

  if ((available = Serial.available()) != 0) {
    available_for_write = Serial1.availableForWrite();
    cb = MIN(MIN(available, available_for_write), sizeof(buffer));
    if (cb) {
      Serial.readBytes(buffer, cb);
      Serial1.write(buffer, cb);
    }
  }
  if ((available = Serial1.available()) != 0) {
    available_for_write = Serial.availableForWrite();
    cb = MIN(MIN(available, available_for_write), sizeof(buffer));
    if (cb) {
      Serial1.readBytes(buffer, cb);
      Serial.write(buffer, cb);
    }
  }

#if defined(ARDUINO_UNOR4_WIFI)
  if ((available = Serial3.available()) != 0) {
    available_for_write = Serial3.availableForWrite();
    cb = MIN(MIN(available, available_for_write), sizeof(buffer));
    if (cb) {
      Serial3.readBytes(buffer, cb);
      Serial3.write(buffer, cb);
    }
  }
#else
  if ((available = Serial2.available()) != 0) {
    available_for_write = Serial2.availableForWrite();
    cb = MIN(MIN(available, available_for_write), sizeof(buffer));
    if (cb) {
      Serial2.readBytes(buffer, cb);
      Serial2.write(buffer, cb);
    }
  }
#endif
  digitalWrite(5, HIGH);
  delayMicroseconds(100); // give time form things to propagate
  digitalWrite(5, LOW);
}

Hi @KurtE - I hope you don't mind a few questions.
The differences between the R4 WiFi and Minima get really confusing for me.
For now I am concentrating on the R4 WiFi because I want to use BLE.

So you created a UART4 on pins 18 & 19 correct?

The standard Pinout shows an SCI UART on D0 & D1 (P301 & P302).

It also shows a different UART on the ESP32-S3 header which is P109 & P110 (SCI9) according to the wiring diagram.
I believe this is the one used for the Serial Monitor back out to the USB port?

The pin definition for the WiFi variant has 3 UARTs:

/****** UART CORE DEFINES ******/

#define SERIAL_HOWMANY		3
#define UART1_TX_PIN        22
#define UART1_RX_PIN        23
#define UART2_TX_PIN        1
#define UART2_RX_PIN        0
#define UART3_TX_PIN        24
#define UART3_RX_PIN        25

From experimentation it seems like UART1 is for the Serial Monitor back through the USB port and UART3 is used by the BLE library, so it must also be tied to the ESP32-S3 (and the wiring diagram shows P501 & P502 (SCI1) traversing the level translator.

The advanced section of the Full Pinout shows an additional UART on D18 & D19 (P100 & P101) and that is what you have successfully enabled?

That's very cool.

So there is hope to somehow enable the SCI I2C (Wire2) on D0 & D1 (P301 & P302) even though they are defaulted to UART2?

Do you think that can be done while still using the Serial Monitor (USB) and BLE radio, which I believe are UART1 & UART3, but not really sure?

Thank you for your wisdom

Not a problem. Note I am new to these boards as well!
So take some of this with a grain of salt.

Correct

For the Wifi Board, there are 3 UARTS/Serial objects that are defined:
If you look at the header file: Arduino.h you will see:

#ifndef NO_USB
#define Serial  SerialUSB
#define Serial1 _UART1_
#define Serial2 _UART2_
#define Serial3 _UART3_
#define Serial4 _UART4_
#define Serial5 _UART5_
#else
#define Serial _UART1_
#define Serial1 _UART2_
#define Serial2 _UART3_
#define Serial3 _UART4_
#define Serial4 _UART5_
#endif

The Wifi board is built with NO_USB

So: Serial, which is our USB Serial (through the ESP32) is built using UART1 on pins 22, 23
which are TXD9/RXD9 or SCI 9

For Serial1 uses UART2 on pins 0, 1 - which are SCI 2

Serial2 -> UART3 pins 24/25 Are SCI 1, is used to communicate between the main processor and ESP32 and this is for Wifi and BLE. And Side note: SCI1 has FIFO hardware buffer. 2 and 9 - do not but instead have simple double buffer setup.

So I created Serial3 which by their defines maps to UART4 and so I looked for available SCI pins,
We are already using SCI(1, 2, 9), so the only left is SCI0, so I looked for TXD0/RXD0
Found TXD0 on 11, 18, 35 and RXD0 on 12, 19, 36
Have not tried 11 and 12 but 35, 36 are for the LED matrix so not easy to get to so I tried
18, 19 which worked.

Now the Minima does not have the ESP32 and uses the processor chips built in USB capabilities.
So the mapping for Serial->UARTx is different.
it only has defined Serial1 -> _UART1
So I used Serial2 in my example which goes to UART2

There is no reason why it should not work. Obviously you could not use the Serial1 object if those pins are doing something else.

To verify this, I pulled out an SSD1306 128x64 display. And I am using the Adafruit SSD1306 library. So I brought up their example sketch, modified it slightly as my display has I2C address 0x3c default was 0x3d and it worked..

So then moved it to pins 0, 1
Changed the sketch: To define and use Wire2.

#define SCREEN_ADDRESS 0x3C ///< See datasheet for Address; 0x3D for 128x64, 0x3C for 128x32
#define WIRE2_SCL_PIN 0
#define WIRE2_SDA_PIN 1
TwoWire Wire2(WIRE2_SCL_PIN, WIRE2_SDA_PIN);
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire2, OLED_RESET);

Rebuilt the sketch and the example stuff is running on the display.

Hope that helps

The 3rd I2C bus works!
Thank you @Koepel and @KurtE

I now have 3 active I2C buses along with BLE and the Serial Monitor working together.

I wish I could mark 2 solutions.
@Koepel 's post above does work, but I must have made a dumb mistake when originally trying to test it.
It really helped that @KurtE confirmed it.

It seems to work regardless of the prefer_sci bool being true or false.
I am leaving it set to true since the SCI IIC code seems to have been put in place for some purpose and that is how it appears to be classified on the full pinout diagram...

#include <Wire.h>

#define WIRE2_SCL_PIN 0
#define WIRE2_SDA_PIN 1
TwoWire Wire2(WIRE2_SCL_PIN, WIRE2_SDA_PIN, SPEED_STANDARD, ADDRESS_MODE_7_BITS, true);

void setup() 
{
   Wire2.begin();
}

void loop() 
{

}
1 Like

FYI - after upgrading to core 1.0.4 my 3rd I2C bus had to remove the "SPEED_STANDARD" parameter.

The code I was using...

#include <Wire.h>
#define WIRE2_SCL_PIN 0
#define WIRE2_SDA_PIN 1
TwoWire Wire2(WIRE2_SCL_PIN, WIRE2_SDA_PIN, SPEED_STANDARD, ADDRESS_MODE_7_BITS, true);

...gave the following error message:

'SPEED_STANDARD' was not declared in this scope
TwoWire Wire2(WIRE2_SCL_PIN, WIRE2_SDA_PIN, SPEED_STANDARD, ADDRESS_MODE_7_BITS, true);
^~~~~~~~~~~~~~

exit status 1

Compilation error: 'SPEED_STANDARD' was not declared in this scope

Hovering my mouse pointer over Wire2 for the hint showed:

TwoWire Wire2(WIRE2_SCL_PIN, WIRE2_SDA_PIN, <recovery - expr>(),ADDRESS_MODE_7_BITS, true)

Just removing SPEED_STANDRD works:

TwoWire Wire2(WIRE2_SCL_PIN, WIRE2_SDA_PIN, ADDRESS_MODE_7_BITS, true);

Peeking around the Wire library it appears they are defining RATE now independently.
Now I just need to confirm I can individually set all 3 I2C busses to different rates.

1 Like