×

TFT绘图条形图开源分享

消耗积分:2 | 格式:zip | 大小:0.35 MB | 2022-10-28

362163

分享资料个

描述

概述

每个人都从连接到他们的微控制器的传感器读取数据并使用数字显示它,但是您是否曾经想以一种新的方式显示它们?图形是解决方案。图的想法很好,但是有一个问题;它涉及用大量计算破坏你的头脑。在 TFT LCD 上创建图形特别困难。

该项目将使您熟悉图形的概念,并且您将能够创建自己的条形图并对其进行个性化。所有的硬计算都会为您完成,您所要做的就是编辑 5 个变量,然后您就有了图表。

功能性

该项目旨在使绘图变得有趣和通用,让您能够在几秒钟内绘制数据,图表完全灵活,可以个性化以使其成为您的,用户可以编辑图表的颜色、标题、显示的数据和别的。该项目允许您在同一个图表上绘制 1 到 4 个值,这是图表的多功能性。

 
 
poYBAGNYtiCAPkpbABrxRObDY7c340.jpg
 
1 / 9一根标有标签
 

该项目具有三个功能,第一个显示专业介绍,如果您愿意,可以排除。

 
poYBAGNYtiuAGlXCAA8PrCN4rD0668.jpg
专业介绍
 

第二个函数将绘制图形,它还将标记 x 和 y 轴。

 
poYBAGNYtj2Abw_xAB0K_StPH68963.jpg
第二个功能
 

最后一个函数将读取所选传感器的值,映射这些值,然后在图表上绘制块/条。

 
pYYBAGNYtkuAK3NsABtYq6DcYuU269.jpg
绘图块
 

下图说明了该项目的功能概述。

 
pYYBAGNYtk2ARApCAABawKVZ-7I985.png
功能概述
 

该设备不断读取传感器并在图表上实时显示数据,因此用户可以轻松地实时监控他/她的房子和他/她的办公室的温度。这是代码概述的图像。

 
pYYBAGNYtlKAfLe5AAAv5K-5zGQ596.png
代码概述
 
  • Read Sensors将读取连接到 Arduino Mega 的传感器的值。
  • Process Data将自动将传感器值映射到图形的大小。
  • Graph Data将在图表上显示映射值。

要想继续这个项目,你所需要知道的只是对 TFT LCD 上的东西如何定位有一个广泛的了解,这将在下面解释。

我将整个 LCD 称为画布,这是绘制所有内容的地方,所有 TFT LCD 库的工作方式都非常相似,因此此代码中的函数也应该与其他库一起使用。下面是在 TFT LCD 上绘制的四边形(矩形)的草图。

 
pYYBAGNYtlWAFLrRAAELLbQ0g1Y204.png
形状草图
 

在这个草图中,绘制了一个矩形,每个点都被标记,用于绘制矩形的代码行是这样的,

tft.fillRect(originX, originY,  sizeX, sizeY, Colour);
  • originX在上图中用'z'表示,这是从屏幕右侧到形状的距离。
  • originY在草图上用“x”表示,这是从屏幕顶部到形状的距离。
  • sizeX是形状在 x 轴上的大小,这是形状的长度。
  • sizeY是形状在 y 轴上的大小,这是形状的高度。

好处

运营项目用户受益于:

  • 在 TFT LCD 上绘制条形图
  • 在几秒钟内完成

建设项目

1 步:所需设备

我使用两个电位器设计了这个例子,尽管一个可以使用任何传感器来绘制图形。这是材料清单。

  • 1、面包板
  • 2、电位器
  • 跳线
 
poYBAGNYtlyAEGZlAA9d_-d-n1g791.jpg
所有组件
 

第2连接电路

下面的示意图显示了电路的接线方式,只需卡在 TFT LCD 上并连接电位器。

 
pYYBAGNYtmGAMmGCAAKTrHNu6Hw423.png
原理图
 

第 3 步:确认代码

代码主要分为三个部分:

  • 设置图表
  • 读取传感器值
  • 绘制图形

下面对这些部分进行说明。

  • 设置图表_
// draw title
 tft.setCursor(10, 10);
 tft.setTextColor(BLUE);
 tft.setTextSize(4);
 tft.println(graphName);
 // draw outline
 tft.drawLine(originX, originY, (originX + sizeX), originY, graphColor);
 tft.drawLine(originX, originY, originX, (originY - sizeY), graphColor);
 // draw lables
 for(int i = 0; i < numberOfMarks; i++)
 {
   tft.drawLine(mark[i], originY, mark[i], minorSizeY, graphColor);
 }
 // draw lable names
 for(int i = 0; i < numberOfMarks; i += 2)
 {
   tft.setCursor((mark[i] + 6), (originY + 10));
   tft.setTextColor(graphColor);
   tft.setTextSize(2);
   tft.println(graphBlock[i / 2]);
 }
 // draw numbers
 for(int i = 0; i < 6; i++)
 {
   tft.drawLine(originX, (originY - number[i]), minorSizeX, (originY - number[i]), graphColor);
 }

