×

蓝牙控制的LED矩阵开源分享

消耗积分:0 | 格式:zip | 大小:0.00 MB | 2023-06-16

陈丽

分享资料个

描述

互联网上充斥着教授如何使用或构建点阵的教程,那么为什么要添加另一个我听到你说的呢?仅仅因为制作 LED 显示屏很有趣,其结果令人赏心悦目,并且在您能想象到的所有方面都非常有用。而且由于我们处于物联网时代,与它进行交互的方式比通过智能手机更好。我使用我构建的 LED 矩阵作为滚动条,只是为了展示这种设备的多功能性。在下文中,我将阐明这个项目的基本构建块。

LED面板

在了解如何构建整个 LED 面板之前,先快速提醒一下 LED 的工作原理。

为了使 LED 亮起,电流应从正极(阳极)流向负极(阴极)。如果 LED 以相反的方式接线,则电流将不会流动并且 LED 将熄灭。

正在开发中的 LED
 

当我们串联连接 n 个 LED 的阳极时,单独控制它们所要做的就是切换它们的阴极 ON 和 OFF。下面是一个 n 等于 8 的共阳极 LED 列。这样,我们不使用 2*n 引脚,而是仅使用 n+1 引脚驱动它们。

LED阵列(列)
 

同样的思路,通过将 n 个 LED 列并排放置,并逐行连接阴极,您可以一次控制一列整个网格。事实上,在大多数(如果不是全部)商用 LED 显示器中,显示器的一列(或一排)仅以循环方式以如此高的频率打开一小部分时间,而人眼。我们的印象是所有列都同时通电,但事实并非如此。这个过程称为时分复用,逐列显示内容的过程称为列扫描(也有行扫描)。最大的优势之一是,我们只需要 n+n 个引脚即可单独控制 n**2 个 LED。例如,以下是“HI”一词在 8x8 LED 矩阵上的显示方式:

 

如何在 8x8 LED 矩阵上显示“HI”字样
 

 

LED的选择

看到点阵是由看起来像通孔 LED 的东西组成的,我一开始天真地认为,从点阵到像我做的那样具有大像素的 LED 显示器所需要的只是封装一个普通的 5mm LED在一个立方体中(换句话说,不需要 SMD LED 灯条)。然而,当我继续实施这个想法时,我很清楚它并不是那么简单。

我尝试了 3 种类型的通孔 LED:

  • 常规的水透明 LED
  • 漫射 LED
  • 草帽 LED 灯
poYBAGNy7yWAGmGuAABEkAOT2tc995.png
3种通孔LED
 

我的最终决定是使用草帽 LED,因为它们提供了宽视角(大约 140°),这要归功于 LED 内部的镜子,它可以在水平方向上反射垂直光线。相比之下,普通的 5 毫米 LED 具有狭窄的光束角(最多 60°)。结果,光线被正面聚焦并在像素表面上形成一个亮点。在这两个之间站着漫射 LED。他们的信封带有不透明的表面,可以将光线分散到更大的角度,但会以更暗的光强度为代价。

在下图中,您可以看到三个“像素”,每个像素使用不同的 LED 类型。

pYYBAGNy7yeAJl9LAAB_JJXLhQ8061.png
50 mm x 50 mm 矩阵“像素”由不同的通孔 LED 类型制成
 

 

LED面板驱动器

驱动器是执行 LED 面板逻辑的芯片。在其最基本的形式中,它是一个允许我们以独立于微控制器的方式控制 16 个数字输出引脚的组件(当然,我们仍然必须编写依赖于微控制器的代码来对其进行编程)。以下是一些可能的选择:

  • 移位寄存器:74HC595,...
  • GPIO 扩展器:MCP23017、MCP23S17、...
  • LED 矩阵驱动器:制造的 LED 显示器使用专用驱动器。这些芯片要复杂得多,因为它们考虑了许多因素:电流值、功耗、亮度控制、颜色混合(用于 RGB 显示器)、视觉效果的平滑度、鬼影消除......

我用 MCP23017 开车。我希望我能给你一个选择这个选择的奇特理由,但事实是,这就是我在制作时所知道的全部,并且考虑到时间限制和 LED 矩阵相对较小的尺寸(380mm x 380mm x 47mm),我没有看到 I²C 总线慢的任何原因,所以我选择了 MCP23017。话虽如此,我会推荐一个专用的 LED 矩阵驱动器,例如 MAX7219。

MCP23017 GPIO 扩展器

GPIO 扩展器是一种为微控制器提供更多通用输入/输出端口的设备。它通常通过同步串行通信接口与微控制器进行通信。

pYYBAGNy7ymACIYgAABJzepE6pk098.png
图片由 www.microchip.com 提供
 

MCP23017提供 16额外的 GPIO 端口(通过 2 个寄存器:GPIOA 和 GPIOB)和中断(INTA 和 INTB)。它使用 I²C 接口进行通信,该接口需要一条时钟线(SCL 引脚)和一条数据线(SDA 引脚),因此通过地址(通过引脚 A0、A1 和 A2)进行识别。它通过引脚 VDD(5V 或 3.3V)和引脚 VSS(接地)供电。

