在为您的项目提供无线功能时,433Mhz ASK 混合发射器和接收器是工程师、开发人员和爱好者的常见选择,因为它价格低廉、易于使用的库和社区支持。我们还使用此433MHz RF模块构建了很少的项目,例如RF控制的家庭自动化和无线门铃。但通常 ASK 混合发射器和接收器是不够的,它的低范围和单向通信特性使其不适用于许多应用为了解决这个不断出现的问题,HopeRF 的开发人员设计了一个很酷的新射频模块,称为RFM69HCW。在本教程中,我们将了解 RFM69HCW 射频模块及其优势。
RFM69HCW RF模块
RFM69HCW 是一种廉价且易于使用的无线电模块,可在未经许可的 ISM(工业、科学和医学)频段运行,类似于我们在之前项目中使用的nRF24L01 射频模块。它可用于在两个模块之间进行通信,也可以配置为网状网络以在数百个模块之间进行通信,这使其成为为家庭自动化和其他数据采集项目中使用的传感器构建廉价短程无线网络的完美选择。
RFM69HCW的特点:
+20 dbm- 100兆瓦电源输出能力
高灵敏度:在 1.2 kbps 时低至 -120 dBm
可编程 Pout:-18 至 +20 dBm,步长为 1dB
在模块的电压范围内保持恒定的射频性能
FSK、GFSK、MSK、GMSK 和 OOK 调制
内置位同步器执行时钟恢复
115 dB+ 动态范围 RSSI
具有超快 AFC 的自动射频感应
具有 CRC-16、AES-128、66 字节 FIFO 的数据包引擎 内置温度传感器
高链接预算
成本非常低
RFM69HCW - 硬件概述
频率
RFM69HCW设计为在ISM(行业,科学和医学)频段中工作,这是一套无执照的无线电频率,用于低功率,短距离设备。不同的频率在不同的区域合法,因此该模块具有许多不同版本的315,433,868和915MHz的原因。所有主要的射频通信参数都是可编程的,其中大部分可以动态设置,RFM69HCW 还提供了可编程窄带和宽带通信模式的独特优势。
注意:由于其功率相对较低和短期,因此在小型项目中实现此模块不会成为问题,但是如果您想从产品中制造产品,请确保您使用正确的频率你的地点。
范围
那么,这个链接预算是多少,为什么它如此重要?链接预算就像所有其他预算一样,是您一开始就拥有的东西,如果您的预算用完,您将随着时间的推移而花费,您将无法花费更多。
链路预算还与发送方和接收方之间的链路或连接有关,它由发送方的传输功率和接收方的灵敏度填充,以分贝或 dB为单位计算,它也是频率-依赖。链路预算会被发送方和接收方之间的各种障碍物和噪声扣除,例如距离电缆墙树木建筑物,如果链路预算用完,接收器只会在输出端产生一些噪声,我们不会得到任何可用信号。根据 RFM69HCW 的数据表,与 ASK 混合发射器的 105 dB 相比,它的链路预算为 140 dB,但这意味着这是一个重要的区别吗?幸运的是,我们发现Radio Link Budget Calculators online 所以让我们做一些计算来更好地理解这个话题。首先,假设我们在发送方和接收方之间有一条视线连接,并且一切都很完美,因为我们知道RFM69HCW的预算是 140 dB,所以让我们检查一下我们可以通信的最大理论距离,我们将所有内容都设置为零并且距离到 500KM,频率到 433MHz,我们得到 139.2 dBm 的水平接收功率
现在,我将一切设置为零,距离 9KM 频率为 433MHz,我们得到 104.3 dBm 的水平接收功率
所以通过上面的比较,我想我们都可以同意RFM69模块远远优于ASK混合发射器和接收器模块。
警告!必须将天线连接到模块,因为没有它,模块可能会被其自身的反射功率损坏。
创建天线并不像听起来那么难。最简单的天线可以仅由单股 22SWG 线制成。频率的波长可以通过公式v / f计算,其中v是传输速度,f是(平均)传输频率。在空气中,v等于c,即光速,即 299.792.458 m/s。因此 433 MHz 波段的波长为 299.792.458 / 433.000.000 = 34,54 cm。其中一半是 17,27 厘米,四分之一是 8,63 厘米。
对于 433 MHz 波段,波长为 299.792.458 / 433.000.000 = 69.24 cm。其中一半是 34,62 厘米,四分之一是 17,31 厘米。所以从上面的公式中,我们可以看出天线导线长度的计算过程。
电力需求
RFM69HCW 的工作电压介于 1.8V 至 3.6V 之间,传输时可吸收高达 130mA 的电流。在下表中,我们可以清楚地看到模块在不同条件下的功耗
警告:如果您选择的 Arduino 使用 5V 逻辑电平与外围设备进行通信,将模块直接连接到 Arduino 会损坏模块
在本教程中,我们将使用两个 Arduino Nano 和两个逻辑电平转换器与模块进行通信。我们使用 Arduino nano 是因为内置的内部调节器可以非常有效地管理峰值电流。下面硬件部分的Fritzing图会更清楚的给你解释。
注意:如果您的电源无法提供 130mA 的峰值电流,您的 Arduino 可能会重新启动,或者更糟糕的是模块可能无法正常通信,在这种情况下,低 ESR 的大容量电容器可以改善这种情况
RFM69模块引脚和描述
准备定制开发板
当我购买该模块时,它没有配备与面包板兼容的分线板,因此我们决定自己制作一个。如果您可能必须这样做,那么只需按照步骤操作即可。另外,请注意,这些步骤不是强制性的,您只需将电线焊接到射频模块并将它们连接到面包板,它仍然可以工作。我遵循此程序只是为了获得稳定而坚固的设置。
第 1 步:准备 RFM69HCW 模块的原理图
第 2 步:在您选择的任何 PCB 设计软件上进行电路板布局
第 3 步:为它准备一个 PCB,我正在关注这个Home Made PCB 教程。我将脚印印在铜板上,然后将其放入蚀刻溶液中
第 4 步:按照两个电路板的程序,将您的模块焊接到封装上。焊接两个模块后,如下所示
RFM69HCW 射频模块的引脚如下图所示
所需材料
以下是与模块通信所需的事项列表
两个 RFM69HCW 模块(具有匹配频率):
434 兆赫 (WRL-12823)
两个 Arduino(我正在使用 Arduino NANO)
两个逻辑电平转换器
两个分线板(我使用的是定制的分线板)
一个按钮
四个 LED
一个 4.7K 电阻 四个 220Ohms 电阻
跳线
漆包铜线 (22AWG),用于制作天线。
最后焊接(如果你还没有这样做的话)
硬件连接
在本教程中,我们使用 Arduino nano,它使用 5 伏逻辑,但 RFM69HCW 模块使用 3.3 伏逻辑电平,如上表所示,因此要在两个设备之间正确通信,必须使用逻辑电平转换器,如下图所示我们已经向您展示了如何将 Arduino nano 连接到 RFM69 模块。
Fritzing 图发送节点
连接表发送节点
Fritzing 图接收器节点
连接表接收节点
运行示例草图
在本教程中,我们将设置两个 Arduino RFM69 节点并让它们相互通信。在下面的部分中,我们将了解如何借助 LowPowerLab 的 Felix Rusu 编写的 RFM69 库来启动和运行模块。
导入库
希望您之前做过一些 Arduino 编程,并且知道如何安装库。如果不采取检查此链接的导入 .zip 库部分
插入节点
将发送器节点的 USB 插入您的 PC,应将一个新的 COM 端口号添加到 Arduino IDE 的“工具/端口”列表中,将其向下笔,现在插入接收器节点,另一个 COM 端口应出现在工具/端口列表,也写下来,借助端口号,我们将草图上传到发送方和接收方节点。
打开两个 Arduino 会话
在第一个会话加载后,通过双击 Arduino IDE 图标打开两个 Arduino IDE 会话,必须打开两个 Arduino 会话,因为这样您可以打开两个 Arduino 串行监视器窗口并同时监视两个节点的输出
打开示例代码
现在,当一切都设置好后,我们需要在两个 Arduino 会话中打开示例代码,然后转到
文件 》 示例 》 RFM6_LowPowerLab 》 示例 》 TxRxBlinky
并点击打开它
修改示例代码
在代码顶部附近,查找#define NETWORKID 并将值更改为 0。使用此 ID,您的所有节点都可以相互通信。
查找#define FREQUENCY 更改它以匹配板频率(我的是 433_MHz)。
查找 #define ENCRYPTKEY 这是您的 16 位加密密钥。
查找 #define IS_RFM69HW_HCW,如果您使用的是 RFM69_HCW 模块,请取消注释
最后,查找#define NODEID 它应该默认设置为接收器
现在将代码上传到您之前设置的接收器节点。
是时候修改发件人节点的草图了
现在在#define NODEID 宏中将其更改为 SENDER 并将代码上传到您的 Sender 节点。
就是这样,如果您正确地完成了所有操作,您就有两个完整的工作模型可供测试。
示例草图的工作
成功上传 Sketch 后,您将观察到与 Arduino 的引脚 D4 连接的红色 LED 亮起,现在按下 Sender Node 中的按钮,您将观察到红色 LED 关闭,绿色 LED 是连接到 Arduino 的 Pin D5 点亮如下图所示
您还可以观察 Button Pressed!串行监视器窗口中的文本,如下所示
现在观察连接到发送节点的引脚 D9 的蓝色 LED,它会闪烁两次,在接收节点的串行监视器窗口中,您将看到以下消息以及连接到 D9 引脚的蓝色 LED接收器节点将亮起。如果您在接收器节点的串行监视器窗口中看到上述消息,并且 LED 亮起,恭喜!您已成功将 RFM69 模块与 Arduino IDE 通信。
RFM69HCW 发射器代码:
// ************************************************ ******************************************
// 用于 Moteino 的示例 RFM69 草图来说明:
/ / - 发送
// - 接收
// - 自动传输控制
// - 按钮读取/中断
// **************************** ****************************************************** *********
// 当您按下 SENDER Moteino 上的按钮时,它将向
// RECEIVER Moteino 发送一条短消息并等待来自
// RECEIVER的 ACK(确认已收到消息)莫泰诺。如果收到 ACK,SENDER 将闪烁板载 LED
// 几次。RECEIVER 侦听特定令牌,并交替板载 LED
// 每当收到此令牌时,状态从 HIGH 变为 LOW,反之亦然。
// ************************************************ ******************************************
// 硬件设置:
// **** ****************************************************** ************************************
// 在发送方上,将一个瞬时触觉按钮连接到 D3,如下所示:
// __-__
// __| |___
// GND ----> BTN ----> D3 (D11 on MoteinoMEGA)
// 用 NODEID=RECEIVER 将这个草图加载到 RECEIVER 上(在下面的配置部分调整)
// 用这个加载这个草图到 SENDER NODEID=SENDER(在下面的配置部分调整)
//RFM69 库和 Felix Rusu 的代码 - felix@lowpowerlab.com
// 在以下位置获取库:https
://github.com/LowPowerLab/
// 确保在下面的配置部分调整设置!!!
// ************************************************ ************************************
// 版权所有 Felix Rusu 2016, http://www.LowPowerLab.com /联系方式
// ********************************************** ************************************
// 许可证
// ********* ****************************************************** ***********************
// 这个程序是免费软件;您可以重新分发它 // 和/或根据
自由软件发布
的 GNU 通用 // 公共许可证的条款对其进行修改
// 基础; 许可证的第 3 版,或
//(由您选择)任何更高版本。
//
// 分发这个程序是希望它
// 有用,但没有任何保证;甚至没有
// 对适销性或适用于
// 特定用途的默示保证。有关更多详细信息,请参阅 GNU General Public
// 许可证。
//
// 可以在
// http://www.gnu.org/licenses/gpl-3.0.txt
查看许可证
//
// 请维护此许可信息以及作者身份
// 和在此代码的任何重新分发中的版权声明
// *************************** ****************************************************** *****
#include
:
//www.github.com/lowpowerlab/rfm69 #include
#include
#include
// ***************************************************************************************** ********************************************************** **************
// ****重要的广播设置 - 您必须更改/配置才能匹配硬件收发器配置!****
// **************************************************** ********************************************************** ********************
#define NetworkID 100 //在彼此交流的所有节点上相同
#Define接收器1 //网关/接收器的唯一ID
#Define Sender 2
#define nodeid接收器//更改为“发件人”,如果这是发件人节点(带有按钮的节点)
//匹配频率到您的Moteino上的Radio的硬件版本(UNCOMENTING ONE):
#DEFINE频率RF69_4333MHZ
//#定义频率RF69_868MHz
//#定义频率RF69_915MHz
#define Encryptkey“ sampleCencryptkey” //所有节点上的16个字符/字节完全相同!
#Define IS_RFM69HW_HCW //仅适用于RFM69HW/HCW!如果您有RFM69W/CW,请抛弃!
// ***************************************************************************************** ********************************************************** ***************************
#define ENABLE_ATC //comment out this line to disable AUTO TRANSMISSION CONTROL
#define ATC_RSSI -75
//** ********************************************************** ************************************************************************************************************************************************************************** baud
115200
#ifdef __avr_atmega1284p__
#define LED 15 // Moteino Megas在D15上有LED
#define button_int 1 //中断1(d3)上的
用户按钮#define button_pin 11 //中断1(d3)上的用户按钮
#else #else#
define led 9 // moteinos在d9
#define button_int 1 //用户按钮上有leds leds。中断1(d3)
#define button_pin 3 //中断1(d3)上的用户按钮
#endif
#Define LED_GREEN 4 //发件人上的Green LED
#Define LED_RED 5 //发件人上的红色LED
#Define RX_TOGGLE_PIN_PIN 7 // GPIO在接收器上切换
#万一
void setup(){
serial.begin(serial_baud);
radio.Initialize(频率,nodeid,networkID);
#IFDEF IS_RFM69HW_HCW
RADIO.SETHIGHPOPTOR(); //必须仅适用于RFM69HW/HCW!
#endif
Radio.Encrypt(Encryptkey);
#ifdef
enable_atc radio.enableAutopower(atc_rssi);
#万一
char buff [50];
sprintf(buff,“ \ nlisting at%d MHz ...”,频率== RF69_43333MHz?433:频率== RF69_868MHz?868:915);
serial.println(buff);
serial.flush();
pinmode(button_pin,input_pullup);
pinmode(LED,输出);
actactInterRupt(button_int,handlebutton,fall);
PinMode(LED_GREEN,输出);
pinmode(LED_RED,输出);
pinmode(rx_toggle_pin,输出);
DigitalWrite(LED_GREEN,低);
DigitalWrite(LED_RED,高);
}
// ********这是针对D3(中断1)的按钮中断的基于中断的拒绝,
#define flag_interrupt 0x01
volatile int maineventflags = 0;
boolean buttonpressed = false;
void handlebutton()
{
maineventFlags | = flag_interrupt;
}
字节LEDSTATE = low; // low = 0
void loop(){
// ********这是基于中断的基于D3(中断1)的按钮的中断be拒绝,
if(maineventflags&flag_interrupt)
{
lowpower.power.power.power.powerdown(sleep_120ms,adc_off,adc_off,adc_off,adc_on,bod_on,bod_on );
maineventflags&= 〜Flag_interrupt;
if(!digitalread(button_pin)){buttonpresse
= true;
}
}
if(buttonpats)
{
serial.println(“按下按钮!”);
buttonpressed = false;
if(LEDSTATE == LOW)
{
LEDSTATE = HIGH;
DigitalWrite(LED_GREEN,高);
DigitalWrite(LED_RED,低);
}
else
{
ledState = low;
DigitalWrite(LED_GREEN,低);
DigitalWrite(LED_RED,高);
}
if(Radio.SendWithRetry(接收器,“ HI”,2))//目标节点ID,字符串或字节数组的消息,消息长度
闪烁(LED,40,3); //眨眼LED 3次,眨眼之间的40ms
}
//检查是否收到某些东西(可能是从广播中中断的东西)
,如果(Radio.ReceivedOne())
{
//收到serial
serial.print的打印消息('['[''' ); serial.print(radio.senderid); serial.print(“]”);
serial.print((char*)radio.data);
serial.print(“ [rx_rssi:“”); serial.print(radio.rssi); serial.print(“”]);
序列号.println();
//检查收到的消息是否长2个字节,并检查消息是否专门为“ HI”
if(radio.datalen == 2 && radion.data [0] =='H'&& radio.data [1] =='i')
{
if(ledState == low)
ledState = high;
否则LEDSTATE =低;
DigitalWrite(LED,LEDSTATE);
DigitalWrite(RX_TOGGLE_PIN,LEDSTATE);
}
//检查发件人是否想要ACK
if(radio.ackRequested())
{
radio.sendack();
serial.print(“ - ack send”);
}
}
radio.receivedone(); //将收音机放入RX模式
serial.flush(); //确保在睡觉之前将所有串行数据都计时
。
void blink(字节销,字节delay_ms,byte loops)
{
for(字节i = 0; i
{
digitalwrite(pin,high);
延迟(delay_ms);
DigitalWrite(PIN,Low);
延迟(DELAY_MS);
}
}
RFM69HCW接收器代码:
// ******************************************************* **************************************************************************************************************************************************************************
#include
#include
#include
// ***************************************************************************************** ********************************************************** **************
// ****重要的广播设置 - 您必须更改/配置才能匹配硬件收发器配置!****
// **************************************************** ********************************************************** ********************
#define NetworkID 100 //在彼此交流的所有节点上相同
#Define接收器1 //网关/接收器的唯一ID
#Define Sender 2
#define nodeid接收器//更改为“发件人”,如果这是发件人节点(带有按钮的节点)
//匹配频率到您的Moteino上的Radio的硬件版本(UNCOMENTING ONE):
#DEFINE频率RF69_4333MHZ
//#定义频率RF69_868MHz
//#定义频率RF69_915MHz
#define Encryptkey“ sampleCencryptkey” //所有节点上的16个字符/字节完全相同!
#Define IS_RFM69HW_HCW //仅适用于RFM69HW/HCW!如果您有RFM69W/CW,请抛弃!
// ***************************************************************************************** ********************************************************** ***************************
#define ENABLE_ATC //comment out this line to disable AUTO TRANSMISSION CONTROL
#define ATC_RSSI -75
//** ********************************************************** ************************************************************************************************************************************************************************** baud
115200
#ifdef __avr_atmega1284p__
#define LED 15 // Moteino Megas在D15上有LED
#define button_int 1 //中断1(d3)上的
用户按钮#define button_pin 11 //中断1(d3)上的用户按钮
#else #else#
define led 9 // moteinos在d9
#define button_int 1 //用户按钮上有leds leds。中断1(d3)
#define button_pin 3 //中断1(d3)上的用户按钮
#endif
#Define LED_GREEN 4 //发件人上的Green LED
#Define LED_RED 5 //发件人上的红色LED
#Define RX_TOGGLE_PIN_PIN 7 // GPIO在接收器上切换
#万一
void setup(){
serial.begin(serial_baud);
radio.Initialize(频率,nodeid,networkID);
#IFDEF IS_RFM69HW_HCW
RADIO.SETHIGHPOPTOR(); //必须仅适用于RFM69HW/HCW!
#endif
Radio.Encrypt(Encryptkey);
#ifdef
enable_atc radio.enableAutopower(atc_rssi);
#万一
char buff [50];
sprintf(buff,“ \ nlisting at%d MHz ...”,频率== RF69_43333MHz?433:频率== RF69_868MHz?868:915);
serial.println(buff);
serial.flush();
pinmode(button_pin,input_pullup);
pinmode(LED,输出);
actactInterRupt(button_int,handlebutton,fall);
PinMode(LED_GREEN,输出);
pinmode(LED_RED,输出);
pinmode(rx_toggle_pin,输出);
DigitalWrite(LED_GREEN,低);
DigitalWrite(LED_RED,高);
}
// ********这是针对D3(中断1)的按钮中断的基于中断的拒绝,
#define flag_interrupt 0x01
volatile int maineventflags = 0;
boolean buttonpressed = false;
void handlebutton()
{
maineventFlags | = flag_interrupt;
}
字节LEDSTATE = low; // low = 0
void loop(){
// ********这是基于中断的基于D3(中断1)的按钮的中断be拒绝,
if(maineventflags&flag_interrupt)
{
lowpower.power.power.power.powerdown(sleep_120ms,adc_off,adc_off,adc_off,adc_on,bod_on,bod_on );
maineventflags&= 〜Flag_interrupt;
if(!digitalread(button_pin)){buttonpresse
= true;
}
}
if(buttonpats)
{
serial.println(“按下按钮!”);
buttonpressed = false;
if(LEDSTATE == LOW)
{
LEDSTATE = HIGH;
DigitalWrite(LED_GREEN,高);
DigitalWrite(LED_RED,低);
}
else
{
ledState = low;
DigitalWrite(LED_GREEN,低);
DigitalWrite(LED_RED,高);
}
if(Radio.SendWithRetry(接收器,“ HI”,2))//目标节点ID,字符串或字节数组的消息,消息长度
闪烁(LED,40,3); //眨眼LED 3次,眨眼之间的40ms
}
//检查是否收到某些东西(可能是从广播中中断的东西)
,如果(Radio.ReceivedOne())
{
//收到serial
serial.print的打印消息('['[''' ); serial.print(radio.senderid); serial.print(“]”);
serial.print((char*)radio.data);
serial.print(“ [rx_rssi:“”); serial.print(radio.rssi); serial.print(“”]);
序列号.println();
//检查收到的消息是否长2个字节,并检查消息是否专门为“ HI”
if(radio.datalen == 2 && radion.data [0] =='H'&& radio.data [1] =='i')
{
if(ledState == low)
ledState = high;
否则LEDSTATE =低;
DigitalWrite(LED,LEDSTATE);
DigitalWrite(RX_TOGGLE_PIN,LEDSTATE);
}
//检查发件人是否想要ACK
if(radio.ackRequested())
{
radio.sendack();
serial.print(“ - ack send”);
}
}
radio.receivedone(); //将收音机放入RX模式
serial.flush(); //确保在睡觉之前将所有串行数据都计时
。
void blink(字节销,字节delay_ms,byte loops)
{
for(字节i = 0; i
{
digitalwrite(pin,high);
延迟(delay_ms);
DigitalWrite(PIN,Low);
延迟(DELAY_MS);
}
}
评论
查看更多