风筝
发表于: 2020-10-21 17:06:19 | 显示全部楼层

在制作基于微控制器的项目时,有时会需要在两个设备之间进行通信,要么是基于双工/收发器的操作(两个设备都可以同时发送和接收),要么是基于半双工的操作,其中通信是一个单向的(正在接收的设备无法发送,以及正在发送数据的设备无法接收)。


有很多方式可以实现上述两种通信模式中的任何一种,并且这些选择通常取决于项目的需求,尤其是设备之间的距离和成本。对于两个微控制器之间的短距离、低预算的通信方式,其中一种最优选使用的方式是使用433MHz RF发送器和接收器模块的射频通信。在本篇文章中,我们将介绍如何使用这些模块在两个Arduino开发板之间建立通信。


433 MHz发射器和接收器模块

txrx.jpg

这些模块因其低成本和易用性在创客和DIY爱好者中非常受欢迎。它们用于两个微控制器之间的所有短距离、半双工的通信形式,其中一个微控制器用作发送器,另一个微控制器用作接收器。这些模块是ASK(幅移键控)或OOK(开关键控)型RF模块,这意味着它们在发送逻辑“零”时通常不消耗功率,因此消耗的功率非常低。这种低功耗使其在基于电池的实施中非常有用。下面列出了一些发射器和接收器模块的规格。


433MHz发射器模块的规格

tx.jpg

√    工作电压:3V – 12V

√    工作电流:最大小于40mA,最小9mA

√    谐振模式:(SAW)

√    调制模式:ASK

√    工作频率:433.92MHz

√    发射功率:25mWF

√    频率误差:+ 150kHz(max)

√    通讯速率:小于10Kbps

√    发射范围:90m(在开放空间)


433MHz接收器模块规格

rx.jpg

√    工作电压: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提供电源。如下图所示连接组件。

transmitter.jpg


接收器电路原理图

接收器电路由433 MHz射频接收器模块、ST7735 1.8寸彩色TFT显示屏和Arduino Uno开发板组成。如下图所示连接组件。

1.8tft_bb.png


完成所有连接后,我们现在可以为该项目编写代码。


代码

就像我们必须搭建两个设备一样,我们将为该项目编写两个不同的代码。其中一个代码是控制发送器,另一种代码是控制接收器。为了轻松编写本文的代码,我们将使用可轻松驱动项目各部分的库。对于RF模块,我们将使用virtual wire库来发送和接收数据,而对于接收到的数据的显示,我们将使用Adafruit GFXAdafruit ST7735库来轻松更新ST7735 LCD显示屏。我们将使用Adafruit DHT传感器库轻松地从DHT22传感器获取温度和湿度数据。


代码背后的算法很简单。对于发射器,从DHT22获取温度和湿度值,然后通过RF发射器发送到接收器。对于接收器,使用RF接收器模块获取由发送器发送的温度和湿度值,然后在LCD上显示。与往常一样,我们将对这两个项目的代码进行简要说明。


发射器的代码

首先包含将在代码中使用的库。

  1. //Written by Nick Koumaris
  2. //info@educ8s.tv

  3. #include <VirtualWire.h>
  4. #include "DHT.h"
复制代码

之后,我们声明将DHT连接到的Arduino的引脚,并指定要使用的DHT的类型。

  1. #define DHTPIN 4  

  2. #define DHTTYPE DHT22
复制代码

接下来,我们定义Arduino的引脚,该引脚将用作我们的数据传输引脚(连接到RF发送器模块的数据引脚),然后创建将一个用于发送数据的结构体package。

  1. const int led_pin = 13;
  2. const int transmit_pin = 12;

  3. struct package
  4. {
  5.   float temperature ;
  6.   float humidity ;
  7. };
复制代码

接下来,我们定义一个package实例,并创建DHT类的实例以处理DHT传感器。

  1. typedef struct package Package;
  2. Package data;

  3. DHT dht(DHTPIN, DHTTYPE);
复制代码

完成这些操作后,我们转到void setup()函数,在其中设置TX引脚和其他参数以初始化RF模块。

  1. void setup()
  2. {
  3.     // Initialise the IO and ISR
  4.     vw_set_tx_pin(transmit_pin);
  5.     vw_set_ptt_inverted(true); // Required for DR3100
  6.     vw_setup(500);       // Bits per sec
  7.     pinMode(led_pin, OUTPUT);
  8. }
复制代码

接下来是void loop()函数,我们可以使用 readSensor()函数获取温度和湿度。获取数据后,使用vw_send()函数发送数据。延迟2000毫秒,以在数据之间创建一段时间间隔,并确保发送前另一个已发送完成。

  1. void loop()
  2. {
  3.   digitalWrite(led_pin, HIGH); // Flash a light to show transmitting
  4.   readSensor();
  5.   vw_send((uint8_t *)&data, sizeof(data));
  6.   vw_wait_tx(); // Wait until the whole message is gone
  7.   digitalWrite(led_pin, LOW);
  8.   delay(2000);
  9. }