pYYBAGNy7yuAeDw2AABC6Z4BTlU553.png
数据表中的快照
 

MCP23017 能够以 3 种不同的 I²C 总线频率工作:100kHz、400kHz 和 1.7MHz。在这个项目中,100kHz 就足够了。但可以肯定的是,在更长的距离(例如米)上执行通信将需要您增加 I²C 总线频率以获得良好的响应时间,在这种情况下,我建议您放弃 I²C 并尝试另一种设计速度更快的通信协议.

在 Arduino 上对 MCP23017 进行编程

Adafruit 编写了一个开源来在 Arduino 上对 MCP23017 进行编程。它提供了设置 GPIOA 和 GPIOB 寄存器的方向、读取和写入它们、设置和处理中断以及设置集成上拉电阻值的功能。

一句话,确保在一条指令中一次设置寄存器 GPIOA 和 GPIOB 的位(库中有一个函数可以做到这一点)。否则,Arduino 和 LED 矩阵之间的通信将会很慢,而且您最终会得到闪烁的像素,而不是平滑的滚动。

蓝牙连接

谁想到 Arduino 上的蓝牙就想到了HC-05 蓝牙模块该设备将带有串行端口配置文件 (SPP) 的蓝牙添加到 Arduino。蓝牙 SPP 基本上意味着,一旦启用蓝牙的设备与 HC-05 模块配对,两者将以模拟串行电缆的方式进行通信。这是一个串行通信。

poYBAGNy7zCAUlBjAAA6zxLq8A4485.jpg
图片由 http://www.dsdtech-global.com 提供
 

HC-05有2种功能模式:AT指令模式进行配置,数据透传模式进行数据传输。我不需要对这个模块进行任何额外的配置,所以我在数据透传模式下使用它。它附带一个数据表,该数据表在如何配对、如何接线以及如何在 Internet 上查找额外文档方面非常全面。

在这个项目中,我仅使用 HC-05 模块通过蓝牙从智能手机接收文本字符串。然后在 LED 矩阵上滚动接收到的文本字符串。

对 HC-05 蓝牙模块进行编程

由于该设备模拟串行接口,因此可以使用SoftwareSerial Arduino 库对其进行编程。数据是串行接收的,一次一个字符,因此需要编写后处理代码。

另一个智慧之言(这将节省我几天的工作),在将代码上传到 Arduino 之前,断开 HC-05 的发送和接收引脚与 Arduino 的连接,否则上传将失败。

将智能手机与 HC-05 蓝牙模块配对

HC-05 与 Android 兼容,但与 iOS 不兼容。您需要做的就是在您的 Android 设备(手机、平板电脑等)上安装蓝牙终端应用程序。启动应用程序后,其余部分不言自明。

全部打包

我用普通纸板制作了 LED 矩阵的外壳。我使用白色泡沫板将 LED 分开(我最初使用黑色泡沫板,但后来尽可能多地用白色泡沫代替,因为白色反射光更好)。覆盖 LED 矩阵正面的塑料片厚度为 0.5 毫米,背面附有一层薄薄的白色尼龙丝,以实现更好的光扩散。

LED矩阵的外盒尺寸为380mm x 380mm x 47mm。每个像素为 40mm x 40mm x 30mm 大。

 
 
 
pYYBAGNy7zOAGH9_AABB32L9D6U624.jpg
 
1 / 11
 

 


声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉

评论(0)
发评论

下载排行榜

全部0条评论

快来发表一下你的评论吧 !

'+ '

'+ '

