基于微控制器的433MHz发射器和接收器模块间的通信方案

在制作基于微控制器的项目时,有时会需要在两个设备之间进行通信,要么是基于双工/收发器的操作(两个设备都可以同时发送和接收),要么是基于半双工的操作,其中通信是一个单向的(正在接收的设备无法发送,以及正在发送数据的设备无法接收)。
有很多方式可以实现上述两种通信模式中的任何一种,并且这些选择通常取决于项目的需求,尤其是设备之间的距离和成本。对于两个微控制器之间的短距离、低预算的通信方式,其中一种最优选使用的方式是使用433mhz rf发送器和接收器模块的射频通信。在本篇文章中,我们将介绍如何使用这些模块在两个arduino开发板之间建立通信。
433 mhz发射器和接收器模块
这些模块因其低成本和易用性在创客和diy爱好者中非常受欢迎。它们用于两个微控制器之间的所有短距离、半双工的通信形式,其中一个微控制器用作发送器,另一个微控制器用作接收器。这些模块是ask(幅移键控)或ook(开关键控)型rf模块,这意味着它们在发送逻辑“零”时通常不消耗功率,因此消耗的功率非常低。这种低功耗使其在基于电池的实施中非常有用。下面列出了一些发射器和接收器模块的规格。
433mhz发射器模块的规格
√ 工作电压:3v – 12v
√ 工作电流:最大小于40ma,最小9ma
√ 谐振模式:(saw)
√ 调制模式:ask
√ 工作频率:433.92mhz
√ 发射功率:25mwf
√ 频率误差:+ 150khz(max)
√ 通讯速率:小于10kbps
√ 发射范围:90m(在开放空间)
433mhz接收器模块规格
√ 工作电压:5.0vdc + 0.5v
√ 工作电流:≤5.5mamax
√ 调制模式:ook / ask
√ 工作频率:433.92mhz
√ 带宽:2mhz
√ 灵敏度:超过–100dbm(50ω)
为了演示使用这些模块可以轻松地将无线功能添加到项目中,我们将制作一个带有远程数据显示的气象站。气象站将主要由温湿度传感器和433 rf发射器模块组成。它将测量环境的温度和湿度,并将其通过rf发送器发送到st7735 1.8寸彩色tft显示屏上的显示单元(通过rf接收器模块接收)。
所需的组件
● arduino uno开发板
● 433mhz射频套件
● dht22温湿度传感器
● 1.8寸彩色tft显示屏
● 面包板
● 跳线
原理图
该项目有两个原理图。第一个用于发送器,该发送器获取环境的温度和湿度,并将其发送到项目的接收器,后者在显示屏上显示数据。
发送器电路原理图
发送器电路包括一个arduino开发板、dht22温湿度传感器以及433mhz rf发送器模块。当arduino与计算机断开连接时,可以使用电池组为arduino提供电源。如下图所示连接组件。
接收器电路原理图
接收器电路由433 mhz射频接收器模块、st7735 1.8寸彩色tft显示屏和arduino uno开发板组成。如下图所示连接组件。
完成所有连接后,我们现在可以为该项目编写代码。
代码
就像我们必须搭建两个设备一样,我们将为该项目编写两个不同的代码。其中一个代码是控制发送器,另一种代码是控制接收器。为了轻松编写本文的代码,我们将使用可轻松驱动项目各部分的库。对于rf模块,我们将使用virtual wire库来发送和接收数据,而对于接收到的数据的显示,我们将使用adafruit gfx和adafruit st7735库来轻松更新st7735 lcd显示屏。我们将使用adafruit dht传感器库轻松地从dht22传感器获取温度和湿度数据。
代码背后的算法很简单。对于发射器,从dht22获取温度和湿度值,然后通过rf发射器发送到接收器。对于接收器,使用rf接收器模块获取由发送器发送的温度和湿度值,然后在lcd上显示。与往常一样,我们将对这两个项目的代码进行简要说明。
发射器的代码
首先包含将在代码中使用的库。
//written by nick koumaris
//info@educ8s.tv
#include 《virtualwire.h》
#include “dht.h”
之后,我们声明将dht连接到的arduino的引脚,并指定要使用的dht的类型。
#define dhtpin 4
#define dhttype dht22
接下来,我们定义arduino的引脚,该引脚将用作我们的数据传输引脚(连接到rf发送器模块的数据引脚),然后创建将一个用于发送数据的结构体package。
const int led_pin = 13;
const int transmit_pin = 12;
struct package
{
float temperature ;
float humidity ;
};
接下来,我们定义一个package实例,并创建dht类的实例以处理dht传感器。
typedef struct package package;
package data;
dht dht(dhtpin, dhttype);
完成这些操作后,我们转到void setup()函数,在其中设置tx引脚和其他参数以初始化rf模块。
void setup()
{
// initialise the io and isr
vw_set_tx_pin(transmit_pin);
vw_set_ptt_inverted(true); // required for dr3100
vw_setup(500); // bits per sec
pinmode(led_pin, output);
}
接下来是void loop()函数,我们可以使用 readsensor()函数获取温度和湿度。获取数据后,使用vw_send()函数发送数据。延迟2000毫秒,以在数据之间创建一段时间间隔,并确保发送前另一个已发送完成。
void loop()
{
digitalwrite(led_pin, high); // flash a light to show transmitting
readsensor();
vw_send((uint8_t *)&data, sizeof(data));
vw_wait_tx(); // wait until the whole message is gone
digitalwrite(led_pin, low);
delay(2000);
}
接收器的代码
首先包含将要使用的库。
//written by nick koumaris
//info@educ8s.tv
#include 《virtualwire.h》
#include 《adafruit_st7735.h》
#include 《adafruit_gfx.h》
接下来,我们声明与lcd引脚相连的arduino引脚。
#define tft_cs 10
#define tft_rst 8
#define tft_dc 9
adafruit_st7735 tft = adafruit_st7735(tft_cs, tft_dc, tft_rst);
// option 2: use any pins but a little slower
#define tft_sclk 13 // set these to be whatever pins you like!
#define tft_mosi 11 // set these to be whatever pins you like!
接下来,我们声明rf接收器模块的数据引脚所连接的arduino引脚(receive_pin),并创建char型变量来保存温度和湿度值。
const int receive_pin = 12;
char temperaturechar[10];
char humiditychar[10];
接下来,我们创建一个类似于发射器代码中的结构体package。
struct package
{
float temperature = 0.0;
float humidity = 0.0;
};
完成此操作后,我们转到void setup()函数,在该函数中我们初始化显示屏,rf接收器模块设置比特率并启动接收器。
void setup()
{
tft.initr(initr_blacktab);
tft.fillscreen(st7735_black);
printui();
delay(1000);
// initialise the io and isr
vw_set_rx_pin(receive_pin);
vw_setup(500); // bits per sec
vw_rx_start(); // start the receiver pll running
}
接下来,是void loop()函数。通过使用vw_have_message()函数检查是否已收到消息。如果收到消息,我们将从中提取温度和湿度数据,并将其显示在lcd上。
void loop()
{
uint8_t buf[sizeof(data)];
uint8_t buflen = sizeof(data);
if (vw_have_message()) // is there a packet for us?
{
vw_get_message(buf, &buflen);
memcpy(&data,&buf,buflen);
serial.print(“package:”);
serial.print(data.temperature);
string temperaturestring = string(data.temperature,1);
temperaturestring.tochararray(temperaturechar,10);
tft.fillrect(10,20,80,30,st7735_black);
printtext(temperaturechar, st7735_white,10,20,3);
string humiditystring = string(data.humidity,1);
humiditystring.tochararray(humiditychar,10);
tft.fillrect(10,95,80,100,st7735_black);
printtext(humiditychar, st7735_white,10,95,3);
serial.print(“”);
serial.println(data.humidity);
}
}
该代码还包括一些用于以更用户友好的方式显示结果的函数。
void printtext(char *text, uint16_t color, int x, int y,int textsize)
{
tft.setcursor(x, y);
tft.settextcolor(color);
tft.settextsize(textsize);
tft.settextwrap(true);
tft.print(text);
}
void printui()
{
printtext(“temperature”, st7735_green,30,5,1); // temperature static text
printtext(“o”, st7735_white,90,13,2);
printtext(“c”, st7735_white,105,20,3);
printtext(“humidity”, st7735_blue,30,80,1); // temperature static text
printtext(“%”, st7735_white,90,95,3);
}
效果演示
将相应的代码上传到每个arduino开发板。 两个arduino开发板都可以使用电池组供电。 开机后几分钟,您应该会在lcd上看到温度和湿度数据。
433mhz发射器和接收器模块的范围通常很小,但是通过焊接外部天线,它们的通讯范围可以增大。


