How to change RGB colors using the Arduino Uno R4?

I have an arduino uno r4 connected to a p6 led matrix, but I don't know how to fine tune the red, green, and blue of the rgb colors.



#define R1 D3    // Red data for upper half
#define G1 D5    // Green data for upper half
#define B1 D6    // Blue data for upper half
#define R2 D9    // Red data for lower half
#define G2 D10    // Green data for lower half
#define B2 D11    // Blue data for lower half
#define A A0  // Address line A
#define B A1  // Address line B
#define C A2  // Address line C
#define CLK 13 // Clock pin
#define LAT A3 // Latch pin
#define OE 12  // Output enable pin

#define RED 1
#define BLUE 1
#define GREEN 1

// setup() ํ•จ์ˆ˜๋Š” ํ”„๋กœ๊ทธ๋žจ์ด ์‹œ์ž‘๋  ๋•Œ ํ•œ ๋ฒˆ๋งŒ ์‹คํ–‰๋˜๋ฉฐ, ํ•€์„ ์„ค์ •ํ•˜๊ณ  ์ดˆ๊ธฐํ™” ์ž‘์—…์„ ์ˆ˜ํ–‰ํ•ฉ๋‹ˆ๋‹ค.
void setup() {

  pinMode(CLK, OUTPUT);  // CLK ํ•€์„ ์ถœ๋ ฅ ๋ชจ๋“œ๋กœ ์„ค์ • (๋ฐ์ดํ„ฐ ์ „์†ก์šฉ ํด๋Ÿญ ์‹ ํ˜ธ)
  pinMode(LAT, OUTPUT);  // LAT ํ•€์„ ์ถœ๋ ฅ ๋ชจ๋“œ๋กœ ์„ค์ • (๋ž˜์น˜ ์‹ ํ˜ธ)
  pinMode(OE, OUTPUT);   // OE ํ•€์„ ์ถœ๋ ฅ ๋ชจ๋“œ๋กœ ์„ค์ • (์ถœ๋ ฅ ํ™œ์„ฑํ™” ์ œ์–ด)
  pinMode(A, OUTPUT);    // A ์ฃผ์†Œ ๋ผ์ธ์„ ์ถœ๋ ฅ ๋ชจ๋“œ๋กœ ์„ค์ • (ํ–‰ ์„ ํƒ์šฉ)
  pinMode(B, OUTPUT);    // B ์ฃผ์†Œ ๋ผ์ธ์„ ์ถœ๋ ฅ ๋ชจ๋“œ๋กœ ์„ค์ • (ํ–‰ ์„ ํƒ์šฉ)
  pinMode(C, OUTPUT);    // C ์ฃผ์†Œ ๋ผ์ธ์„ ์ถœ๋ ฅ ๋ชจ๋“œ๋กœ ์„ค์ • (ํ–‰ ์„ ํƒ์šฉ)

  pinMode(R1, OUTPUT);   // R1 ํ•€์„ ์ถœ๋ ฅ ๋ชจ๋“œ๋กœ ์„ค์ • (์ƒ๋‹จ ๋นจ๊ฐ„์ƒ‰ LED ์ œ์–ด)
  pinMode(G1, OUTPUT);   // G1 ํ•€์„ ์ถœ๋ ฅ ๋ชจ๋“œ๋กœ ์„ค์ • (์ƒ๋‹จ ๋…น์ƒ‰ LED ์ œ์–ด)
  pinMode(B1, OUTPUT);   // B1 ํ•€์„ ์ถœ๋ ฅ ๋ชจ๋“œ๋กœ ์„ค์ • (์ƒ๋‹จ ํŒŒ๋ž€์ƒ‰ LED ์ œ์–ด)
  pinMode(R2, OUTPUT);   // R2 ํ•€์„ ์ถœ๋ ฅ ๋ชจ๋“œ๋กœ ์„ค์ • (ํ•˜๋‹จ ๋นจ๊ฐ„์ƒ‰ LED ์ œ์–ด)
  pinMode(G2, OUTPUT);   // G2 ํ•€์„ ์ถœ๋ ฅ ๋ชจ๋“œ๋กœ ์„ค์ • (ํ•˜๋‹จ ๋…น์ƒ‰ LED ์ œ์–ด)
  pinMode(B2, OUTPUT);   // B2 ํ•€์„ ์ถœ๋ ฅ ๋ชจ๋“œ๋กœ ์„ค์ • (ํ•˜๋‹จ ํŒŒ๋ž€์ƒ‰ LED ์ œ์–ด)

  digitalWrite(OE, LOW); // OE ํ•€์„ LOW๋กœ ์„ค์ •ํ•˜์—ฌ ์ถœ๋ ฅ ํ™œ์„ฑํ™”
  clearMatrix();         // LED ๋งคํŠธ๋ฆญ์Šค๋ฅผ ์ดˆ๊ธฐํ™”ํ•˜์—ฌ ๋ชจ๋“  LED๋ฅผ ๋•๋‹ˆ๋‹ค.
  //drawPixel(5, 5, true);
   // (5, 5) ์œ„์น˜์— ๋ณด๋ผ์ƒ‰ ํ”ฝ์…€์„ ๊ทธ๋ฆฝ๋‹ˆ๋‹ค.
   drawPixel(5, 5, true);
}

