一、OpenMV  IDE

1、简单数据通信
import time

from pyb import UART
uart = UART(3, 115200, timeout_char=200)
uart.init(115200, bits=8, parity=None, stop=1) # init with given parameters

while True:
    FH = bytearray([0xb3,0xb3])     #帧头,控制板接收数据以后判断,转化为字节传送,不能用16进制直接传
    uart.write(FH)                  #写到串口
    uart.write("Logan")             #写数据
    FH = bytearray([0x0d,0x0a])     #结束标志,换行和回车的ascll
    uart.write(FH)
    time.sleep_ms(1000)             #延时

2、多字节数据通信
def send_data(x,y,w,h):
    global uart;
    uart.write(str(x))
    uart.write(bytearray([0x20]))   # 发送空格
    uart.write(str(y))
    uart.write(bytearray([0x20]))
    uart.write(str(w))
    uart.write(bytearray([0x20]))
    uart.write(str(h))
    uart.write(bytearray([0x20]))

3、寻找最大色块,传递中心点坐标及矩形长宽
import time
import sensor
import math
import image
import ustruct
from pyb import UART


uart = UART(3, 115200, timeout_char=200)
uart.init(115200, bits=8, parity=None, stop=1)  # init with given parameters

threshold_index = 4                             # 0 for red, 1 for green, 2 for blue
thresholds = [
    (30, 100, 15, 127, 15, 127),  # generic_red_thresholds
    (30, 100, -64, -8, -32, 32),  # generic_green_thresholds
    (0, 30, 0, 64, -128, 0),      # generic_blue_thresholds
    (82, 100, 75, -49, -22, 31),  # generic_white_thresholds
    (21, 83, 32, 65, 31, 63),
]

sensor.reset()
sensor.set_pixformat(sensor.RGB565)
sensor.set_framesize(sensor.QVGA)# QVGA的中心坐标:160,120
sensor.skip_frames(time=2000)    # 跳过2000毫秒的帧让相机图像在改变相机设置后稳定下来
sensor.set_auto_gain(False)      # 必须关闭才能进行颜色跟踪
sensor.set_auto_whitebal(False)  # 必须关闭才能进行颜色跟踪
clock = time.clock()

def find_max(blobs):
    max_size=0
    for blob in blobs:
        if blob.pixels() > max_size:
            max_blob = blob
            max_size = blob.pixels()
    return max_blob


def send_data(x,y,w,h):
    global uart;
    FH = bytearray([0xb3,0xb3])     # 帧头
    uart.write(FH)                  # 写到串口

    uart.write(str(x))
    uart.write(bytearray([0x20]))   # 发送空格
    uart.write(str(y))
    uart.write(bytearray([0x20]))
    uart.write(str(w))
    uart.write(bytearray([0x20]))
    uart.write(str(h))

    uart.write(bytearray([0x20]))
    FH = bytearray([0x0d,0x0a])     # 帧尾,换行和回车的ascll
    uart.write(FH)



while True:
    clock.tick()
    img = sensor.snapshot()
    blobs = img.find_blobs([thresholds[threshold_index]])

    #如果找到了目标颜色
    if blobs:
        max_blob = find_max(blobs)
        cx=max_blob[5]
        cy=max_blob[6]
        cw=max_blob[2]
        ch=max_blob[3]

        # 这些值取决于max_blob不是圆形的,否则它们将不稳定.
        # 检查max_blob是否显著偏离圆形
        if max_blob.elongation() > 0.5:
            img.draw_edges(max_blob.min_corners(), color=(255, 0, 0))
            img.draw_line(max_blob.major_axis_line(), color=(0, 255, 0))
            img.draw_line(max_blob.minor_axis_line(), color=(0, 0, 255))

        # 这些值始终是稳定的。
        # img.draw_rectangle(max_blob.rect())
        img.draw_rectangle(160,120,35,35)
        img.draw_cross(cx, cy)

        # 注意-max_blob旋转仅限于0-180。
        img.draw_keypoints(
            [(cx, cy, int(math.degrees(max_blob.rotation())))], size=20
        )

        send_data(cx,cy,cw,ch)      # 发送数据

        print(cx,cy,cw,ch)
        print(clock.fps())

二、STM32串口中断模式接收

1、初始化
#include "string.h"
#include "stdio.h"
#include "stdlib.h"

#define RXBUFFERSIZE  256

char RxBuffer[RXBUFFERSIZE],rx_buf[RXBUFFERSIZE];
uint8_t aRxBuffer;
uint8_t Uart1_Rx_Cnt = 0;
int flag=0;

printf("Hello World!\r\n");
HAL_Delay(200);
HAL_UART_Receive_IT(&huart2, (uint8_t *)&aRxBuffer, 1);


int fputc(int ch, FILE *f)
{
    HAL_UART_Transmit(&huart1, (uint8_t *)&ch, 1, 0xffff);
	HAL_UART_Transmit(&huart2, (uint8_t *)&ch, 1, 0xffff);
    return ch;
}
 
