在嵌入式電子產品中制作無線項目變得非常重要和有用,因為沒有雜亂的電線,這使得設備更加方便和便攜。有各種無線技術,例如藍牙、WiFi、433 MHz RF(射頻)等。每種技術都有其自身的優(yōu)缺點,例如成本、距離或范圍傳輸、速度或吞吐量等。今天我們將使用STM32 的射頻模塊以無線方式發(fā)送和接收數(shù)據(jù)。
在這里,我們將連接一個 433MHz 射頻無線模塊與 STM32F103C8 微控制器。該項目分為兩部分。發(fā)送器將與 STM32 連接,接收器將與 Arduino UNO 連接。發(fā)射和接收部分都會有不同的電路圖和草圖。
在本教程中,RF 發(fā)射器向接收器端發(fā)送兩個值:使用超聲波傳感器測量的距離和電位計ADC值(0 到 4096),該值映射為(0 到 100)之間的數(shù)字。Arduino的RF 接收器接收這兩個值并以無線方式在16x2 LCD 顯示器中打印這些距離和數(shù)字值。
所需組件
STM32F103C8微控制器
Arduino UNO
433Mhz 射頻發(fā)射器和接收器
超聲波傳感器 (HC-SR04)
16x2 液晶顯示器
10k 電位器
面包板
連接電線
433Mhz 射頻發(fā)射器和接收器模塊)
射頻發(fā)射器引腳:
射頻接收器引腳:
433 MHz 模塊規(guī)格:
接收器工作電壓:3V 至 5V
發(fā)射器工作電壓:3V 至 5V
工作頻率:433 MHz
傳輸距離:3米(不帶天線)至100米(最大)
調制技術:ASK(幅移鍵控)
數(shù)據(jù)傳輸速度:10Kbps
STM32F103C8射頻發(fā)射器電路圖
射頻發(fā)射器和 STM32F103C8 之間的電路連接:
超聲波傳感器和 STM32F103C8 之間的電路連接:
STM32F103C8 連接一個10k 電位器,為 STM32 的 ADC 引腳 PA0 提供輸入模擬值(0 至 3.3V)。
帶有Arduino Uno的RF接收器電路圖
射頻接收器和 Arduino UNO 之間的電路連接:
16x2 LCD 和 Arduino UNO 之間的電路連接:
下面將簡要解釋編碼。草圖將分為兩部分,第一部分是發(fā)射器部分,另一部分是接收器部分。所有草圖文件和工作視頻將在本教程結束時提供。要了解有關射頻模塊與 Arduino Uno 接口的更多信息,請點擊鏈接。
為無線射頻傳輸編程STM32F103C8
STM32F103C8 可以使用 Arduino IDE 進行編程。無需 FTDI 編程器或 ST-Link即可將代碼上傳到 STM32F103C8。只需通過 STM32 的 USB 端口連接到 PC 并開始使用ARDUINO IDE進行編程。
首先包含 Radiohead 庫,可以從這里下載。因為這個庫使用 ASK(幅移鍵控技術)來傳輸和接收數(shù)據(jù)。這使得編程非常容易。您可以通過進入 Sketch->include library->Add .zip library 在草圖中包含庫。
#include
正如在發(fā)射器端的本教程中一樣,超聲波傳感器用于測量距離,因此定義了觸發(fā)和回波引腳。
#define trigPin PB1 #define echoPin PB0
接下來,將 RH_ASK 庫的對象名稱設置為 rf_driver,并使用諸如速度 (2000)、RX 引腳 (PA9) 和 TX 引腳 (PA10) 等參數(shù)。
RH_ASK rf_driver(2000, PA9, PA10);
接下來,聲明該程序所需的 Strings 變量。
字符串傳輸號碼; 字符串傳輸距離; 字符串傳輸;
接下來在 void setup() 中,初始化 RH_ASK rf_driver 的對象。
rf_driver.init();
之后觸發(fā)引腳設置為 OUTPUT 引腳,PA0(連接到電位器)和回波引腳設置為 INPUT 引腳。串行通信以 9600 的波特率開始。
序列號.開始(9600); pinMode(PA0,輸入); pinMode(echoPin,輸入); pinMode(trigPin,輸出);
接下來在 void loop() 中,首先將輸入模擬電壓的電位器值轉換為數(shù)字值(找到 ADC 值)。由于STM32 的 ADC具有 12 位分辨率。因此,數(shù)字值從 (0 到 4096) 變化,映射到 (0 到 100)。
int 模擬輸入 = 模擬讀?。≒A0); int pwmvalue = map(模擬輸入,0,4095,0,100);
接下來,使用超聲波傳感器測量距離,方法是設置觸發(fā)器高低,延遲 2 微秒。
數(shù)字寫入(trigPin,低); 延遲微秒(2); digitalWrite(trigPin, HIGH); 延遲微秒(10); 數(shù)字寫入(trigPin,低);
回波針感測反射回來的波,即觸發(fā)波反射回來的持續(xù)時間用于使用公式計算物體的距離。通過點擊鏈接了解更多超聲波傳感器如何計算距離。
持續(xù)時間長 = pulseIn(echoPin, HIGH); 浮動距離=持續(xù)時間*0.034/2;
現(xiàn)在測量的數(shù)據(jù)數(shù)量和距離都轉換為字符串數(shù)據(jù)并存儲在相應的字符串變量中。
傳輸數(shù)=字符串(pwm值); 傳輸距離 = 字符串(距離);
兩個字符串都作為一行添加并存儲在稱為傳輸?shù)淖址校禾枴?,”用于分隔兩個字符串。
傳輸=傳輸_pwm +“,”+傳輸距離;
傳輸字符串被轉換為字符數(shù)組。
const char *msg = transmit.c_str();
數(shù)據(jù)被傳輸并等待直到它被發(fā)送。
rf_driver.send((uint8_t *)msg, strlen(msg)); rf_driver.waitPacketSent();
發(fā)送的字符串數(shù)據(jù)也顯示在串行監(jiān)視器中。
序列號.println(msg);
將 Arduino UNO 編程為 RF 接收器
Arduino UNO 使用 Arduino IDE 進行編程。在接收器部分,從發(fā)射器部分發(fā)送并由 RF 接收器模塊接收的數(shù)據(jù)和接收到的字符串數(shù)據(jù)被拆分為各自的數(shù)據(jù)(距離和數(shù)量)并顯示在 16x2 LCD 顯示屏上。
讓我們簡要地看一下接收器編碼:
就像在發(fā)射器部分一樣,首先包含 RadiohHead 庫。因為這個庫使用 ASK(幅移鍵控技術)來傳輸和接收數(shù)據(jù)。這使得編程非常容易。
#include
由于這里使用的是 LCD 顯示器,所以還包括了液晶庫。
#include
與 Arduino UNO 連接的 16x2 LCD 顯示引腳使用 lcd 作為對象指定和聲明。
液晶液晶(2,3,4,5,6,7);
接下來聲明用于存儲字符串數(shù)據(jù)的字符串數(shù)據(jù)變量。
字符串 str_receive; 字符串 str_number; 字符串 str_distance;
Radiohead 庫的對象已聲明。
RH_ASK 射頻;
現(xiàn)在在void setup() 中,LCD 顯示設置為 16x2 模式,并顯示并清除歡迎消息。
lcd.開始(16,2); lcd.print("電路文摘"); lcd.setCursor(0,1); lcd.print("STM32 射頻"); 延遲(5000); lcd.clear();
之后,初始化rf對象。
rf.init();
現(xiàn)在在void loop() 中,數(shù)組 buf[] 被聲明為大小為 7。因為從發(fā)送器發(fā)送的數(shù)據(jù)有 7,包括“,”。因此,根據(jù)要傳輸?shù)臄?shù)據(jù)進行更改。
uint8_t buf[7]; uint8_t buflen = sizeof(buf);
如果該字符串在 rf 接收器模塊中可用,則 if 函數(shù)會檢查大小并執(zhí)行。rf.recv()用于接收數(shù)據(jù)。
如果 (rf.recv(buf, &buflen))
buf具有接收到的字符串,因此接收到的字符串存儲在str_receive字符串變量中。
str_receive = String((char*)buf);
如果檢測到兩個字符串之間的“,”,則此for循環(huán)用于將接收到的字符串分成兩部分。
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 數(shù)組,通過將字符串轉換為字符數(shù)組,將分成兩個的字符串存儲在相關數(shù)組中。
字符數(shù)串[4]; 字符距離字符串[3]; str_distance.toCharArray(distancestring,3); str_number.toCharArray(numberstring,3);
之后使用 atoi() 將字符數(shù)組轉換為整數(shù)
int 距離 = atoi(距離字符串); int number = atoi(numberstring);
轉換成整數(shù)值后,距離和數(shù)字值顯示在 16x2 LCD 顯示屏中
lcd.setCursor(0,0); lcd.print("編號:"); lcd.print(數(shù)字); lcd.setCursor(0,1); lcd.print("距離:"); lcd.print(距離); lcd.print("cm");
分別在STM32和Arduino UNO中上傳發(fā)射器和接收器代碼后,使用STM32測量的數(shù)字和物體距離等數(shù)據(jù)通過RF發(fā)射器傳輸?shù)絉F接收器,接收到的值以無線方式顯示在LCD顯示屏上。
測試基于 STM 32 的射頻發(fā)射器和接收器
1.當數(shù)字為0且物體距離為6cm時。
2.當數(shù)字47和物體距離為3cm時。
發(fā)射器代碼(STM32F103C8):
//433MHZ射頻發(fā)射器與STM32F103C8
//發(fā)射機代碼
//電路文摘
#include
#define trigPin PB1 //設置超聲波傳感器的Trigpin為PB1
#define echoPin PB0 //設置超聲波傳感器的echoPin為PB0
RH_ASK rf_driver(2000, PA9, PA10); //設置引腳PA9為接收器,PA10為發(fā)送器,2000為速度
字符串傳輸_pwm;//存儲字符串值的字符串
字符串傳輸距離;
字符串傳輸;
無效設置()
{
// 初始化 ASK 對象
rf_driver.init();
序列號.開始(9600);
pinMode(PA0,輸入);
pinMode(echoPin,輸入);
pinMode(trigPin,輸出);
}
無效循環(huán)()
{
int 模擬輸入 = 模擬讀?。≒A0);// 來自連接到電位器的引腳 PA0 的 ADC 值
int pwmvalue = map(模擬輸入,0,4096,0,100);// 將 0 到 4096 轉換為 0 到 100
數(shù)字寫入(trigPin,低);//將超聲波的TrigPin設為LOW
延遲微秒(2);
digitalWrite(trigPin, HIGH); //使Ultrasonic HIGH的TrigPin
延遲微秒(10);
數(shù)字寫入(trigPin,低);//將超聲波的TrigPin設為LOW
持續(xù)時間長 = pulseIn(echoPin, HIGH); //接收反射的Echo信號
浮動距離=持續(xù)時間*0.034/2;//計算對象的CM距離
傳輸_pwm =字符串(pwm值);//將值轉換為字符串
傳輸距離 = 字符串(距離);//將值轉換為字符串
傳輸=傳輸_pwm +“,”+傳輸距離;//在一行中添加兩個字符串
const char *msg = transmit.c_str(); //
rf_driver.send((uint8_t *)msg, strlen(msg)); //發(fā)送字符串
rf_driver.waitPacketSent();
序列號.println(msg); //用于調試的串行打印值
延遲(1000);
}
接收器代碼(Arduino UNO):
//接收器Arduino代碼
//433MHZ射頻,STM32F103C8作為發(fā)射器
//電路文摘
#include
#include
液晶液晶(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(); //初始化射頻對象
}
無效循環(huán)()
{
uint8_t buf[7];
uint8_t buflen = sizeof(buf);
如果 (rf.recv(buf, &buflen))
{
str_receive = String((char*)buf); // 從發(fā)送器接收字符串
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);
休息;
}
}
字符數(shù)串[4];
字符距離字符串[3];
str_distance.toCharArray(distancestring,3); //將字符串轉換為字符數(shù)組
str_number.toCharArray(numberstring,3);
int 距離 = atoi(距離字符串);//將數(shù)組轉換成整數(shù)值
int number = atoi(numberstring);
lcd.setCursor(0,0);
lcd.print("編號:");
lcd.print(數(shù)字); //在LCD顯示屏上顯示數(shù)值
lcd.setCursor(0,1);
lcd.print("距離:");
lcd.print(距離);//在液晶顯示屏上顯示距離值
lcd.print("cm");
延遲(1500);
lcd.clear();
}
}
-
微控制器
+關注
關注
48文章
7555瀏覽量
151429 -
STM32
+關注
關注
2270文章
10900瀏覽量
356087 -
射頻模塊
+關注
關注
5文章
82瀏覽量
19734 -
STM32F103C8
+關注
關注
1文章
23瀏覽量
8089
發(fā)布評論請先 登錄
相關推薦
評論