Critical R4 WiFi defects and limitations to know before you waste your time

Very helpful, david_2018. Thank you.

With the i2c expansion board was the issue that it was not recognized on the bus, or once connected it did not perform as expected?

I want to honor your curiosity, so I'll recount some of the error messages I saw, but I don't want to dive down a troubleshooting rabbit hole with this or any other issue I've noted. If you or anyone else can produce a working sketch and the expansion board it worked with I will gratefully acknowledge my error and delete this particular post. Same for all the other issues.


I2C Scanner
Scanning...
...hung there and never changed


Scanning...
Unknown error at address 0x01
Unknown error at address 0x02
Unknown error at address 0x03
Unknown error at address 0x04
Unknown error at address 0x05
...etc, etc.


No devices found.


Error initializing MCP23017. Check wiring!
...Wiring was perfect, triple-checked


No I2C Devices Found

When was the last time you tried it? A fix for this bug was made last year:

It was released in version 1.2.1 of the "Arduino UNO R4 Boards" platform, released 2024-09-16.

When an Arduino Cloud IoT Thing connects to the Arduino Cloud server, the RTC's time is synced with an NTP server. NTP servers return Coordinated Universal Time (UTC). If you find that you get unexpected time values after the RTC has been synced with an NTP server, this that your code is expecting the RTC to be set with the local time. The correct approach is for your code to expect the RTC to be set with UTC time, then if you want local time, apply the appropriate offset.

The ArduinoIoTCloud library used by Thing sketches to communicate with the Arduino Cloud IoT service provides a getLocalTime() function that provides the local time. This is for the time zone that is configured in the metadata of the Thing. You can use it in your Thing sketch code like this:

ArduinoCloud.getLocalTime()

Which one? Just a chip or board like one from Waveshare.

Which pins are you you using to hook it up?

Which I2C scanner sketch?

Details help. As maybe using wrong Wire device. Maybe missing or improper pull-up resistors.

Some earlier threads suggested inserting a short delay

I don't know about the problems claimed by the AI (I've already expressed my feelings about those claims), but the basic functionality works fine for me.

I uploaded this sketch that writes a value to EEPROM:

#include <EEPROM.h>

void setup() {
  EEPROM.write(0, 123);
}

void loop() {}

Then I uploaded this sketch that reads the value and prints it to Serial:

#include <EEPROM.h>

void setup() {
  Serial.begin(9600);
  delay(1000);  // Give time for serial connection to initialize
  Serial.println(EEPROM.read(0));
}

void loop() {}

@catjampow if you try that, do you see 123 printed in Serial Monitor as expected?

Cool.

Thank you KurtE.

To honor your curiosity, I'll share the info below, but as I wrote to cattledog earlier, I don't want to dive down a troubleshooting rabbit hole with this or any other issue I've noted. If you want to help, produce a working sketch and the expansion board it worked with. If you can, I will gratefully acknowledge my error and your expertise and delete or revise this particular post. Same for all the other issues.

CQRobot MCP23017 IO Expansion Board Compatible with Raspberry Pi/Micro:bit/Arduino/STM32. I2C Interface Control, 2 Signal Pins Increase to 16 Input/Output Pins, Supports UP to 8 Simultaneous Uses. (Amazon)

Thank you, prtillsch. This is very helpful.

I have edited my post on this issue to point to your solution with the caveat that your RTC time then is now only as good as the last time you successfully invoked ArduinoCloud.getLocalTime() minus whatever drift the onboard RTC experiences. For accurate time all the time the solution is to install an external, battery-operated clock, such as an Adafruit DS3231.

I should clarify that EEPROM worked in the sense that it captured the bit of info it was supposed to capture, but not reliably as near as I could tell. As I said, my observations may have been confounded by my RTC issues.

It seems there might be a misunderstanding. ArduinoCloud.getLocalTime() generally only reads the time value from the RTC.

The RTC's time is set by the ArduinoCloud.update() call after the connection to the network has been made:

Click here to reveal code references

