Simple RGB Blink Sketch

I wanted to have a simple RGB Blink for the RP2040 CONNECT to use in my class, and the following code works fine, but there are some problems with it (see below)

// program to blink the built-in red, green and blue leds on RP204
#include <WiFiNINA.h> // defines pin names and connection to built-in RGB leds

void setup() {
  Serial.begin(9600);
//  while (!Serial);
  // Setup the 3 led pins as OUTPUT
  pinMode(LEDR, OUTPUT);
  pinMode(LEDG, OUTPUT);
  pinMode(LEDB, OUTPUT);
  // start with leds off
  digitalWrite(LEDR, LOW);
  digitalWrite(LEDG, LOW);
  digitalWrite(LEDB, LOW);
  Serial.println(" RGB Blink program start");
}

void loop() {
  for (float duration = 1000.; duration > .0000001; duration = .8 * duration) {
    int blinkmsec = (int)duration;
    digitalWrite(LEDR, HIGH);
    delay(blinkmsec);
    digitalWrite(LEDR, LOW);
    digitalWrite(LEDG, HIGH);
    delay(blinkmsec);
    digitalWrite(LEDG, LOW);
    digitalWrite(LEDB, HIGH);
    delay(blinkmsec);
    digitalWrite(LEDB, LOW);
  }
  delay(2000);
  Serial.println(LEDR);
  Serial.println(LEDG);
  Serial.println(LEDB);
}

(1) Note that the while(!Serial) line is commented out, because, if it isn't ,the leds never come on.
(2) If the Serial Monitor window is open when I try to upload a sketch, the IDE reports that it can't open my Serial port. I must close the window, and then upload to get it to work properly.
(3) After a successful upload with the leds blinking, if I open the Serial Monitor window, the prints in the loop function work. But if I hit the reset button on the RP2040, the Serial Monitor window freezes with nothing coming out.
(4) Because of the above two observations, I can never see the print in the setup routine.

Simple things ought to be simple, but the RP2040 doesn't seem to be there yet, so I'm delaying my introduction of the RP2040 to my class any projects.

#include <WiFiNINA.h> // defines pin names and connection to built-in RGB leds

Does that line of code really do what the comment says ?

That would seem to imply that Serial is not connecting

  for (float duration = 1000.; duration > .0000001; duration = .8 * duration)

duration starts with a value of 1000 and the for loop iterates while duration is greater than .0000001 How many times will the for loop iterate ?

Pretty close to it. You can see my explanation here:

I used a nano 33 of some kind early last year and had a number of funky issues, including odd behavior with Serial. I eventually set it aside and used something else. I expect things are better now, but it seems to take a while for the toolchain to catch up with the new hardware.

For classroom use, I'd suggest staying with hardware that's been tested to death by many users.

May I recommend to include a lesson on data types in your class? Floating point operations are expensive. The Cortex-M0+ processor used in the RP2040 does not even have floating point hardware and therefore needs to use a library with software FP.

@wildbill If you set the expectations right, using a new product can be a good thing. Probably many people here stayed with this hobby or profession because of the challenges. Not because it was so easy and tested to death before. :slight_smile:

Hello
take a pure Arduino board like a NANO.

Thanks all for the replies. My specific objective with the class was to introduce them to a powerful new controller, and I expected to run into some issues with it. I'm a veteran of the early wars with ESP32s, where I encountered a number of incompatibilities with Arduino libraries designed for AVRs. Please realize I have only about 2 hours of experience with the CONNECT so far, and I'm not about to give up on it. Relative to some specific comments...

Does that line of code really do what the comment says ?

That's my terse summary of the good work cited by pert, where he points out that the built-in leds are actually connected to a separate, embedded ESP32 in the WiFi module, and are not connected directly to the RP2040.

That would seem to imply that Serial is not connecting

I agree, but the funny thing is that eventually it does connect if the while statement is not there, but the code seems to hang if it is. Still a mystery to me. I would note that ESP32s have their warts with Serial too: using while(!Serial) seems to do nothing at all on ESP32s. Using delay(50) after Serial.begin solves it. Without that, early prints in setup() are not executed.

Floating point operations are expensive.

Yep, it's weird to use floating point in a loop like this, but I was specifically trying to slow down execution as the delay diminished to small values. I was counting on expensive floating point to do that.

I forgot to mention one other issue: If I leave the Serial Monitor window open when I try to upload code, the upload fails, saying it cannot connect to the serial port. I must close the window and then do the upload. So there's a little work remaining to use the Arduino IDE with the CONNECT.

Well, onward and upward. For me, learning is what it's all about...

@jacktheSE
What about that for loop ?
How many times will it iterate ?

If you include the while(!Serial); it should wait for you to open the Serial monitor before completing the setup, and then once connected continue with the setup, and print the required lines.

At the moment it prints the lines before you have the monitor open to receive them.

That is not what it does at all. What while(!Serial); does is to wait for the Serial object to be initialised but that has nothing to do with opening the Serial monitor

I've just tried it on my Connect and with the line commented out it proceeds straight to the loop(), whilst with the line included it waits for you to open the serial monitor before completing the setup and printing the line

So, I ran some controlled experiments with while (!Serial) commented out. What I found was interesting, and had nothing to do with the while statement:
Experiment #1: Opened IDE (1.18.15), then plugged in CONNECT to USB, opened the Serial Monitor (printout from already-loaded sketch started), then I compiled and uploaded. Result: Sketch uploaded fine, and print from setup() worked fine, even with while (!Serial) commented out.
Experiment #2: Hit the break button on the CONNECT and it restarted, but the port apparently went dead. No prints from setup() or the loop().
Experiment #3: Tried to compile and upload, and ,as the IDE got to the upload, it just froze. Tried to compile again and the IDE threw an error "port not connected"
Experiment #4: Closed the Serial Monitor and reopened it, but it did not connect properly.
Now for the confusing part:
Experiment #5 Closed the Serial Monitor, compile and upload worked with window closed. Opened the Serial Monitor, and it was loop() printing, but of course I missed the setup() print.
Experiment #7: Repeated Experiment #1, and it worked just like before.

So my conclusion so far is that the break button is the culprit for the problems I was having. Neither AVRs nor ESP32s have this problem, which could be a source of confusion for CONNECT newbies, at least...

On Arduino boards with native USB the while(!Serial); will not complete before ether the Serial Monitor or the Serial Plotter window is opened.

I am quite certain this was intentionally implemented because the native USB connection on these boards cannot stay active while the MCU is reset. Therefore, one would always lose the first Serial prints in a sketch.
This is not an issue on boards with separate USB chips because they can stay active while the MCU is reset and therefore can received Serial communication and forward it via USB immediately.