Onboard LEDs refusing to work properly


#1

Hello,

I’m currently trying to write some small exercises for teenagers and something went wrong with the last bit of code I’m testing. I have the LED matrix available and want the robot to print numbers from 1 to 10 on the matrix then have the onboard LEDs blinking and I can’t seem to do it.

This is my code:

void loop() {
  for (int num = 0; num <= 10; num++) {
    matrix.showNum(num);
    delay(500);
  }
  while (1) {
    leds.setColor(255, 0, 0);
    leds.show();
    delay(500);
    leds.setColor(0, 0, 0);
    leds.show();
    delay(500);
  }
}

The program does enter the loop because the number on the matrix stays stuck at 10. I tried changing the condition from always true to an integer incrementing up until 10, the number on the matrix goes back to 0 after 10 secondes. So it appears that everything works fine except the LEDs instructions.

If I comment the for, its instructions, the while, and let only the blinking code, it works perfectly.
If I write another instruction in the while, this instruction works (I tried matrix.showNum(100))
If I write matrix.showNum(100); followed by only the leds.setColor(255, 0, 0); leds.show(); in the while, the LEDs do light up in red.
If I write the thing just above and put a leds.setColor(0, 0, 0); leds.show(); as the first instruction of the code, the LEDs still light up in red but never turn off.
I may have tried other combinations but I don’t remember them right off the bat. The point is it’s all acting really weird. Does the LED matrix get in conflict with the onboard LEDs or something? That is my last idea at that point :frowning:


#2

Can you post the entire sketch?

One thing that jumps out at me is that the while loop never exits and so the code will not ever get to the next iteration of the loop method.

You could also restructure the code to use a state variable to indicate whether or not the leds should be on or off rather than using a non-exiting while loop. :slight_smile:

For example:

bool currentState = true;

void loop() {
  for (int num = 0; num <= 10; num++) {
    matrix.showNum(num);
    delay(500);
  }

  if (currentState == true) {
    leds.setColor(255, 0, 0);
    currentState = !currentState;
  } else {
    leds.setColor(0, 0, 0);
    currentState = !currentState;
  } 
    leds.show();
    delay(500);
}

The if-test could be shortened further by using a custom method to isolate the state change:

bool currentState = true;

void toggleLEDs() {
   (currentState) ? leds.setColor(255, 0, 0) : leds.setColor(0, 0, 0);
   leds.show();
   currentState = !currentState;
   delay(500);
}

void loop () {
  for (int num = 0; num <= 10; num++) {
    matrix.showNum(num);
    delay(500);
  }

  toggleLEDs();
}

I haven’t had a chance to test the code (yet), but this is the basis of how I might approach it.


#3

OK, I took a stab at what I think you might be trying to. The program below increments the numbers on the matrix and turns the onboard LEDs on and off based on every other number. You can alter the toggleLEDs method to change the behavior if this does not suit your needs or simply insert an additional toggleLEDs method after the delay if you want the LEDs to flash every time the number changes.

#include <MeMCore.h>

// Onboard LED parameters
const int PORT = 7;
const int SLOT = 2;

// LED Selection
const int BOTH_LEDS = 0;
const int RIGHT_LED = 1;
const int LEFT_LED  = 2;

MeRGBLed leds(PORT, SLOT);  // declare onboard LEDs object
MeLEDMatrix matrix(4);              // declare LED Matrix object

// declare state variable
bool currentState = true;

// toggle the LEDs based on the current state
void toggleLEDs() {
  (currentState) ? leds.setColor(255, 0, 0) : leds.setColor(0, 0, 0);
  leds.show();
  currentState = !currentState;
}

// default setup method
void setup() {
}

// default loop method
void loop() {
  for (int num = 0; num <= 10; num++) {
    matrix.showNum(num);
    toggleLEDs();
    delay(500);
  }
}

#4

Ah sorry for having been unclear, that’s not what I’m trying to do. I’m trying to first print the ten numbers, then have the LEDs blink, without ever going back to the numbers afterwards.

A less weird way to do what I want to do would be this:

void setup() {
  for (int num = 0; num <= 10; num++) {
    matrix.showNum(num);
    delay(500);
  }
}
void loop() {
  leds.setColor(255, 0, 0);
  leds.show();
  delay(500);
  leds.setColor(0, 0, 0);
  leds.show();
  delay(500);
}

