使用STM32的射频模块以无线方式发送和接收数据

发布时间:2023-06-25  

嵌入式电子产品中制作无线项目变得非常重要和有用,因为没有杂乱的电线,这使得设备更加方便和便携。有各种无线技术,例如蓝牙、WiFi、433 MHz RF(射频)等。每种技术都有其自身的优缺点,例如成本、距离或范围传输、速度或吞吐量等。今天我们将使用STM32 的射频模块以无线方式发送和接收数据。


在这里,我们将连接一个 433MHz 射频无线模块与 STM32F103C8 微控制器。该项目分为两部分。发送器将与 STM32 连接,接收器将与 Arduino UNO 连接。发射和接收部分都会有不同的电路图和草图。


在本教程中,RF 发射器向接收器端发送两个值:使用超声波传感器测量的距离和电位计ADC值(0 到 4096),该值映射为(0 到 100)之间的数字。Arduino的RF 接收器接收这两个值并以无线方式在16x2 LCD 显示器中打印这些距离和数字值。

所需组件

STM32F103C8微控制器

Arduino UNO

433Mhz 射频发射器和接收器

声波传感器 (HC-SR04)

16x2 液晶显示器

10k 电位器

面包板

连接电线

433Mhz 射频发射器和接收器模块)

poYBAGMW_RKAOvz-AAKpQUI5gdo268.png

射频发射器引脚:

poYBAGMW_ReAOOkMAAASEnq92p4995.png

射频接收器引脚:

pYYBAGMW_RuAT2WgAAATsUpH2-g381.png

433 MHz 模块规格:

接收器工作电压:3V 至 5V

发射器工作电压:3V 至 5V

工作频率:433 MHz

传输距离:3米(不带天线)至100米(最大)

调制技术:ASK(幅移键控)

数据传输速度:10Kbps

STM32F103C8射频发射器电路图

pYYBAGMW_SWAHKrtAAIRtVh2LaM579.png

pYYBAGMW_SGARLbBAAaw4KJFslo483.png

射频发射器和 STM32F103C8 之间的电路连接:

poYBAGMW_SyAH1W4AAAOAGl2qfo045.png

超声波传感器和 STM32F103C8 之间的电路连接:

pYYBAGMW_TKADJmCAAAOPQjdJqM774.png

STM32F103C8 连接一个10k 电位器,为 STM32 的 ADC 引脚 PA0 提供输入模拟值(0 至 3.3V)。

带有Arduino Uno的RF接收器电路图

poYBAGMW_TeAVVdeAAFKTCYLQ_M012.png

pYYBAGMW_XaADvQjAAe5DiMSJd4408.png

射频接收器和 Arduino UNO 之间的电路连接:

poYBAGMW_XyAKGtRAAAmuTowTpY967.png

16x2 LCD 和 Arduino UNO 之间的电路连接:

pYYBAGMW_YGAdph-AAB0Dsoxh2c821.png

下面将简要解释编码。草图将分为两部分,第一部分是发射器部分,另一部分是接收器部分。所有草图文件和工作视频将在本教程结束时提供。要了解有关射频模块与 Arduino Uno 接口的更多信息,请点击链接。

为无线射频传输编程STM32F103C8

STM32F103C8 可以使用 Arduino IDE 进行编程。无需 FTDI 编程器或 ST-Link即可将代码上传到 STM32F103C8。只需通过 STM32 的 USB 端口连接到 PC 并开始使用ARDUINO IDE进行编程。

首先包含 Radiohead 库,可以从这里下载。因为这个库使用 ASK(幅移键控技术)来传输和接收数据。这使得编程非常容易。您可以通过进入 Sketch->include library->Add .zip library 在草图中包含库。

#include     

正如在发射器端的本教程中一样,超声波传感器用于测量距离,因此定义了触发和回波引脚。


#define trigPin PB1                             

#define echoPin PB0          

接下来,将 RH_ASK 库的对象名称设置为 rf_driver,并使用诸如速度 (2000)、RX 引脚 (PA9) 和 TX 引脚 (PA10) 等参数。


RH_ASK rf_driver(2000, PA9, PA10);             

接下来,声明该程序所需的 Strings 变量。


字符串传输号码;                            

字符串传输距离;

字符串传输;

接下来在 void setup() 中,初始化 RH_ASK rf_driver 的对象。


rf_driver.init();

