Displaying multiple letters on 16*16 LED using PWM signal

This is for displaying letters in a 16*16 LED matrix.The code only works for the first case, which is 1095. The switch case does not work when the Rcvalue is 1195,1295; it only checks for the first case and ends the switch case.

#include <Adafruit_NeoPixel.h>
#define RCpin 10
int RCvalue;
#define MATRIX_WIDTH 16
#define MATRIX_HEIGHT 16
#define MATRIX_PIN 7 // Change this to match your data pin

Adafruit_NeoPixel matrix = Adafruit_NeoPixel(MATRIX_WIDTH * MATRIX_HEIGHT, MATRIX_PIN, NEO_GRB + NEO_KHZ800);



void setup() {
    Serial.begin(9600); // Serial for debug
    pinMode(RCpin, INPUT);
    matrix.begin();
    matrix.show();
}

void loop() {
    displayLetter();
}




void displayLetter() {
  RCvalue=pulseIn(RCpin, HIGH);
  Serial.println(RCvalue);
  switch(RCvalue)
  {
    case 1095:
    {  
       byte m[MATRIX_HEIGHT][MATRIX_WIDTH] = {
        {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
        {0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0},
        {0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0},
        {0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0},
        {0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0},
        {0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0},
        {0, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1, 1, 0},
        {0, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 0},
        {0, 1, 1, 1, 0, 0, 1, 1, 1, 1, 0, 0, 1, 1, 1, 0},
        {0, 1, 1, 1, 0, 0, 0, 1, 1, 0, 0, 0, 1, 1, 1, 0},
        {0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0},
        {0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0},
        {0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0},
        {0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0},
        {0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0},
        {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
      };
      displayletter(m);
      break;
    }
    case 1195:
    {
        byte k[MATRIX_HEIGHT][MATRIX_WIDTH] = {
        {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
        {0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 1, 1, 1, 0},
        {0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 0},
        {0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 1, 1, 1, 0},
        {0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 1, 1, 1, 0},
        {0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 1, 1, 1, 0},
        {0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 0},
        {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0},
        {0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 0},
        {0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 1, 1, 1, 0},
        {0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 1, 1, 1, 0},
        {0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 1, 1, 1, 0},
        {0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 0},
        {0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 1, 1, 1, 0},
        {0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0},
        {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
        };
      displayletter(k);
      break;
    }
    case 1295:
    {
      byte i[MATRIX_HEIGHT][MATRIX_WIDTH] = {
        {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
        {0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0},
        {0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0},
        {0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0},
        {0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0},
        {0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0},
        {0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0},
        {0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0},
        {0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0},
        {0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0},
        {0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0},
        {0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0},
        {0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0},
        {0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0},
        {0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0},
        {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
      };
      displayletter(i);
      break;
    }
    case 1395:
    {
       byte t[MATRIX_HEIGHT][MATRIX_WIDTH] = {
        {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
        {0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0},
        {0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0},
        {0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0},
        {0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0},
        {0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0},
        {0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0},
        {0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0},
        {0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0},
        {0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0},
        {0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0},
        {0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0},
        {0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0},
        {0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0},
        {0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0},
        {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
      };
      displayletter(t);

      break;
    }

  }
}
void displayletter(byte letter[MATRIX_HEIGHT][MATRIX_WIDTH]){
  for (int y = 0; y < MATRIX_HEIGHT; y++) { //
    for (int x = 0; x < MATRIX_WIDTH; x++) {
      if (letter[y][x] == 1) {
        int pixelNumber;
        if (y % 2 == 0) {
          // Even rows
          pixelNumber = y * MATRIX_WIDTH + x;
        } else {
          // Odd rows
          pixelNumber = y * MATRIX_WIDTH + (MATRIX_WIDTH - 1 - x);
        }
        matrix.setPixelColor(pixelNumber, matrix.Color(255, 0, 0)); // Set the color to red (you can change this)
      }
    }
  }
  matrix.show(); // Display the pattern
}

As a rule, you can't define a local variable inside the case.
Define the letters in global space, use the PROGMEM to reduce memory consumption

Correction: it seems not to be true in this case, because the code above uses {...} to limit the scope of letter matrices.

As far I see, your every letter matrix seems to be a bits. Using the byte type for matrix elements waste 8 times more memory than you really need to display it.

It works even when we declare it as a local variable. The problem is that the switch case is not checking other cases except the first case.

Try to move letters outside the switch() statement - you will see that the problem will be resolved. But it is your program...

Please explain a logic of your code. Why do you expect that the pulseIn() will return a pulse length values exact in set 1095, 1195, 1295... ? Do you understand that if this will be 1296 instead of 1295 - the code won't work?

Which type arduino are you using? The compiles shows 1246 bytes of ram used, the LED matrix will take another 768, that is getting too close to using all the memory in an UNO/Nano.

I used drone kit library to override Pixhawk's PWM signal, giving 1100 for the letter k and 1200 for the letter m. After that, I observed that the RC value is 1095 with k.

Arduino UNO

Are you sure that it will be always 1095 and not in range, say 1093-1097 ?

try to code your letters as bit arrays rather than bytes. However... this will not solve memory problems. You just need a bigger controller

The memory should be ok coding the letters as bit arrays, that reduces the ram usage to 350 bytes not including the buffer for the LEDs, 222 bytes if PROGMEM is used.

You wrote that compiler shows 1246 bytes of ram used, and it is NOT INCLUDE the letter arrays since the arrays are local. So reducing the letters size probably won't to resolve the issue. But I agree that OP should try it.

Might be better to check for a range of values, instead of very specific numbers:

void displayLetter() {
  RCvalue = pulseIn(RCpin, HIGH);
  Serial.println(RCvalue);
  if (RCvalue < ((1095 + 1195) / 2)){ //checks for midway between 1095 and 1195
    displayletter(m);
  }
  else if (RCvalue < ((1195 + 1295) / 2)){
    displayletter(k);
  }
  else if (RCvalue < ((1295 + 1395) / 2)){
    displayletter(i);
  }
  else {
    displayletter(t);
  }
}

Sorry, I forgot to mention I made the arrays global so I could get the memory usage numbers.

2 Likes

this changes everything :slight_smile:

I changed the code it is entering the if-else blocks but the letter is not displayed on the LED.

Just verifying you have Neopixels, not an LED matrix. If Neopixel, where do you have pixel 0 (lower right? lower left)?

In my case, I am using Neopixel LEDs, and I get the output on the LED's without a PWM signal.

Concerning the 16x16, I get a strange output from your code...
letters
I have been helping with a Neopixel matrix project. I placed the 192x16 "map" in PROGMEM on a 32x16 Neopix matrix using text characters as color indicators, and read it out of PROGMEM in the same method you use... Feel free to examine, use and ask.

Looks like every other row is reversed, likely because you are wiring the matrix rows differently.