2023.12.10汇报
发表于更新于
字数总计:1.4k阅读时长:5分钟 中国
2023.12.10汇报
Zehua比赛内容
伊戈尔杯
器件选型
1.红外循迹模块
受光线影响很大,需要反复调试
2.灰度循迹模块
受光线影响较大。
3.openmv
识别赛道黑点
通讯方式
检测高低电平
电控原理
速度控制
PWM
位置调整
一共4个灰度循迹模块,每边各两个。最内部的两个检测到黑线让两侧轮子以一个较小的差速前进。外侧的两个检测到黑线则让两侧轮子以相反方向转。
void run_2(void) { stop=HAL_GPIO_ReadPin(stop_GPIO_Port, stop_Pin); track4 = HAL_GPIO_ReadPin(right_out_GPIO_Port, right_out_Pin); track3 = HAL_GPIO_ReadPin(right_in_GPIO_Port, right_in_Pin); track2 = HAL_GPIO_ReadPin(left_in_GPIO_Port, left_in_Pin); track1 = HAL_GPIO_ReadPin(left_out_GPIO_Port, left_out_Pin); if ((track1 == 1 && track2 == 0 && track3 == 0 && track4 == 0)||(track1 == 1 && track2 == 1 && track3 == 0 && track4 == 0)) turn_left_high(); else if (track1 == 0 && track2 == 1 && track3 == 0 && track4 == 0) turn_left_low(); else if (track1 == 0 && track2 == 0 && track3 == 1 && track4 == 0) turn_right_low(); else if ((track1 == 0 && track2 == 0 && track3 == 0 && track4 == 1)||(track1 == 0 && track2 == 0 && track3 == 1 && track4 == 1)) turn_right_high(); else if(stop==1) { stopMotors(); HAL_Delay(10000); } else if ((track1==1&&track4==1&&track3==1)||(track1==1&&track4==1&&track2==1)||(track2==1&&track3==1&&track4==1)||(track2==1&&track3==1&&track1==1)) { HAL_Delay(1); track4 = HAL_GPIO_ReadPin(right_out_GPIO_Port, right_out_Pin); track3 = HAL_GPIO_ReadPin(right_in_GPIO_Port, right_in_Pin); track2 = HAL_GPIO_ReadPin(left_in_GPIO_Port, left_in_Pin); track1 = HAL_GPIO_ReadPin(left_out_GPIO_Port, left_out_Pin); if ((track1==1&&track4==1&&track3==1)||(track1==1&&track4==1&&track2==1)||(track2==1&&track3==1&&track4==1)||(track2==1&&track3==1&&track1==1)) { stopMotors(); HAL_Delay(10000); } } else ahead(); }
|
2.位置式PID
参考:https://blog.csdn.net/lqj11/article/details/116165991
3.停车黑线识别
问题:行驶中误触发
解决办法1:任意三个传感器同时检测到黑线,则延迟1ms再次检测,若仍检测到,则停车
办法2:移动平均滤波器(问ChatGPT得到的答案)
移动平均滤波器是一种常用的信号处理技术,用于平滑噪声信号或减少信号中的高频成分。它的基本原理是通过对一系列连续输入信号进行平均来计算输出信号。
移动平均滤波器的操作步骤如下:
- 定义一个固定大小的窗口或缓冲区,用于存储输入信号的历史数据。
- 每当有新的输入信号到达,将其添加到窗口的末尾,并将最早的输入信号从窗口的开头移除,以保持窗口的大小不变。
- 对窗口中的所有输入信号进行求和,并将求和结果除以窗口的大小,得到平均值。
- 平均值作为输出信号。
#include <stdio.h>
#define WINDOW_SIZE 3
float movingAverageFilter(float input) { static float window[WINDOW_SIZE] = {0}; static int currentIndex = 0; float sum = 0;
window[currentIndex] = input;
for (int i = 0; i < WINDOW_SIZE; i++) { sum += window[i]; }
currentIndex = (currentIndex + 1) % WINDOW_SIZE;
return sum / WINDOW_SIZE; }
int main() { float inputSignal[] = {1.2, 2.5, 3.1, 2.8, 4.0}; int inputSignalSize = sizeof(inputSignal) / sizeof(float);
printf("Input Signal: "); for (int i = 0; i < inputSignalSize; i++) { float filteredSignal = movingAverageFilter(inputSignal[i]); printf("%.2f ", filteredSignal); } printf("\n");
return 0; }
|
极客赛
器件选型
FPM10A指纹识别模块
舵机
ASRPRO语音识别模块
PCF8591模数转换
通讯方式
IO口电平
UART串口通讯
串口发送数据:
HAL_UART_Transmit(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size, uint32_t Timeout)
|
UART_HandleTypeDef *huart UATR的别名 如 : UART_HandleTypeDef huart1; 别名就是huart1
*pData 需要发送的数据
Size 发送的字节数
Timeout 最大发送时间,发送数据超过该时间退出发送
发送字符a。
char ZZX='a'; HAL_UART_Transmit(&huart1,(uint8_t *)&ZZX,1, 0xffff);
|
接收字符并且返回接收到的字符:
基本流程:main函数中使能串口接收中断HAL_UART_Receive_IT()接收数据>接收到数据进入串口接收中断回调函数HAL_UART_RxCpltCallback()
####### 声明变量用来接收数据
#define RXBUFFERSIZE 256
char TxBuffer[RXBUFFERSIZE]; uint8_t RxBuffer=0; uint8_t Uart1_Rx_Cnt = 0;
|
变量RxBuffer是在接收中断函数HAL_UART_Receive_IT()中用来存储接收到的数据,数组TxBuffer是在串口接收中断回调函数HAL_UART_RxCpltCallback()存储中断函数HAL_UART_Receive_IT()中接收到的数据。
####### 启用接收中断(放置在main函数中)
HAL_UART_Receive_IT(&huart1, (uint8_t *)&RxBuffer, 1);
|
只触发一次中断,每次接收完数据要重复调用。
####### 设置串口接收中断回调函数HAL_UART_RxCpltCallback()
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart) { UNUSED(huart);
if(Uart1_Rx_Cnt >= 255) { Uart1_Rx_Cnt = 0; memset(TxBuffer,0x00,sizeof(TxBuffer)); HAL_UART_Transmit(&huart1, (uint8_t *)"数据溢出", 10,0xFFFF); } else { TxBuffer[Uart1_Rx_Cnt++] = RxBuffer; if((TxBuffer[Uart1_Rx_Cnt-1] == 0x0A)&&(TxBuffer[Uart1_Rx_Cnt-2] == 0x0D)) { HAL_UART_Transmit(&huart1, (uint8_t *)&TxBuffer, Uart1_Rx_Cnt,0xFFFF); while(HAL_UART_GetState(&huart1) == HAL_UART_STATE_BUSY_TX); Uart1_Rx_Cnt = 0; memset(TxBuffer,0x00,sizeof(TxBuffer)); } } HAL_UART_Receive_IT(&huart1, (uint8_t *)&RxBuffer, 1); }
|
根据接收到的字符点亮LED灯:
方法同上,但无需配置串口接收中断回调函数HAL_UART_RxCpltCallback()
while (1) { if(RxBuffer=='a') { HAL_GPIO_WritePin(LED_GPIO_Port, LED_Pin, GPIO_PIN_SET); HAL_UART_Receive_IT(&huart1, (uint8_t *)&RxBuffer, 1); } if(RxBuffer=='b') { HAL_GPIO_WritePin(LED_GPIO_Port, LED_Pin, GPIO_PIN_RESET); HAL_UART_Receive_IT(&huart1, (uint8_t *)&RxBuffer, 1); } }
|
IIC通讯