我已经构建了一个 10x10RGB(没有 WS2811 ......,正常的)LED 矩阵,带有 5 个移位寄存器和 1 个 arduino micro。
我的问题现在是我的代码似乎很慢,或者 16Mhz 的 arduino 无法处理一个不错的赫兹速率。目前,当我使用下面的代码时,会出现一些闪烁/滞后。我认为大约 60Hz-100Hz 的赫兹率会非常好。我已经将 Arduino IDE 编译器设置从 -Os 更改为 -O3 以获得更好的速度(它确实有效)。
该代码具有用于亮度控制的位角调制和多路复用功能。
所以我的问题:是否值得创建一个数组,其中预定义了所有可能的值(10 个值,只有 int < 10),然后在第 312 行使用它们:
BitMapR1[intLayerSel / 10] = _byte;
我搜索了internt,发现一些文章告诉arduinos(或微控制器)的划分非常慢。
setBitMaps() 是位角调制发生的地方 myloop() 是多路复用发生的地方
代码: http: //pastebin.com/tkFZsVxS <-- 看看这里
class FLED {
private:
bool b;
public:
FLED();
void show();
};
FLED::FLED() : b(false) {
}
void FLED::show() {
}
class LED {
private:
uint8_t LEDname;
uint8_t R;
uint8_t G;
uint8_t B;
public:
LED();
uint8_t getR();
uint8_t getG();
uint8_t getB();
void setR(uint8_t _R);
void setG(uint8_t _G);
void setB(uint8_t _B);
};
LED::LED() : R(0), G(0), B(0) {
}
uint8_t LED::getR() {
return R;
}
uint8_t LED::getG() {
return G;
}
uint8_t LED::getB() {
return B;
}
void LED::setR(uint8_t _R) {
R = _R;
}
void LED::setG(uint8_t _G) {
G = _G;
}
void LED::setB(uint8_t _B) {
B = _B;
}
LED leds[100];
FLED FastLED;
void setup() {
//set pins to output so you can control the shift register
pinMode(2, OUTPUT);
pinMode(4, OUTPUT);
pinMode(3, OUTPUT);
pinMode(5, OUTPUT);
//Serial.begin(250000);
//noInterrupts();
}
unsigned long lngLast = 0;
uint8_t BitMapR1[10] = {
B00000000,
B00000000,
B00000000,
B00000000,
B00000000,
B00000000,
B00000000,
B00000000,
B00000000,
B00000000
};
uint8_t BitMapR2[10] = {
B00000000,
B00000000,
B00000000,
B00000000,
B00000000,
B00000000,
B00000000,
B00000000,
B00000000,
B00000000
};
uint8_t BitMapR3[10] = {
B00000000,
B00000000,
B00000000,
B00000000,
B00000000,
B00000000,
B00000000,
B00000000,
B00000000,
B00000000
};
uint8_t BitMapR4[10] = {
B00000000,
B00000000,
B00000000,
B00000000,
B00000000,
B00000000,
B00000000,
B00000000,
B00000000,
B00000000
};
LED CRGB(byte _R, byte _G, byte _B) {
LED _LED = LED();
_LED.setR(constrain(_R / 16, 0, 15));
_LED.setG(constrain(_G / 16, 0, 15));
_LED.setB(constrain(_B / 16, 0, 15));
return _LED;
}
void loop() {
//Serial.print(micros()); Serial.println(" Start");
leds[0] = CRGB(36, 0, 0);
leds[1] = CRGB(103, 0, 0);
leds[2] = CRGB(170, 0, 0);
leds[3] = CRGB(255, 0, 0);
leds[4] = CRGB(255, 0, 0);
leds[5] = CRGB(170, 0, 0);
..........
leds[96] = CRGB(103, 0, 0);
leds[97] = CRGB(36, 0, 0);
leds[98] = CRGB(0, 0, 0);
leds[99] = CRGB(0, 0, 0);
//Serial.print(micros()); Serial.println(" Objekte");
BAM();
//Serial.print(micros()); Serial.println(" BAM");
}
void BAM() {
for (byte cycle = 1; cycle <= 15; cycle++) {
//Serial.print(micros()); Serial.println(" bSetBitMaps");
setBitMaps(cycle, 1);
//Serial.print(micros()); Serial.println(" aSetBitMaps");
lngLast = micros();
myloop();
delayMicroseconds(50);
turnoff();
//Serial.print(micros()); Serial.println(" aMyloop");
}
}
void turnoff() {
PORTD &= ~_BV(PORTD2);
ShiftOut(B00000000);
ShiftOut(B00000000);
ShiftOut(B00000000);
ShiftOut(B00000000);
ShiftOut(B00000000);
PORTD |= _BV(PORTD2);//LatchPin
}
void setBitMaps(byte cycle, byte pos) {
//Register 1
for (byte intLayerSel = 0; intLayerSel < 100; intLayerSel += 10){
byte _byte = 0;
for (byte i = intLayerSel; i < intLayerSel + 8; i++) {
if (cycle == 1 && (leds[i].getR() & (1 << pos - 1)) != 0) {
_byte = _byte << 1;
_byte = _byte + B00000001;
}
else if ((cycle == 2 || cycle == 3) && (leds[i].getR() & (1 << pos)) != 0) {
_byte = _byte << 1;
_byte = _byte + B00000001;
}
else if (cycle >= 4 && cycle <= 7 && (leds[i].getR() & (1 << pos + 1 )) != 0) {
_byte = _byte << 1;
_byte = _byte + B00000001;
}
else if (cycle >= 8 && cycle <= 15 && (leds[i].getR() & (1 << pos + 2)) != 0) {
_byte = _byte << 1;
_byte = _byte + B00000001;
}
else {
_byte = _byte << 1;
_byte = _byte + B00000000;
}
}
BitMapR1[intLayerSel / 10] = _byte;
}
for (byte intLayerSel = 0; intLayerSel < 100; intLayerSel += 10) {
byte _byte = 0;
for (byte i = intLayerSel + 8; i < intLayerSel + 10; i++) {
if (cycle == 1 && (leds[i].getR() & (1 << pos - 1)) != 0) {
_byte = _byte << 1;
_byte = _byte + B00000001;
}
else if ((cycle == 2 || cycle == 3) && (leds[i].getR() & (1 << pos)) != 0) {
_byte = _byte << 1;
_byte = _byte + B00000001;
}
else if (cycle >= 4 && cycle <= 7 && (leds[i].getR() & (1 << pos + 1 )) != 0) {
_byte = _byte << 1;
_byte = _byte + B00000001;
}
else if (cycle >= 8 && cycle <= 15 && (leds[i].getR() & (1 << pos + 2)) != 0) {
_byte = _byte << 1;
_byte = _byte + B00000001;
}
else {
_byte = _byte << 1;
_byte = _byte + B00000000;
}
}
for (byte i = intLayerSel; i < intLayerSel + 6; i++) {
if (cycle == 1 && (leds[i].getG() & (1 << pos - 1)) != 0) {
_byte = _byte << 1;
_byte = _byte + B00000001;
}
else if ((cycle == 2 || cycle == 3) && (leds[i].getG() & (1 << pos)) != 0) {
_byte = _byte << 1;
_byte = _byte + B00000001;
}
else if (cycle >= 4 && cycle <= 7 && (leds[i].getG() & (1 << pos + 1 )) != 0) {
_byte = _byte << 1;
_byte = _byte + B00000001;
}
else if (cycle >= 8 && cycle <= 15 && (leds[i].getG() & (1 << pos + 2)) != 0) {
_byte = _byte << 1;
_byte = _byte + B00000001;
}
else {
_byte = _byte << 1;
_byte = _byte + B00000000;
}
}
BitMapR2[intLayerSel / 10] = _byte;
}
}
void myloop() {
byte bLayerA;
byte bLayerB;
for (byte bLayerTop = 1; bLayerTop <= 10; bLayerTop++) {
//Serial.print(micros()); Serial.println(" startML");
bLayerA = B00000000;
bLayerB = B00000000;
switch (bLayerTop) {
case 1:
bLayerA = B10000000;
break;
case 2:
bLayerA = B01000000;
break;
case 3:
bLayerA = B00100000;
break;
case 4:
bLayerA = B00010000;
break;
case 5:
bLayerA = B00001000;
break;
case 6:
bLayerA = B00000100;
break;
case 7:
bLayerA = B00000010;
break;
case 8:
bLayerA = B00000001;
break;
case 9:
bLayerB = B00000010;
break;
case 10:
bLayerB = B00000001;
break;
}
/*
if (bLayerTop == 1) {
bLayerA = B10000000;
} else if (bLayerTop == 2) {
bLayerA = B01000000;
} else if (bLayerTop == 3) {
bLayerA = B00100000;
} else if (bLayerTop == 4) {
bLayerA = B00010000;
} else if (bLayerTop == 5) {
bLayerA = B00001000;
} else if (bLayerTop == 6) {
bLayerA = B00000100;
} else if (bLayerTop == 7) {
bLayerA = B00000010;
} else if (bLayerTop == 8) {
bLayerA = B00000001;
} else if (bLayerTop == 9) {
bLayerB = B00000010;
} else if (bLayerTop == 10) {
bLayerB = B00000001;
}
*/
//Serial.print(micros()); Serial.println(" bWait");
while (micros() - lngLast < 50) {
//Serial.println("call");
}
//Serial.print(micros()); Serial.println(" aWait");
turnoff();
PORTD &= ~_BV(PORTD2); //Latch LOW
//OutPut Enable = False
PORTD |= _BV(PORTD5);
byte bLayer = bLayerTop - 1;
ShiftOut(bLayerA); //Register 5
ShiftOut(bLayerB + BitMapR4[bLayer]); //Register 4
ShiftOut(BitMapR3[bLayer]); //Register 3
ShiftOut(BitMapR2[bLayer]); //Register 2
ShiftOut(BitMapR1[bLayer]); //Register 1
//take the latch pin high so the LEDs will light up:
PORTD |= _BV(PORTD2);//Latch High
//OutPut Enable = True
PORTD &= ~_BV(PORTD5);
// pause before next value:
//delay(1);
//delayMicroseconds(100);
// Serial.print(micros()); Serial.println(" end");
lngLast = micros();
}
}
void ShiftOut(byte myDataOut) {
// This shifts 8 bits out MSB first,
//on the rising edge of the clock,
//clock idles low
//internal function setup
byte i = 0;
//clear everything out just in case to
//prepare shift register for bit shifting
PORTD &= ~_BV(PORTD3);//Data off
PORTD &= ~_BV(PORTD4);//Clock off
//for each bit in the byte myDataOutï
//NOTICE THAT WE ARE COUNTING DOWN in our for loop
//This means that %00000001 or "1" will go through such
//that it will be pin Q0 that lights.
for (i = 0; i <= 7; i++) {
PORTD &= ~_BV(PORTD4);//Clock aus
//if the value passed to myDataOut and a bitmask result
// true then... so if we are at i=6 and our value is
// %11010100 it would the code compares it to %01000000
// and proceeds to set pinState to 1.
/*
//00001010 - 00000010 = true
switch (myDataOut & (1 << i)) {
case 0:
Serial.println("0");
PORTD &= ~_BV(PORTD3);//Data aus
break;
case 1: //case true
Serial.println("1");
PORTD |= _BV(PORTD3);//Data an
break;
}
*/
/*
digitalWrite(3, myDataOut & (1 << i));
*/
if ( myDataOut & (1 << i) ) {
PORTD |= _BV(PORTD3);//Data an
} else {
PORTD &= ~_BV(PORTD3);//Data aus
}
//register shifts bits on upstroke of clock pin
PORTD |= _BV(PORTD4);//Clock an
//zero the data pin after shift to prevent bleed through
PORTD &= ~_BV(PORTD3);//Data aus
}
}