这些小活动你都参加了吗?快来围观一下吧!>>
电子产品世界» 论坛首页» 活动中心» 板卡试用» 【TOPWAY7寸智能屏】充电桩显示屏(更新第6章分享源代码,共同提高)

共8条 1/1 1 跳转至

【TOPWAY7寸智能屏】充电桩显示屏(更新第6章分享源代码,共同提高)

院士
2021-07-10 21:52:20 打赏

【TOPWAY7寸智能屏】充电桩显示屏

项目名称:
电动汽车充电桩显示屏
项目介绍:
拓普微的显示屏做为终端模块之一接入到充电桩系统中(另有微信APP小程序方案)。
拓普微的显示屏主要设计三组界面:
1、充电状态界面。在充电现场给用户以图形、动态、实时显示充电的当前状态,包括当前充电时间,充电电压、充电电流、充电功率,已充电电量,当前费用等。
2、充电完成,显示充电结算单。
3、充电空闲,显示充电桩信息、广告等。
考虑到220v充电的实验环境成本较高,亦较难实现,本次以给手机充电为实验环境,获取手机充电过程中的实际数据为显示数据。


试用进程(点击链接进入对应楼层):

1、快递收到,开箱演示厂家demo

2、充电桩待机界面的创建

3、充电桩充电界面的创建

4、充电桩充电完成界面的创建

5、串口是调试口,网口才是通讯口

6、分享源代码,共同提高

7、to be continue...





关键词: TOPWAY7 充电 显示屏

院士
2021-07-10 22:13:40 打赏
2楼

快递收到,开箱演示厂家demo

周五下午德邦的快递员终于打来了盼望多日的电话——到公司楼下取快递。这份快递不是别人家的,正是深圳拓普微公司的智能液晶屏HMT070ETD-1D。

首先,包装简约实用。内容也分为三个部分:液晶屏和线,说明书与填充丰富的泡沫。坦白讲,这泡沫还真是扛事,外包装的纸箱都压变型了,也保护了产品屏幕无丝毫影响。

找来了DC2.5mm的接头,直流小电源,将电压输出调整到标准的12v,打开输出,出厂自带的demo程序便展示在了眼前。

屏保界面展示了滑动开锁的应用,操作起来灵敏度适中,也很顺利的进入了主程序。

主程序是其余几个demo,分别是石油、化工常见的管道控制应用,仪表盘应用、数据曲线图等以不同的领域和背景做出来的常见应用演示示例。

看过演示示例,一方面可以肯定我将要设计的充电桩控制显示屏肯定没有技术难点了;另一方面,我觉得,我的设计方案是不是大材小用了。

总体而言,这款HMT070ETD-1D智能液晶屏功能丰富,性能强劲,可玩性较大。大家期待我的更多DIY,更多试用心得吧!



院士
2021-07-21 00:31:16 打赏
3楼
充电桩待机界面的创建

充电桩的三个典型状态之一——待机状态。参考国家电网的设计方案,其充电桩在待机的时候是循环播放图片广告。所以我也就参考其设计,设计成这个样子了。


DSCN5130.JPG


我使用了拓普微的界面设计工具,添加底部的文字与两张图片(软件里称为图标),用于显示我们的赞助商。

在左上,使用1个图标矩阵,即4个图标来显示一幅图片。此智能屏仅可以上传1/4的屏幕大小的图片,所以将整张图片给拆解了。在右上部添加了时钟显示,用来显示当前的时间,在右中部添加了一个二维码来标识充电桩的基本信息,比如计费,维护等。

时钟、二维码的设计实在是太方便了,控件拖拽即完成。

在图片的显示虽然有些局限性,但拓普微其实也有另外的解决方案——使用背景图片的方式,而国家电网的方案也是这样的。只不过,我当时仅设计了三个状态,于是才有了现在的workaround方案。

最后,大家可以扫描一下我的二维码,这个可是真实有效的呀!


院士
2021-07-26 14:24:50 打赏
4楼

自己给自己顶个帖子。

满20个帖子后,更新下一章精彩内容。


院士
2021-07-29 09:13:58 打赏
5楼

充电桩充电界面的创建

充电桩的三个核心状态之一充电状态。充电状态要以最直观的数据方式显示给客户。现在是什么状态,充了多少电,已经花了多少钱?

当然,还要有停止充电的操作按键。

在设计界面的时候,参考了拓普微设计手册的建议,将固定字符串与背景图设计在一起,虽然灵活度看似下降,但确实节省了数据空间,减少了算力需求,增加了显示屏的显示速度。

先上一个界面的图。

charge.jpg

数据显示数字的增加也非常方便,直接拖拽控件即可,然后再添加变量,给数字控件分配一个寄存器地址。

在通讯的过程中,与Modbus协议类似,都是写入或读取寄存器地址的方式,所以对于Modbus这个通用的全球标准大家还是非常值得学习与借鉴的。

以下是我本次数据的指令,非常方便与拓普微的显示屏通讯的。

