m基于VDLL的矢量型GPS信号跟踪算法matlab仿真

news2024/11/27 2:25:02

目录

1.算法概述

2.仿真效果预览

3.MATLAB部分代码预览

4.完整MATLAB程序


1.算法概述

      载波跟踪环是传统独立式GPS接收机最脆弱的环节,针对弱信号环境下其比伪码跟踪环路更容易失锁的问题,给出一种基于矢量频率锁定环(vector-frequency lock loop,VFLL)的载波跟踪方法。给出VFLL理论推导及实现过程,并以最小二乘估计方法证明VFLL在载波跟踪性能上优于频率锁定环(frequency lock loop,FLL)。静止场景时9颗卫星实验结果显示,本文给出的方法能够实现14 dB/Hz微弱GPS信号的载波跟踪。 矢量型GPS信号跟踪算法(矢量延迟锁定环VDLL)


 

   而在VDLL中,仅仅在DLL中对码跟踪进行改进,使其通过中心滤波器,而载波跟踪和传统的算法相同。所以,下面将重点对延迟锁定环进行改进,也就是你的课题的VDLL延迟锁定环。而VDFLL则是对码和载波分别进行改进。其基本结构如下所示:

       即使用卡尔曼替代PLL,使用EKF替代DLL。这个是VDFLL,而VDLL则使用扩展卡尔曼滤波替代原DLL即可。

       提出的VDLL(vector delay lock loop)方法直接估计用户位置信息,由于用户物理动态有限,与传统的独立通道码环相比,跟踪的维度和带宽都更小,所以该方法具有更强的鲁棒性.阐述了VDLL与传统独立通道码跟踪环的本质区别,建立了VDLL的非线性系统模型,推导了系统观测量与传输延迟估计误差的具体线性化关系,确立了观测误差方差矩阵的计算公式;然后对非线性系统模型进行线性化,给出了多卫星联合跟踪下用户位置更新的EKF(extended Kalman filte-ring)滤波算法.

EKF

      扩展卡尔曼滤波(Extended Kalman Filter,EKF)是标准卡尔曼滤波在非线性情形下的一种扩展形式,它是一种高效率的递归滤波器(自回归滤波器)。EKF的基本思想是利用泰勒级数展开将非线性系统线性化,然后采用卡尔曼滤波框架对信号进行滤波,因此它是一种次优滤波。

标准卡尔曼滤波KF的状态转移方程和观测方程为 

{​{\mathbf{\theta }}_{k}}=\mathbf{A}{​{\mathbf{\theta }}_{k-1}}+\mathbf{B}{​{\mathbf{u}}_{k-1}}+{​{\mathbf{s}}_{k}}

{​{\mathbf{z}}_{k}}=\mathbf{C}{​{\mathbf{\theta }}_{k}}+{​{\mathbf{v}}_{k}}

扩展卡尔曼滤波EKF的状态转移方程和观测方程为

{​{\mathbf{\theta }}_{k}}=f({​{\mathbf{\theta }}_{k-1}})+{​{\mathbf{s}}_{k}}          (1)

{​{\mathbf{z}}_{k}}=h({​{\mathbf{\theta }}_{k}})+{​{\mathbf{v}}_{k}}             (2)

利用泰勒展开式对(1)式在上一次的估计值处展开得

{​{\mathbf{\theta }}_{k}}=f({​{\mathbf{\theta }}_{k-1}})+{​{\mathbf{s}}_{k}}=f(\left\langle {​{\mathbf{\theta }}_{k-1}} \right\rangle )+{​{\mathbf{F}}_{k-1}}\left( {​{\mathbf{\theta }}_{k-1}}-\left\langle {​{\mathbf{\theta }}_{k-1}} \right\rangle \right)+{​{\mathbf{s}}_{k}}          (3)

 再利用泰勒展开式对(2)式在本轮的状态预测值处展开得

{​{\mathbf{z}}_{k}}=h({​{\mathbf{\theta }}_{k}})+{​{\mathbf{v}}_{k}}=h\left( \mathbf{\theta }_{​{k}}^{\mathbf{'}} \right)+{​{\mathbf{H}}_{k}}\left( {​{\mathbf{\theta }}_{k}}-\mathbf{\theta }_{​{k}}^{\mathbf{'}} \right)+{​{\mathbf{v}}_{k}}            (4)

