分享三个例程:使用ESP32做一个实时语音对讲机,MQTT协议实现公网对讲,ESP32 | 您所在的位置:网站首页 › 远程可视对讲 › 分享三个例程:使用ESP32做一个实时语音对讲机,MQTT协议实现公网对讲,ESP32 |
分享三个例程:使用ESP32做一个实时语音对讲机,MQTT协议实现公网对讲,ESP32-CAM 上传图像数据到网络。并附上例程链接。可以比对着看来学习NOW,MQTT使用方法。想办法把图像和语音代码融合在一起,实现声音和图像同步传输。 一:使用ESP32做一个实时语音对讲机2022-08-05 C/C++编程,ESP32/ESP8266 4 条评论 3311 次阅读 最近突发奇想,制作一个数字式的音频通信系统,顺便学习一下I2S与ESP-NOW协议 刚开始查阅资料,发现油管上的已经有人做过了,但是使用的C++,并用了数据流的处理流程,比较晦涩难懂,代码量也很大,属于是炫技的作品,我这篇文章使用C重新写一遍,并且代码量大大降低,也很容易理解,let’s get started! 上一篇博客中已经详细讲解了I2S通信协议,在ESP32中有两个硬件I2S,我们可以通过简单的配置使用它 ESP-NOW是乐鑫的私有协议,相比于传统的七层协议,ESP-NOW只保留了物理层与数据连接层,在其之上封装了ESP-NOW协议,但是这个协议是不开源的,意味着我们看不到这个协议的源码,只能使用封装出来的接口。 使用的软件: Arduino IDE ESP32扩展包 2.0.4(最新) 编程思路: 发送:初始化I2S采集后,数据会源源不断的存放在DMAbuf中,按下按键,将数据取出,转换成需要的格式,最终转换成8bit数据发送出去。 接受:在ESP-NOW接受回调函数中,将接收到的数据重新转换为16位, 发送到I2S中的DMA去。注意,在没有接收到消息的是否,需清空dambuf,要不然会重复播放上一帧的音频,发出很大的噪音。 数据流向:I2S采集->原始32bit->16bit->8bit->esp-now发送->接收到数据8bit->转换为16bit->I2S播放 具体配置: 麦克风采集配置 const i2s_config_t rec_i2s_config = { .mode = i2s_mode_t(I2S_MODE_MASTER | I2S_MODE_RX), .sample_rate = SAMPLE_RATE, .bits_per_sample = I2S_BITS_PER_SAMPLE_32BIT, .channel_format = I2S_CHANNEL_FMT_ONLY_RIGHT, .communication_format = i2s_comm_format_t(I2S_COMM_FORMAT_I2S| I2S_COMM_FORMAT_I2S_MSB), .intr_alloc_flags = ESP_INTR_FLAG_LEVEL1, .dma_buf_count = 2, .dma_buf_len = 256, } 扬声器采集配置: const i2s_config_t spk_i2s_config = { .mode = (i2s_mode_t)(I2S_MODE_MASTER | I2S_MODE_TX), .sample_rate = SAMPLE_RATE, .bits_per_sample = I2S_BITS_PER_SAMPLE_16BIT, .channel_format = I2S_CHANNEL_FMT_RIGHT_LEFT, //2-channels .communication_format =(i2s_comm_format_t)(I2S_COMM_FORMAT_I2S), .intr_alloc_flags = 0, .dma_buf_count = 2, .dma_buf_len = 256, }; 其中,dambuf的两个参数的设定比较有讲究,可以点击这里学习。 硬件连接: INMP441: BCK —>>>IO4 WS —>>>IO15 data—>>>IO13 MAX98357: BCK —>>>IO26 WS —>>>IO22 data—>>>IO25 开源github链接:https://gitlab.ifengyu.com/tianshuaikang/esp32-audio-communication 二:MQTT协议实现公网对讲使用MQTT做一个公网对讲机 上一篇博客中,使用ESP32与ESP-NOW协议做了一个短距离对讲机(https://www.bilibili.com/video/BV1qT411L7WX),发布了一个视频在B站。
我曾经也有一篇文章简单的叙述了MQTT的工作原理与搭建过程(怎样在自己的电脑上搭建MQTT),MQTT可以运行在几乎所有的设备上,例如公网服务器(Linux、Windows系统等)、树莓派、局域网电脑等,当然,如果MQTT服务运行在局域网中,那就只能实现局域网的消息转发。如果你没有公网服务器,可以使用我的MQTT地址,我的MQTT服务器将会免费开放到2025年。我使用的MQTT Broker为EMQ免费开源版,并且修改了cfg文件,将速率与可接入设备限制调高。 如果你只想实现无限对讲,不想关注MQTT,那就看下面的代码吧,代码git链接放在文章最后! 首先需要在Arduino中安装pubsubclient库,这个库是可以运行在ESP上的MQTT库,源码也非常简单,非常值得学习。 代码上基于上个视频的硬件与代码,硬件连接完全相同,软件只进行了通信协议的修改。(重点:)代码中需要修改的只有两个地方,第一个地方是WIFI账号与密码(2.4G),第二个地方是修改角色,发送端或者接收端,具体位于AudioMqtt.h中的SENDER宏定义,你需要将该项设置为1,编译烧录给带有麦克风的设备,再将该项设置为0,编译烧录给带有扬声器的设备。烧录给两个设备,按下发射端的板载按钮说话,你应该就可以听到扬声器中你的声音了。 我们已经了解了MQTT协议的工作原理,我们也可以在电脑上写一段python脚本订阅发布的音频数据并且播放出来,python需要的库为paho-mqtt与pyaudio,代码也在git中,是audiotest.py。 git地址:https://gitlab.ifengyu.com/tianshuaikang/esp32audiomqtt 三:ESP32-CAM 上传图像数据到网络ESP32-CAM上传图像数据到Python上位机 预防踩坑放在前面:目前安信可官方版的CAM模块已经停售,库存货比较贵,市面上的都是仿制的,质量良莠不齐,给开发带来了很多困扰,经过实际测试,发现山寨货主要有以下几个坑: 1、发热严重,不加散热片长时间运行几乎到了烫手的地步,加上散热片也不会好很多 2、在分辨率大于640*480后,信号变得异常的差,丢包严重,但如果用手捏着天线,数据传输又会稳定很多 第二个原因上网查原因可能是山寨CAM天线附近包了一层地,那么如何避免踩坑? 目前网上的山寨CAM主要有以下两种,位于卡槽右下角的电阻,一种是四个电阻,另一种是六个电阻,建议买四个电阻的(官方板是四个电阻),效果比六个电阻的好很多。
程序原理: 初始化ov2640,设定引脚、速率、图片像素、图像格式等参数,另外,板载的SRAM可以设定更大的像素 重点:为什么使用jpeg的图片格式?jpeg是图片的一种有损压缩格式,我们使用网络传输可以节省很多带宽,提升帧率,举个例子,一张320*240像素的图像原始大小为15.36KB,压缩后可能只有2KB。而且OV2640可以直接输出jpeg格式的图片,不用处理器压缩占用时间 我们使用arduino上封装好的库,可以直接获取图片数组,因为ESP32 UDP每个包最大只有1460字节,因此还需要分包发送,我将图片分为1400个字节+1字节的索引,索引代表这个图片的第几个包,如果为0XFF代表这长图片传输完成了,分包代码如下: uint8_t *P_temp = fb->buf; //暂存指针初始位置 int pic_length = fb->len; //获取图片字节数量 int pic_pack_quantity = pic_length / max_packet_byte; //将图片分包时可以分几个整包 int remine_byte = pic_length % max_packet_byte; //余值,即最后一个包的大小 for (int j = 0; j < pic_pack_quantity; j++) //发送图片信息,这是按分包循环发送,每一次循环发送一个包 { sendImgAray(fb->buf, max_packet_byte,j); //将图片分包发送 fb->buf+=max_packet_byte; //图片内存指针移动到相应位置 } sendImgAray(fb->buf, remine_byte,0xFF); //发送最后一个包,剩余的数据python上位机: python上位机用UDP协议,修改为当前机器的IP地址和端口号,接受数据后通过判断数据最后一位确定图片是否传输完成,将接收到的数组转换成opencv的img图像,图像就显示出来了,可以通过w、s按钮调整灯光亮度。如果没有图像数据,整个界面是卡死的状态。 代码开源地址:https://gitlab.ifengyu.com/tianshuaikang/espcam2pc.git |
今日新闻 |
推荐新闻 |
专题文章 |
CopyRight 2018-2019 实验室设备网 版权所有 |