What changes are necessary to port a sketch to a different board? (Uno to RP2040)

I have a Seeedxiao RP2040 (apparently equivalent to a Pi Pico), and I am trying, as a learning tool to install or port the tamaguino Arduino Uno project. I have successfully compiled the provided .ino file in the Arduino IDE with the "Arduino Uno" board selected. However, compiling the same .ino file with RP2040 board selected throws up the errors shown below.

I am very early in learning how to use Arduino code and Arduino IDE; I'm not looking to create a Tamaguino so I don't need to actually get this code to run. I just have no understanding of why the same code would throw errors when compiled for two different processors. (I know the pins and memory size are different, but this is something else). I haven't found any documentation that points to differences in the way that different boards would run the same code, except this discussion.

Can someone point me to documentation or similar sources that I should be referencing when trying to get code for one board to work on another? (Other than pin reference changes). Troubleshooting help would be appreciated, but what I really need is helping knowing what knowledge I'm missing to troubleshoot myself.

/Users/xavier/Desktop/tamaguino2/Tamaguino-noInputResistor/Tamaguino-noInputResistor.ino:368:1: warning: converting to non-pointer type 'char' from NULL [-Wconversion-null]
  368 | };
      | ^
/Users/xavier/Desktop/tamaguino2/Tamaguino-noInputResistor/Tamaguino-noInputResistor.ino:368:1: warning: converting to non-pointer type 'char' from NULL [-Wconversion-null]
/Users/xavier/Desktop/tamaguino2/Tamaguino-noInputResistor/Tamaguino-noInputResistor.ino:368:1: warning: converting to non-pointer type 'char' from NULL [-Wconversion-null]
/Users/xavier/Desktop/tamaguino2/Tamaguino-noInputResistor/Tamaguino-noInputResistor.ino:368:1: warning: converting to non-pointer type 'char' from NULL [-Wconversion-null]
/Users/xavier/Desktop/tamaguino2/Tamaguino-noInputResistor/Tamaguino-noInputResistor.ino:368:1: warning: converting to non-pointer type 'char' from NULL [-Wconversion-null]
/Users/xavier/Desktop/tamaguino2/Tamaguino-noInputResistor/Tamaguino-noInputResistor.ino:368:1: warning: converting to non-pointer type 'char' from NULL [-Wconversion-null]
/Users/xavier/Desktop/tamaguino2/Tamaguino-noInputResistor/Tamaguino-noInputResistor.ino:368:1: warning: converting to non-pointer type 'char' from NULL [-Wconversion-null]
/Users/xavier/Desktop/tamaguino2/Tamaguino-noInputResistor/Tamaguino-noInputResistor.ino:368:1: warning: converting to non-pointer type 'char' from NULL [-Wconversion-null]
/Users/xavier/Desktop/tamaguino2/Tamaguino-noInputResistor/Tamaguino-noInputResistor.ino: In function 'void loop()':
/Users/xavier/Desktop/tamaguino2/Tamaguino-noInputResistor/Tamaguino-noInputResistor.ino:508:12: error: invalid types 'int [3][float]' for array subscript
  508 |       poops[round(poopometer)]=random(20,display.width()+32);
      |            ^