https://github.com/arduino-libraries/ArduinoIoTCloud/blob/2.6.1/src/utility/time/TimeService.cpp#L303-L332

unsigned long TimeServiceClass::getRemoteTime()
{
  if(connected()) {
#ifdef HAS_TCP
    /* At first try to obtain a valid time via NTP.
     * This is the most reliable time source and it will
     * ensure a correct behaviour of the library.
     */
    if(_con_hdl->getInterface() != NetworkAdapter::CELL) {
      unsigned long const ntp_time = NTPUtils::getTime(_con_hdl->getUDP());
      if(isTimeValid(ntp_time)) {
        return ntp_time;
      }
    }
    DEBUG_WARNING("TimeServiceClass::%s cannot get time from NTP, fallback on connection handler", __FUNCTION__);
#endif  /* HAS_TCP */

    /* As fallback if NTP request fails try to obtain the
     * network time using the connection handler.
     */
    unsigned long const connection_time = _con_hdl->getTime();
    if(isTimeValid(connection_time)) {
      return connection_time;
    }
    DEBUG_WARNING("TimeServiceClass::%s cannot get time from connection handler", __FUNCTION__);
  }

  /* Return known invalid value because we are not connected */
  return EPOCH;
}

And then periodically:

Click here to reveal code references

https://github.com/arduino-libraries/ArduinoIoTCloud/blob/2.6.1/src/ArduinoIoTCloudThing.cpp#L147-L172

