在制作基于微控制器的項目時,有時會需要在兩個設備之間進行通信,要么是基于雙工/收發器的操作(兩個設備都可以同時發送和接收),要么是基于半雙工的操作,其中通信是一個單向的(正在接收的設備無法發送,以及正在發送數據的設備無法接收)。
有很多方式可以實現上述兩種通信模式中的任何一種,并且這些選擇通常取決于項目的需求,尤其是設備之間的距離和成本。對于兩個微控制器之間的短距離、低預算的通信方式,其中一種最優選使用的方式是使用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上顯示。與往常一樣,我們將對這兩個項目的代碼進行簡要說明。
發射器的代碼
首先包含將在代碼中使用的庫。
//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發射器和接收器模塊的范圍通常很小,但是通過焊接外部天線,它們的通訊范圍可以增大。
編輯:hfy
-
微控制器
+關注
關注
48文章
7542瀏覽量
151316 -
接收器
+關注
關注
14文章
2468瀏覽量
71873 -
發射器
+關注
關注
6文章
848瀏覽量
53451
發布評論請先 登錄
相關推薦
評論