'+ ''+ '
'+ ''+ ''+ '
'+ ''+ '' ); $.get('/article/vipdownload/aid/'+webid,function(data){ if(data.code ==5){ $(pop_this).attr('href',"/login/index.html"); return false } if(data.code == 2){ //跳转到VIP升级页面 window.location.href="//m.obk20.com/vip/index?aid=" + webid return false } //是会员 if (data.code > 0) { $('body').append(htmlSetNormalDownload); var getWidth=$("#poplayer").width(); $("#poplayer").css("margin-left","-"+getWidth/2+"px"); $('#tips').html(data.msg) $('.download_confirm').click(function(){ $('#dialog').remove(); }) } else { var down_url = $('#vipdownload').attr('data-url'); isBindAnalysisForm(pop_this, down_url, 1) } }); }); //是否开通VIP $.get('/article/vipdownload/aid/'+webid,function(data){ if(data.code == 2 || data.code ==5){ //跳转到VIP升级页面 $('#vipdownload>span').text("开通VIP 免费下载") return false }else{ // 待续费 if(data.code == 3) { vipExpiredInfo.ifVipExpired = true vipExpiredInfo.vipExpiredDate = data.data.endoftime } $('#vipdownload .icon-vip-tips').remove() $('#vipdownload>span').text("VIP免积分下载") } }); }).on("click",".download_cancel",function(){ $('#dialog').remove(); }) var setWeixinShare={};//定义默认的微信分享信息,页面如果要自定义分享,直接更改此变量即可 if(window.navigator.userAgent.toLowerCase().match(/MicroMessenger/i) == 'micromessenger'){ var d={ title:'蓝牙控制的LED矩阵开源分享',//标题 desc:$('[name=description]').attr("content"), //描述 imgUrl:'https://'+location.host+'/static/images/ele-logo.png',// 分享图标,默认是logo link:'',//链接 type:'',// 分享类型,music、video或link,不填默认为link dataUrl:'',//如果type是music或video,则要提供数据链接,默认为空 success:'', // 用户确认分享后执行的回调函数 cancel:''// 用户取消分享后执行的回调函数 } setWeixinShare=$.extend(d,setWeixinShare); $.ajax({ url:"//www.obk20.com/app/wechat/index.php?s=Home/ShareConfig/index", data:"share_url="+encodeURIComponent(location.href)+"&format=jsonp&domain=m", type:'get', dataType:'jsonp', success:function(res){ if(res.status!="successed"){ return false; } $.getScript('https://res.wx.qq.com/open/js/jweixin-1.0.0.js',function(result,status){ if(status!="success"){ return false; } var getWxCfg=res.data; wx.config({ //debug: true, // 开启调试模式,调用的所有api的返回值会在客户端alert出来,若要查看传入的参数,可以在pc端打开,参数信息会通过log打出,仅在pc端时才会打印。 appId:getWxCfg.appId, // 必填,公众号的唯一标识 timestamp:getWxCfg.timestamp, // 必填,生成签名的时间戳 nonceStr:getWxCfg.nonceStr, // 必填,生成签名的随机串 signature:getWxCfg.signature,// 必填,签名,见附录1 jsApiList:['onMenuShareTimeline','onMenuShareAppMessage','onMenuShareQQ','onMenuShareWeibo','onMenuShareQZone'] // 必填,需要使用的JS接口列表,所有JS接口列表见附录2 }); wx.ready(function(){ //获取“分享到朋友圈”按钮点击状态及自定义分享内容接口 wx.onMenuShareTimeline({ title: setWeixinShare.title, // 分享标题 link: setWeixinShare.link, // 分享链接 imgUrl: setWeixinShare.imgUrl, // 分享图标 success: function () { setWeixinShare.success; // 用户确认分享后执行的回调函数 }, cancel: function () { setWeixinShare.cancel; // 用户取消分享后执行的回调函数 } }); //获取“分享给朋友”按钮点击状态及自定义分享内容接口 wx.onMenuShareAppMessage({ title: setWeixinShare.title, // 分享标题 desc: setWeixinShare.desc, // 分享描述 link: setWeixinShare.link, // 分享链接 imgUrl: setWeixinShare.imgUrl, // 分享图标 type: setWeixinShare.type, // 分享类型,music、video或link,不填默认为link dataUrl: setWeixinShare.dataUrl, // 如果type是music或video,则要提供数据链接,默认为空 success: function () { setWeixinShare.success; // 用户确认分享后执行的回调函数 }, cancel: function () { setWeixinShare.cancel; // 用户取消分享后执行的回调函数 } }); //获取“分享到QQ”按钮点击状态及自定义分享内容接口 wx.onMenuShareQQ({ title: setWeixinShare.title, // 分享标题 desc: setWeixinShare.desc, // 分享描述 link: setWeixinShare.link, // 分享链接 imgUrl: setWeixinShare.imgUrl, // 分享图标 success: function () { setWeixinShare.success; // 用户确认分享后执行的回调函数 }, cancel: function () { setWeixinShare.cancel; // 用户取消分享后执行的回调函数 } }); //获取“分享到腾讯微博”按钮点击状态及自定义分享内容接口 wx.onMenuShareWeibo({ title: setWeixinShare.title, // 分享标题 desc: setWeixinShare.desc, // 分享描述 link: setWeixinShare.link, // 分享链接 imgUrl: setWeixinShare.imgUrl, // 分享图标 success: function () { setWeixinShare.success; // 用户确认分享后执行的回调函数 }, cancel: function () { setWeixinShare.cancel; // 用户取消分享后执行的回调函数 } }); //获取“分享到QQ空间”按钮点击状态及自定义分享内容接口 wx.onMenuShareQZone({ title: setWeixinShare.title, // 分享标题 desc: setWeixinShare.desc, // 分享描述 link: setWeixinShare.link, // 分享链接 imgUrl: setWeixinShare.imgUrl, // 分享图标 success: function () { setWeixinShare.success; // 用户确认分享后执行的回调函数 }, cancel: function () { setWeixinShare.cancel; // 用户取消分享后执行的回调函数 } }); }); }); } }); } function openX_ad(posterid, htmlid, width, height) { if ($(htmlid).length > 0) { var randomnumber = Math.random(); var now_url = encodeURIComponent(window.location.href); var ga = document.createElement('iframe'); ga.src = 'https://www1.elecfans.com/www/delivery/myafr.php?target=_blank&cb=' + randomnumber + '&zoneid=' + posterid+'&prefer='+now_url; ga.width = width; ga.height = height; ga.frameBorder = 0; ga.scrolling = 'no'; var s = $(htmlid).append(ga); } } openX_ad(828, '#berry-300', 300, 250);