ArduinoCloudThing::State ArduinoCloudThing::handleConnected() {
  /* Check if a primitive property wrapper is locally changed.
  * This function requires an existing time service which in
  * turn requires an established connection. Not having that
  * leads to a wrong time set in the time service which inhibits
  * the connection from being established due to a wrong data
  * in the reconstructed certificate.
  */
  updateTimestampOnLocallyChangedProperties(getPropertyContainer());

  /* Configure Time service with timezone data:
  * _utcOffset [offset + dst]
  * _utcOffsetExpireTime [posix timestamp until _utcOffset is valid]
  */
  if (_utcOffsetProperty->isDifferentFromCloud() ||
      _utcOffsetExpireTimeProperty->isDifferentFromCloud()) {
    _utcOffsetProperty->fromCloudToLocal();
    _utcOffsetExpireTimeProperty->fromCloudToLocal();
    TimeService.setTimeZoneData(_utcOffset, _utcOffsetExpireTime);
  }

  /* Check if any property needs encoding and send them to the cloud */
  Message message = { PropertiesUpdateCmdId };
  deliver(&message);

  if (getTime() > _utcOffsetExpireTime) {

The only time calling ArduinoCloud.getLocalTime() will set the RTC is if the RTC has not already been configured, or if more than 24 hours have passed since the last time a sync with the NTP server was performed:

Click here to reveal code references

Edited to refer to ArduinoCloud.update() rather than ArduinoCloud.getLocalTime(). Now reads, "However, your RTC time then is now only as good as the last time your sketch successfully calls ArduinoCloud.update()."

You must call ArduinoCloud.update() regularly in the Arduino Cloud IoT Thing sketch in order for it to work correctly.

Fixed.

Sorry it is not just my curiosity. But what I was asking for is the generic type information,
that should be posted for any problems you might be having, with this or other boards.

That is maybe a simple description of what you are trying to do, a picture of your wiring and link to your device. what code you are actually running. That way it is easy for some of
us to take a quick look and maybe have suggestions.

But in this case, I was curious and ordered a board. Not the same one as yours:
Amazon.com: Waveshare MCP23017 IO Expansion Board I2C Interface Expands 16 I/O Pins Compatible with Both 3.3V and 5V Levels : Electronics
But looks more or less identical.

I first ran it using the I2C scanner and my first hiccup was I plugged the power pin to VIN
on the UNO R4 and nothing worked...

Been a while since I played with this board, and forgot WIN is not hooked up to the USB power... Moved to +5v pin and the LED on the MCP23017 lit up... Then the Wire Scanner showed this board as there.

Note: I am using my own version of wire scanner
UNOR4-stuff/test_sketches/Wire_Scanner_all_UnoR4 at main · KurtE/UNOR4-stuff
I slightly modified it to remove the extra Wire object that one can create.

Output:

Scanning(Wire)...
Device found at address 0x27  (MCP23017,MCP23008,PCF8574,LCD16x2,DigoleDisplay)
done

Scanning(Wire1)...
No I2C devices found

Scanning(Wire)...
Device found at address 0x27  (MCP23017,MCP23008,PCF8574,LCD16x2,DigoleDisplay)
done
...

Note: It is not uncommon for a wire scanner to semi-hang and/or take a long time
to scan or shows lots of errors, if there are no devices attached to the wire bus?
Or more specifically if there are no PULL-UP resistors on the SCL/SDA IO lines,
which leaves the IO level floating. In this case the MCP board has weak PUs (10K)
on it so that can take care of the issue. In some cases you might need stronger one.

If you look at the wire section of the Cheat Sheet:
Arduino UNO R4 WiFi User Manual | Arduino Documentation

The pullups are not mounted on the PCB but there are footprints to do so if needed.

I have the Adafruit MCP23017 library installed:
I loaded up their example mcp23xx_button sketch.

I modified it by changing it to use the 17 and not the 8

//Adafruit_MCP23X08 mcp;
Adafruit_MCP23X17 mcp;

I told it which wire object to talk to:
if (!mcp.begin_I2C(0x27)) {

And it started up.
At first you did not see anything, but I then jumper from PA1 to GND and started to print

Button Pressed!
Button Pressed!
Button Pressed!

Until I removed the jumper.

Hope that helps...

Post #8 seems to be somewhat inaccurate as well as a little vague.

As a matter of curiosity, what metrics were used to determine its reliability and what statistical conclusions did you reach? What specific reliability issues did you encounter or observe that led you to conclude that information was stored "but not reliably as near as I could tell"? Do you have a code example to demonstrate this?

The R4 has two programmable chips - the ESP32 WiFi module and the Renesas R4AM1. The R4AM1 does have native EEPROM memory. The limitations of EEPROM in general and as applied to some Atmel chips have been known for a long time. Usually the amount of EEPROM available is very small and there have been concerns expressed regarding its longevity. However, I have a project that was published some 5 years ago that makes use of EEPROM memory to store settings and to date haven't received any significant complaint about problems in that area. That is not to say that problems might not occur, but at the same time I am not convinced that they are as pervasive or as frequent as is sometimes implied or that has been indicated by the AI bot used to generate/supplement the information in that post . It should also be borne in mind that the target audience for Arduino is education/hobbyist rather than professional or industrial deployment. I am not yet aware of what the word is on the longevity of EEPROM memory in the Renesas R4AM1? Its a completely different beast to the older Atmel 8-bit chips.

On the other hand, as correctly stated, Espressif did not implement EEPROM on their ESP32 series modules, a fact that can be determined by consulting the ESP32 datasheet. I presume this is the chip being referred to as Arduino R4 WiFi thereby conflating the UNO R4 board as a whole with the onboard ESP32 module. For compatibility reasons and convenience, the Arduino framework does implement an emulation of EEPROM using flash memory as a "workaround" which for that reason might not be particularly efficient, however the programmer is not tied to using that approach. The LittleFS filesystem can be used instead and configuration parameters or data stored in a file.

Thank you, KurtE,

You have proved a number of points: A) It is indeed possible to connect an I2C expansion board to an R4 Wifi and read a pin. B) To pull that off on your own you need to have true mastery of Arduino and its vagaries. C) Absent that, you must have at least advanced beginner skills, real perseverance, and you must rely on the kind of expert advice that is so generously offered in this forum.

To answer your question, I ran out of pins for my project and simply wanted more to work with.

