#include when programming for Pico

Hi,

I have installed the Philhower core for Pico.

I'm trying to use I2C on Pico. I have plugged in the Pico and set the board and serial port but when I compile a few lines of code it does not seems to find the Philhower code base.

https://arduino-pico.readthedocs.io/en/latest/contrib.html#porting-libraries-and-applications-to-the-core

void setup() {
  // put your setup code here, to run once:
  
// detect Arduino-Pico (earlephilhower) core:
#ifdef ARDUINO_ARCH_RP2040
#define USE_PICO
#include <Wire.h>
  setSDA(17);
  setSCL(16);
//is pico
#else 
 not pico error
#endif

}

void loop() {
  // put your main code here, to run repeatedly:

}



sketch_apr11a:10:3: error: 'setSCL' was not declared in this scope
   10 |   setSCL(16);
      |   ^~~~~~
exit status 1
'setSDA' was not declared in this scope

With or without the #include it fails to compile.
I'm never sure what the IDE is or is not doing behind the scenes. What difference does it make selecting a board and how do I access the Philhower core code ?

Thx.

  setSDA(17);
  setSCL(16);

These function calls are not in a function. What happens if you move them and teh controlling code to setup() ?

Here are the functions setSDA() and setSCL(): https://github.com/earlephilhower/arduino-pico/blob/master/libraries/Wire/src/Wire.h#L48

#include <Wire.h>

void setup() 
{
  Wire.setSDA(17);  // wrong pin, choose a pin that is allowed.
  Wire.setSCL(16);  // wrong pin, choose a pin that is allowed.
  Wire.begin();
  ...
}

Why make it hard, if you can make it easy ? What is wrong with the default pins ? SDA = 4, SCL = 5.

It think that 17 is not allowed for SDA and 16 is not allowed for SCL.

Yes, of course, I should be specifying

Wire.setSDA()

At least it finds it now.

void setup() {
  // put your setup code here, to run once:
  
// detect Arduino-Pico (earlephilhower) core:
#ifdef ARDUINO_ARCH_RP2040
#define USE_PICO
#include <Wire.h>
  pin_size_t I2C1_SDA,I2C1_SCL;
  boolean pinsetOK;
  pinsetOK=Wire1.setSDA(I2C1_SDA) &&  Wire1.setSCL(I2C1_SCL);
  Wire1.begin();
//is pico
#else 
 not pico error
#endif

}
.arduino15/packages/rp2040/hardware/rp2040/3.7.2/libraries/Wire/src/Wire.h:42:10: warning: 'void setup()::TwoWire::begin()' used but never defined
   42 |     void begin() override;
      |          ^~~~~
/svn/stm32/.arduino15/packages/rp2040/hardware/rp2040/3.7.2/libraries/Wire/src/Wire.h:50:10: warning: 'bool setup()::TwoWire::setSCL(pin_size_t)' used but never defined
   50 |     bool setSCL(pin_size_t scl);
      |          ^~~~~~
.arduino15/packages/rp2040/hardware/rp2040/3.7.2/libraries/Wire/src/Wire.h:49:10: warning: 'bool setup()::TwoWire::setSDA(pin_size_t)' used but never defined
   49 |     bool setSDA(pin_size_t sda);
      |          ^~~~~~
exit status 1
Error compiling for board Raspberry Pi Pico.

A #include goes above the setup() function and preferably above the global variables.
Initialization code should be in the setup() function.

I gave something that works. Start with something that works, then slowly try to adjust it, keeping it working.

The 'C' and 'C++' language has very specific code syntax. It does not solve any mistake for you. At this moment it seems as if you are randomly throwing code around and hope that it works.

There is no "#ifdef MY_NAME_IS_EARLE" define to check for the core. I'm not sure that your solution will always work in the future.

Why make it hard when you can make it easy.
Is there a reason to use the second I2C bus ? Can you tell why ?
If you want to use Wire1, then why not use the default pins, SDA = 26, and SCL = 27.

#include <Wire.h>

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

#ifdef MY_NAME_IS_EARLE

LOL, is that real? Cool. The doc recommends:
#if defined(ARDUINO_ARCH_RP2040) && !defined(__MBED__)