什么是电脑切换器?4路KVM切换器介绍
在电梯前室为什么要放置正压送风压力传感器?
TI全新精密宽带宽ADC可提升数据采集性能,同时使尺寸和功耗减小一半
NVIDIA RTX:领先的视觉计算平台
要点新闻 AI机器人Geek+1.5亿B轮融资 科技股泡沫或将破灭
基于微控制器的433MHz发射器和接收器模块间的通信方案
中国电信在5G网络建设充分发挥了64TR MassiveMIMO AAU的性能优势
如何编写有利于编译器优化的代码
不同结构的HDI设计会对成本带来哪些影响​?
爆苹果高管用iPad贿赂美国警长获得许可证
有哪些常见无线网络安全威胁?我们又该怎么防范?
解析Docker、Kubernetes、Openshift的发展历史及架构
ChatGPT可能取代哪些岗位?
电子电路调试常见故障原因_电子电路查找故障的方法
从三个方面来介绍LED透明屏幕工作稳定性的解决方案
到2022年,全球车用毫米波雷达市场规模总计约160亿美元
高空抛物悲剧频出,各大科技公司为AI安防保驾护航
DO30-E数字式三用表校验仪的相关功能说明
泰州移动打造5G智慧购物中心建设,5G带来购物场景的全新改变
冰箱容易漏电的几大部位