方案解析:纸张计数装置-测多少张不重要,关键是准确!(源码开源)

首页-达尔闻    基础应用    方案解析:纸张计数装置-测多少张不重要,关键是准确!(源码开源)

我们是来自中国民航大学的参赛队员(胡冀威王启鑫 莫浩杰),在2019全国电赛F题中取得国一的成绩,在此分享我们的作品,感谢达尔闻邀约。

戳这里看视频》》

作品的源码可以在“达尔闻说”公众号,回复:F题代码,即可获得。

 

 

我们的作品应用FDC2214电容传感器芯片测量电容值所用的LC谐振原理,采用矩阵压缩拟合算法和中值平均滤波算法,设计并制作一套应用电容传感器FDC2214计量纸张的系统。系统主要由STM32F407处理器及其最小系统、FDC2214电容传感器芯片及其外围电路、二线制平行电容极板及其固定结构构成。

 

 

赛前准备与赛题选择
 
 
 

赛前准备:我们组一开始准备时就准备的控制类,也做了往年的一些真题,比如风力摆、板球控制系统等等,也准备了单片机控制板,电机驱动板等常用的模块。8月1日清单公布后至7日赛题公布之前,我们组参照网上的一些赛题预测与自己的想法来准备了一些器件,按照控制类的惯例买了云台、小车…,怎么说呢?

 
赛题公布后:赛题公布后一直有人吐槽今年的出题,感觉今年没了控制类和电源类,反正我们学校电源组的同学都惊呆了。经过简单讨论后我们组先选了3道题:A题、F题、H题;我的队友去年做的是无线充电小车,被无线充电的谐振坑惨了,直接就说不考虑无线充电了;电磁炮的话我以前稍有了解,感觉太危险就没有考虑;就只剩下F题了。

仔细读题后感觉这题和2018年的手势识别题很像,只不过要求变高了,要求极板大小50mm,线长500mm。找了块FDC2214的板子接上极板后放几张纸测试了下,数据变化还挺大的,方案基本可行,便确定了题目。

 

作品硬件组成
 
STM32主控板:系统的总控制器,采用STM32F407VGT6单片机,上面集成了常用的按键和OLED显示屏。

FDC2214传感器板:

极板:极板粘贴在上层的亚克力板和下层的纤维板上,为了保证极板的突出不会让纸张产生形变,周围贴了一圈垫片用来把纸张垫起来。垫片就是将极板上的铜层腐蚀掉后做成的。极板通过屏蔽线连接FDC2214的IN0A、IN0B。

显示屏:主控板上面自带的显示屏太小了,不方便评委老师查看测试结果,用了一块串口屏来显示测试结果。

软件代码(开源)

FDC2214传感器配置:根据数据手册上的说明得知,当传感器配置为差分模式时,具有更高的灵敏度,因此在程序上将传感器配置为差分模式。为了能测量更多的纸张数量,将传感器配置为全电流模式,增强驱动力。

  • /*!
  • * @brief FDC2214初始化函数
  • * @return 1:成功;0:失败
  • * @since v1.0 * Sample usage: FDC2214_Init();
  • */ uint8_t FDC2214_Init(void)
  • {
  • uint16_t deviceID = 0;
  • deviceID = FDC2214_Read16(FDC2214_Addr, FDC2214_DEVICE_ID); //读器件ID
  • if (deviceID == FDC2214_ID) { FDC2214_Reset();
  • FDC2214_SetRcount(FDC2214_Channel_0, 600); //600 cycles 转换周期 FDC2214_SetSettleCount(FDC2214_Channel_0, 200); //200 cycles 等待时间 FDC2214_SetChannelClock(FDC2214_Channel_0, 2, 1); //设置时钟分频,1分频,40MHz FDC2214_SetActiveChannel(FDC2214_Channel_0); //开启通道0
  • FDC2214_SetCurrentMode(0); //全电流激活模式
  • FDC2214_SetClockSource(1); //外部时钟源
  • FDC2214_SetHighCurrentMode(1); //高电流传感器驱动
  • FDC2214_SetMUX_CONFIG(0, FDC2214_Channel_Sequence_0_1, FDC2214_Bandwidth_10M); //关闭自动扫描,10MHz带宽        
  • FDC2214_SetSleepMode(0);  //退出睡眠状态,开始工作
  • return 1;
  • }
  • return 0;
  • }

 

纸张数的计算:DealData_BaseData是一个数组,记录了不同纸张数的FDC2214读数,比如DealData_BaseData[0]记录的是1张纸的FDC2214读数、DealData_BaseData[1]记录的是22张纸的FDC2214读数,以此类推。通过计算当前读数与基准值的误差,然后进行排序,最小的即为最接近的纸张数。

  • static int cmpfunc(const void *a, const void *b) { return ((dealData *)a)->error - ((dealData *)b)->error; } //计算纸张数uint16_t DealData_Calculate(void) { uint32_t dataTemp = 0; dataTemp = FDC2214_Data;//缓存FDC2214数据 DealData_Init(0); for (uint16_t i = 0; i < PAPER_COUNT; i++) { DealData_ErrorData[i].error = fabs((double)((int32_t)dataTemp - (int32_t)DealData_BaseData[i])); //记录当前值与存储基准值的误差 } qsort(DealData_ErrorData, PAPER_COUNT, sizeof(dealData), cmpfunc); //将误差从小到大快速排序 return DealData_ErrorData[0].index;//返回最小值,及最接近的值 }

自校准程序:因为采用对数函数进行拟合y=A*ln(x)+B,需要计算出2个参数A、B,采用矩阵来计算这两个参数,这样的优点是可以输入多个已知数来进行计算,提高准确度。矩阵运算库采用的是CMSIS-DSP库。计算后得出A、B两个参数,将这两个参数带入y=A*ln(x)+B中,计算出当纸张数为X时的理论FDC2214读数,然后将这个数填入DealData_BaseData作为基准值。

自校准程序以及作品的全部程序,可以在“达尔闻说”公众号,回复:F题代码,即可获得。

 
写在最后,一些建议
 
一定要找好队友,不一定要那种特别强,但也尽量别找基础比较弱的,3个人要配合好,别都到了测评现场还在吵架。
 
  • 单片机就不用多说了,TI的、ST的都行,找一款自己用得最熟的。把常用的程序模块化,比如ADC、PWM、定时器、OLED显示等等。用的时候直接复制过来用,可以节约很多时间。
  • 程序上尽量有一个可以调参数的菜单,这样可以脱机调参数,而不必每次都连电脑改参数了。菜单推荐GitHub上一个开源的OLED菜单SOLGUI,用起来也比较方便。https://github.com/MaxwellXyao/SOLGUI_V2
  • 常用的模块还是要多备点,能自己做的尽量自己做,避免出现2018年TI杯省赛那样要求在板子上打上序列号。

     

2019年9月20日 13:49
收藏