// loop() ํ•จ์ˆ˜๋Š” ๋ฐ˜๋ณต์ ์œผ๋กœ ์‹คํ–‰๋˜๋ฉฐ, ์—ฌ๊ธฐ์„œ๋Š” ํ•„์š”ํ•˜์ง€ ์•Š์œผ๋ฏ€๋กœ ๋น„์›Œ๋‘ก๋‹ˆ๋‹ค.
void loop() {
  // No loop actions needed; the pixel will stay on
  //drawPixel(5, 5, true);
}

// clearMatrix() ํ•จ์ˆ˜๋Š” LED ๋งคํŠธ๋ฆญ์Šค์˜ ๋ชจ๋“  LED๋ฅผ ๋„๋Š” ์—ญํ• ์„ ํ•ฉ๋‹ˆ๋‹ค.
void clearMatrix() {
  for (int row = 0; row < 16; row++) {  // ๋งคํŠธ๋ฆญ์Šค์˜ ๋ชจ๋“  16๊ฐœ ํ–‰์„ ๋ฐ˜๋ณต ์ฒ˜๋ฆฌํ•ฉ๋‹ˆ๋‹ค.
    selectRow(row);                    // ๊ฐ ํ–‰์„ ์„ ํƒํ•ฉ๋‹ˆ๋‹ค.
    shiftOutData(0x00);                // ๋ชจ๋“  ์—ด์„ 0์œผ๋กœ ์„ค์ •ํ•˜์—ฌ ํ•ด๋‹น ํ–‰์˜ ๋ชจ๋“  LED๋ฅผ ๋•๋‹ˆ๋‹ค.
    latchData();                       // ๋ž˜์น˜ ์‹ ํ˜ธ๋ฅผ ํ†ตํ•ด ๋ฐ์ดํ„ฐ๋ฅผ ๋งคํŠธ๋ฆญ์Šค์— ์ ์šฉํ•ฉ๋‹ˆ๋‹ค.
  }
}

