×

使用OLED显示器作为外接显示器

消耗积分:2 | 格式:zip | 大小:0.43 MB | 2022-11-07

王越建

分享资料个

描述

当您想探索如何将小型显示器用作产品、原型或项目的界面时,可能很难快速探索不同的选项。通过image2cpp等工具您可以将绘制的图像转换为 Arduino 代码并将其上传到 Arduino。但理想情况下,您可以直接在屏幕上绘图,就像Figma Mirror如何在手机上工作一样,您可以在其中对设计进行编辑并立即在手机上看到发生的变化。

短视频展示了一部手机,并在其上方贴了一个已绘制和剪切 UI 元素的剪纸。可以用纸或纸板制成的原型,以查看需要什么尺寸的显示器并在转向“真实”硬件之前探索 UX 流程。
 

制作小屏幕原型的一种快速而肮脏的方法是将手机“放入”原型中,并且只使用手机屏幕的一小部分进行显示,而手机的其他部分可用于“伪造”LED 或电容式按钮(我最多可以做到 1.5 毫米,具体取决于触摸屏)。这可以使用 Figma 之类的工具来完成,但是当 p5 或 Framer 需要更多复杂性时。如果您想让手机上的内容在触摸屏之外进行交互,您可以让ESP32 充当手机的键盘,然后可以使用它来创建物理旋钮、滑块或按钮。但在某些时候,最好转向真正的硬件,检查质量、亮度、精确的像素密度,有时你的原型可能无法达到现代手机的大小;)

 

pYYBAGNkrT-Ac2gAAAGZzwkoTY8378.png
处理应用程序中显示的像素
 

 

poYBAGNkrUGAbgpKAACSxkvbE4o225.png
实际硬件上显示的像素
 

 

此代码包含一个处理草图,该草图捕获光标当前位置的像素(以及光标右下角的一个框)。这些像素被发送到 Arduino,Arduino 使用u8g2将其发送到显示器。原理类似于From Pixel to Neopixel 项目。这样,任何在电脑上制作图形的工具(从 Paint 到 After Effects,从 GameMaker 到 p5,从 Sketch 到 Figma)都可以用来控制显示器上的像素,这对于体验原型(你想要为人们提供产品体验,同时仍然能够对流程、内容和副本进行敏捷更改。

使其工作的步骤

  • 获取上面描述的硬件(显示应该是u8g2库支持的)
  • 得到一个 Arduino,任何 Arduino 都可以,只要它使用串行连接连接到计算机。并下载Arduino (pro) IDE (或使用网络编辑器)
  • 下载Processing IDE (如果您还没有获得它),该代码应该可以在 Mac OSx 和 Windows 上运行,因此希望它在未来可以继续运行。它可能被视为间谍软件,因为它确实会查看屏幕上发生的事情,但它不会将其发送到 Arduino 以外的任何地方。
  • 通过转到 Sketch > Include Library > Manage Libraries 并搜索u8g2并通过Oliver安装库来获取库
  • 下载或复制并粘贴代码并将代码上传到 Arduino。
  • 运行 Processing 草图,您应该准备好探索显示器上的动画、界面和动态内容
  • 在处理中确保选择了正确的端口
  • 如果你想使用 Figma 创建屏幕,一个好的技巧是在 Chrome 或 Chromium 中打开Figma 镜像并打开检查器,切换设备工具栏并将屏幕缩小到显示器的精确分辨率。

Arduino代码解释

Arduino 代码“简单地”从处理中获取数据并将其传递到显示器上。要知道一条消息已经开始,它会等待一个“S”和一个“.”。这不是很科学,但是在将一个字节解释为显示器的亮度之后,它似乎大部分时间都起作用,之后的所有字节都保存在一个数组中然后传递给显示器,这需要一些内存来自 Arduino,所以“流式传输”它可能是一个更好的解决方案,但现在它可以工作,而不必深入到 u8g2 库中。串行波特率是你可以玩的,我现在让它在 2Mbps 上工作,但这取决于你的微控制器

处理代码解释

在处理过程中,它从光标位置开始截取当前边界框,根据屏幕的宽度和高度向下和向右移动。当然,您也可以将其更改为固定位置;如果您希望仍能使用光标。

由于我将它与 1 位单色显示器一起使用,因此每一位都代表一个像素。这使得从像素转换为字节有点复杂,它从每个像素获取亮度并检查亮度是否高于 126,如果是,则将 1 添加到比特流,否则,它会添加 0。

如果您使用 fe 4 位灰度显示器,则需要对代码进行一些更改以使其正常工作,类似于多色显示器。我已经让它与 1.8" 彩色 TFT 显示器一起工作,帧率为 1fps;如果您对此感兴趣或有提高速度的好主意,请告诉我。

处理采用它可以找到的第一个串行端口;有时这是正确的,有时您需要更改它以选择正确的串行端口。这可以通过更改 Serial.list()[0]; 类似于 Serial.list()[1]; 或 Serial.list()[2]; 在处理草图下方的监视器中,您可以看到操作系统可以找到的不同串行端口。在 Arduino 中,您可以在窗口的右下角看到当前端口的正确名称。

免责声明

在小型显示器上更容易对内容进行原型设计这一事实并不是将屏幕放置在所有产品中的任何理由。(动态)屏幕对于有视觉障碍的人和无法将眼睛集中在屏幕上的人来说可能是一个真正的负担。考虑定位良好的 LED,因为它们不会改变位置,您可以更轻松地了解位置。考虑给用户提供触觉再保证反馈的按钮。考虑机械开关(在视觉和物理上都代表状态)。我们通过原型设计获得的时间应该用于探索测试和构建各种选项。

pYYBAGNkrUmAOmwJABFl0jwIPX8081.jpg
在汽车的 UI 设计中,驾驶员需要能够专注于道路,而不是用眼睛搜索按钮。对我来说,汽车正在从按钮、开关和表盘转向全触摸屏显示器,这对我来说似乎很可怕。因为您需要将注意力集中在道路上,并且您不必查看手指准确触摸屏幕的位置。
 

 


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

评论(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:'使用OLED显示器作为外接显示器',//标题 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);