之后触发引脚设置为 OUTPUT 引脚,PA0(连接到电位器)和回波引脚设置为 INPUT 引脚。串行通信以 9600 的波特率开始。


   序列号.开始(9600);

    pinMode(PA0,输入);

    pinMode(echoPin,输入);

    pinMode(trigPin,输出);

接下来在 void loop() 中,首先将输入模拟电压的电位器值转换为数字值(找到 ADC 值)。由于STM32 的 ADC具有 12 位分辨率。因此,数字值从 (0 到 4096) 变化,映射到 (0 到 100)。


    int 模拟输入 = 模拟读取(PA0);                  

    int pwmvalue = map(模拟输入,0,4095,0,100);        

接下来,使用超声波传感器测量距离,方法是设置触发器高低,延迟 2 微秒。


    数字写入(trigPin,低);                          

    延迟微秒(2);

    digitalWrite(trigPin, HIGH);                          

    延迟微秒(10);

    数字写入(trigPin,低);                          

回波针感测反射回来的波,即触发波反射回来的持续时间用于使用公式计算物体的距离。通过点击链接了解更多超声波传感器如何计算距离。


    持续时间长 = pulseIn(echoPin, HIGH);              

    浮动距离=持续时间*0.034/2;                 

现在测量的数据数量和距离都转换为字符串数据并存储在相应的字符串变量中。


    传输数=字符串(pwm值);                     

    传输距离 = 字符串(距离);                

两个字符串都作为一行添加并存储在称为传输的字符串中,逗号“,”用于分隔两个字符串。


  传输=传输_pwm +“,”+传输距离;   

传输字符串被转换为字符数组。


    const char *msg = transmit.c_str();    

数据被传输并等待直到它被发送。


    rf_driver.send((uint8_t *)msg, strlen(msg));         

    rf_driver.waitPacketSent();         

发送的字符串数据也显示在串行监视器中。


    序列号.println(msg);                                     

将 Arduino UNO 编程为 RF 接收器


Arduino UNO 使用 Arduino IDE 进行编程。在接收器部分,从发射器部分发送并由 RF 接收器模块接收的数据和接收到的字符串数据被拆分为各自的数据(距离和数量)并显示在 16x2 LCD 显示屏上。


让我们简要地看一下接收器编码:


就像在发射器部分一样,首先包含 RadiohHead 库。因为这个库使用 ASK(幅移键控技术)来传输和接收数据。这使得编程非常容易。


#include                 

由于这里使用的是 LCD 显示器,所以还包括了液晶库。


#include    

与 Arduino UNO 连接的 16x2 LCD 显示引脚使用 lcd 作为对象指定和声明。


液晶液晶(2,3,4,5,6,7);    

接下来声明用于存储字符串数据的字符串数据变量。


字符串 str_receive;                

字符串 str_number; 

字符串 str_distance;

Radiohead 库的对象已声明。


      RH_ASK 射频;                          

现在在void setup() 中,LCD 显示设置为 16x2 模式,并显示并清除欢迎消息。


    lcd.开始(16,2);              

    lcd.print("电路文摘");  

    lcd.setCursor(0,1); 

    lcd.print("STM32 射频"); 

    延迟(5000);

    lcd.clear();

之后,初始化rf对象。


rf.init();                    

现在在void loop() 中,数组 buf[] 被声明为大小为 7。因为从发送器发送的数据有 7,包括“,”。因此,根据要传输的数据进行更改。


    uint8_t buf[7];                       

    uint8_t buflen = sizeof(buf);

如果该字符串在 rf 接收器模块中可用,则 if 函数会检查大小并执行。rf.recv()用于接收数据。


如果 (rf.recv(buf, &buflen))                       

buf具有接收到的字符串,因此接收到的字符串存储在str_receive字符串变量中。


str_receive = String((char*)buf);                         