// drawPixel() ํ•จ์ˆ˜๋Š” ํŠน์ • ์œ„์น˜ (x, y)์— LED๋ฅผ ์ผœ๊ฑฐ๋‚˜ ๋„๋Š” ์—ญํ• ์„ ํ•ฉ๋‹ˆ๋‹ค.
void drawPixel(int x, int y, bool on) {
  int row = y;  // y ๊ฐ’์„ ์‚ฌ์šฉํ•˜์—ฌ ์„ ํƒํ•  ํ–‰(row)์„ ์„ค์ •ํ•ฉ๋‹ˆ๋‹ค.

  selectRow(row);  // ์ฃผ์–ด์ง„ ํ–‰์„ ์„ ํƒํ•ฉ๋‹ˆ๋‹ค.

  // ์—ด(column)์„ ์„ค์ •ํ•˜๊ธฐ ์œ„ํ•ด ๋ฃจํ”„๋ฅผ ์‹คํ–‰ํ•ฉ๋‹ˆ๋‹ค.
  for (int i = 0; i < 32; i++) {  // 32๊ฐœ์˜ ์—ด์„ ๋ฐ˜๋ณต ์ฒ˜๋ฆฌํ•ฉ๋‹ˆ๋‹ค.
    digitalWrite(CLK, LOW);       // ํด๋Ÿญ ์‹ ํ˜ธ๋ฅผ LOW๋กœ ์„ค์ •ํ•˜์—ฌ ๋ฐ์ดํ„ฐ ์ „์†ก์„ ์ค€๋น„ํ•ฉ๋‹ˆ๋‹ค.

    if (i == x) {  // ํ˜„์žฌ ์—ด์ด x ์ขŒํ‘œ์™€ ์ผ์น˜ํ•˜๋Š”์ง€ ํ™•์ธํ•ฉ๋‹ˆ๋‹ค.
      if (row < 8) {  // ํ–‰์ด ์ƒ๋‹จ ์ ˆ๋ฐ˜์— ์†ํ•˜๋Š” ๊ฒฝ์šฐ
        analogWrite(R1, RED); // ์ƒ๋‹จ ์ ˆ๋ฐ˜์˜ ๋นจ๊ฐ„์ƒ‰ LED๋ฅผ ์ œ์–ดํ•ฉ๋‹ˆ๋‹ค.
        analogWrite(B1, BLUE); // ์ƒ๋‹จ ์ ˆ๋ฐ˜์˜ ํŒŒ๋ž€์ƒ‰ LED๋ฅผ ์ œ์–ดํ•ฉ๋‹ˆ๋‹ค.
        analogWrite(G1, GREEN); // ์ƒ๋‹จ ์ ˆ๋ฐ˜์˜ ํŒŒ๋ž€์ƒ‰ LED๋ฅผ ์ œ์–ดํ•ฉ๋‹ˆ๋‹ค.
      } else {  // ํ–‰์ด ํ•˜๋‹จ ์ ˆ๋ฐ˜์— ์†ํ•˜๋Š” ๊ฒฝ์šฐ
        analogWrite(R2, RED); // ํ•˜๋‹จ ์ ˆ๋ฐ˜์˜ ๋นจ๊ฐ„์ƒ‰ LED๋ฅผ ์ œ์–ดํ•ฉ๋‹ˆ๋‹ค.
        analogWrite(B2, BLUE); // ํ•˜๋‹จ ์ ˆ๋ฐ˜์˜ ํŒŒ๋ž€์ƒ‰ LED๋ฅผ ์ œ์–ดํ•ฉ๋‹ˆ๋‹ค.
        analogWrite(G2, GREEN); // ์ƒ๋‹จ ์ ˆ๋ฐ˜์˜ ํŒŒ๋ž€์ƒ‰ LED๋ฅผ ์ œ์–ดํ•ฉ๋‹ˆ๋‹ค.
      }
    } else {  // ํ˜„์žฌ ์—ด์ด x ์ขŒํ‘œ์™€ ์ผ์น˜ํ•˜์ง€ ์•Š๋Š” ๊ฒฝ์šฐ
      analogWrite(R1, LOW);  // ํ•ด๋‹น ์—ด์˜ LED๋ฅผ ๋•๋‹ˆ๋‹ค.
      analogWrite(B1, LOW);  // ํ•ด๋‹น ์—ด์˜ LED๋ฅผ ๋•๋‹ˆ๋‹ค.
      analogWrite(G1, LOW);  // ํ•ด๋‹น ์—ด์˜ LED๋ฅผ ๋•๋‹ˆ๋‹ค.
      analogWrite(G2, LOW);  // ํ•ด๋‹น ์—ด์˜ LED๋ฅผ ๋•๋‹ˆ๋‹ค.
      analogWrite(R2, LOW);  // ํ•ด๋‹น ์—ด์˜ LED๋ฅผ ๋•๋‹ˆ๋‹ค.
      analogWrite(B2, LOW);  // ํ•ด๋‹น ์—ด์˜ LED๋ฅผ ๋•๋‹ˆ๋‹ค.
    }

    digitalWrite(CLK, HIGH);  // ํด๋Ÿญ ์‹ ํ˜ธ๋ฅผ HIGH๋กœ ์„ค์ •ํ•˜์—ฌ ๋ฐ์ดํ„ฐ๋ฅผ ์ „์†กํ•ฉ๋‹ˆ๋‹ค.
  }

  latchData();  // ๋ž˜์น˜ ์‹ ํ˜ธ๋ฅผ ํ†ตํ•ด ๋ฐ์ดํ„ฐ๋ฅผ ๋งคํŠธ๋ฆญ์Šค์— ์ ์šฉํ•ฉ๋‹ˆ๋‹ค.
}

