使用STM32的ADC功能采集摇杆横轴和纵轴的电压数据来确定摇杆的位置是一种常见的读取摇杆状态的一种方式,关键点是如何准确的通过这些数据将摇杆的动作反映到我们的屏幕等载体上。
首先我们先分析一下摇杆的电路原理图,从图中可以看到摇杆检测转动位置的原理就是通过两个电位器来实现的,我们通过读取摇杆拨动时,不同位置产生的不同电压值,就可以此为数据进行描述摇杆的拨动情况。
但是在使用这些数据的同时存在一些问题,即如何确定电压值与拨动情况的关系。因为摇杆采用的是电位器,即可调电阻,所以根据电阻分压的原理我们可以知道,当摇杆拨动到不同的位置时,对应的电压与电阻成正比。故根据电阻的线性变化,我们知道摇杆产生的电压也是线性变化的。故电压值与拨动位置之间的关系应该也是线性的。又因为摇杆拨动时我们较难确定当前的摇杆与不拨动时到底位置偏差为多少,所以我们在确定其线性时,可以将摇杆的位置拨动到最远的两端进行记录数据,并且也记录没有拨动摇杆时的数据,并以此进行线性拟合,确定两者之间的线性关系。
根据以上分析,本文基于STM32和0.96英寸OLED和摇杆进行实现,将摇杆的动作反应到OLED上面。
第一步:采集数据,通过STM32的ADC功能采集摇杆的横轴和纵轴的电压数据,以拨动摇杆的拨动位置最左/前,中间值(不拨动摇杆),最右/后值记录数据使用表格记录。
例如:
摇杆位置 | 摇杆电压值对应的ADC值 | OLED偏移值 |
最左/前 | 3900 | -10 |
不拨动 | 1865 | 0 |
最右/后 | 10 | 10 |
第二步:确定反应摇杆动作的数据范围。本文采用的是OLED,故采取偏移距离为-10到10个像素点,即摇杆不拨动的情况下,将摇杆位置显示在屏幕中央。使摇杆的动作在OLED上通过偏移距离的形式展示出来。
第三步:利用上面采集的数据和数据范围,使用MATLAB上的曲线拟合器进行线性拟合。
步骤如下:
一、 将获取到的数据导入到mahlab中,在曲线拟合器中选择导入X(摇杆电压值对应的ADC值),Y(OLED偏移值)的数据。
二、 在多项式次数中选择为一次,因为是线性关系。
三、 在画面的中可以明显的看到拟合图,发现拟合效果较好,并且可以在右下角看到拟合结果,P1与P2就是我们需要的值
第四步:编写相应代码并在硬件上面进行验证
通过ADC读取电压值的代码和OLED屏显示的代码,不是本文讨论的重点,所以就不展开了,本文OLED屏显示代码采用的是江协科技的开源OLED显示屏代码。
测试代码如下
#include "OLED.h"
#include "AD.h"
#include "Delay.h"
#include "init.h"
#include "stm32f10x.h"
int main()
{
Init();//初始化所需外设
//程序稍加简略,移除了不相关的语句,仅作测试
while(1)
{
yaogan_X_pianyi=(int)(-0.0049*(double)AD[1]+10.1849);//X轴线性函数
yaogan_Y_pianyi=(int)(-0.0051*(double) AD [2]+9.8901); //Y轴线性函数
OLED_DrawCircle(64+yaogan_X_pianyi,40+yaogan_Y_pianyi,10,OLED_FILLED);
//画一个小圆,表示摇杆位置
OLED_DrawCircle(64,40,20,OLED_UNFILLED);
//画一个大圆,包括表示摇杆位置的小圆能够到达的最大范围
OLED_Update();//更新屏幕
OLED_Clear();//清除OLED显示数组
Delay_ms(20);//阻塞延时
}
}
优点:线性拟合效果较好,并且在硬件设备上面实测效果也可以接受。
缺点:数据采集阶段可以采集的数量较少,所以拟合程度的好坏极大的取决于摇杆的线性程度。