基于stm32的多向风速检测,利用esp32组网接收
近来帮一个师兄做实验,师兄要求检测多旋翼的产生风场的情况,那就要采集一个点上x,y,z轴方向上的风速,而且要做十个点的数据检测。
准备
师兄给了两篇论文我其中一篇有介绍风轮式测速的方法
所以要想测风速,就是用用stm32数脉冲的频率,然后再乘以0.1就是风速了。
写程序
刚开始我用了定时器输入捕获来获得脉冲频率,但是这种方法实测效果很差,而且在风叶差不多停下的时候数据会突变。我参考了下面的博客。
https://www.cnblogs.com/strongerHuang/p/5662338.html
因为达不到要求,我转向STM32的外部时钟源模式,即可以根据外部脉冲信号进行计数,然后另外设定定时器定时中断去读取计数器的值。我用的是stm32最小系统板只有两个外部触发管脚分别为TIM1的PA12,TIM2的PA0。所以用TIM3作为定时器设置时间。
定时器初始化
void TIM3_Int_Init(u16 arr,u16 psc)
{
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
NVIC_InitTypeDef NVIC_InitStructure;
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE);
TIM_TimeBaseStructure.TIM_Period = arr;
TIM_TimeBaseStructure.TIM_Prescaler =psc;
TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1;
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure);
TIM_ITConfig(TIM3,TIM_IT_Update,ENABLE );
NVIC_InitStructure.NVIC_IRQChannel = TIM3_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
TIM_Cmd(TIM3, ENABLE);
}
void TIM2_Cap_Init(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPD;
GPIO_Init(GPIOA, &GPIO_InitStructure);
GPIO_ResetBits(GPIOA,GPIO_Pin_0);
TIM_TimeBaseStructure.TIM_Period = 0xFFFF;
TIM_TimeBaseStructure.TIM_Prescaler =0;
TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1;
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure);
TIM_ITRxExternalClockConfig(TIM2,TIM_TS_ETRF);
TIM_ETRClockMode2Config(TIM2, TIM_ExtTRGPSC_OFF, TIM_ExtTRGPolarity_NonInverted, 0);
TIM_SetCounter(TIM2, 0);
TIM_Cmd(TIM2,ENABLE );
}
void TIM1_Cap_Init(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM1, ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPD;
GPIO_Init(GPIOA, &GPIO_InitStructure);
GPIO_ResetBits(GPIOA,GPIO_Pin_12);
TIM_TimeBaseStructure.TIM_Period = 0xFFFF;
TIM_TimeBaseStructure.TIM_Prescaler =0;
TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1;
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure); //¸ù¾ÝTIM_TimeBaseInitStructÖÐÖ¸¶¨µÄ²ÎÊý³õʼ»¯TIMXµÄʱ¼ä»ùÊý
TIM_ITRxExternalClockConfig(TIM1,TIM_TS_ETRF); //ÅäÖÃÍⲿ´¥·¢£¬·ñÔò²»»á¼ÆÊý
TIM_ETRClockMode2Config(TIM1, TIM_ExtTRGPSC_OFF, TIM_ExtTRGPolarity_NonInverted, 0);
TIM_SetCounter(TIM1, 0);
TIM_Cmd(TIM1,ENABLE );
}
中断配置
void TIM3_IRQHandler(void)
{
uint16_t CNT_2;
uint16_t fq_2;
uint16_t fq_1;
uint16_t CNT_1;
if(TIM_GetITStatus(TIM3,TIM_IT_Update)!= RESET)
{
TIM_ClearITPendingBit(TIM3,TIM_IT_Update);
CNT_2=TIM_GetCounter(TIM2);
fq_2=CNT_2; //读取1S内计数器的cnt值
CNT_1=TIM_GetCounter(TIM1);
fq_1=CNT_1; //读取1S内计数器的cnt值
speed_one=0.1*fq_1; //频率*0.1就是风速
speed_two=0.1*fq_2;
TIM_SetCounter(TIM2,0);
TIM_SetCounter(TIM1,0);
}
}
ESP32端
其实网上很多人用来组网都是esp8266,我用的是esp32。这个esp32比esp8266强大就用它来做组网,思路是以电脑和多个esp32组成局域网,运用TCP连接,电脑作为主机,esp32作为从机不断地发送stm32读取的风速给电脑,电脑上用网络调试助手可以对数据进行储存。
连接WiFi速度超快
#include <WiFi.h>
const char *ssid = "speed";//输入WiFi的名字
const char *password = "********";//输入你WiFi的密码
const IPAddress serverIP(192,168,1,107); //这个可以进路由器管理页面更改电脑在路由器的ip地址
uint16_t serverPort = 80; //服务器端口号
WiFiClient client; //声明一个客户端对象,用于与服务器进行连接
void setup()
{
Serial.begin(115200);
Serial.println();
WiFi.mode(WIFI_STA);
WiFi.setSleep(false); //关闭STA模式下wifi休眠,提高响应速度
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED)
{
delay(500);
Serial.print(".");
}
Serial.println("Connected");
Serial.print("IP Address:");
Serial.println(WiFi.localIP());
}
void loop()
{
Serial.println("尝试访问服务器");
if (client.connect(serverIP, serverPort)) //尝试访问目标地址
{
Serial.println("访问成功");
client.print("start!"); //向服务器发送数据
while (client.connected()||client.available()) //如果已连
{
if(Serial.available())
{
String lines = Serial.readStringUntil('\n');
client.write(lines.c_str()); //将收到的数据回发sever
}
if (client.available()) //如果有数据可读取
{
String line = client.readStringUntil('\n'); //读取数据到换行符
Serial.print("读取到数据:");
Serial.println(line);
client.write(line.c_str()); //将收到的数据回发sever
}
}
Serial.println("关闭当前连接");
client.stop(); //关闭客户端
}
else
{
Serial.println("访问失败");
client.stop(); //关闭客户端
}
delay(500);
}
在烧录esp32的代码时要把stm32和esp32物理连接的串口记得要断开!!!
在网络调试助手上接收
最后
第一次写请各位多多包涵。