这部分代码将使用给定的参数以及自动计算的参数绘制图形的每个特征,绘制图形的标题,然后标记轮廓,然后标记 x 和 y 轴。

  • 读取传感器
// get the values of the sensors
 valueBlock[0] = analogRead(A14);
 valueBlock[1] = analogRead(A15);
 if(proDebug)
 {
   Serial.println(valueBlock[0]);
   Serial.println(valueBlock[1]);
   Serial.println("");
 }
 // map the sensor values to the graph size
 for(int i = 0; i < numberOfBlocks; i++)
 {
   posBlock[i] = map(valueBlock[i], 0, graphRange, originY, (originY - sizeY));
 }

此代码将读取连接到引脚 A14 和 A15 的传感器,然后将根据图形的大小映射结果。

  • 绘制图形
// draw the blocks - draw only if value differs
 for(int i = 0; i < numberOfBlocks; i++)
 {
   if(posBlock[i] > (prevPosBlock[i] + 2) || posBlock[i] < (prevPosBlock[i] - 2))
   {
     prevPosBlock[i] = posBlock[i];
     tft.fillRect((mark[i * 2] + 1), (originY - sizeY), (boxSize - 1), sizeY, WHITE);
     delay(10);
     tft.fillRect((mark[i * 2] + 1), posBlock[i], (boxSize - 1), (originY - posBlock[i]), blockColor);
   }
 }

代码的最后一部分将绘制图表的块/条,整个部分和其他部分一样灵活,可以适应用户的喜好,在下一部分中学习设置它们。

个性图表

有一个显示两个电位器值的图表很好,但我相信每个人都想在图表上显示他们自己的值,从温度到太阳辐射,使用 1 块或 4 块,这就像编辑一样简单一个变量。闲置变量是您必须编辑的所有内容。

bool proDebug = 0;       
bool displayValues = true;
uint16_t graphColor = BLUE;
uint16_t blockColor = GREEN;
String graphName = "Bar Chart";
String graphBlock[] = {"Pot1", "Pot2"};
int graphRange = 1024;
int numberOfBlocks = 2;
  • proDebug启用打印到串口监视器,其默认位置为 0(关闭),打开时(1/true),设备需要打开串口监视器,然后将值打印到串口监视器,非常适合故障排除。
  • displayValues调节是否应为每个条显示值,打开时,每个传感器的值显示在每个块的底部,默认为 true。
  • graphColor设置图表的颜色,x 和 y 轴上的线条和数字将以所选颜色显示。
  • blockColour设置图表的块/条显示的颜色。
  • graphName设置图表的名称,它以蓝色显示在图表的顶部。
  • graphBlocks保存图表上每个块/条的名称。
  • graphRange是传感器可以输出的最高数字,此数字对于绘图至关重要,必须正确设置,如果要显示原始模拟引脚的值,如电位器,请将其设置为 1024,模拟引脚的最大值. 如果您使用的是输出手势值的传感器,例如温度传感器,则可以将该值设置为 50 之类的高数字。(请注意,该图表尚未使用负数进行测试)
  • numberOfBlocks表示图表中需要的块数,确保该数等于字符串中的元素数graphBlock[]

所有其他值都是自动计算的,这样您就可以减少担心代码的时间,而有更多时间享受图表。

增加价值

请按照以下指南深入了解如何添加或减去块并编辑块显示的值。

 
pYYBAGNYtmSAf2BFAAIGaD-0s5g895.png
 
1 / 7打开项目
 

走得更远_

您可以进一步试验该项目,尝试编辑 originX、originY、sizeX 和 sizeY 常量,以使您的图形在屏幕上具有不同的大小和位置。主草图附有一个头文件,它包含一些颜色的颜色代码,尝试更改图表和条形的颜色。就是这样,您的个性化图表已准备就绪。

图书馆

  • Elegoo 库 - 版权所有 (c) 2012 Adafruit Industries 在BSD 许可下

背景

我在网上浏览了一些灵感,发现没有在 TFT LCD 上绘图的项目,反正我正在使用的那个也没有。所以我开始从头开始构建一个,然后决定我应该给它一个界面,允许整个图表通过只编辑少量变量来适应任意数量的传感器,所以我忙于数学并得到了这个项目完成。这样一来,如果想要绘制其他数据图表,就不必一遍又一遍地重写代码(节省 iCloud 空间)。

 

 


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

评论(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.lene-v.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:'TFT绘图条形图开源分享',//标题 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.lene-v.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);