如果检测到两个字符串之间的“,”,则此for循环用于将接收到的字符串分成两部分。


      for (int i = 0; i < str_receive.length(); i++)             

      { 

      if (str_receive.substring(i, i+1) == ",")                  

      { 

      str_number = str_receive.substring(0, i); 

      str_distance = str_receive.substring(i+1); 

      休息; 

      }

声明两个值的两个 char 数组,通过将字符串转换为字符数组,将分成两个的字符串存储在相关数组中。


      字符数串[4]; 

      字符距离字符串[3];

      str_distance.toCharArray(distancestring,3);             

      str_number.toCharArray(numberstring,3);

之后使用 atoi() 将字符数组转换为整数


      int 距离 = atoi(距离字符串);                   

      int number = atoi(numberstring);

转换成整数值后,距离和数字值显示在 16x2 LCD 显示屏中


      lcd.setCursor(0,0); 

      lcd.print("编号:"); 

      lcd.print(数字);                 

      lcd.setCursor(0,1); 

      lcd.print("距离:"); 

      lcd.print(距离);                   

      lcd.print("cm");

分别在STM32和Arduino UNO中上传发射器和接收器代码后,使用STM32测量的数字和物体距离等数据通过RF发射器传输到RF接收器,接收到的值以无线方式显示在LCD显示屏上。


测试基于 STM 32 的射频发射器和接收器

1.当数字为0且物体距离为6cm时。

poYBAGMW_PaAN-MsAAbluVE2PLA288.png

2.当数字47和物体距离为3cm时。

pYYBAGMW_PKAUi2rAAYfr71s6Cs483.png
发射器代码(STM32F103C8):


//433MHZ射频发射器与STM32F103C8


//发射机代码


//电路文摘


#include //RadioHead 库


#define trigPin PB1 //设置超声波传感器的Trigpin为PB1


#define echoPin PB0 //设置超声波传感器的echoPin为PB0


RH_ASK rf_driver(2000, PA9, PA10); //设置引脚PA9为接收器,PA10为发送器,2000为速度





字符串传输_pwm;//存储字符串值的字符串


字符串传输距离;


字符串传输;


无效设置()


{


// 初始化 ASK 对象


rf_driver.init();


序列号.开始(9600);


pinMode(PA0,输入);


pinMode(echoPin,输入);


pinMode(trigPin,输出);


}





无效循环()


{


int 模拟输入 = 模拟读取(PA0);// 来自连接到电位器的引脚 PA0 的 ADC 值


int pwmvalue = map(模拟输入,0,4096,0,100);// 将 0 到 4096 转换为 0 到 100





数字写入(trigPin,低);//将超声波的TrigPin设为LOW


延迟微秒(2);


digitalWrite(trigPin, HIGH); //使Ultrasonic HIGH的TrigPin


延迟微秒(10);


数字写入(trigPin,低);//将超声波的TrigPin设为LOW


持续时间长 = pulseIn(echoPin, HIGH); //接收反射的Echo信号


浮动距离=持续时间*0.034/2;//计算对象的CM距离


传输_pwm =字符串(pwm值);//将值转换为字符串


传输距离 = 字符串(距离);//将值转换为字符串


传输=传输_pwm +“,”+传输距离;//在一行中添加两个字符串


const char *msg = transmit.c_str(); //


rf_driver.send((uint8_t *)msg, strlen(msg)); //发送字符串


rf_driver.waitPacketSent();


序列号.println(msg); //用于调试的串行打印值


延迟(1000);


}





接收器代码(Arduino UNO):


//接收器Arduino代码


//433MHZ射频,STM32F103C8作为发射器


//电路文摘





#include //包含 RadioHead 库


#include //包含LCD显示库





液晶液晶(2,3,4,5,6,7); //使用连接到 Arduino 的引脚初始化 lcd


字符串 str_receive; //存储值的字符串


字符串 str_number;


字符串 str_distance;





RH_ASK 射频;//rf 作为 RG_ASK 的对象


无效设置()


{


lcd.开始(16,2);//液晶屏设置为16x2模式


lcd.print("电路文摘"); //显示欢迎信息


lcd.setCursor(0,1);


lcd.print("STM32 射频");


延迟(5000);


lcd.clear();


rf.init(); //初始化射频对象


}





无效循环()


{


uint8_t buf[7];


uint8_t buflen = sizeof(buf);


如果 (rf.recv(buf, &buflen))


{


str_receive = String((char*)buf); // 从发送器接收字符串


for (int i = 0; i < str_receive.length(); i++) // 将字符串拆分为两个字符串


{


if (str_receive.substring(i, i+1) == ",")


{


str_number = str_receive.substring(0, i);


str_distance = str_receive.substring(i+1);


休息;


}


}


字符数串[4];


字符距离字符串[3];





str_distance.toCharArray(distancestring,3); //将字符串转换为字符数组


str_number.toCharArray(numberstring,3);





int 距离 = atoi(距离字符串);//将数组转换成整数值


int number = atoi(numberstring);





lcd.setCursor(0,0);


lcd.print("编号:");


lcd.print(数字); //在LCD显示屏上显示数值


lcd.setCursor(0,1);


lcd.print("距离:");


lcd.print(距离);//在液晶显示屏上显示距离值


lcd.print("cm");


延迟(1500);


lcd.clear();


}


}


文章来源于:电子工程世界    原文链接
本站所有转载文章系出于传递更多信息之目的,且明确注明来源,不希望被转载的媒体或个人可与我们联系,我们将立即进行删除处理。

相关文章

    )主机程序 #include#include #define _SUCC_0x0f//数据传送成功#define _ERR_0xf0//数据传送失败unsigned char Table[9......
    上电串口助手收到的消息: 注意: 电压必须5V否则,给模块发送AT指令没有用。 正常情况下,模块插上SIM电话卡,供电达到5V时,模块上电会返回以下提示信息。 当模块出现 “SMS Ready”字符串提示时,说明模块......
    ;//发送失败   }A7139_SEND_TYPE;   volatile A7139_SEND_TYPE SendConfig; //发送数据的信息   //接收数据结构   typedef......
      */   9  大致意思是:发送成功的数据,称为被consumed(消费)掉了,而发送失败的数据,称为被dropped(丢弃)掉了。所以当网卡发送数据失败时,不应该调dev_kfree_skb......
    拉位于的超级充电桩网络在 2022 年曾出现过蓄意破坏的情况,攻击者不仅隔断充电线,而且还抽取了内部的铜线用于卖钱。 各位开电动汽车的IT之家网友,你在日常使用过程中遇到充电失败过吗?主要是什么原因?欢迎在评论区留言。 ......
    串口还没有完成先前的字符'h'的发送任务,串口处于忙碌的状态,因此现在是无法正确打开串口发送中断的,因此字符'e'发送失败。后续的字符也是同样的情况。 这就说明,采用中断发送方式时,连续发送是会发送失败的,串口......
    有:   • Redial机制有差别   • MSD的optional data有差别,Glonass的可选数据多一些。   • MSD发送失败的话,可以用短消息重发   3GPP标准:   • ETSI......
    汽车tbox故障什么原因造成的;汽车Tbox(Telematics Box,车载通信盒)是一种集成了通信技术和计算机技术的设备,通常安装在汽车内部,用于实现车辆的远程监控、数据传输、智能......
    组成一个CAN总线网络系统,当这两个ID相同的模块同时往CAN总线端发送数据时将会造成仲裁失败。 2. CANID冲突的现象 以CSM300为例进行说明,电路硬件简易连接图如图4所示,用两个上位机通过两路串口同时给两个相同配置的模块发送......
    模块组成一个CAN总线网络系统,当这两个ID相同的模块同时往CAN总线端发送数据时将会造成仲裁失败。 2. CANID冲突的现象 以CSM300为例进行说明,电路硬件简易连接图如图4所示,用两个上位机通过两路串口同时给两个相同配置的模块发送......

