从点到线,从线到面。现在开始要来一片的 LED 了,一大波的 LED 正在到来!
因为手头没有现成的模块,手头只有 595,所以这里每一个示例程序都是使用 74HC595 扩展 IO 口的。后面不多加备注了。
现成的模块还有其它专门的驱动芯片的,程序写起来就更简单了,要根据具体的驱动芯片来决定程序,这个程序不通用的哦。
别看到静止两个字,这里点阵可是动态扫描的哟。所以程序里不能有 delay() 等阻塞主函数的延时函数。
// ---------------------------------------------------------------------------- // LEDLattice.ino // // Created 2015-06-07 // By seesea <seesea2517#gmail#com> // // LED 点阵 // 使用两个 74HC595 驱动单色 LED 点阵 // // ---------------------------------------------------------------------------- const unsigned char latchPin = 10; // 595 的 ST_CP const unsigned char clockPin = 9; // 595 的 SH_CP const unsigned char dataPin = 8; // 595 的 DS #define SIZE 7 // 点阵的行列数 // 每一行的模值 const byte row[] = { 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80 }; // 心形的取模 const byte heart[] = { 0xFF, 0x93, 0x6D, 0x7D, 0xBB, 0xD7, 0xEF, 0xFF }; void setup () { pinMode(latchPin, OUTPUT); pinMode(clockPin, OUTPUT); pinMode(dataPin, OUTPUT); Serial.begin(9600); } void loop() { showArrPic(heart); } // 显示数组所代表的图片 void showArrPic(const byte arr[]) { for (unsigned char i = 0; i < 8; ++i) { digitalWrite(latchPin, LOW); shiftOut(dataPin, clockPin, LSBFIRST, (byte) arr[i]); shiftOut(dataPin, clockPin, LSBFIRST, (byte) row[i]); digitalWrite(latchPin, HIGH); } } // 另一种方式显示数组所代表的图片 void showArrPic2(const byte arr[]) { static unsigned char i = 0; digitalWrite(latchPin, LOW); shiftOut(dataPin, clockPin, LSBFIRST, arr[i]); shiftOut(dataPin, clockPin, LSBFIRST, row[i]); digitalWrite(latchPin, HIGH); if (++i >= SIZE) i = 0; }
简单看看接线吧,没有现成的模块,都是手工现搭的,纯天然……不建议自己搭,麻烦耗时还容易出错。(偷懒只在 VCC 处接了一个限流电阻,效果也还过得去,不怕麻烦的同学可以多加几个 :D )
没错,它动起来了,所以它是动态扫描的。好吧,前面的语句是错误的示范 :D
这个程序示范了一个位移动画。
// ---------------------------------------------------------------------------- // latticeDownHeart.ino // // Created 2015-06-07 // By seesea <seesea2517#gmail#com> // // 点阵动画:飘落的心 // 使用两个 74HC595 驱动单色 LED 点阵,显示一个向下飘落的心,展示位移动画 // // ---------------------------------------------------------------------------- const unsigned char latchPin = 10; // 595 的 ST_CP const unsigned char clockPin = 9; // 595 的 SH_CP const unsigned char dataPin = 8; // 595 的 DS const unsigned long delayMs = 90; // 图像运动延时时间 #define SIZE 8 // 点阵的行列数 // 每一行的模值 const byte row[] = { 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80 }; // 心形的取模 const byte heart[] = { 0xFF, 0x93, 0x6D, 0x7D, 0xBB, 0xD7, 0xEF, 0xFF }; void setup () { pinMode(latchPin, OUTPUT); pinMode(clockPin, OUTPUT); pinMode(dataPin, OUTPUT); Serial.begin(9600); } void loop() { static char y = -8; static unsigned long lastTick = millis(); // 延时一定时间后,移动坐标 if (millis() - lastTick > delayMs) { ++y; lastTick = millis(); if (y > SIZE) y = -8; } showArrPic(heart, 0, y); } // 显示数组所代表的图片 // 以 (x, y) 为左上角起点位置,默认在 (0, 0) 位置显示 // 坐标系: // +------> // | x // | // v y // void showArrPic(const byte arr[], char x, char y) { for (char i = 0; i < SIZE; ++i) { if (i + x < 0 || i + x >= SIZE || i + y < 0 || i + y >= SIZE) { continue; } digitalWrite(latchPin, LOW); shiftOut(dataPin, clockPin, LSBFIRST, (byte) arr[i + x]); shiftOut(dataPin, clockPin, LSBFIRST, (byte) row[i + y]); digitalWrite(latchPin, HIGH); } }
咦,手机拍下的效果还有拖影,将就点吧,意思到了就行:):
这里演示了一个逐帧动画。
// ---------------------------------------------------------------------------- // LEDLattice.ino // // Created 2015-06-07 // By seesea <seesea2517#gmail#com> // // 点阵动画:人物走路的逐帧动画演示 // 使用两个 74HC595 驱动单色 LED 点阵 // // ---------------------------------------------------------------------------- const unsigned char latchPin = 10; // 595 的 ST_CP const unsigned char clockPin = 9; // 595 的 SH_CP const unsigned char dataPin = 8; // 595 的 DS const unsigned long frameDelayMs = 200; #define FRAME_NUM 4 // 关键帧帧数 #define SIZE 8 // 点阵的行列数 // 每一行的模值 const byte row[] = { 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80 }; // 人物走路的关键帧的取模 const byte man[FRAME_NUM][SIZE] = { {0xE7,0xE7,0xFF,0xC3,0xC5,0xE7,0xDB,0xBD}, {0xE7,0xE7,0xFF,0xE7,0xE3,0xE7,0xEB,0xDB}, {0xE7,0xE7,0xFF,0xE7,0xE7,0xE7,0xE7,0xE7}, {0xE7,0xE7,0xFF,0xE7,0xE3,0xE7,0xEB,0xDB} }; void setup () { pinMode(latchPin, OUTPUT); pinMode(clockPin, OUTPUT); pinMode(dataPin, OUTPUT); Serial.begin(9600); } void loop() { static unsigned long lastTick = millis(); static unsigned char frame = 0; // 延时一帧时间后,进入下一帧 if (millis() - lastTick >= frameDelayMs) { lastTick = millis(); ++frame; if (frame >= FRAME_NUM) frame = 0; } showArrPic(man[frame]); } // 显示数组所代表的图片 void showArrPic(const byte arr[]) { for (unsigned char i = 0; i < SIZE; ++i) { digitalWrite(latchPin, LOW); shiftOut(dataPin, clockPin, LSBFIRST, (byte) arr[i]); shiftOut(dataPin, clockPin, LSBFIRST, (byte) row[i]); digitalWrite(latchPin, HIGH); } }
没有绘画天份,这全是手工点出来的点阵越看越不像,大家将就点吧: