打印

Arduino 入门程序示例之一片 LED

[复制链接]
1786|2
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
starsnow|  楼主 | 2016-11-25 23:21 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
本帖最后由 starsnow 于 2016-11-25 23:23 编辑

概述
从点到线,从线到面。现在开始要来一片的 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);
}


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);
}

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);
}

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);
    }
}

没有绘画天分,这全是手工点出来的点阵越看越不像,大家将就点吧:

相关帖子

沙发
netlhx| | 2016-11-26 11:30 | 只看该作者
好看,我也要学点灯

使用特权

评论回复
板凳
starsnow|  楼主 | 2016-11-26 12:02 | 只看该作者
netlhx 发表于 2016-11-26 11:30
好看,我也要学点灯

谢谢支持~~等灯等登!

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

3

主题

17

帖子

2

粉丝