https://arduino-pico.readthedocs.io/en/latest/contrib.html#porting-libraries-and-applications-to-the-core

Is there a reason to use the second I2C bus ? Can you tell why ?

I'm trying to port something else running on Teensy using Wire1, I just want a compiler switch to flip between them. When it didn't work, I just stripped out the essential lines to post something here. On Teensy : I2C1_SDA=17;

The 'C' and 'C++' language has very specific code syntax.

... which the IDE then messes with behind my back and creates main() in secret. :wink: And changing include search paths invisibly.

Since setup() is run once, what does it matter whether #include Wire.h is above or inside setup() as long as it is before the first reference to Wire1 ?

I put the include inside the ifdef because I'm anticipating the need to ensure it finds the right one: Teensy or Pico.

The main() function that the IDE adds does not mess with your sketch. It calls some functions necessary to set up the Arduino hardware, calls setup() once and then repeatedly calls loop()

In doing so it uses standard C/C++ syntax, so I don't know what your point is

My point is I don't know what it's doing ! Sometimes trying make things "simpler" by dumbing them down makes it more obscure and more complicated .

No! I made it up, some kind of TV series I think: https://en.wikipedia.org/wiki/My_Name_Is_Earl
Good to know that there is a recommended way.

An "include" is a text based include of that file, no matter what that file is. You can not put that in setup().
If your real questions is about portability between the Teensy and the Raspberry Pi Pico, then why don't you ask the real question ?

That's easy to answer. Here is the main() function from the Arduino IDE

/*
  main.cpp - Main loop for Arduino sketches
  Copyright (c) 2005-2013 Arduino Team.  All right reserved.

  This library is free software; you can redistribute it and/or
  modify it under the terms of the GNU Lesser General Public
  License as published by the Free Software Foundation; either
  version 2.1 of the License, or (at your option) any later version.

  This library is distributed in the hope that it will be useful,
  but WITHOUT ANY WARRANTY; without even the implied warranty of
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  Lesser General Public License for more details.

  You should have received a copy of the GNU Lesser General Public
  License along with this library; if not, write to the Free Software
  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
*/

#include <Arduino.h>

// Declared weak in Arduino.h to allow user redefinitions.
int atexit(void (* /*func*/ )()) { return 0; }

// Weak empty variant initialization function.
// May be redefined by variant files.
void initVariant() __attribute__((weak));
void initVariant() { }

void setupUSB() __attribute__((weak));
void setupUSB() { }

int main(void)
{
 init();

 initVariant();

#if defined(USBCON)
 USBDevice.attach();
#endif
 
 setup();
    
 for (;;) {
 loop();
 if (serialEventRun) serialEventRun();
 }
        
 return 0;
}

If you supply your own main() function in your sketch than it will be used instead of the standard one

Many thanks, I didn't realise that. I'll look at doing that. The less inherent jiving around the better, for my taste.

OK. What do I need to do to convert drehmflight controller to run on Pico?

Which drehmflight ? Please give more information. Links to it, everything. Not only the code, but a schematic as well.
Why do you want to convert it to a Raspberry Pi Pico ?

I'm not sure if I want to be part of that project. Running a fake MPU-6050 at a 1MHz I2C bus :scream:

How about I can get a Pico for about 1/10 the price?

Teensy are nice boards but pricey.

Nobody asked you to, that was your idea insisting on knowing what the "real problem" was.

The reason I posted here was simplified to a problem with using the IDE.

You did not explain why the #include does not work inside setup().

The IDE tries to dumb it down to "put your setup code here, to run once:" and "put your main code here, to run repeatedly:" but apparently this does not work.

What are you ranting on about ? What schematic?

I just found this github repo and wondered whether it could run on Pico instead of Teensy because those boards are prohibitively expensive for just messing around.

Skip the next couple of cups of cappuccino and maybe you'll be able to afford that "prohibitively expensive" Teensy.

Maybe you should not assume everyone buys $20 cappuccinos like you do.

That would be true if the .h file included only #define statements, but it is likely that it also has C code that isn't legal if it's inside a function. (actually, the log you quoted included only "warnings"; I'm not sure what the "error" was.)

You'll need two sets if #ifdef statements (or more); one for the #include, and one for the board-specific code in setup()