最新 Arduino 驱动 12接口/户外 LED显示屏/LED点阵屏/LED单元板
起因
现有的驱动LED显示屏的资料,比较好的只有这个。但是它驱动的是08接口的室内显示屏,而我要驱动的是12接口的户外显示屏。两种屏幕的区别在于户外屏幕点阵比较稀疏,而且二者的扫描方式,驱动方式都不太一样。我花了一个下午才摸索出了它的使用方式,因此分享给大家,希望大家不必再绕弯路。
材料准备
- 12接口(户外)LED单元板一块:比如我是从[这里]买的,大家搜索“半户外 LED 单元板”就可以了。我的板是16x32大小。
- Arduino Uno一块
- 5V电源一个(比如充电宝、给手机充电的头)
硬件搭建
1.显示屏电源的焊接
LED单元板使用的是5V的电源,但是它只提供了两个旋螺丝的地方供接电源。因此我们要进行如下焊接:USB公头的+,-接到导线的+,-。这样之后USB直接插入手机充电器/充电宝,导线链接到显示屏的电源上。
2.Arduino与显示屏的连接
首先我们要知道12接口每个引脚的定义:
OE A
N B
N C
N CLK
N HS
N R
N G
GND D
- N:表示没有任何用
- A,B,C,D:行选择。由于我们是16x32的板,所以只会用到A,B(也就是0~3),至于为什么等到后面再说
- OE:使能。如果是高电平则屏幕会亮,低电平则强制所有灯都灭
- GND:地。(这些引脚中没有VCC脚...我也不知道为啥它能正常工作)
- CLK,HS,R:就是74HC595中的SHCP,STCP,DS。具体自行学习595芯片。
- G:本来指绿色,我们因为是单色所以没用。
接下来就是把它们连接到Arduino的引脚上了。我的库的默认设置如下:
const int A=,const int B=,const int CLK=,const int STB=,const int R=,const int OE=
当然,你也可以在库初始化的时候修改。
软件搭建
1.库的代码
我自己写了一个库,代码如下:
#include <Arduino.h>
#include "DotMatrix.h" class LEDScreenHelper {
public:
LEDScreenHelper(const int WIDTH=,
const int A=,const int B=,const int CLK=,
const int STB=,const int R=,const int OE=):
HEIGHT(),WIDTH(WIDTH),A(A),B(B),SHCP(CLK),STCP(STB),DS(R),OE(OE){} void setup(){
pinMode(A,OUTPUT);
pinMode(B,OUTPUT);
pinMode(STCP,OUTPUT);
pinMode(SHCP,OUTPUT);
pinMode(DS,OUTPUT);
pinMode(OE,OUTPUT);
} void setRow(byte row){
digitalWrite(A,row&0x01);
digitalWrite(B,row&0x02);
} void sendColData(byte data){
for(int i = ;i<;++i){
digitalWrite(DS,(data&0x80));
data<<=;
digitalWrite(SHCP,);
digitalWrite(SHCP,);
}
} void setOE(bool enable){
digitalWrite(OE, enable);
} void display(DotMatrix &data){
for(int row = ;row<;++row){
digitalWrite(OE,);
for(int col = ;col<WIDTH/;++col){
byte val = data.get((-((col&)<<)+row),(col>>));
sendColData(~val);
}
setRow(row);
digitalWrite(STCP,);
digitalWrite(STCP,);
digitalWrite(OE,);
}
digitalWrite(OE,);
} private:
const int HEIGHT,WIDTH;
const int A,B,SHCP,STCP,DS,OE;
};
其中需要#include "DotMatrix.h"如下:
#ifndef DOT_MATRIX
#define DOT_MATRIX typedef unsigned char uchar;
#define THROW(str) ; #define BYTE_LEN 8
#define CHECK_VAR(i,j) if((i)<0||(j)<0||(i)>=height||(j)>=width)THROW("Index out of Bound")
#define POS(matrix,i,j) (*((matrix) + (i) * (width) + (j)))
#define POS_BIT_GET(matrix,i,j) (POS((matrix),(i),(j)/BYTE_LEN) & (1<<(BYTE_LEN-(j)%BYTE_LEN-1)))
#define POS_BIT_SET_TRUE(matrix,i,j) (POS((matrix),(i),(j)/BYTE_LEN) |= (1<<(BYTE_LEN-(j)%BYTE_LEN-1)))
#define POS_BIT_SET_FALSE(matrix,i,j) (POS((matrix),(i),(j)/BYTE_LEN) &= (0xFF ^ (1<<(BYTE_LEN-(j)%BYTE_LEN-1))))
#define POS_BIT_SET(m,i,j,b) ((b)!=0)?POS_BIT_SET_TRUE((m),(i),(j)):POS_BIT_SET_FALSE((m),(i),(j)) /**
* Remember: This class will only use `matrix` but NOT DELETE it
*/
class DotMatrix {
public:
DotMatrix(int w,int h,uchar *matrix, bool isNowClearMatrix=true):
width(w),height(h),matrix(matrix){
if(isNowClearMatrix)clearData();
}
DotMatrix(const DotMatrix &src){
Serial.println("DotMatrix copy construction - please avoid");
width = src.width;
height = src.height;
matrix = src.matrix;
}
~DotMatrix(){} void clearData(){
memset(matrix,,width*height*);
} inline void set(int i,int j,uchar val){
CHECK_VAR(i,j);
POS(matrix,i,j) = val;
} inline uchar get(int i,int j){
CHECK_VAR(i,j);
return POS(matrix,i,j);
} inline void setBit(int i,int jBit, bool b){
CHECK_VAR(i,jBit/);
POS_BIT_SET(matrix,i,jBit,b);
} inline bool getBit(int i,int jBit){
CHECK_VAR(i,jBit/);
return POS_BIT_GET(matrix,i,jBit);
} void fillTo(DotMatrix &fillTo, int xOffset, int yOffset, int scale){
this->fillTo(fillTo,xOffset,yOffset,scale,scale,,,width*BYTE_LEN,height);
} /**
* fill the rect [xSrcBeg,ySrcBeg,xSrcEnd,ySrcEnd] to `fillTo` by the `offset` and `scale`
* @param The things by **bit**
*/
void fillTo(DotMatrix &fillTo, int xOffset, int yOffset, int xScale, int yScale,
int xSrcBeg, int ySrcBeg, int xSrcEnd, int ySrcEnd) {
for(int i = ySrcBeg;i<ySrcEnd;++i){
for(int j = xSrcBeg;j<xSrcEnd;++j){
for(int ii=;ii<yScale;++ii){
for(int jj=;jj<xScale;++jj){
//VAR_DUMP_INLINE(i);VAR_DUMP_INLINE(j);VAR_DUMP_INLINE(ii);VAR_DUMP(jj);
fillTo.setBit(yOffset+(i-ySrcBeg)*yScale+ii, xOffset+(j-xSrcBeg)*xScale+jj, POS_BIT_GET(matrix,i,j));
}
}
}
}
} void print(){
for(int i = ;i<height;++i){
for(int j = ;j<width;++j){
for(int k = ;k>=;--k){
Serial.print((get(i,j) & (<<k))!=);
}
Serial.print(" ");
}
Serial.println(" ");
}
Serial.flush();
} int getWidth(){
return width;
} int getHeight(){
return height;
} uchar *getMatrix(){
return matrix;
}
private:
int width,height;
uchar *matrix;
private:
friend class DisplayHelper;
};
#undef BYTE_LEN
#undef POS
#undef POS_BIT #endif
解释一下,DotMatrix这个类是一个二维矩阵的操作类,只要给它一个一维数组作为存储空间,它就可以模拟出一个二维的数组。这样可以减少Arduino上的内存分配与销毁。
2.库的使用
#include <Arduino.h>
#include "LEDScreenHelper.h" LEDScreenHelper helper;
unsigned char data[*];
DotMatrix matrix(,,data); void setup(){
helper.setup();
for(int i = ;i<;++i){
for(int j = ;j<;++j){
matrix.set(i,j,i+j*);
}
}
} void loop(){
helper.display(matrix);
}
例程如上。它的效果是把屏幕想象成一个左上角为(0,0)的坐标系,然后8个点(1byte)看成一块,每一块的0-3bit表示y坐标,4-5bit表示j坐标。
效果如下:
原理
LED显示屏的原理答大体如下:首先对于一“行”,使用74HC595进行点亮,因此可以做到锁存之类。接下来,通过不停地切换“行选择”来达到点亮每一行的效果。从这个原理可以看出,我们的代码必须不停地对显示屏进行输出,否则最多只有一行会正常显示,其它全部会暗掉。
注意事项
- 如果就驱动那一块单元板,不需要买40块那种的开关电源!就算你要买,也先问清楚怎么和220V接,貌似要自己搞连接线。
- 程序中不要让它一直亮着,而要让大部分时间内OE=0,也就是不亮。这样子相当于PWM,能够让它的功耗降低,从而5V 2A的电源才足够。
- 貌似显示屏的电源不接也可以,接了会更亮一点;貌似显示屏电源和Arduino电源不共地也可以,虽然有人说要共地,有人甚至说要同一个电源。这个我不知道到底要怎么做,有知道的人麻烦告诉我一下,谢谢
最新 Arduino 驱动 12接口/户外 LED显示屏/LED点阵屏/LED单元板的更多相关文章
- 【玩转单片机系列001】 08接口双色LED显示屏驱动方式探索
前些日子,从淘宝上购得一块08接口的双色LED显示屏(打算做个音乐频谱显示器),捣鼓了好几天,终于搞清楚了其控制原理,在这里做个总结,算是备忘吧. 1.LED显示屏的扫描方式 LED显示屏的扫描方式有 ...
- 「雕爷学编程」Arduino动手做(28)——RGB全彩LED模块
37款传感器与模块的提法,在网络上广泛流传,其实Arduino能够兼容的传感器模块肯定是不止37种的.鉴于本人手头积累了一些传感器和模块,依照实践出真知(一定要动手做)的理念,以学习和交流为目的,这里 ...
- csuoj 1507: 超大型LED显示屏
http://acm.csu.edu.cn/OnlineJudge/problem.php?id=1507 1507: 超大型LED显示屏 时间限制: 1 Sec 内存限制: 128 MB 提交: ...
- 超大型 LED 显示屏
http://acm.hunnu.edu.cn/online/?action=problem&type=show&id=11574&courseid=0 题目 E. 超大型 L ...
- 在 WindowMobile 上的模拟LED 显示屏插件(转)
源:在 WindowMobile 上的模拟LED 显示屏插件 我在给一个对话框上的控件查找翻看合适的图标时,无形中看到了一个LED显示屏的图标,这里所说的LED显示屏是指由很多LED灯密集排列组成的点 ...
- arduino驱动安装
方法一:使用官方提供的一键安装程序安装 打开Arduino在你电脑上的位置如果你的电脑是32位系统,就运行dpinst-x86.exe如果是64位系统,就运行dpinst-amd64.exe然后在弹出 ...
- LED 控制卡 单元板 接口引脚定义
LED 12接口 使能 <--- OE A ---> 行选择信号 N B ---> 行选择信号 N C ---> 行选择信号 N CLK ---> 时钟信号 N LAT/ ...
- [转帖]完美解决NVIDIA最新显卡驱动无法安装。(修改教程篇,各机型都可以)
http://blog.sina.com.cn/s/blog_53e2b55e0100lyx2.html ———————————————————————————————————— 前段时间,有 ...
- 使用Arduino驱动基于ST7533芯片的TFT屏
在合宙通信买了一个1.8寸的TFT屏,驱动芯片是ST7533,本来打算使用Air800直接驱动,但由于其他原因,放弃了.于是尝试使用arduino驱动,为了屏幕刷新速度更快,采用硬件SPI. 硬件连接 ...
随机推荐
- Keil 4.7a版本问题&Jlink Clone问题
听PP说Keil 4.7A新出,支持代码自动补全.激动之至,keil官网急填,下载安装. 问题即刻遇见①,电脑蓝屏,安装包损坏.当下载安装包未下载完时,续传安装包没用了.还是重下载吧,免得浪费时间. ...
- [转]ArcGIS计算图斑的四邻坐标(XMin,XMax,YMin,YMax)
1.背景: 在国土,调查等行业业务里面经常有需要计算某个图斑的四邻坐标,即xmax,xmin,ymin,ymax;也就是常说的MBR(最小外包矩形),本教程演示如何计算一个shapefile文件上的图 ...
- 269. Alien Dictionary
题目: There is a new alien language which uses the latin alphabet. However, the order among letters ar ...
- Data Flow ->> Union All
Wrox的<Professional Microsoft SQL Server 2012 Integration Services>一书中再讲Merge的时候有这样一段解释: This t ...
- github简单使用教程(转)
github是一个基于git的代码托管平台,付费用户可以建私人仓库,我们一般的免费用户只能使用公共仓库,也就是代码要公开.对于一般人来说公共仓库就已经足够了,而且我们也没多少代码来管理,O(∩_∩)O ...
- URAL 1233 Amusing Numbers 好题
参照了nocow上的解法,照搬过来…… 易知一个数X在数列中在另一个数Y前,当且仅当X前缀小于Y或前缀相等X短,那么我们分布考虑,比如对于数48561: 5位上:10000~48560; 4位上:10 ...
- (二)javascript中int和string转换
在javascript里怎么样才能把int型转换成string型 (1)var x=100 a = x.toString() (2)var x=100; a = x +""; // ...
- 两个学生OJ差集
这个程序非常简单,因为用了最笨的办法,不过运行一点儿也不慢... 在我们学校OJ平台每个人的个人信息中都有Solved Problems List,我们可以用这个简单的程序输入两个人解决问题的所有题号 ...
- 【HDOJ】1362 The Bermuda Triangle
1. 题目描述给定几个三角形拼成一个百慕大三角形. 2. 基本思路基本思路肯定是搜索,关键点是剪枝.(1) 若存在长度为$l$的边,则一定可以拼成长度为$k \cdot l$的三角形,则可拼成长度为$ ...
- 巧用ifstream判断文件是否存在
最近在写手写数字的识别软件,训练样例数量巨大而且数字个数不唯一,有可能在中途粘出一部分做测试样例.因此写下面的脚本来获取文件名,之后丢到训练函数里. #include <algorithm> ...