Example "MultipleBlinks" does not work (solved 2nd)

With Ardouno IDE 2.0.0 beta7: Compile and upload works.
According to the description, the multi-color LED should be switched on and off. As described, I entered '1' and '0', text is displayed, but the LED does nothing.

Please post the code so that we don't have to guess what you are referring to

Are you a robot? I cannot assess this answer otherwise!
Why should I copy here an example that can be reached in the IDE with 2 mouse clicks?

Have it your own way and do not make it as easy as possible to provide help

All of those examples build elf and not uf2 for me - so it's definitely not running for me.

WARNING: library Scheduler claims to run on mbed architecture(s) and may be incompatible with your current board which runs on mbed_nano architecture(s).
Sketch uses 79452 bytes (0%) of program storage space. Maximum is 16777216 bytes.
Global variables use 53348 bytes (19%) of dynamic memory, leaving 216988 bytes for local variables. Maximum is 270336 bytes.
/home/user/.arduino15/packages/arduino/tools/rp2040tools/1.0.2/rp2040load -v -D /tmp/arduino_build_210032/MultipleBlinks.ino.elf 

Not sure if you're having the same problem but they do not even load directly from the Arduino IDE for me.

Here's what I had to do to get MultipleBlinks to load.

  1. Export the binary through the UI
  2. Find elf2utf2 (mine was in ~/.arduino15/packages/arduino/tools/rp2040tools/1.0.2/elf2utf2)
  3. Run elf2utf2 against the exported binary
  4. Put the Connect in bootloader mode (hit the button twice)
  5. Copy the utf2 binary to the storage device

When it comes back online it still doesn't work. You can use the serial port to type '0' or '1' like the example says and you'll see "Led turned off!" but nothing happens with the RGB LED.

Edit: Nothing happens because those pins aren't defined in the pins.h for this board :upside_down_face:

Hello all.

Here's the sketch:

https://github.com/arduino/ArduinoCore-mbed/blob/2.1.0/libraries/Scheduler/examples/MultipleBlinks/MultipleBlinks.ino

#include <Scheduler.h>

int led1 = LEDR;
int led2 = LEDG;
int led3 = LEDB;

void setup() {
  Serial.begin(9600);

  // Setup the 3 pins as OUTPUT
  pinMode(led1, OUTPUT);
  pinMode(led2, OUTPUT);
  pinMode(led3, OUTPUT);

  // Add "loop2" and "loop3" to scheduling.
  // "loop" is always started by default.
  Scheduler.startLoop(loop2);
  Scheduler.startLoop(loop3);
}

// Task no.1: blink LED with 1 second delay.
void loop() {
  digitalWrite(led1, HIGH);

  // IMPORTANT:
  // When multiple tasks are running 'delay' passes control to
  // other tasks while waiting and guarantees they get executed.
  delay(1000);

  digitalWrite(led1, LOW);
  delay(1000);
}

// Task no.2: blink LED with 0.1 second delay.
void loop2() {
  digitalWrite(led2, HIGH);
  delay(100);
  digitalWrite(led2, LOW);
  delay(100);
}

// Task no.3: accept commands from Serial port
// '0' turns off LED
// '1' turns on LED
void loop3() {
  if (Serial.available()) {
    char c = Serial.read();
    if (c == '0') {
      digitalWrite(led3, LOW);
      Serial.println("Led turned off!");
    }
    if (c == '1') {
      digitalWrite(led3, HIGH);
      Serial.println("Led turned on!");
    }
  }

  // IMPORTANT:
  // We must call 'yield' at a regular basis to pass
  // control to other tasks.
  yield();
}

Here's the fix:

In order to make this sketch work for the Nano RP2040 Connect, it's necessary to change these lines:

int led1 = LEDR;
int led2 = LEDG;
int led3 = LEDB;

to this:

#include <WiFiNINA.h>
NinaPin led1 = LEDR;
NinaPin led2 = LEDG;
NinaPin led3 = LEDB;