/Users/xavier/Desktop/tamaguino2/Tamaguino-noInputResistor/Tamaguino-noInputResistor.ino:573:16: warning: cast to pointer from integer of different size [-Wint-to-pointer-cast]
  573 |             if((const char*)pgm_read_word(&(mainMenu[menu][subMenu+1]))==NULL){
      |                ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/Users/xavier/Desktop/tamaguino2/Tamaguino-noInputResistor/Tamaguino-noInputResistor.ino:586:16: warning: cast to pointer from integer of different size [-Wint-to-pointer-cast]
  586 |             if((const char*)pgm_read_word(&(mainMenu[menu][1]))!=NULL){
      |                ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/Users/xavier/Desktop/tamaguino2/Tamaguino-noInputResistor/Tamaguino-noInputResistor.ino:620:28: warning: cast to pointer from integer of different size [-Wint-to-pointer-cast]
  620 |           if(subMenu!=1 && (const char*)pgm_read_word(&(mainMenu[menu][1][0]))!=NULL){
      |                            ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/Users/xavier/Desktop/tamaguino2/Tamaguino-noInputResistor/Tamaguino-noInputResistor.ino:623:28: warning: cast to pointer from integer of different size [-Wint-to-pointer-cast]
  623 |           if(subMenu==1 && (const char*)pgm_read_word(&(mainMenu[menu][1][0]))==NULL){
      |                            ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/Users/xavier/Desktop/tamaguino2/Tamaguino-noInputResistor/Tamaguino-noInputResistor.ino:626:28: warning: cast to pointer from integer of different size [-Wint-to-pointer-cast]
  626 |           if(subMenu==1 && (const char*)pgm_read_word(&(mainMenu[menu][1][0]))!=NULL && menuDepth){
      |                            ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/Users/xavier/Desktop/tamaguino2/Tamaguino-noInputResistor/Tamaguino-noInputResistor.ino:629:14: warning: cast to pointer from integer of different size [-Wint-to-pointer-cast]
  629 |           if((const char*)pgm_read_word(&(mainMenu[menu][1][0]))!=NULL){
      |              ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/Users/xavier/Desktop/tamaguino2/Tamaguino-noInputResistor/Tamaguino-noInputResistor.ino:635:18: warning: converting to non-pointer type 'int' from NULL [-Wconversion-null]
  635 |           action=NULL;
      |                  ^~~~
/Users/xavier/Desktop/tamaguino2/Tamaguino-noInputResistor/Tamaguino-noInputResistor.ino:685:16: warning: converting to non-pointer type 'int' from NULL [-Wconversion-null]
  685 |         action=NULL;
      |                ^~~~
/Users/xavier/Desktop/tamaguino2/Tamaguino-noInputResistor/Tamaguino-noInputResistor.ino:715:28: error: invalid operands of types 'float' and 'int' to binary 'operator%'
  715 |       if(round(cloud1XPos) % 5 == 0){
      |          ~~~~~~~~~~~~~~~~~ ^ ~
      |               |              |
      |               float          int
/Users/xavier/Desktop/tamaguino2/Tamaguino-noInputResistor/Tamaguino-noInputResistor.ino:888:37: error: invalid operands of types 'float' and 'int' to binary 'operator%'
  888 |       if(paused && round(cloud1XPos)%2==0){
      |                    ~~~~~~~~~~~~~~~~~^~
      |                         |            |
      |                         float        int
/Users/xavier/Desktop/tamaguino2/Tamaguino-noInputResistor/Tamaguino-noInputResistor.ino:906:32: error: invalid operands of types 'float' and 'int' to binary 'operator%'
  906 |           if(round(cloud1XPos) % 3 ==0){
      |              ~~~~~~~~~~~~~~~~~ ^ ~
      |                   |              |
      |                   float          int
/Users/xavier/Desktop/tamaguino2/Tamaguino-noInputResistor/Tamaguino-noInputResistor.ino:914:32: error: invalid operands of types 'float' and 'int' to binary 'operator%'
  914 |           if(round(cloud1XPos) % 3 ==0){
      |              ~~~~~~~~~~~~~~~~~ ^ ~
      |                   |              |
      |                   float          int
/Users/xavier/Desktop/tamaguino2/Tamaguino-noInputResistor/Tamaguino-noInputResistor.ino: In function 'char* getItem(int, int)':
/Users/xavier/Desktop/tamaguino2/Tamaguino-noInputResistor/Tamaguino-noInputResistor.ino:1321:10: warning: address of local variable 'oneItem' returned [-Wreturn-local-addr]
 1321 |   return oneItem;
      |          ^~~~~~~
/Users/xavier/Desktop/tamaguino2/Tamaguino-noInputResistor/Tamaguino-noInputResistor.ino:1319:8: note: declared here
 1319 |   char oneItem [STRING_SIZE];
      |        ^~~~~~~

exit status 1

Compilation error: invalid types 'int [3][float]' for array subscript

Example: in e.g. the error for line 914 above, it appears that round() is returning a float value instead of integer. Why would round() return a float value when compiled here, but (presumably) return an integer when compiled for the Arduino Uno?

It comes down to how various things are implemented in each particular core.

If you take a look in Arduino.h for the AVR core, you'll find the following line:

#define round(x)     ((x)>=0?(long)((x)+0.5):(long)((x)-0.5))

So, with an AVR board, round() returns a long.

But if you look in Arduino.h for the RP2040 core you'll find the following:

// Try and make the best of the old Arduino abs() macro.  When in C++, use
// the sane std::abs() call, but for C code use their macro since stdlib abs()
// is int but their macro "works" for everything (with potential side effects)
#ifdef abs
#undef abs
#endif // abs
#ifdef __cplusplus
using std::abs;
using std::round;
#else
#define abs(x) ({ __typeof__(x) _x = (x); _x >= 0 ? _x : -_x; })
#define round(x) ({ __typeof__(x) _x = (x); _x >= 0 ? (long)(_x + 0.5) : (long)(_x - 0.5); })
#endif

With this core, and c++ code, you don't use the macros like you did with the AVR code, but std::round instead. Which returns some manner of floating point number depending on how it's used, but definitely not a long or int.

The answer to the topic question is pretty much: whatever needs to be changed. There's not going to be a fast and hard list of things. It'll depend on what functions you call and how they're implemented. You're just going to have to work your way through each error and warning.

We won't even talk about library incompatibilities; you'll run into those soon enough!

Did someone say "round()" ? https://github.com/arduino/ArduinoCore-API/issues/76

This is the answer I needed. I hadn't even heard the term "core" during my previous googling, much less knew I could read it so easily! This opens up a whole new world of stuff to review. Thanks!

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.