智能车竞赛的WiFi图传代码

目录

说明:

一、my_spi_wifi.c文件

1.1 预编译和全局变量

1.2 my_spi_wifi_init函数

1.3 my_spi_wifi_rece函数

1.4 my_spi_wifi_image_init函数

1.5 my_spi_wifi_image_send函数

1.6 my_spi_wifi_image_senfOriginal函数

1.7 my_spi_wifi_image_SendOriginal_BX函数

1.8 my_wifi_image_send函数

 二、my_spi_wifi.h文件


说明:

根据逐飞的库,进行了wifi图传代码的封装

编译环境:ADS 1.80

一、my_spi_wifi.c文件

1.1 预编译和全局变量

#include "zf_common_headfile.h"
//选择协议,必选一个,不然没办法通信
//#define UTP
#define TCP


uint8 wifi_spi_test_buffer[] = "初始化成功\n";
uint8 wifi_spi_get_data_buffer[256];
uint32 data_length = 0;
// 图像备份数组,在发送前将图像备份再进行发送,这样可以避免图像出现撕裂的问题
IFX_ALIGN(4) uint8 image_copy[MT9V03X_H*MT9V03X_W];

1.2 my_spi_wifi_init函数

/*  @wifi初始化函数
 *  @说明:根据逐飞库修改而来
 *  @作者:吴广金
 *  @时间:2024年3月7日
 * */
void my_spi_wifi_init(void)
{
    while(wifi_spi_init(WIFI_SSID_TEST, WIFI_PASSWORD_TEST))
    {
        printf("\r\n connect wifi failed. \r\n");
        system_delay_ms(100);                                                   // 初始化失败 等待 100ms
    }
    printf("\r\n module version:%s",wifi_spi_version);                          // 模块固件版本
    printf("\r\n module mac    :%s",wifi_spi_mac_addr);                         // 模块 MAC 信息
    printf("\r\n module ip     :%s",wifi_spi_ip_addr_port);                     // 模块 IP 地址

    // zf_device_wifi_spi.h 文件内的宏定义可以更改模块连接(建立) WIFI 之后,是否自动连接 TCP 服务器、创建 UDP 连接
    if(0 == WIFI_SPI_AUTO_CONNECT)                                              // 如果没有开启自动连接 就需要手动连接目标 IP
    {
        while(wifi_spi_socket_connect(                                          // 向指定目标 IP 的端口建立连接
#ifdef UDP//建立udp连接
            "UDP",                                                              // 指定使用UDP方式通讯
#endif
#ifdef TCP //建立TCP连接
            "TCP", // 指定使用TCP方式通讯
#endif
            WIFI_SPI_TARGET_IP,                                                 // 指定远端的IP地址,填写上位机的IP地址
            WIFI_SPI_TARGET_PORT,                                               // 指定远端的端口号,填写上位机的端口号,通常上位机默认是8080
            WIFI_SPI_LOCAL_PORT))                                               // 指定本机的端口号
        {
            // 如果一直建立失败 考虑一下是不是没有接硬件复位
            printf("\r\n Connect UDP/TCP Servers error, try again.");
            system_delay_ms(100);                                               // 建立连接失败 等待 100ms
        }
    }
    // 发送测试数据至服务器
    data_length = wifi_spi_send_buffer(wifi_spi_test_buffer, sizeof(wifi_spi_test_buffer));
    wifi_spi_udp_send_now();
    if(!data_length)
    {
        printf("\r\n send success.");
    }
    else
    {
        printf("\r\n %ld bytes data send failed.", data_length);
    }


}

1.3 my_spi_wifi_rece函数

/*  @wifi接收函数
 *  @说明:根据逐飞库修改而来
 *  @作者:吴广金
 *  @返回值:uint32类型,返回接收到的数据
 *  @时间:2024年3月7日
 * */
uint32 my_spi_wifi_rece(void)
{
    data_length = wifi_spi_read_buffer(wifi_spi_get_data_buffer, sizeof(wifi_spi_get_data_buffer));
    if(data_length)                                                         // 如果接收到数据 则进行数据类型判断
    {
        printf("\r\n Get data: <%s>.", wifi_spi_get_data_buffer);
        if(!wifi_spi_send_buffer(wifi_spi_get_data_buffer, data_length))
        {
            wifi_spi_udp_send_now();
            printf("\r\n send success.");
            memset(wifi_spi_get_data_buffer, 0, data_length);          // 数据发送完成 清空数据
        }
        else
        {
            printf("\r\n %ld bytes data send failed.", data_length);
            return data_length;
        }
    }


}

1.4 my_spi_wifi_image_init函数

/*  @图像发送函数初始化
 *  @说明:根据逐飞库修改而来
 *  @作者:吴广金
 *  @时间:2024年3月7日
 * */