Why is the WiFiNINA library needed?

The Nano RP2040 Connect uses the u-blox NINA-W102 module for Wi-Fi connectivity. But this module is also just a standard ESP32 microcontroller. No reason to let those precious GPIO pins go to waste. So the RGB LED is connected to the NINA module, rather than taking up the RP2040 pins. So in order to blink these LEDs it's necessary for the RP2040 to communicate with the NINA module. That communication is handled by the WiFiNINA library.

This is described in the technical reference.

Why is the NinaPin type needed?

You can see that the NINA's pins are controlled by the familiar Arduino language pinMode() and digitalWrite()functions. But under the hood, this works quite differently when controlling these pins vs the RP2040's pins. The WiFiNINA library provides function overloads that use the NinaPin type for the pin number parameter instead of the usual PinName type:

There appears to be work in progress to improve on this situation with the Scheduler library:

3 Likes

To Pert: Thank you, this 4 lines where very helpful. I will remember your instructions at further experiments.

You're welcome. I'm glad if I was able to be of assistance.

Back with the inevitable (??) changes with Arduino - why?
This no longer works with nano_embed/2.2.0!
NanoPin has been changed to a class.
Why are working parts changed over and over again?

The change to a class was made in the pull request I linked to in my original reply. The description in that pull request provides an explanation for why the change was made:
https://github.com/arduino/ArduinoCore-mbed/pull/227

Some sketches use a pattern like

int potpin = A5

Since NinaPin was an enum, the implicit cast was taking place, and any subsequent call to analogRead() would not use the Nina functions.

It'll work again if you do assignment inside setup():

NinaPin led1(0);
NinaPin led2(0);
NinaPin led3(0);

void setup() {
led1 = LEDR;
led2 = LEDG;
led3 = LEDB;
...
}

another solution - simply use #define for all LEDs outside setup and it'll always work, for all possible boards:

#define led1 LEDR
#define led2 LEDG
#define led3 LEDB

Could someone explain why the pins A4, A5, A6, A7 included in enum NinaPin please? I can see from the " Nano RP2040 Connect technical reference" that LEDR, LEDG, LEDB are controlled by the WiFiNINA library, can someone point me to the documentation for A4, A5, A6, A7?

The only reference I found was the schematic:
https://store.arduino.cc/products/arduino-nano-rp2040-connect#viewer-frame_container
Clipboard01

You can see that these are actually the ADC pins on the ESP32 microcontroller of the Nano RP2040 Connect's u-blox NINA-W102 Wi-Fi radio module.

This means that, in order to get an analog reading from one of these pins, the sketch running on the RP2040 must send a command to the ESP32 to tell its firmware to read the pin, then send that reading back to the RP2040. The RP2040 microcontroller itself only has a 4 channel ADC, while people are accustomed to having 8 on the classic Nano, Nano Every, Nano 33 IoT, and Nano 33 BLE. Meanwhile the ESP32, which otherwise is only used as a Wi-Fi adapter, has those precious ADC pins that were just sitting there doing nothing. So the RP2040 Connect designer routed the A4-A7 pins to the ESP32.

The WiFiNINA library is used for communicating with these NINA-W102 modules on Arduino boards, so the code to handle those analog pins was put in that library.

1 Like

Thanks that explains it nicely. How do I ask to get this info added the " Nano RP2040 Connect technical reference"? I've lost several hours on "debugging" this issue, and the RGB pins are already explained there, just needs a note about the others to prevent confusion?

However ... in my opinion it would be much tidier for people programming Arduino rp2040 if we didn't need these special NinaPin variables to handle the ESP32. Could the version of analogRead() for the rp2040 be modified to divert those pins "automatically' to ESP32 instead. Then the pin names/numbers could be first class citizens freely stored and passed around in programs like anything else.

I believe the most effective way to go about that is by submitting your suggestion via the contact form:
https://www.arduino.cc/en/contact-us/

1 Like