charge fee aa 3d 00 08 00 0C 00 EA cc 33 c3 3c charge voltage aa 3d 00 08 00 04 01 FA cc 33 c3 3c charge current aa 3d 00 08 00 06 03 EA cc 33 c3 3c charge power aa 3d 00 08 00 08 00 EA cc 33 c3 3c charge soc aa 3d 00 08 00 0e 00 5A cc 33 c3 3c charge time aa 3d 00 08 00 0a 00 5A cc 33 c3 3c




院士
2021-08-08 09:43:42 打赏
6楼

充电桩充电完成界面的创建

充电桩的三个核心状态最后一个状态——充电完成状态。充电完成状态主要是提示当前的充电完成后的信息,如充电时间,充电电量,充电费用。

在经过前两个界面的设计后,这个最后一个界面在有了GUI后,实现过程非常顺利。大致仅用了10分钟左右。

end_show.jpg

这里也给大家一个tip:咱们在设计的时候,需要先将所需要的变量,或者需要的变量先设计并保存起来。当界面设计的时候,需要哪些变量显示,直接从这个变量里面选择。如果不需要这个变量,则空闲此变量,而不要不设计,不提供,甚至删除其变量。——这样为后续升级会带来一些不必要的困难。


院士
2021-09-04 20:53:27 打赏
7楼

串口是调试口,网口才是通讯口

说来惭愧,拿手显示屏就看到了板子后面突起的RJ45座子。在平放时,不得不在海绵垫下再挖一个槽才可以使其“平放”,但并未对其功能注意。
说来再次惭愧,阅读说明书时,也仅看到如何使用网口更新固件,没有看到在下一页的网络接口通讯说明……
所以我一直错怪了显示屏仅能连接一个设备,需要多个设备显示时,则需要一个类HUB的设备来“收集-发散”命令与数据。
显示屏提供了RS232协议电平的DB9接口,非常适合我们通过PC机调试,但其由于接口独占的方式,并不适合多机接入,而这时,以太网的通讯方式便轻松解决上述烦恼。
下面,我们来看看使用以太网通讯与显示屏交互数据难不难?

我们还是在SGTools软件里面打开工程设置的界面,选择网络配置的tab页,做出以下网络设置(大家要根据自己的网络环境自行配置哟)

我们再打SSCOM软件,使用TCP方式连接,非常方便就连接到液晶屏所建立的服务器。发送电压指令如下所示:

接下来我们看一下我的网络连接情况的全家福。

全家福.jpg





院士
2021-09-05 16:38:14 打赏
8楼

分享源代码,共同提高

本次试用活动过程还是写了不少的代码,在本帖子里面将其开源,共享。

液晶屏仅为数据显示,而数据的控制与采集全部来自LPC1768开发板。

以下是与INA219电流采样芯片IIC通讯的源代码,做为示例供大家参考:


int8_t openI2C(tI2CMasterClass *pDev, tI2CMasterMode mode) { switch(pDev->busNum) { case 0: { if(pDev->state == busInit) { LPC_SC->PCONP |= (1 << 7); /* shutdown I2C0 */ LPC_SC->PCONP |= (1 << 15); LPC_PINCON->PINSEL1 &= ~(0x03 << 22); /*PINSEL1 bit23、22 01 SDA0*/ LPC_PINCON->PINSEL1 |= (0x01 << 22); LPC_PINCON->PINMODE1 &= ~(0x03 << 22); LPC_PINCON->PINMODE1 |= (0x01 << 22); LPC_PINCON->PINMODE_OD0 |= (0x01 << 27); LPC_PINCON->PINSEL1 &= ~(0x03 << 24); /*PINSEL1 bit25、24 01 SCL0*/ LPC_PINCON->PINSEL1 |= (0x01 << 24); LPC_PINCON->PINMODE1 &= ~(0x03 << 24); LPC_PINCON->PINMODE1 |= (0x01 << 24); LPC_PINCON->PINMODE_OD0 |= (0x01 << 28); LPC_PINCON->I2CPADCFG = 0x00; /*--- Reset registers ---*/ LPC_I2C0->I2SCLL = (uint32_t)i2cBusRate[pDev->busSpeed].i2scllData; LPC_I2C0->I2SCLH = (uint32_t)i2cBusRate[pDev->busSpeed].i2sclhData; NVIC_EnableIRQ(I2C0_IRQn); LPC_I2C0->I2CONSET = (0x01 << BIT_I2EN); pDev->state = busIdle; } if(pDev->state != busIdle) { return (-2); } break; } default: { /* bus number is illegal */ return (-1); } } pDev->busMode = mode; return 0; } int8_t closeI2C(tI2CMasterClass *pDev) { if(pDev->state == busComplete) { pDev->state = busIdle; return 0; } return (-1); } /** * @brief * @param * @retval -1 = not idle; * @date 2019-03-09 20:22 * @note first write regAddr *wBufPtr and then read *rdBufPtr rdLen bytes */ int8_t wrReadI2c(tI2CMasterClass *pDev, uint8_t *rdBufPtr, uint16_t rdLen, uint8_t *wBufPtr, uint16_t wLen) { if(pDev->state != busIdle) { return (-1); } pDev->pRcvBuf = rdBufPtr; pDev->rcvBufLength = rdLen; pDev->pSendBuf = wBufPtr; pDev->sendBufLength = wLen; pDev->busMode = busWR; pDev->state = busWait; LPC_I2C0->I2CONCLR = (1 << BIT_AA) | (1 << BIT_SI) | (1 << BIT_STA); LPC_I2C0->I2CONSET = (1 << BIT_STA); return 0; } int8_t writeI2c(tI2CMasterClass *pDev, uint8_t *wBufPtr, uint16_t wLen) { if(pDev->state != busIdle) { return (-1); } pDev->pSendBuf = wBufPtr; pDev->sendBufLength = wLen; pDev->busMode = busWrite; pDev->state = busWait; LPC_I2C0->I2CONCLR = (1 << BIT_AA) | (1 << BIT_SI) | (1 << BIT_STA); LPC_I2C0->I2CONSET = (1 << BIT_STA); return 0; } /** * @brief * @param * @retval * @date 2019-03-09 11:30 * @note */ void I2C0_IRQHandler(void) { static char enterCnt = 0; uint8_t statVal; statVal = LPC_I2C0->I2STAT & 0xf8; switch(statVal) { case 0x08: /* STATUS_SENDSTART */ { gI2cBus[0].state = busBusy; switch(gI2cBus[0].busMode) { case busRead: { LPC_I2C0->I2DAT = gI2cBus[0].salveAddr | 0x01; break; } case busWrite: case busWR: { LPC_I2C0->I2DAT = gI2cBus[0].salveAddr & 0xFE; break; } } LPC_I2C0->I2CONSET = (1 << BIT_AA); LPC_I2C0->I2CONCLR = (1 << BIT_SI) | (1 << BIT_STA); break; } case 0x10: /* STATUS_REPEATSTART */ { LPC_I2C0->I2DAT = gI2cBus[0].salveAddr | 0x01; LPC_I2C0->I2CONSET = (1 << BIT_AA); LPC_I2C0->I2CONCLR = (1 << BIT_SI) | (1 << BIT_STA); break; } case 0x20: { LPC_I2C0->I2CONSET = (1 << BIT_AA) | (1 << BIT_STO); LPC_I2C0->I2CONCLR = (1 << BIT_SI); break; } case 0x18: case 0x28: { switch(gI2cBus[0].busMode) { case busWrite: case busWR: { if(gI2cBus[0].sendBufLength > 0) { LPC_I2C0->I2DAT = *(gI2cBus[0].pSendBuf); gI2cBus[0].pSendBuf++; gI2cBus[0].sendBufLength--; LPC_I2C0->I2CONSET = (1 << BIT_AA); LPC_I2C0->I2CONCLR = (1 << BIT_SI); } else { if(gI2cBus[0].busMode == busWR) { LPC_I2C0->I2CONSET = (1 << BIT_STA); LPC_I2C0->I2CONCLR = (1 << BIT_SI) | (1 << BIT_AA); } else { LPC_I2C0->I2CONSET = (1 << BIT_STO) | (1 << BIT_AA); /* send stop flag */ LPC_I2C0->I2CONCLR = (1 << BIT_SI); gI2cBus[0].state = busComplete; } } break; } case busRead: { Debug_Info("loop here!\r\n", statVal); break; } default: { Debug_Info("default here!\r\n", statVal); break; } } break; } case 0x40: { if(gI2cBus[0].rcvBufLength <= 1) { LPC_I2C0->I2CONCLR = (1 << BIT_AA) | (1 << BIT_SI); } else { LPC_I2C0->I2CONSET = (1 << BIT_AA); LPC_I2C0->I2CONCLR = (1 << BIT_SI); } break; } case 0x48: { LPC_I2C0->I2CONSET = (1 << BIT_STO) | (1 << BIT_AA); /* send stop flag */ LPC_I2C0->I2CONCLR = (1 << BIT_SI); gI2cBus[0].state = busError; break; } case 0x50: { *gI2cBus[0].pRcvBuf++ = LPC_I2C0->I2DAT; gI2cBus[0].rcvBufLength--; if(gI2cBus[0].rcvBufLength == 1) { LPC_I2C0->I2CONCLR = (1 << BIT_AA) | (1 << BIT_SI); } else { LPC_I2C0->I2CONSET = (1 << BIT_AA); LPC_I2C0->I2CONCLR = (1 << BIT_SI); } break; } case 0x58: { *gI2cBus[0].pRcvBuf++ = LPC_I2C0->I2DAT; gI2cBus[0].rcvBufLength--; LPC_I2C0->I2CONSET = (1 << BIT_STO) | (1 << BIT_AA); /* send stop flag */ LPC_I2C0->I2CONCLR = (1 << BIT_SI); gI2cBus[0].state = busComplete; break; } default: { LPC_I2C0->I2CONSET = (1 << BIT_STO) | (1 << BIT_AA); /* send stop flag */ LPC_I2C0->I2CONCLR = (1 << BIT_SI); break; } } }


亲爱的网友们,具体的工程文件请参见我的代码仓库

https://gitee.com/jobszheng5/learn1768





共8条 1/1 1 跳转至

回复

匿名不能发帖!请先 [ 登陆 注册]