void my_spi_wifi_image_init(void)
{
    //初始化逐飞上位机助手,推荐在摄像头初始化后
    // 逐飞助手初始化 数据传输使用高速WIFI SPI
    seekfree_assistant_interface_init(SEEKFREE_ASSISTANT_WIFI_SPI);
    //配置图传参数
    // 发送总钻风图像信息(仅包含原始图像信息)
    seekfree_assistant_camera_information_config(SEEKFREE_ASSISTANT_MT9V03X, image_copy, MT9V03X_W, MT9V03X_H);

}

1.5 my_spi_wifi_image_send函数

/*  @图像发送函数(人视角正转图像)
 *  @说明:这时上位机显示的图像为人视角的正面图,但与实际图像处理上的坐标不一样
 *  @作者:吴广金
 *  @时间:2024年3月7日
 * */
void my_spi_wifi_image_send(void)
{
    uint8 i = 0;
    uint8 j = 0;
    uint16 offset;
    // 在发送前将图像备份再进行发送,这样可以避免图像出现撕裂的问题
    for(i = 120-1 ;i > 0;i--)
    {
        offset = i*188;
        for(j = 0;j<188;j++)
        {
            //图像复制
            image_copy[offset+j] = out[(119-i)*188+j];
            //扫线情况
            if((119-i)>34&&(119-i)<82&&((119-i)%2==1))
             {
               //左右两条边线
               if(j==all_out_left[((119-i)-35)/2])
                   image_copy[offset+j] = 0xFD;
               if(j==all_out_right[((119-i)-35)/2])
                   image_copy[offset+j] = 0xFD;
               //中间边线
               if(j==all_out_scan_mid[((119-i)-35)/2])
                   if((((119-i)-35)/2)==12)
                       image_copy[offset+j] = 0xFD;
                   else
                       image_copy[offset+j] = 0;
             }
        }
    }
    // 发送图像
    seekfree_assistant_camera_send();
#ifdef UDP
//    wifi_spi_udp_send_now();
#endif
}

1.6 my_spi_wifi_image_senfOriginal函数

/*  @图像发送函数(原始图像)
 *  @说明:这时上位机显示的图像为实际图像
 *  @作者:吴广金
 *  @时间:2024年3月7日
 * */
void my_spi_wifi_image_sendOriginal(void)
{
    // 在发送前将图像备份再进行发送,这样可以避免图像出现撕裂的问题
    memcpy(image_copy, out, MT9V03X_IMAGE_SIZE);
    // 发送图像
    seekfree_assistant_camera_send();
#ifdef UDP
//    wifi_spi_udp_send_now();
#endif
}

1.7 my_spi_wifi_image_SendOriginal_BX函数

/*  @图像发送函数(原始图像+边线)
 *  @说明:这时上位机显示的图像为实际图像
 *  @作者:吴广金
 *  @时间:2024年3月7日
 * */
void my_spi_wifi_image_sendOriginal_BX(void)
{
    uint8 i = 0;
    uint8 j = 0;
    uint16 offset;
    // 在发送前将图像备份再进行发送,这样可以避免图像出现撕裂的问题
    memcpy(image_copy, out, MT9V03X_IMAGE_SIZE);
    for( i = 0;i < 120;i ++)
    {
        offset = i*188;
        for(j = 0;j < 188;j ++)
        {
            //扫线情况
            if(i>34&&i<82&&(i%2==1))
             {
               //左右两条边线
               if(j==all_out_left[(i-35)/2])
                   image_copy[offset+j] = 0xFD;
               if(j==all_out_right[(i-35)/2])
                   image_copy[offset+j] = 0xFD;
               //中间边线
               if(j==all_out_scan_mid[(i-35)/2])
                   if(((i-35)/2)==12)
                       image_copy[offset+j] = 0xFD;
                   else
                       image_copy[offset+j] = 0;
             }
        }
    }
    // 发送图像
    seekfree_assistant_camera_send();
#ifdef UDP
//    wifi_spi_udp_send_now();
#endif
}

1.8 my_wifi_image_send函数

/*  @图像发送函数(选择函数)
 *  @说明:选择一种图形传输方式进行传输
 *  @参数(IMAGE_SEND data):图像传输的枚举
 *  @作者:吴广金
 *  @时间:2024年3月7日
 * */
void my_wifi_image_send(IMAGE_SEND data)
{
    switch(data){
        case 0:
            break;
        case FRONTVIEW:
            my_spi_wifi_image_send();//人视角图像
            break;
        case ORIGINAL:
            my_spi_wifi_image_sendOriginal();//原始图像
            break;
        case OUTER:
            my_spi_wifi_image_sendOriginal_BX();//原始图像+扫线
            break;
        default:
            break;
    }
}

 二、my_spi_wifi.h文件

#ifndef __MYSPIWIFI_H_
#define __MYSPIWIFI_H_
#include "zf_common_headfile.h"
#define WIFI_SSID_TEST          "MERCURY_1646"  //wifi账号
#define WIFI_PASSWORD_TEST      "858714786"      //wifi密码

