Uno r4 Wifi gives <util\delay> not found error with SSH1106 display

I am having problems getting a SH1106 OLED 1.3" display working with the r4 wifi.
I have a setup where I am using a satellite receiver and showing Lat & Long degrees on an OLED display. It works fine with 0.9" SSD1306 but I wanted slightly bigger.
I have all the correct library's installed and the setup works with nano & SSH1106 display but not with Uno r4 Wifi.

C:\Users\vaughn\Documents\Arduino\libraries\Adafruit_SH1106\Adafruit_SH1106.cpp:31:11: fatal error: util/delay.h: No such file or directory
#include <util/delay.h>
^~~~~~~~~~~~~~
compilation terminated.
exit status 1
Error compiling for board Arduino Uno R4 WiFi.

The error means that Adafruit_SH1106 library is not adapted to Uno R4 yet.

1 Like

Sorry, I could be wrong, but I am not sure if that library is one that is maintained by Adafruit.

Is it the one that is located up at: davidperrenoud/Adafruit_SH1106: SH1106 oled driver library for 'monochrome' 128x64 and 128x32 OLEDs! (github.com) ?

Unfortunately, I don't think this one will be as simple to resolve as to simply remove using the usage of the header file. As I believe this library uses things like portOutputRegister and the like, which are not compatible with the the AVR versions.

However possibly another option, is to maybe try the Adafruit library: Adafruit_SH110x
image

I don't know how specific that library is, to their setup, but the do have two examples:

I verified the SPI version compiled.

I have not tried it on any of these displays yet. I may have one around here, but recently I tried to organize things, and as such can not find anything :slight_smile:

Hope that helps

1 Like

I don't think so. The reason is that the line number in the error message (31):

Doesn't match the location in the code of that repo:

But this one does match:

1 Like

In any way, the both files includes this line, so the both wont be compiled on R4 board...

1 Like

That line isn't really the issue. It is trivial to disable the #include directive, as was already done for the ATSAM3X8E-based boards (e.g., Due) in the library code. It doesn't appear that the declarations from that header are even referenced by the code so there isn't any side effect from its disabling.

Unfortunately, as KurtE already noted, fixing that problem only gets you to the next problems caused by incompatibilities in other parts of the code. For example, if I compile this sketch for the UNO R4 WiFi after disabling that #include directive:

#include <Adafruit_SH1106.h>
void setup() {}
void loop() {}

Compilation fails:

In file included from C:\Users\per\AppData\Local\Arduino15\packages\arduino\hardware\renesas_uno\1.0.2\libraries\Wire/Wire.h:23:0,
                 from c:\Users\per\Documents\Arduino\libraries\Adafruit_SH1106-master\Adafruit_SH1106.cpp:35:
c:\Users\per\Documents\Arduino\libraries\Adafruit_SH1106-master\Adafruit_SH1106.cpp: In member function 'void Adafruit_SH1106::begin(uint8_t, uint8_t, bool)':
C:\Users\per\AppData\Local\Arduino15\packages\arduino\hardware\renesas_uno\1.0.2\cores\arduino/Arduino.h:76:92: error: cannot convert 'volatile uint16_t* {aka volatile short unsigned int*}' to 'PortReg* {aka volatile unsigned char*}' in assignment
 #define portOutputRegister(port)    &(((R_PORT0_Type *)IOPORT_PRV_PORT_ADDRESS(port))->PODR)
                                                                                            ^
c:\Users\per\Documents\Arduino\libraries\Adafruit_SH1106-master\Adafruit_SH1106.cpp:179:19: note: in expansion of macro 'portOutputRegister'
     csport      = portOutputRegister(digitalPinToPort(cs));
                   ^~~~~~~~~~~~~~~~~~
C:\Users\per\AppData\Local\Arduino15\packages\arduino\hardware\renesas_uno\1.0.2\cores\arduino/Arduino.h:76:92: error: cannot convert 'volatile uint16_t* {aka volatile short unsigned int*}' to 'PortReg* {aka volatile unsigned char*}' in assignment
 #define portOutputRegister(port)    &(((R_PORT0_Type *)IOPORT_PRV_PORT_ADDRESS(port))->PODR)
                                                                                            ^
c:\Users\per\Documents\Arduino\libraries\Adafruit_SH1106-master\Adafruit_SH1106.cpp:181:19: note: in expansion of macro 'portOutputRegister'
     dcport      = portOutputRegister(digitalPinToPort(dc));
                   ^~~~~~~~~~~~~~~~~~
C:\Users\per\AppData\Local\Arduino15\packages\arduino\hardware\renesas_uno\1.0.2\cores\arduino/Arduino.h:76:92: error: cannot convert 'volatile uint16_t* {aka volatile short unsigned int*}' to 'PortReg* {aka volatile unsigned char*}' in assignment
 #define portOutputRegister(port)    &(((R_PORT0_Type *)IOPORT_PRV_PORT_ADDRESS(port))->PODR)
                                                                                            ^
c:\Users\per\Documents\Arduino\libraries\Adafruit_SH1106-master\Adafruit_SH1106.cpp:187:21: note: in expansion of macro 'portOutputRegister'
       clkport     = portOutputRegister(digitalPinToPort(sclk));
                     ^~~~~~~~~~~~~~~~~~
