ESP32公网对讲机

这篇具有很好参考价值的文章主要介绍了ESP32公网对讲机。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

一、前言

其实做这个项目最初的痛点是为了改善家里的楼上楼下交流(家里房子带阁楼)太费嗓子的问题,不要说什么打电话、微信语音什么的,不接受!存在即合理!顺便正好用ESP32做点东西,那么就开始吧。

二、介绍

2.1 音频
  • 音道

目前常见的有单声道,双声道这都很好理解

还有2.1声道 就是在双声道上加了个低音声道

5.1声道 早期影院 分别是正前方声道、左前方声道、右前方声道,左声道,右声道和一个低音声道

现在影院一般是7.1声道

  • 采样频率

音频采样就是从模拟信号转化为数字信号的过程,采样率就是每秒对声音采样的次数,采样率越高声音就越自然,人类对频率可识别范围大概在20hz~20000hz间。常见的采样频率44.1khz, 8khz, 16khz等 其实8khz对于人来说已经足够了

  • 采样位数

采样后还要进行量化和编码操作。位数常见的有8位,16位,32位等

  • dma_buf_len及dma_buf_cnt说明

I2S DMA

2.2 方案

使用UDP广播进行通信。将UDP数据包发送至一个特殊地址ip(公网ip),最后通过路由器将数据广播到网络中所有的设备.即可以做到只要设备联网后不管多远都可以进行通信。

使用UDP最大的好处就是可以不用等待对方有没有收到,所有在监听的设备都能收到,繁重的工作都交给路由器处理啦。

esp32对讲机,网络,udp,网络协议,Powered by 金山文档
esp32对讲机,网络,udp,网络协议,Powered by 金山文档
2.3 过程
  • 硬件

主控: ESP32 *2

Mic: Inmp411 *2

功放: MAX98357A *2

喇叭 *2

  1. 首先测试Mic和功放的好坏--通过Mic将我说的话通过喇叭播放出来。这里使用的Mic和功放都是I2S 标准飞利浦协议进行数据传输

Inmp411

esp32对讲机,网络,udp,网络协议,Powered by 金山文档

(引脚只有 对右边VCC GND SD,对左边L/R WS SCK)

L/R为左右声道选择,这里选择的是左声道 注意要接GND

具体引脚定义

#define MIC_I2S_NUM (0)
#define MIC_I2S_BCK_IO GPIO_NUM_32
#define MIC_I2S_WS_IO GPIO_NUM_25
#define MIC_I2S_DO_IO GPIO_NUM_33

Inmp411是走I2S协议的,程序里面使用单声道(左) 所有只有在低电平时候数据有效

esp32对讲机,网络,udp,网络协议,Powered by 金山文档

我使用的IDF是V4.3的 I2S配置过程:

需要先安装程序 i2s_driver_install();

再配置引脚 i2s_set_pin()

相关需要使用到的其他接口eg: i2s_read(); i2s_write();等

具体配置如下

    void Inmp441_Config(StreamBufferHandle_t mic_stream_buf)
    {
        i2s_config_t i2s_config = {
         // 接收模式
        .mode = I2S_MODE_MASTER | I2S_MODE_RX,
        // 采样率 8000khz
        .sample_rate = SAMPLE_RATE,
        // 采样位数 16位
        .bits_per_sample = I2S_BITS_PER_SAMPLE_16BIT,
        // 采样通道为左通道
        .channel_format = I2S_CHANNEL_FMT_ONLY_LEFT,
        // I2S通信格式I2S 标准飞利浦
        .communication_format = I2S_COMM_FORMAT_STAND_I2S,
        //
        .dma_buf_count = 3,
        .dma_buf_len = 256,
        .use_apll = false,
        .tx_desc_auto_clear = false,
        .fixed_mclk = 0,
        .intr_alloc_flags = ESP_INTR_FLAG_LEVEL1 // Interrupt level 1
    };
    esp_err_t err = i2s_driver_install(MIC_I2S_NUM, &i2s_config, 0, NULL);
    if (err != ESP_OK)
    {
        ESP_LOGI(TAG, "Error initializing I2S Mic\n");
    }

    i2s_pin_config_t pin_config = {
        .bck_io_num = MIC_I2S_BCK_IO,
        .ws_io_num = MIC_I2S_WS_IO,
        .data_in_num = MIC_I2S_DO_IO};
    err = i2s_set_pin(MIC_I2S_NUM, &pin_config);
    if (err != ESP_OK)
    {
        ESP_LOGI(TAG, "Error setting I2S mic pins\n");
    }

    ESP_LOGI(TAG, "Init audio!\n");
    xTaskCreate(Read_Inmp441_Data_Task, "Read_Inmp441_Data_Task", 4096, (void *)mic_stream_buf, 4, NULL);//(void *)mic_stream_buf
}