复制代码

接收器的代码

首先包含将要使用的库。

  1. //Written by Nick Koumaris
  2. //info@educ8s.tv

  3. #include <VirtualWire.h>
  4. #include <Adafruit_ST7735.h>
  5. #include <Adafruit_GFX.h>
复制代码

接下来,我们声明与LCD引脚相连的Arduino引脚。

  1. #define TFT_CS     10
  2. #define TFT_RST    8                     
  3. #define TFT_DC     9
  4. Adafruit_ST7735 tft = Adafruit_ST7735(TFT_CS,  TFT_DC, TFT_RST);

  5. // Option 2: use any pins but a little slower
  6. #define TFT_SCLK 13   // set these to be whatever pins you like!
  7. #define TFT_MOSI 11   // set these to be whatever pins you like!
复制代码

接下来,我们声明RF接收器模块的数据引脚所连接的Arduino引脚(receive_pin),并创建char型变量来保存温度和湿度值。

  1. const int receive_pin = 12;
  2. char temperatureChar[10];
  3. char humidityChar[10];
复制代码

接下来,我们创建一个类似于发射器代码中的结构体package。

  1. struct package
  2. {
  3.   float temperature = 0.0;
  4.   float humidity = 0.0;
  5. };
复制代码

完成此操作后,我们转到void setup()函数,在该函数中我们初始化显示屏,RF接收器模块设置比特率并启动接收器。

  1. void setup()
  2. {
  3.     tft.initR(INITR_BLACKTAB);
  4.     tft.fillScreen(ST7735_BLACK);
  5.     printUI();
  6.     delay(1000);

  7.     // Initialise the IO and ISR
  8.     vw_set_rx_pin(receive_pin);
  9.     vw_setup(500);   // Bits per sec
  10.     vw_rx_start();       // Start the receiver PLL running
  11. }
复制代码

接下来,是void loop()函数。通过使用vw_have_message()函数检查是否已收到消息。如果收到消息,我们将从中提取温度和湿度数据,并将其显示在LCD上。

  1. void loop()
  2. {
  3.     uint8_t buf[sizeof(data)];
  4.     uint8_t buflen = sizeof(data);

  5. if (vw_have_message())  // Is there a packet for us?
  6.   {
  7.     vw_get_message(buf, &buflen);
  8.     memcpy(&data,&buf,buflen);

  9.     Serial.print("\nPackage:");
  10.     Serial.print(data.temperature);
  11.     String temperatureString = String(data.temperature,1);
  12.     temperatureString.toCharArray(temperatureChar,10);
  13.     tft.fillRect(10,20,80,30,ST7735_BLACK);
  14.     printText(temperatureChar, ST7735_WHITE,10,20,3);

  15.     String humidityString = String(data.humidity,1);
  16.     humidityString.toCharArray(humidityChar,10);
  17.     tft.fillRect(10,95,80,100,ST7735_BLACK);
  18.     printText(humidityChar, ST7735_WHITE,10,95,3);

  19.     Serial.print("\n");
  20.     Serial.println(data.humidity);
  21.   }
  22. }
复制代码

该代码还包括一些用于以更用户友好的方式显示结果的函数。

  1. void printText(char *text, uint16_t color, int x, int y,int textSize)
  2. {
  3.   tft.setCursor(x, y);
  4.   tft.setTextColor(color);
  5.   tft.setTextSize(textSize);
  6.   tft.setTextWrap(true);
  7.   tft.print(text);
  8. }

  9. void printUI()
  10. {
  11.     printText("TEMPERATURE", ST7735_GREEN,30,5,1);  // Temperature Static Text
  12.     printText("o", ST7735_WHITE,90,13,2);
  13.     printText("C", ST7735_WHITE,105,20,3);

  14.     printText("HUMIDITY", ST7735_BLUE,30,80,1);  // Temperature Static Text
  15.     printText("%", ST7735_WHITE,90,95,3);
  16. }
复制代码

效果演示

将相应的代码上传到每个Arduino开发板。 两个Arduino开发板都可以使用电池组供电。 开机后几分钟,您应该会在LCD上看到温度和湿度数据。


433MHz发射器和接收器模块的范围通常很小,但是通过焊接外部天线,它们的通讯范围可以增大。以上就是本文的所有内容,如有任何疑问,请随时在本帖下面进行回复。

跳转到指定楼层
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

主题 700 | 回复: 1479



手机版|

GMT+8, 2024-3-29 07:40 , Processed in 0.148595 second(s), 6 queries , Gzip On, MemCache On. Powered by Discuz! X3.5

YiBoard一板网 © 2015-2022 地址:河北省石家庄市长安区高营大街 ( 冀ICP备18020117号 )

快速回复 返回顶部 返回列表