其中,{\mathbf{F}}_{k-1}{\mathbf{H}}_{k}分别表示函数f(\mathbf{\theta })h(\mathbf{\theta })\left\langle {​{\mathbf{\theta }}_{k-1}} \right\rangle\mathbf{\theta }_{k}^{'}处的雅克比矩阵。

(注:这里对泰勒展开式只保留到一阶导,二阶导数以上的都舍去,噪声假设均为加性高斯噪声)

基于以上的公式,给出EKF的预测(Predict)和更新(Update)两个步骤:

Propagation:

\mathbf{\theta }_{k}^{'}=f(\left\langle {​{\mathbf{\theta }}_{k-1}} \right\rangle)

\mathbf{\Sigma }_{k}^{'}=\mathbf{F}_{k-1}{​{\mathbf{\Sigma }}_{k-1}}{​{\mathbf{F}}_{k-1}^{T}}+\mathbf{Q}

Update:

\mathbf{S}_{k}^{'}={​{\left( \mathbf{H_{k}\Sigma }_{k}^{'}{​{\mathbf{H}}_{k}^{T}}+\mathbf{R} \right)}^{-1}}

\mathbf{K}_{k}^{'}=\mathbf{\Sigma }_{k}^{'}{​{\mathbf{H}}_{k}^{T}}\mathbf{S}_{k}^{'}

\left\langle {​{\mathbf{\theta }}_{k}} \right\rangle =\mathbf{\theta }_{k}^{'}+\mathbf{K}_{k}^{'}\left( {​{\mathbf{z}}_{k}}-{h(\theta }_{k}^{'}) \right)

{​{\mathbf{\Sigma }}_{k}}=\left( \mathbf{I}-\mathbf{K}_{k}^{'}\mathbf{H}_{k} \right)\mathbf{\Sigma }_{k}^{'}

其中的雅克比矩阵{\mathbf{F}}_{k-1}{\mathbf{H}}_{k}分别为

{​{\mathbf{F}}_{k-1}}={​{\left. \frac{\partial f}{\partial \mathbf{\theta }} \right|}_{\left\langle {​{\mathbf{\theta }}_{k-1}} \right\rangle }}{​{\mathbf{H}}_{k}}={​{\left. \frac{\partial h}{\partial \mathbf{\theta }} \right|}_{\mathbf{\theta }_{k}^{'}}}

       雅可比矩阵的计算,在MATLAB中可以利用对自变量加上一个eps(极小数),然后用因变量的变化量去除以eps即可得到雅可比矩阵的每一个元素值。

2.仿真效果预览

matlab2022a仿真结果如下:

 

 

 

 

 

 

3.MATLAB部分代码预览

...............................................................
%参数初始化 
time      = 1000*(10^(-3));     % 数据发送时间
time_unit = 20*(10^(-3));      % 数据跳变时间单位
time_cyc  = 1*(10^(-3));       % 一个完整扩频码周期
fs        = 5*(10^6);
nn        = time_cyc*fs;
kk        = (time/time_cyc)*nn;% 数据总采样点
F_if      = 1.25*(10^6);       % 载波中频
F_Carrier = 1575.42*(10^6);    % L1波段载波频率
CA_freq   = 1.023*(10^6);      % CA码速率
 
%%
%%
%生成C/A码
PN = func_CAcodegen(svnum);
CA = [];
k  = 5;
for n = 1:length(PN)
    CA((1+k*(n-1)):k*n) = PN(n)*ones(1,k);%CA码扩展
end
tc                      = 1/(k*CA_freq); 
loop_time               = time/time_cyc;
 
%%
%%
%模拟产生测试信号源
[Signal_Source,Phase_signal,buffer_bit_data]=func_CreateSource(iniphcode,inifd,iniph,snr); 
 
%%
%%
%在模拟之前,首先需要进行捕获
[fd_ac,f_ac_code,Corr_value] = func_acquire(Signal_Source);
figure
mesh(Corr_value);title('捕获结果');
 
%信号中断起始时间
break_start = 400;
break_end   = 800;
 
 
P0            = [0 0
                 0 1];
P             = [P0 zeros(2,2*(loop_time-1))];
T             = 0.1;
LL            = loop_time;
Y0            = [0;1];
data_out(:,1) = Y0;           %Y的第一列等于Y0
A             = [1 T
                 0 1];   
B             = [1/2*(T)^2 T]';
H             = [1 0];
Q             = (0.25)^2; 
R             = (0.25)^2; 
X             = zeros(1,loop_time);
    
      
%%
%%
%跟踪参数设置
tracking_parameter();
%进行跟踪
for i = 1:1:loop_time   
    
    i
 
    %开始循环,每次循环去除一段数据
    %开始循环,每次循环去除一段数据
    %模拟信号突然中断
    if i > break_start & i < break_end
    Signal = 0.0001*rand(1,nn);%中断的时候,该段数据为随机的噪声干扰
    else
    Signal = Signal_Source((i-1)*nn+1:i*nn);
    end
    
    %产生本地载波
    t                 = [0:nn-1]*ts;
    track_dopplar     = fd_ac + track_freq_pll;
    Track_Freq_Buffer = [Track_Freq_Buffer track_dopplar];
    track_dopplar2    = [track_dopplar2   track_freq_pll];
     
    Local_I           = cos(2*pi*(F_if+track_dopplar)*t + Last_Phase);
    Local_Q           = sin(2*pi*(F_if+track_dopplar)*t + Last_Phase);
    Iph               = 2*pi*(F_if+track_dopplar)*t + Last_Phase;
    Local_Ph_Buffer   = [Local_Ph_Buffer Iph];
    Last_Phase        = Last_Phase + 2*pi*(F_if+track_dopplar)*time_cyc;   
 
    
    %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    Carrier_I         = Local_I;%产生本地的载波
    Carrier_Q         = Local_Q;%产生本地的载波
    
 
 
    %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    %产生本地相位码
    %利用DLL的思路
    %当前
    ph_code_p = offside;
    fd_code_p = track_dopplar;
    CA_Code_p = func_CA(ph_code_p,fd_code_p,i);
    lc_p      = CA_Code_p.*Signal;
    %早
    ph_code_e = offside+diffoffside;
    fd_code_e = track_dopplar;
    CA_Code_e = func_CA(ph_code_e,fd_code_e,i);
    lc_e      = CA_Code_e.*Signal;        
    %迟
    ph_code_l = offside-diffoffside;
    fd_code_l = track_dopplar;
    CA_Code_l = func_CA(ph_code_l,fd_code_l,i);
    lc_l      = CA_Code_l.*Signal;
 
    %下变频
    Local_P_I = lc_p.*Carrier_I;
    Local_P_Q = lc_p.*Carrier_Q;
    Local_E_I = lc_e.*Carrier_I;
    Local_E_Q = lc_e.*Carrier_Q;
    Local_L_I = lc_l.*Carrier_I;
    Local_L_Q = lc_l.*Carrier_Q;
 
    
    
    %积分运算
    IPSum     = sum(Local_P_I);
    QPSum     = sum(Local_P_Q);
    IESum     = sum(Local_E_I);
    QESum     = sum(Local_E_Q);
    ILSum     = sum(Local_L_I);
    QLSum     = sum(Local_L_Q);
    
 
 
    
    
    %码相位环路控制
    %鉴想器 
    theta_code        = ((IESum.^2+QESum.^2)-(ILSum.^2+QLSum.^2))/((IESum.^2+QESum.^2)+(ILSum.^2+QLSum.^2));
     
    I2_Q2(i)          = IESum.^2 + QESum .^2;
     
    %kalman
    data(:,i)       = theta_code;
    j               = (i-1)*2+1;
    K               = P(:,j:j+1)*H'*inv(H*P(:,j:j+1)*H'+R);%滤波增益
    data_out(:,i)   = data_out(:,i)+K*(data(1,1)-H*data_out(:,i));  %估计
    data_out(:,i+1) = A*data_out(:,i);                     %预测
    P(:,j:j+1)      = (eye(2,2)-K*H)*P(:,j:j+1);  %误差
    P(:,j+2:j+3)    = A*P(:,j:j+1)*A'+B*Q*B';   %kalman滤波
 
    CodeErr         = data_out(1,i)/20;
    
    
    %码环NCO
    offside           = offside_old+k1*CodeErr;      %码NCO的输出
 
    theta_code_old    = theta_code;  %将当前结果保存,用于下一个循环的码跟踪
    CodeErr_old       = CodeErr;        %将当前结果保存,用于下一个循环的码跟踪
    offside_old       = offside;        %将当前结果保存,用于下一个循环的码跟踪
    Bk_DLL            = [Bk_DLL theta_code];   %记录跟踪过程中的码环鉴想器的输出
    Track_Code_Buffer = [Track_Code_Buffer offside];  %记录跟踪过程中的码环NCO的数出
   
    
    %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 
 
    %载波跟踪
    %载波跟踪
    %载波跟踪
    theta_pll      = atan(QPSum/IPSum);
    PLLinput       = theta_pll/(2*pi*time_cyc);
    Bk_PLL         = [Bk_PLL theta_pll];
 
    %LoopFilter       
    PLLoutput      = func_CarLoopFilter(carrierw,carrierpllb/2,PLLinput,PLLinput_old,PLLoutput_old); 
 
    track_freq_pll = -PLLoutput;
 
    PLLinput_old   = PLLinput;       
    PLLoutput_old  = PLLoutput;       
 
    adj_flag          = track_dopplar - track_dopplar_old; 
    track_dopplar_old = track_dopplar; 
    adj_buffer        = [adj_buffer adj_flag];
      
    outdata           = sign(real(IPSum)); 
    ALL_Buffer_Data   = [ALL_Buffer_Data outdata];
          
    if adj_flag < 1      
       add = add+1;
    else
       add = 0;
    end
    if add >= 2          
       dem_flag = 1;
    end
    
    if dem_flag == 1
       count_time   = i;
       count_buffer = [count_buffer count_time];
       Buffer_Data  = [Buffer_Data outdata];
    end
end
 
%%
%%
%位同步与数据解调
Buffer_Data_out = func_bitssync(Buffer_Data,count_buffer);  
l_i_d           = time/time_unit;
l_o_d           = length(Buffer_Data_out);
l_zeros         = l_i_d - l_o_d;
Buffer_Data_out = [zeros(1,l_zeros) Buffer_Data_out]; 
 
%跟踪误差
l_dll     = length(Track_Code_Buffer);
l_fll     = length(Track_Freq_Buffer);
diata_dll = (Track_Code_Buffer(40:l_dll)-iniphcode);  
  
break_start = 400;
break_end   = 800;
%多普勒频率跟踪
figure;
plot(Track_Freq_Buffer);
xlabel('时间(ms)');
ylabel('多普勒频率跟踪结果(Hz)')
title('多普勒频率跟踪结果');
grid on
hold on
 
plot(break_start,min(Track_Freq_Buffer):0.01:max(Track_Freq_Buffer),'r-*','LineWidth',3);hold on
plot(break_end,min(Track_Freq_Buffer):0.01:max(Track_Freq_Buffer),'r-*','LineWidth',3);hold off
 
 
figure;
plot(I2_Q2(1:end),'LineWidth',3);
xlabel('时间(ms)');
ylabel('I^2+Q^2(Hz)')
title('I^2+Q^2');
grid on
hold on
 
plot(break_start,min(I2_Q2(1:end)):100000:max(I2_Q2(1:end)),'r-*','LineWidth',3);hold on
plot(break_end,min(I2_Q2(1:end)):100000:max(I2_Q2(1:end)),'r-*','LineWidth',3);hold off
 
 
%码相位跟踪
figure;
subplot(211);
plot(Track_Code_Buffer);
xlabel('时间(ms)');
ylabel('码相位跟踪结果');
title('码相位跟踪结果');
grid on
axis([0,length(Track_Code_Buffer),0.8*iniphcode,1.2*iniphcode]);
subplot(212);
plot(diata_dll);
xlabel('时间(ms)');
ylabel('码相位跟踪误差');
title('码相位跟踪误差');
grid on
axis([0,length(diata_dll),-10,10]); 
hold on
 
plot(break_start,-10:0.1:10,'r-*','LineWidth',3);hold on
plot(break_end,-10:0.1:10,'r-*','LineWidth',3);hold off
01_048_m

4.完整MATLAB程序

matlab源码说明_我爱C编程的博客-CSDN博客

V

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/27266.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

集成学习-Boosting

Boosting 采用串行的方式训练&#xff0c;各基分类器之间有依赖。根据当前模型损失函数的负梯度训练新的弱分类器&#xff0c;将训练好的弱分类器以累加的形式结合到现有模型中。 过程中会不断减小损失函数&#xff0c;使模型偏差不断降低&#xff0c;方差不会降低。因为各弱分…

《CTFshow - Web入门》02. Web 11~20

Web 11~20web11知识点题解web12知识点题解web13知识点题解web14知识点题解web15知识点题解web16知识点题解web17知识点题解web18知识点题解web19知识点题解web20知识点题解web11 知识点 dns检查查询&#xff1a;http://dbcha.com/&#xff0c;输入域名&#xff0c;获取flag。…

MySQL数据库期末考试试题及参考答案(07)

版权声明 本文原创作者&#xff1a;谷哥的小弟作者博客地址&#xff1a;http://blog.csdn.net/lfdfhl 一、 填空题 如果不想提交当前事务&#xff0c;可以使用_____语句回滚事务。每个事务都是完整不可分割的最小单元是事务的_____性。MySQL中&#xff0c;显式开启事务的语句…

屏幕视频捕获组件-ByteScout Screen Capturing SDK

使用 ByteScout Screen Capturing SDK&#xff0c;您可以轻松地将屏幕视频捕获功能添加到您的应用程序中。输出带有音频、鼠标移动和点击的高质量桌面屏幕视频录制。 主要优势 只需几行代码即可在您的应用中启用屏幕视频捕获和屏幕录制功能&#xff1b;无需互联网连接即可离线…

Django day1

在windows下可以直接的创建django项目 但是需要把自动生成的templates和setting里面的DIRS里面字段删除&#xff08;templates自动生成的可以删不删都行&#xff0c;我是看视频那个老师删了&#xff0c;但是setting DIRS里面的字段需要删&#xff0c;至于具体为啥我已经忘了&am…

TiDB数据库概述——PD

PD PD的架构与功能TSO的分配PD的调度原理label的作用 PD的架构 PD的个数一般是奇数个的。 PD的主要功能&#xff1a; 整个集群TiKV的元数据存储分配全局ID和事务ID生成全局时间戳TSO收集群信息进行调度提供label&#xff0c;支持高可用提供TiDB Dashboard 路由功能 用key…

vue3使用富文本编辑器wangEditor-v5(未使用composition api写法)

效果 安装 安装核心库和其vue组件库 yarn add wangeditor/editor yarn add wangeditor/editor-for-vuenext使用v-model封装富文本组件editor.vue <template><div class"editor-box"><Toolbar class"toolbar" :editor"editor" …

Flink是什么?场景?处理流的发展演变?

Flink是什么&#xff1f;Flink是什么&#xff1f;为什么选择Flink&#xff1f;什么场景需要处理流数据?处理流的发展演变Flink是什么&#xff1f; Apache Flink 是一个在无界和有界数据流上进行状态计算的框架和分布式处理引擎。Flink 能在所有常见集群环境中运行&#xff0c…

线性表的链式存储的基本

链表是线性表的链式存储方式&#xff0c;逻辑上相邻的数据在计算机内的存储位置不一定相邻&#xff0c;因此&#xff0c;我们需要为每一个元素设置有一个指针来指向与它逻辑相邻的元素。 为此&#xff0c;我们为每个元素设置一个结点&#xff0c;每个结点由数据域和指针域组成…

【3D目标检测】Monocular 3D Object Detection with Pseudo-LiDAR Point Cloud

目录概述整体流程伪点云vs点云2D-3D边界框的一致性约束概述 本文的输入数据仅仅是单目图像&#xff0c;在方法上是融合了伪点云&#xff08;Pseudo-LiDAR&#xff09;的深度信息表示方法与Frustum PointNets的检测方法。 乍一看文章和伪点云原论文Pseudo-LiDAR from Visual De…

Deep-SVDD 方法

两种情况 1. 数据集有正负样本&#xff0c;但正样本的量远远大于负样本为异常检测&#xff0c;即大量的正样本为正常&#xff0c;少数的负样本是异常的。 2. 数据集只有正样本&#xff0c;称为单分类&#xff0c;即只通过正样本训练模型&#xff0c;区分正样本和非正样本。 情…

蓝桥杯2021年第十二届省赛真题-时间显示(C and C++)

这一篇是个小记&#xff0c;真无语了&#xff0c;看见这个题感觉哇塞好简单的感觉&#xff0c;谁知道栽了&#xff0c;烦死了 话不多说&#xff0c;记录一下 C语言 #include<stdio.h> int main() {int a,b,c;long long time;//题上说了10的18次方的正整数&#xff0c;所…

Spring:AOP的五种通知类型(12)

AOP的五种通知类型前置通知&#xff1a;Before注解后置通知&#xff1a;After注解环绕通知&#xff1a;Around注解&#xff08;掌握&#xff09;返回后通知&#xff1a;AfterReturning&#xff08;了解&#xff09;异常后通知&#xff1a;AfterThrowing&#xff08;了解&#x…

直播回顾 | 【原引擎】解密云原生安全:如何应对新型BOT攻击?

BOT流量是指在互联网上对Web网站、APP应用、API接口通过工具脚本、爬虫程序或模拟器等非人工手动操作访问的自动化程序流量&#xff0c;一般也称为机器人流量。而恶意的BOT流量通过利用代理或秒拨IP、手机群控等手段来爬取信息数据、抢刷接口、薅羊毛、外挂作弊等恶意攻击行为&…

招标 | 近期隐私计算项目招标中标25(大连理工大学、中国电信北京研究院、松山湖材料实验室、北京控制工程研究所、光大永明)

开放隐私计算 开放隐私计算 开放隐私计算OpenMPC是国内第一个且影响力最大的隐私计算开放社区。社区秉承开放共享的精神&#xff0c;专注于隐私计算行业的研究与布道。社区致力于隐私计算技术的传播&#xff0c;愿成为中国 “隐私计算最后一公里的服务区”。 177篇原创内容 …

apache-POI ,easyexcel(3个办公软件)

POI介绍 ApachePOI是用Java编写的免费开源的跨平台的JavaAPI&#xff0c;ApachePOI提供API给Java程序对MicrosoftOffice格式档案读和写的功能&#xff0c;其中使用最多的就是使用POI操作Excel文件。 HSSF&#xff0d;提供读写MicrosoftExcelXLS格式档案的功能XSSF&#xff0d;…

【设计模式】适配器模式

适配器模式属于结构型模式&#xff0c;主要解决两个已存在的功能相近的接口间不能兼容的问题。在准备将一个接口对接到另一个接口中时&#xff0c;发现另一个接口&#xff08;目标&#xff09;与准备对接的接口&#xff08;适配者&#xff09;因不兼容而无法正常运行功能时&…

Allegro如何打盲埋孔操作指导

Allegro如何打盲埋孔操作指导 Allegro支持打盲埋孔,具操作如下 首先保证库路径下方有盲埋孔的封装 打开规则管理器 选择Physical规则,点击VIAS,会出现一个对话框,勾选show vias from Library ,出现孔的封装 把孔添加到via list里面去,之后点击ok 加好的效果如

web前端-javascript-数据类型(6种数据类型/字符串、数值、布尔值、空值、未定义、对象,String字符串、引号问题、转义字符、字面量和变量输出)

文章目录数据类型1. 介绍说明2. String 字符串引号问题转义字符字面量和变量的输出数据类型 var str "hello"; str 我说:"今天天气真不错&#xff01;";str 我说:"今天\t天气真不错&#xff01;"; str "\\\\\\";//输出字面量str …

ESP32基础应用之使用两个ESP32通过阿里云物联网平台实现相互通信

文章目录1 阿里云物联网平台2 程序编写2.1 ESP32-COM4 设备2.1 ESP32-COM5 设备3 实验现象分析1 阿里云物联网平台 在设备管理下创建两个设备&#xff0c;参考ESP32基础应用之ESP32与阿里云物联网平台实现数据互传&#xff08;MQTT协议&#xff09; 在规则引擎下创建云产品流…