// selectRow() ํ•จ์ˆ˜๋Š” ์ฃผ์–ด์ง„ ํ–‰(row)์„ ์„ ํƒํ•˜๊ธฐ ์œ„ํ•ด A, B, C ์ฃผ์†Œ ๋ผ์ธ์„ ์„ค์ •ํ•ฉ๋‹ˆ๋‹ค.
void selectRow(int row) {
  digitalWrite(A, row & 1);         // A ํ•€์„ ํ–‰์˜ ์ฒซ ๋ฒˆ์งธ ๋น„ํŠธ๋กœ ์„ค์ •ํ•ฉ๋‹ˆ๋‹ค.
  digitalWrite(B, (row >> 1) & 1);  // B ํ•€์„ ํ–‰์˜ ๋‘ ๋ฒˆ์งธ ๋น„ํŠธ๋กœ ์„ค์ •ํ•ฉ๋‹ˆ๋‹ค.
  digitalWrite(C, (row >> 2) & 1);  // C ํ•€์„ ํ–‰์˜ ์„ธ ๋ฒˆ์งธ ๋น„ํŠธ๋กœ ์„ค์ •ํ•ฉ๋‹ˆ๋‹ค.
}

// shiftOutData() ํ•จ์ˆ˜๋Š” ์ฃผ์–ด์ง„ ๋ฐ์ดํ„ฐ ๋ฐ”์ดํŠธ๋ฅผ ๋งคํŠธ๋ฆญ์Šค์— ์ „์†กํ•ฉ๋‹ˆ๋‹ค.
void shiftOutData(byte data) {
  for (int i = 0; i < 32; i++) {  // 32๊ฐœ์˜ ์—ด์„ ๋ฐ˜๋ณต ์ฒ˜๋ฆฌํ•ฉ๋‹ˆ๋‹ค.
    digitalWrite(CLK, LOW);       // ํด๋Ÿญ ์‹ ํ˜ธ๋ฅผ LOW๋กœ ์„ค์ •ํ•˜์—ฌ ๋ฐ์ดํ„ฐ ์ „์†ก์„ ์ค€๋น„ํ•ฉ๋‹ˆ๋‹ค.
    analogWrite(R1, (data & (1 << (31 - i))) ? HIGH : LOW);  // ์ƒ๋‹จ ์ ˆ๋ฐ˜์˜ ๋นจ๊ฐ„์ƒ‰ LED๋ฅผ ์„ค์ •ํ•ฉ๋‹ˆ๋‹ค.
    analogWrite(B1, (data & (1 << (31 - i))) ? HIGH : LOW);  // ์ƒ๋‹จ ์ ˆ๋ฐ˜์˜ ํŒŒ๋ž€์ƒ‰ LED๋ฅผ ์„ค์ •ํ•ฉ๋‹ˆ๋‹ค.
    analogWrite(G1, (data & (1 << (31 - i))) ? HIGH : LOW);  // ์ƒ๋‹จ ์ ˆ๋ฐ˜์˜ ํŒŒ๋ž€์ƒ‰ LED๋ฅผ ์„ค์ •ํ•ฉ๋‹ˆ๋‹ค.
    analogWrite(G2, (data & (1 << (31 - i))) ? HIGH : LOW);  // ์ƒ๋‹จ ์ ˆ๋ฐ˜์˜ ํŒŒ๋ž€์ƒ‰ LED๋ฅผ ์„ค์ •ํ•ฉ๋‹ˆ๋‹ค.
    analogWrite(R2, (data & (1 << (31 - i))) ? HIGH : LOW);  // ํ•˜๋‹จ ์ ˆ๋ฐ˜์˜ ๋นจ๊ฐ„์ƒ‰ LED๋ฅผ ์„ค์ •ํ•ฉ๋‹ˆ๋‹ค.
    analogWrite(B2, (data & (1 << (31 - i))) ? HIGH : LOW);  // ํ•˜๋‹จ ์ ˆ๋ฐ˜์˜ ํŒŒ๋ž€์ƒ‰ LED๋ฅผ ์„ค์ •ํ•ฉ๋‹ˆ๋‹ค.
    digitalWrite(CLK, HIGH);  // ํด๋Ÿญ ์‹ ํ˜ธ๋ฅผ HIGH๋กœ ์„ค์ •ํ•˜์—ฌ ๋ฐ์ดํ„ฐ๋ฅผ ์ „์†กํ•ฉ๋‹ˆ๋‹ค.
  }
}