C:\Users\per\AppData\Local\Arduino15\packages\arduino\hardware\renesas_uno\1.0.2\cores\arduino/Arduino.h:76:92: error: cannot convert 'volatile uint16_t* {aka volatile short unsigned int*}' to 'PortReg* {aka volatile unsigned char*}' in assignment
 #define portOutputRegister(port)    &(((R_PORT0_Type *)IOPORT_PRV_PORT_ADDRESS(port))->PODR)
                                                                                            ^
c:\Users\per\Documents\Arduino\libraries\Adafruit_SH1106-master\Adafruit_SH1106.cpp:189:21: note: in expansion of macro 'portOutputRegister'
       mosiport    = portOutputRegister(digitalPinToPort(sid));
                     ^~~~~~~~~~~~~~~~~~
c:\Users\per\Documents\Arduino\libraries\Adafruit_SH1106-master\Adafruit_SH1106.cpp:197:11: error: 'class arduino::ArduinoSPI' has no member named 'setClockDivider'
       SPI.setClockDivider (SPI_CLOCK_DIV2); // 8 MHz
           ^~~~~~~~~~~~~~~
c:\Users\per\Documents\Arduino\libraries\Adafruit_SH1106-master\Adafruit_SH1106.cpp:197:28: error: 'SPI_CLOCK_DIV2' was not declared in this scope
       SPI.setClockDivider (SPI_CLOCK_DIV2); // 8 MHz
                            ^~~~~~~~~~~~~~
c:\Users\per\Documents\Arduino\libraries\Adafruit_SH1106-master\Adafruit_SH1106.cpp:197:28: note: suggested alternative: 'AGT_CLOCK_P402'
       SPI.setClockDivider (SPI_CLOCK_DIV2); // 8 MHz
                            ^~~~~~~~~~~~~~
                            AGT_CLOCK_P402
c:\Users\per\Documents\Arduino\libraries\Adafruit_SH1106-master\Adafruit_SH1106.cpp: In member function 'void Adafruit_SH1106::display()':
c:\Users\per\Documents\Arduino\libraries\Adafruit_SH1106-master\Adafruit_SH1106.cpp:551:28: error: 'TWBR' was not declared in this scope
       uint8_t twbrbackup = TWBR;
                            ^~~~

exit status 1

Compilation error: exit status 1
2 Likes

Interestingly, just a week ago I adapted this particular library to another third-party board support package. When you listed the errors - I immediately remembered it.
As for the TWBR line, it must be enclosed in a conditional compilation directive like the file above.
But the line concerning the portOutputRegister(port) is, as I think, a mistake by the creators of R4, this macro must be defined for each new board. Also for the lines about a SPI divisors.

1 Like

@KurtE :guardsman: :guardsman: :guardsman: saved by the cavalry!
I had seen the SH110X in examples, Thought it was for SH1106G and wouldn't work with my display.
Thanks again

Thanks @ptillisch,

I noticed that the line number was not the same, but was not sure if due to different version of the library or not... Noticed that it had some outstanding Pull Requests and issues. Not sure how you handle cases like this, where for example, it looks like the last change that was pulled in was something like 8 years ago. Likewise, the one you found, looks like it has not been updated in maybe 7 years.

I am not sure what approach or policy Arduino does or should do for handling stagnant libraries who may not be actively maintained, but are maybe still widely in use...

Luckily in this case, there is hopefully a better, more up to date and maintained library that will work for this display.

@VaughnByrne - hope it works for you! I believe I ran into a similar question, on a different board, most likely a Teensy and I believe it worked at least for the display that they used...

As I mentioned, in previous response, I think I may have one of them around here somewhere. It is probably in one of these two tubs:

Although I have others still more recently used ones scattered on my desk and shelves or maybe a different box. Like should a display with qwiic connectors go in these boxes or my sparkfun qwiic box ... :smiley:

Just some of the stuff I have collected, or probably horded, for testing out stuff, like this. Or for drivers that a few of us like, @Merlin513 and myself have worked on, like probably one of the last ones, we played with:
image

Which is a GC9A01A
Sorry I digressed here...

Again hope it works and good luck

Oops! I didn't say did I? Yes it worked perfectly.
Hence the cavalry reference.

Someone with the capacity to update and maintain the library can make a fork of the library repository, pull in any valuable work from the pull requests in the parent repository, and make copies of any unresolved valid issue reports in the parent repository.

The Arduino organization does not have any direct control over 3rd party projects. Arduino team members sometimes submit pull requests or issues to 3rd party projects, just as any other member of the community might do.

There is some indirect control in that the Arduino organization does have discretion over which libraries are distributed via the Library Manager system. However, removing a library is only done when a report of serious malicious, illegal, or unethical content is received and confirmed. Such a thing is very rare. I think it might have happened only once (due to a library code's infringement on the original author's copyright by blatant and persistent non-compliance with the open source license granted by the author). But that wouldn't apply in this case, both because there is nothing malicious/illegal/unethical in this library and because the library isn't listed in Library Manager.

Indeed. Even though it is interesting to discuss the subject of what to do about unmaintained open source projects in general, in this particular case I don't think it would be worth the effort to try to revive one of those unmaintained libraries.