I have been learning about Arduino for about four months now. I'm automating my chicken coop which now bristles with sensors, cameras, reed switches, and a stepper motor. I have vibe coded my way through the whole thing, including setting up ESP32-CAMS, a LAMP server, and an Amazon AWS instance. I'm not especially passionate about electronics, but I was certainly drawn to Arduino's founding vision, which is to simplify electronics enough so they become accessible to artists and other lay folk. Obviously, I had no idea of the complexities and limitations that lay before me when I started, but I'm THIS CLOSE to realizing my dream. For sure, I wish it was easier and, if I'm being honest, many of the things I've pointed out seem like they ought to be much more readily accessible than they are, especially in light of Arduino's mission.

I'm not knowledgeable on this subject, but I see this on the Renesas RA4M1 product page:

https://www.renesas.com/en/products/microcontrollers-microprocessors/ra-cortex-m-mcus/ra4m1-32-bit-microcontrollers-48mhz-arm-cortex-m4-and-lcd-controller-and-cap-touch-hmi#overview

  • 8kB Data Flash to store data as in EEPROM

and the EEPROM library bundled with the "Arduino UNO R4 Boards" platform does use flash:

Renesas provides specs for the data flash memory in table 48.72 of the "Renesas RA4M1 Group User’s Manual: Hardware" document:

https://www.renesas.com/en/products/microcontrollers-microprocessors/ra-cortex-m-mcus/ra4m1-32-bit-microcontrollers-48mhz-arm-cortex-m4-and-lcd-controller-and-cap-touch-hmi#documents

Table 48.72 Data flash characteristics (1)

Parameter Symbol Min Typ Max Unit Test conditions
Reprogramming/erasure cycle*1 NDPEC 100,000 1,000,000 - Times -
Data hold time after 10,000 times of NDPEC tDDRP 20*2, *3 - - Year Ta = +85°C
Data hold time after 100,000 times of NDPEC tDDRP 5*2, *3 - - Year Ta = +85°C
Data hold time after 1,000,000 times of NDPEC tDDRP - 1*2, *3 - Year Ta = +25°C
  • Note 1. The reprogram/erase cycle is the number of erasure for each block. When the reprogram/erase cycle is n times (n = 100,000),
    erasing can be performed n times for each block. For instance, when 1-byte programming is performed 1,000 times for different
    addresses in 1-byte blocks, and then the entire block is erased, the reprogram/erase cycle is counted as one. However,
    programming the same address for several times as one erasure is not enabled. Overwriting is prohibited.
  • Note 2. Characteristics when using the flash memory programmer and the self-programming library provided by Renesas Electronics.
  • Note 3. These results are obtained from reliability testing.

To tell the truth, what you are describing are not real drawbacks of the board, but simply a conflict between your expectations and reality.

Hi b707,

I think it's worth quoting Arduino's marketing page for the R4 WiFi and a thoughtful statement from another poster.

Arduino's marketing page for the R4 Wifi says the following:

"Hardware compatibility with UNO form factor: The UNO R4 WiFi maintains the same form factor, pinout, and 5 V operating voltage as its predecessor, the UNO R3, ensuring a seamless transition for existing shields and projects."

Yet, david_2018 noted:

"Unfortunately the UNO R4 WiFi is not compatible with a lot of libraries, particularly older libraries that are not actively supported...One of the major failings of the R4 is that it has UNO in the name, leading to way too many people expecting it to be a drop-in replacement for a classic UNO."

I know you are smart enough and well-versed enough to know that there are lots of other examples. The point is that there are somethings that look outwardly possible on this board that are either impossible or far beyond most people, and it sure would be helpful if people could know what they were in advance.

@catjampow
You are not the first who guessed that the name Uno R4 is not suitable for this board. Look - I wrote almost the same thing 2 years ago:

The whole (and only) problem with this board is that beginners take it as "same as Uno R3, but better" - and expect that everything written for the R3 version will work here too. But this is not so.

This is a completely different board. In the Arduino family, there are many boards that are also completely incompatible with "old Uno" - for example, Nano ESP32 or RP2040. But nobody scolds these boards for the fact that sketches from the examples for R3 do not work on them.