The code is extremely simple because it’s for the very first lesson of a group of 13-15yo who never coded with a textual programmation language before, let alone C. I already introduce them to a lot of basic concepts in that first lesson and won’t tackle functions or ternaries or such for now.

Now my problem is I don’t want to use the setup for reasons I won’t bother describing here, hence why I implemented a second infinite loop inside loop(). My complete code is as following:

#include <MeMCore.h>

MeRGBLed leds(7);
int button = A7;

void setup() {
  pinMode(button, INPUT);
  while (analogRead(button) > 100);
}

void loop() {
  for (int num = 0; num <= 10; num++) {
    matrix.showNum(num);
    delay(500);
  }
  while (1) {
    leds.setColor(255, 0, 0);
    leds.show();
    delay(500);
    leds.setColor(0, 0, 0);
    leds.show();
    delay(500);
  }
}

So nothing much more than what I already posted. There’s just a bit of code in the setup so the program starts only when we click the button.

This code is supposed to print 1 to 10 on the matrix, then stay stuck in the while (1) loop (which indeed prevents to ever go to the second iteration of loop(), but that’s on purpose) to make the LEDs blinks. It does enters the while (1), but the LEDs don’t blink. And I don’t understand why! I honestly don’t really need to find a solution because I can scratch other exercises to make them play with LEDs but I personally would very much like to understand why it doesn’t work :smile:


#5

Ah, okay, so what I might suggest is using a logical flag to control the execution of the matrix printout rather than an infinite loop (see below):

#include <MeMCore.h>

// Onboard LED parameters
const int PORT = 7;
const int SLOT = 2;

// LED Selection
const int BOTH_LEDS = 0;
const int RIGHT_LED = 1;
const int LEFT_LED  = 2;

MeRGBLed leds(PORT, SLOT);  // declare onboard LED object
MeLEDMatrix matrix(4);      // declare LED Matrix object

bool printNumbers = true;   // sentinel value to control matrix display
bool state = true;          // state variable for LEDs

// default setup value
void setup() {
}

// default loop method
void loop() {
  if (printNumbers == true) {
    for (int num = 0; num <= 10; num++) {
      // show number on matrix
      matrix.showNum(num);
      delay(500);
    }
    printNumbers = false;
  }

  // toggle the color of the LEDs
  if (state == true) {
    // set LEDs to red color
    leds.setColor(255, 0, 0);
  } else {
    // set LEDs to black color
    leds.setColor(0,0,0);
  }

  // change the LEDs
    leds.show();

  // toggle the state
  state = !state;

  // wait 500 milliseconds
  delay(500);
}

As a general rule, it’s probably best to avoid infinite loops in the loop method (because it is an infinite loop).


#6

This is a way cleaner way of doing it and I’m gonna take this, thank you very much :slightly_smiling_face:

Weirdly enough, after coming back to it a few days later, my dirty way (the infinite loop in the infinite loop) works too. I guess the lil guy was just in a bad mood last Saturday… Nevertheless, thank you for your quick answer and alternate cleaner way!


#7

No worries, I’m just not a fan of embedding an infinite loop in what is essentially another infinite loop. Glad to have been helpful. :slight_smile:

Chuck


#8

One final thought is that the program can be shortened further by using a tertiary statement directly in the leds.Setcolor() method:

#include <MeMCore.h>

// Onboard LED parameters
const int PORT = 7;
const int SLOT = 2;

// LED Selection
const int BOTH_LEDS = 0;
const int RIGHT_LED = 1;
const int LEFT_LED  = 2;

MeRGBLed leds(PORT, SLOT);  // declare onboard LED object
MeLEDMatrix matrix(4);      // declare LED Matrix object

bool printNumbers = true;   // sentinel value to control matrix display
bool state = true;          // state variable for LEDs

// default setup value
void setup() {
}

// default loop method
void loop() {
  if (printNumbers == true) {
    for (int num = 0; num <= 10; num++) {
      // show number on matrix
      matrix.showNum(num);
      delay(500);
    }
    printNumbers = false;
  }
  
  // set the LED color
  leds.setColor((state == true) ? 255 : 0, 0, 0);
  
  state = !state;   // toggle the state

  leds.show();      // update the LEDs

  // wait 500 milliseconds
  delay(500);
}

#9

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