Can not upload to Raspberry Pi Pico

Any sketch, even the Blink example did not work.

Finally, I got it working :sweat_smile: Here's how I did it.

Start with Windows 10:

  • Download the 2.0 Beta exe-file and install it.
  • Turn on Verbose mode for Upload in the Preferences.
  • Add the Raspberry Pi Pico board.
  • Use the sketch below.
  • Connect the Pico board.
  • If there is no COM port yet, then the upload process will choose the file system. Everything should go automatically.
  • If that does not work, drop a UF2 file onto the Pico "disk", that makes the led blink. No reset needed. [EDIT] The link to that UF2 file was no longer valid
  • If the Pico "disk" is not shown, keep the BOOTSEL button pressed and connect the Pico board to the computer. When the Pico "disk" is connected, release the button.

In linux I did this:

  • Make it work in Windows 10 first.
  • If a modemmanager is installed, remove it.
  • Type groups in a terminal, the dialout must be part of it.
  • Download the 64-bit linux version of the 2.0 Beta and unpack it somewhere in a local folder.
  • Add the Pico board.
  • Turn on Verbose mode for Upload in the Preferences. Close the Arduino IDE.
  • Run the script as sudo: "~/.arduino15/packages/arduino/hardware/mbed_rp2040/2.2.0/post_install.sh". If you see a error message "post_install.sh: 12: [: Illegal number:", ignore it.
  • Start the Arduino IDE 2.0 Beta and connect the Pico board.
  • The serial port of the Pico board programmed in Windows does not work in linux. Use the BOOTSEL. Keep it pressed when connecting to the computer. Upload the sketch and it will use the filesystem. Only after that, it will upload via the new serial port /dev/ttyACM0
  • There will be many errors about serial ports, ignore them.
  • If there are still problems, then try again next day. The next day if might suddenly work better or worse.

This is the sketch that works in Windows and linux with or without the Arduino IDE.

// Raspberry Pi Pico with Arduino IDE 2.0.0-beta.8
// Test sketch

unsigned long previousMillisBlink;
unsigned long intervalBlink = 150;
unsigned long previousMillisTime;
const unsigned long intervalTime = 1000;

bool useSerial = true;

void setup() 
{
  pinMode(LED_BUILTIN, OUTPUT);

  // Wait for the Serial Monitor to be open.
  // But don't wait forever to let it run with just power.
  unsigned long t1 = millis();
  while(!Serial)    // Serial or SerialUSB, they are the same thing
  {
    if( millis() - t1 >= 2000)   // 2 seconds should be enough
    {
      useSerial = false;
      intervalBlink = 50;
      break;
    }
  }

  Serial.begin( 115200);

  // this delay was required during testing before the first Serial.println()
  // In Windows a delay of 200ms is required, in linux 500ms.
  delay( 500);      

  if( useSerial)
  {
    Serial.println( "The sketch has started");
    Serial.println( "Sketch compile time: " __DATE__ ", " __TIME__);
  }
}

void loop() 
{
  unsigned long currentMillis = millis();

  if( currentMillis - previousMillisBlink >= intervalBlink)
  {
    previousMillisBlink = currentMillis;

    // A digitalRead() on a output pin works.
    int ledState = digitalRead( LED_BUILTIN);
    ledState = ledState == HIGH ? LOW : HIGH;
    digitalWrite(LED_BUILTIN, ledState);
  }

  if( currentMillis - previousMillisTime >= intervalTime)
  {
    previousMillisTime += intervalTime;
 
    unsigned long seconds = millis() / 1000UL;   // works for the first 50 days

    if( useSerial)
    {
      if( seconds % 16 == 0)
        Serial.println();

      Serial.print( seconds);
      Serial.print( ", ");
    }
  }
}

[EDIT] Added a Serial.begin