我们与500+贴片厂合作,完美满足客户的定制需求。为品牌提供定制化的推广方案、专属产品特色页,多渠道推广,SEM/SEO精准营销以及与公众号的联合推广...详细>>

利用葫芦芯平台的卓越技术服务和新产品推广能力,原厂代理能轻松打入消费物联网(IOT)、信息与通信(ICT)、汽车及新能源汽车、工业自动化及工业物联网、装备及功率电子...详细>>

充分利用其强大的电子元器件采购流量,创新性地为这些物料提供了一个全新的窗口。我们的高效数字营销技术,不仅可以助你轻松识别与连接到需求方,更能够极大地提高“闲置物料”的处理能力,通过葫芦芯平台...详细>>

我们的目标很明确:构建一个全方位的半导体产业生态系统。成为一家全球领先的半导体互联网生态公司。目前,我们已成功打造了智能汽车、智能家居、大健康医疗、机器人和材料等五大生态领域。更为重要的是...详细>>

我们深知加工与定制类服务商的价值和重要性,因此,我们倾力为您提供最顶尖的营销资源。在我们的平台上,您可以直接接触到100万的研发工程师和采购工程师,以及10万的活跃客户群体...详细>>

凭借我们强大的专业流量和尖端的互联网数字营销技术,我们承诺为原厂提供免费的产品资料推广服务。无论是最新的资讯、技术动态还是创新产品,都可以通过我们的平台迅速传达给目标客户...详细>>

我们不止于将线索转化为潜在客户。葫芦芯平台致力于形成业务闭环,从引流、宣传到最终销售,全程跟进,确保每一个potential lead都得到妥善处理,从而大幅提高转化率。不仅如此...详细>>