为了验证mic数据通信是否正常可以循环读取i2s数据并在上位机上打印出来,说不同的话、不同的音量的打印数值大小对应的数据正常都是会有变化的

i2s_read(MIC_I2S_NUM,
                 &mic_read_buf,
                 READ_BUF_SIZE_BYTES * 2,
                 &i2s_byte_data,
                 ticks_to_wait);
        if (i2s_byte_data > 0)
        {
//          ESP_LOGI(TAG, "mic_read_data = %d", mic_read_data);
            ESP_LOGI(TAG, "mic_read_buf[0] = %d, [1] = %d, [2] = %d, [3] = %d", mic_read_buf[0], mic_read_buf[1], mic_read_buf[2], mic_read_buf[3]);

对于i2s_read()的第三个参数,是以字节为单位!

MAX98357A

esp32对讲机,网络,udp,网络协议,Powered by 金山文档

引脚定义

#define MAX_I2S_NUM (1)
#define MAX_I2S_BCK_IO GPIO_NUM_4
#define MAX_I2S_WS_IO  GPIO_NUM_5
#define MAX_I2S_DO_IO  GPIO_NUM_18

MAX98357通信也是I2S协议的

esp32对讲机,网络,udp,网络协议,Powered by 金山文档

如果选用的是左边声道的话,LRC高电平时数据就是无效的。

具体配置如下

void MAX98357_Config(StreamBufferHandle_t playback_stream_buf)

{

i2s_config_t i2s_config = {

        //发送模式
        .mode = I2S_MODE_MASTER | I2S_MODE_TX,
        //采样率 8000khz
        .sample_rate = SAMPLE_RATE,
        //采样位数 16位
        .bits_per_sample = I2S_BITS_PER_SAMPLE_16BIT,
        //采样通道为左通道
        .channel_format = I2S_CHANNEL_FMT_ONLY_LEFT,
        //I2S通信格式I2S 标准飞利浦
        .communication_format = I2S_COMM_FORMAT_STAND_I2S,
        //
        .dma_buf_count = 3,
        .dma_buf_len = 256,
        .use_apll = false,
        .tx_desc_auto_clear = false,
        .fixed_mclk = 0,
    };
    esp_err_t err = i2s_driver_install(MAX_I2S_NUM, &i2s_config, 0, NULL);
    if (err != ESP_OK)
    {
        ESP_LOGI(TAG, "Error initializing I2S MAX98357\n");
    }

    i2s_pin_config_t pin_config = { 
        .bck_io_num = MAX_I2S_BCK_IO,
        .ws_io_num = MAX_I2S_WS_IO,
        .data_out_num = MAX_I2S_DO_IO
    };
    err = i2s_set_pin(MAX_I2S_NUM, &pin_config);
    if (err != ESP_OK)
    {
        ESP_LOGI(TAG, "Error setting I2S MAX98357 Pins\n");
    }

    ESP_LOGI(TAG, "Init MAX98357!\n");
    xTaskCreate(Playback_MAX98357_Task, "Playback_MAX98357_Task", 4096, (void *)playback_stream_buf, 5, NULL);
}

我们知道队列虽然可以做任务间消息传递的功能,但不方便实时采集不同数据长度的数据,FreeRTOS中给我们提供了一个流缓冲数据--StreamBuff。所谓流数据就像流水一样不断地产生、不断地传输。最典型的就是这种音频数据。

主要关注这几个API接口

xStreamBufferCreate();

xStreamBufferReceive();

xStreamBufferSend();

首先创建结构体

StreamBufferHandle_t mic_stream_buf = NULL;
StreamBufferHandle_t inm_stream_buf = NULL;

然后创建流缓冲区

//创建流缓冲区
mic_stream_buf = xStreamBufferCreate(1200, 2);
inm_stream_buf = xStreamBufferCreate(1200, 2);
Inmp441_Config(mic_stream_buf);
//    Test_1(mic_stream_buf);
MAX98357_Config(inm_stream_buf);
UDP_Connect_Init(mic_stream_buf, inm_stream_buf);

再在相应的有需要地方进行接收和发送。

2. 测试UDP数据转发--之前已经测试过UDP通信了这里就直接进行数据转发。先可以在局域网内测试,把PC当做Serve(需要在PC上写个服务端程序,反正是测试嘛怎么简单怎么来那就用python随便写几行),ESP32当做Client。ESP32通过UDP把数据先发送给Serve,Serve只做转发把收到的数据再发送给Client Client收到数据后直接通过I2S写入功放 至此就可以通过喇叭将从Mic中读到数据播放出来。所以这里创建了两个任务,一个发送任务、一个接收任务

先看发送端

void Send_Data_Task(void *pvParameters)
{
    StreamBufferHandle_t mic_stream_buf = (StreamBufferHandle_t)pvParameters;

    while(1)
    {
        //接收到mic的数据后 不断将数据发送至对应的服务器地址 端口上
        size_t recv_bytes = xStreamBufferReceive(mic_stream_buf,
                                                 &send_mic_buff,
                                                 sizeof(send_mic_buff),
                                                 portMAX_DELAY);
        if(recv_bytes > 0)
        {   
            sendto(client_socket,
                   send_mic_buff,
                   sizeof(send_mic_buff),
                   0,
                   (struct sockaddr *)&server_addr,
                   sizeof(server_addr)); 
        }
    }
}

接收端任务

void Recv_Data_Task(void *pvParameters)
{
    StreamBufferHandle_t inm_stream_buf = (StreamBufferHandle_t)pvParameters;
    int len = 0;

    while(1)
    {
//        memset(recv_mic_buff, 0x00, sizeof(recv_mic_buff)); 
        //接收到服务器发来的数据
        len = recvfrom(client_socket,
                       recv_mic_buff,
                       sizeof(recv_mic_buff),
                       0,
                       (struct sockaddr *)&server_addr,
                       &socklen);
        ESP_LOGI(TAG, "recv_mic_buff[0] = %d, [1] = %d, [2] = %d, [3] = %d", 
                 recv_mic_buff[0], recv_mic_buff[1], recv_mic_buff[2], recv_mic_buff[3]);
        if(len > 0)
        {
            xStreamBufferSend(inm_stream_buf,
                              (void *)recv_mic_buff,
                              sizeof(recv_mic_buff),
                              portMAX_DELAY); 
        }
    }
}

3. 因为是想做个公网对讲机嘛所以得有个公网ip。害,确实为了UDP服务器还整了个阿里云服务器有点奢侈,不过后面还是会用在MQTT服务器的搭建上。既然在局域网内测试通过了那在云上跑的话逻辑也是一样的,不过这里有两点改动。

  • Serve端bind地址和端口以及Client端要连接的服务器的地址和端口

  • 服务端转发逻辑的改变,要将Client_A发送的音频数据通过Serve在发送给Client_B, B收到后给功放任务 从而把消息从一边带到另一边,反向同理。

三、阿里云服务器使用

第一次接触服务器云服务器相关东西简单总结一下使用过程中需要注意的一些东西。

  1. 注册地址

阿里云

进入之后可以根据引导进行选择购买

  1. 设置你的root 账号和密码

esp32对讲机,网络,udp,网络协议,Powered by 金山文档
  1. !!!注意 会有两ip,一个是公网ip一个是私有ip

Client要连接的服务器地址是你的公网ip;Serve端bind的服务器地址是私有地址

esp32对讲机,网络,udp,网络协议,Powered by 金山文档
  1. 设置安全组在安全组中找到配置规则然进来就如图所示的样子,在入网方向中设置协议类型以及端口号等,记得最后需要保存呀。一般默认里面会创建有三个,其中一个是TCP协议端口号22(SSH);这里使用UDP协议的所以要进行手动添加一个。端口号的设定只要符合规则就好

esp32对讲机,网络,udp,网络协议,Powered by 金山文档
  1. 云服务器相当于一台电脑,你需要把你的代码移动到这台电脑上,可以使用SFTP进行传输。这里用到的工具是MobaXterm

esp32对讲机,网络,udp,网络协议,Powered by 金山文档
  1. 远程连接这台电脑,可以通过SSH进行连接,也可以在Ubuntu下进行命令形式连接

至此配置就基本结束了,后面启动程序后就可以愉快的玩耍了

四、总结

整个项目断断续续大概花了13天左右时间完成(实际上可以更快点),其实整个项目从硬件、软件再到云端都是涉及的还是学到很多东西。坑填完了...但没有完全填完,希望下一个主线项目比这个更有挑战!文章来源地址https://www.toymoban.com/news/detail-705335.html

到了这里,关于ESP32公网对讲机的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • ESP32网络开发实例-UDP数据发送与接收

    本文将详细介绍在Arduino开发环境中,如何实现ESP32通过UDP协议进行数据发送与接收。 用户数据报协议 (UDP) 是一种跨互联网使用的通信协议,用于对时间敏感的传输,例如视频播放或 DNS 查找。它通过在数据传输之前不正式建立连接来加速通信。这使得数据可以非常快速地传输

    2024年02月07日
    浏览(48)
  • ESP32网络应用 -- ESP32-S3使用HTTP协议获取城市天气数据

    超文本传输协议(Hypertext Transfer Protocol,HTTP),是一种建立在TCP协议之上,应用非常广泛的请求-响应协议,关于HTTP协议的详细描述,网上已经不乏文章,此处不再详细论述。 作为一款网络功能强大Wi-Fi SOC芯片,ESP32-S3可以通过ESP-IDF编程框架提供的应用程序接口,方便地构建

    2024年02月09日
    浏览(40)
  • 基于ESP32-CAM的RSTP协议网络摄像头

    开发环境:Arduino。 程序语言:C语言。 ESP32-CAM: ESP32 CAM 产品特性 采用低功耗双核32位CPU,可作应用处理器 主频高达240MHz,运算能力高达 600 DMIPS 内置 520 KB SRAM,外置8MB PSRAM 支持UART/SPI/I2C/PWM/ADC/DAC等接口 支持OV2640和OV7670摄像头,内置闪光灯 支持图片WiFI上传 支持TF卡 支持多

    2024年02月16日
    浏览(44)
  • ESP32-CAM网络摄像头系列-01-基于RTSP协议的局域网视频推流/拉流的简单实现

            由于项目需要,最近开始开坑关于ESP32-CAM系列的RTSP网络摄像头系列,该文章为该系列的第一篇文章。用于记录项目开发过程。         使用ESP32-CAM获取图像数据,并通过RTSP协议将获取到的视频流传输到上位机进行显示。         使用ESP32-CAM进行视频推流,

    2024年02月11日
    浏览(60)
  • 【ESP32最全学习笔记(协议篇)——2.ESP32 LoRa】

    关于本教程: 1.ESP32简介                                                                 2.ESP32 Arduino 集成开发环境 3.VS 代码和 PlatformIO 4.ESP32 引脚 5.ESP32 输入输出 6.ESP32 脉宽调制 7.ESP32 模拟输入 8.ESP32 中断定时器 9 .ESP32 深度睡眠 1.ESP32 网络服

    2024年02月04日
    浏览(59)
  • ESP32-CAM , io控制,UDP 数据发送,视频传输

    主代码 附件文件

    2024年02月11日
    浏览(89)
  • ESP32 CAM与服务器(python)UDP视频传输

    ESP32 CAM Arduino代码 UDP Server代码

    2023年04月11日
    浏览(82)
  • 通过ESP32实现实际IoT应用:高级TCP/UDP实现

    第1部分:使用ESP32构建强大的TCP服务器和客户端 介绍 欢迎来到我们关于ESP32上的实际应用和高级主题的详细系列的第一部分。我们首先关注开发TCP(传输控制协议)服务器和客户端,这是物联网中网络通信的基石。本节将涵盖TCP通信的基本知识,如何在ESP32上设置TCP服务器和

    2024年02月02日
    浏览(45)
  • 基于ESP32搭建物联网服务器十二(使用MQTT协议与ESP32互动)

    在之前的文章中:基于ESP32搭建物联网服务器十一(用WEB页面控制引脚(GPIO)功能)_esp32webserver 控制io_你的幻境的博客-CSDN博客 已经简单地介绍了MQTT协议,对比于其它网络协议,MQTT协议在物联网的开发中,它的特点使它适用于大多数受限的环境。例如网络代价昂贵,带宽低、不可

    2024年02月02日
    浏览(50)
  • ESP32-CAM视频传输至公网服务器并转发视频数据流

            有关esp32-cam目前大多数文章都是在写如何在内网(同一网络环境下)的视频传输, 即便是传输服务器上, 视频图像也只是显示在服务器中, 无法将视频数据流再转发到客户端. 先介绍一下大致思路, 很简单, esp32-cam把数据流发送到公网服务器, 服务器将数据原样透传给用

    2024年02月12日
    浏览(44)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包