// latchData() ํ•จ์ˆ˜๋Š” ๋ž˜์น˜ ์‹ ํ˜ธ๋ฅผ ํ†ตํ•ด ๋ฐ์ดํ„ฐ๋ฅผ ๋งคํŠธ๋ฆญ์Šค์— ์ ์šฉํ•ฉ๋‹ˆ๋‹ค.
void latchData() {
  digitalWrite(LAT, HIGH);  // ๋ž˜์น˜ ์‹ ํ˜ธ๋ฅผ HIGH๋กœ ์„ค์ •ํ•ฉ๋‹ˆ๋‹ค.
  //delayMicroseconds(10);    // ์งง์€ ์‹œ๊ฐ„ ๋™์•ˆ ๋Œ€๊ธฐํ•ฉ๋‹ˆ๋‹ค.
  digitalWrite(LAT, LOW);   // ๋ž˜์น˜ ์‹ ํ˜ธ๋ฅผ LOW๋กœ ์„ค์ •ํ•˜์—ฌ ๋ฐ์ดํ„ฐ๋ฅผ ์ ์šฉํ•ฉ๋‹ˆ๋‹ค.
}

I'm having trouble getting this code to work. Setting the rgb red, green, and blue values doesn't change the light, it just increases the number of pixels of that color. Please help.

Your #define statements are using "D#"... which I believe do not compile because "D#" needs to be defined.

Rather than using:

#define R1 D3 // "D3" not defined

use:

#define R1 3 // digital DIO pin 3

Further, why #define "R1" as "3"? Use descriptions, like #define colorRed 3 so you do not need to describe what "R1" means in the comments

See post#7.

I think the Arduino R4 defines those D# macros:

What confuses me about this code is the use of analogWrite(R1,1), etc... into what seems like it might be an external latch.

1 Like

Then how can I use analogwrite...? Can you give me an exact example? I have used analogWrite to use RGB 0~255.

Have you taken a look at the information that Adafruit has here: ?

https://learn.adafruit.com/32x16-32x32-rgb-led-matrix/how-the-matrix-works

" The only downside of this technique is that despite being very simple and fast, it has no PWM control built in! The controller can only set the LEDs on or off. So what do you do when you want full color? You actually need to draw the entire matrix over and over again at very high speeds to PWM the matrix manually. For that reason, you need to have a very fast controller (50 MHz is a minimum) if you want to do a lot of colors and motion video and have it look good".

Would you consider the possibility of using a library?

1 Like

It is going into a latch. Thanks @Brazilino.

If you know how analogWrite works with PWM by switching a signal on and off for different fractions of a period of time, then feeding it into a latch, whose sole purpose is to hold a logic signal constant until updated, is a conceptual error. Depending on the PWM frequency and how the latch update frequency samples it, you could get interesting effects.

To fix it youโ€™ll have to do the pwm calculations yourself in sync with the refresh rate of the matrix.

On the other hand, maybe the R4 will be fast enough if you move drawPixel out of setup() and into loop()?

You will need loop action.

1 Like