typedef enum
{
    FRONTVIEW = 1,
    ORIGINAL = 2,
    OUTER = 3,
}IMAGE_SEND;
void my_spi_wifi_init(void);
//接收函数
uint32 my_spi_wifi_rece(void);
void my_spi_wifi_image_init(void);
void my_spi_wifi_image_send(void);
void my_spi_wifi_image_sendOriginal(void);
void my_spi_wifi_image_sendOriginal_BX(void);
void my_wifi_image_send(IMAGE_SEND data);
#endif

目前基于图像处理使用市场上监控摄像头二次开发的案例很多,包括海康威视萤石开源摄像头;还有使用自带FIFO的OV7725或者OV7670摄像头模块结合stm32进行图传;还有OPENMV+OV7725的图像处理方案;还有一种使用MIPS架构的路由器芯片例如RT5350加免驱MPJG摄像头方案。每一种方案价格都要达到50块以上,因为除了购买摄像头之外还有购买单片机,成本降不下来。 好消息的是,乐鑫科技推出的ESP32芯片能满足图传的需求,某宝基于该芯片出售的ESP32-cam摄像头模块能满足图传的需求,最低价格26块能买到手,性价比相当高,ESP32的运行速度和wifi速度都比ESP8266高。26块集成了ESP32最小系统板和OV2640摄像头和板载蓝牙wifi天线,买了也不亏,一个好点的USB摄像头都不只这个价格了!为啥很少人使用呢?原因是入门比较麻烦。要是使用乐鑫idf去搭建开发图传,很麻烦,很难成功。 国内某个测评网有详细简介:https://post.smzdm.com/p/amm03d0d/ 模块的原理图如下: 模块的全家福如下: 该模块在某宝很多家店铺有售,至于代工厂估计有很多家,但是根据原理图就那么多IO口,资料都是通用的。 经过我自己个人努力,半年时间内掌握了ESP32图传技术,采用的是Arduino开发环境开发,很多情况下使用库函数来快速实现图传的功能。搭建开发环境也花了不少时间,后面根据一个教程搭建成功了。 搭建视频链接:https://pan.baidu.com/s/1_xYw-Mg3LPb5vqMuVgiD2A 提取码:qdl2 搭建软件及素材:链接:https://pan.baidu.com/s/1eIES_hDWNgr5lZD4akP9Jw 提取码:zrwu 最后是我根据搭建环境自带的图传源码修改裁剪后的图传源码(在最后免费下载),该源码是我将三四个源码文件裁剪修改合成一个源码文件,实现了图传功能,代码精简利于阅读和学习,先进行配置和运行的说明: (1)整个工程就是一个9kb的源码,名字叫websocket.ino文件,然后修改热点的名称和密码: (2)找一个CH340的USB转TTL电平的模块,某宝几块钱有卖的,按照下图接上模块: 右边的模块就是USB转TTL模块,主要是用来下载程序和串口调试,左边接ESP32模块,右边接电脑。 个人建议给cam模块供电压5V在第一张原理图左下角的端口供电,免得电源不足,不要接错了! UoR就是RX端 UOT是TX端 这两个端跟CH340的RX、TX交叉连接,如图示 将IO0端口与GND连接上之后就可以马上下载程序了: (3)用Arduino下载程序:(如果下载过程中出现失败,可以尝试按下模块的RST按键) (4)创建一个热点,名称和密码都与(1)的步骤相同,让ESP32的wifi能连上,我就用笔记本电脑创建了一个热点,然后打开串口Arduino监视器或者打开一个串口调试助手,打开电脑与CH340链接的串口,拔掉cam模块中IO0与GND链接的线(第三张图灰色的线,不断开就不能启动程序只能不断下载),再按下一次cam模块的RST按钮松开,如下图: 从图上看出,RST按下时,第一次程序运行不对,第二次运行正确了,打印出IP地址。右下角显示有设备连上热点。多试试几次就能成功的! (5)打开谷歌浏览器,输入网址串口打印的网址:172.25.139.2(个人具体IP看打印为准)就可以看到摄像头采集的视频流,相当流畅,如下图所示:(其他浏览器可能失败) 由于摄像前面的保护膜没有撕掉,所以有点模糊,视频还是很流畅的。 总结:该项目演示了用ESP32作为一个STA模式连上路由器或者笔记本热点,在同一个局域网环境下用浏览器登录ESP32的IP地址就可以收看ESP32摄像头采集下来的图像信息。后期会陆续发布根据此源码升级成视频监控小车、视频监控智能控制摄像头、视频监控系统和手机客户端图传、stm单片机图传接收、机器人视觉人脸签到系统、远程MQTT图传手机app接收、局域网javaweb显示图传、等等项目,敬请期待。
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

跳河轻生的鱼

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值