int fgetc(FILE *f)
{
    uint8_t ch = 0;
    HAL_UART_Receive(&huart1, &ch, 1, 0xffff);
	HAL_UART_Receive(&huart2, &ch, 1, 0xffff);
    return ch;
}

2、串口回调
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
    UNUSED(huart);
	if(huart==&huart2){
		HAL_GPIO_TogglePin(GPIOF,LED_Pin);		//有数据则翻转LED灯

		RxBuffer[Uart1_Rx_Cnt] = aRxBuffer;
		Uart1_Rx_Cnt++;
		if((RxBuffer[Uart1_Rx_Cnt-1] == 0xb3)&&(RxBuffer[Uart1_Rx_Cnt-2] == 0xb3)) flag=1;		 //帧头判定
		else if((RxBuffer[Uart1_Rx_Cnt-2] == 0x0d)&&(RxBuffer[Uart1_Rx_Cnt-1] == 0x0a)) flag=2;  //帧尾判定
		else flag=0;

		switch (flag)
        {
        	case 1:
				Uart1_Rx_Cnt = 0;
				memset(RxBuffer,0x00,sizeof(RxBuffer));
        		break;
        	case 2:
				RxBuffer[Uart1_Rx_Cnt-1] = '\0';
				RxBuffer[Uart1_Rx_Cnt-2] = '\0';
				strcpy(rx_buf,RxBuffer);
				printf("%s\r\n",rx_buf);
				while(HAL_UART_GetState(&huart2) == HAL_UART_STATE_BUSY_TX);
				Uart1_Rx_Cnt = 0;
				memset(RxBuffer,0x00,sizeof(RxBuffer));
        		break;
			default:break;
        }
	HAL_UART_Receive_IT(&huart2, (uint8_t *)&aRxBuffer, 1);
	}
}

3、CUBEMX开启串口

USART1:STM32与电脑通信

USART2:STM32与OPENMV通信

四、DMA传输版本

1、main.c
#include "stdio.h"
#include "string.h"
#include "stdlib.h"

#define RXBUFFERSIZE  256

volatile uint8_t recv_end_flag = 0; //接收结束标志位
uint8_t RxBuffer2[RXBUFFERSIZE],rx_buf2[RXBUFFERSIZE];


	HAL_UART_Transmit_DMA(&huart1,(uint8_t *)"Hello\r\n",sizeof("Hello\r\n"));
	HAL_Delay(200);

	__HAL_UART_ENABLE_IT(&huart2, UART_IT_IDLE);
	HAL_UART_Receive_DMA(&huart2,RxBuffer2,sizeof(RxBuffer2));

2、stm32f4xx_hal.c
extern volatile uint8_t recv_end_flag; //接收结束标志位
extern uint8_t RxBuffer2[RXBUFFERSIZE],rx_buf2[RXBUFFERSIZE];

int cx=0,cy=0;

void USART2_IRQHandler(void)
{
  /* USER CODE BEGIN USART2_IRQn 0 */

  /* USER CODE END USART2_IRQn 0 */
  HAL_UART_IRQHandler(&huart2);
  /* USER CODE BEGIN USART2_IRQn 1 */
	uint8_t tmp_flag =__HAL_UART_GET_FLAG(&huart2,UART_FLAG_IDLE); 	//获取IDLE标志位
	if((tmp_flag != RESET))											//通过标志位判断接收是否结束
	{
		recv_end_flag = 1; 											//置1表明接收结束
		__HAL_UART_CLEAR_IDLEFLAG(&huart2);							//清除标志位
		HAL_UART_DMAStop(&huart2);

		strcpy((char *)rx_buf2,(char *)RxBuffer2);
		int st=0,cnt_blank=0;
		for(int i=0;rx_buf2[i];i++){
			if(rx_buf2[i]==' ') {
				cnt_blank++;
				int temp=0;
				for(int j=st;j<i;j++) temp=temp*10+(rx_buf2[j]-'0');
				switch (cnt_blank)
				{
					case 1:cx=temp;st=i+1;break;
					case 2:cy=temp;break;
					default:break;
				}
			}
		}
		printf("%d  %d\r\n",cx,cy);
		HAL_UART_Receive_DMA(&huart2,RxBuffer2,sizeof(RxBuffer2));		//开启DMA接收,方便下一次接收数据
	}
  /* USER CODE END USART2_IRQn 1 */
}

CUBEMX配置及更多详见【STM32+HAL】DMA应用

源码【STM32+HAL】DMA应用NO.2

 五、巨人之肩

STM32与openmv通信(HAL库)

Openmv 与 Stm32f407通信

OpenMV与STM32之间的通信(附源码)

 六、接线图

Logo

有“AI”的1024 = 2048,欢迎大家加入2048 AI社区

更多推荐