JSN-SR0T4-2.0 超聲波測距模塊可提供 20cm-600cm 的非接觸式距離感測功能,測距精度可達高到 2mm,採用工業級一體化超聲波探頭設計,防水型,性能穩定,兼容市場上所有的 MCU 工作。
基本原理
作爲超聲波測距模塊,本模塊與HC-SR04雷同,二者可相互作爲參考。
(JSN-SR04T和HC-SR04似乎是同一家公司的產品,其中,JSN-SR04T的模式一與HC-SR04的基本使用相兼容)
超聲波測距模塊,原理自然而然就是超聲波測距,通過計算超聲波在空氣中經過的路程來測量距離,具體原理爲:
對模塊的Trig引腳發送一個持續時間不小於10us的高電平脈衝作爲觸發信號,當模塊接收到觸發信號後,模塊內部向外界發出8個40kHz的超聲波脈衝,同時Echo引腳由0置1。當超聲波脈衝遇到被測障礙物並反射回測距模塊時,Echo引腳電平由1置0,一次測距結束。通過計算Echo引腳高電平持續時間即可求得超聲波傳輸時間,進而求解出所測距離。
.
.
.
代碼思路
代碼思路有兩種,一種是通過定時器的輸入捕獲來計算時間,另一種是通過外部中斷結合定時器的開閉來計算時間,個人覺得第二種比較簡單,故採用第二種。
具體思路爲:
通過MPU不斷控制Trig控制端發送觸發信號,使得模塊處於實時測距狀態,定時器和外部中斷開啓,每當測距模塊向外發送高頻信號時,將觸發Echo引腳的外部中斷,外部中斷中,通過控制定時器的開閉來測量反應時間,從而通過換算得到距離。
.
.
.
部分代碼
初始化函數
簡單對GPIO進行初始化
//initialize the pin of jsn-sr04t
void JSN_SR04T_Init(void)
{
//定義GPIO初始化結構體
GPIO_InitTypeDef GPIO_InitStruct;
//初始化相應IO口時鐘
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOE, ENABLE);
//初始化GPIO參數 引腳Trig,用於輸出一個持續10us的高電平觸發信號,觸發超聲波模塊開始發送超聲波
GPIO_InitStruct.GPIO_Mode = GPIO_Mode_OUT;
GPIO_InitStruct.GPIO_OType = GPIO_OType_PP; //這裏的推輓是針對輸出的
GPIO_InitStruct.GPIO_Pin = GPIO_Pin_0;
GPIO_InitStruct.GPIO_Speed = GPIO_High_Speed; //速度是針對輸出的
GPIO_Init(GPIOE, &GPIO_InitStruct);
//初始化GPIO參數 引腳Echo,用於檢測超聲波的發射/接收狀態
GPIO_InitStruct.GPIO_Mode = GPIO_Mode_IN;
GPIO_InitStruct.GPIO_Pin = GPIO_Pin_1;
GPIO_InitStruct.GPIO_PuPd = GPIO_PuPd_DOWN; //這裏的上拉是針對輸入來說的,下拉先復位,等待高電平
GPIO_Init(GPIOE, &GPIO_InitStruct);
}
.
.
觸發函數
根據模塊工作原理進行簡單的電平處理
//let jsn-sr04t to let out a signal to begin to detecting
void JSN_SR04T_Start(void)
{
GPIO_SetBits(GPIOE,GPIO_Pin_0); //置位
delay_us(10); //持續10us的高電平
GPIO_ResetBits(GPIOE,GPIO_Pin_0); //復位,實現一次觸發超聲波測距模塊
}
.
.
外部中斷響應函數
用於對定時器的控制進而計算反應時間
/*外部中斷用於檢測觸發引腳Echo的狀態:*/
/*當模塊Trig發出一次觸發信號,模塊將向外發送高頻信號,同時Echo將被拉高;當模塊接收到反射回來的高頻信號,Echo將被拉低;*/
/*當Echo被拉高進入外部中斷函數,不斷readBit判斷Echo是否被拉低,從而得到TIM4的持續時間*/
u8 exti_i = 0; //用於表示求和次數
float temp = 0; //用於暫存Distance,以便求和
float Distance; //超聲波測到的距離
float sum = 0; //用於累加Distance,以便求平均
float Distance_error = 0.717; //超聲波測距模塊的系統誤差
//中斷響應函數
void EXTI1_IRQHandler(void)
{
delay_us(10); //延時消抖
if( EXTI_GetITStatus(EXTI_Line1) != RESET )
{
TIM_SetCounter(TIM4,0); //重置計時器的值
TIM_Cmd(TIM4,ENABLE); //使能定時器開始計數
while(GPIO_ReadInputDataBit(GPIOE,GPIO_Pin_1)); //定時器計數的同時,死循環等待低電平,即接收到反射超聲波
TIM_Cmd(TIM4,DISABLE); //失能定時器,定格計數值
//先換算成時間單位秒,然後乘以聲速344得到路程,再除以2得到距離,最後轉換成cm單位
//Distance = TIM_GetCounter(TIM4) * 0.0001f * (344.0f+5.0f*0.607f) * 0.5f + Distance_error; //頻率1Mhz,計數一次爲0.001ms,TIM_GetCounter(TIM4)*(10^-6)*344m/s*0.5*10^2
//通常所指的常溫是指20℃時的氣溫(344m/s),氣溫每升高1℃,聲速就增加0.607m/s //實際拿來計算的值爲:得到的值再加上系統誤差Distance_error
temp = TIM_GetCounter(TIM4) * 0.0001f * (344.0f+5.0f*0.607f) * 0.5f + Distance_error; //頻率1Mhz,計數一次爲0.001ms,TIM_GetCounter(TIM4)*(10^-6)*344m/s*0.5*10^2 //這裏之所以乘的是0.0001是因爲單位換算m換成cm
sum += temp;
exti_i++;
if(exti_i==10)//求和10次之後求平均
{
Distance = sum / 10.0f;
exti_i = 0;
sum = 0;
}
EXTI_ClearITPendingBit(EXTI_Line1); //清除LINE0上的中斷標誌位
}
}
.
.
這樣,main函數裏只要反覆觸發反覆向串口打印測得數據即可:
與HC-SR04模塊的區別
使用這個模塊,一個原因是因爲其一體化防水設計,將主控板和收發器件分離,使得模塊能夠在潮溼甚至多水的環境下正常工作。
另外,HC-SR04測距範圍爲2cm-400cm,較適用於短距離的測距;
而JSN-SR04T的測量範圍爲20cm-600cm,能夠滿足大空間的距離測量;
但是,本模塊的測量角度高達75°,測距時容易受周邊環境的影響;
而 HC-SR04的測量角度爲15°,受周邊環境的影響較小;
如果要對管道內物體的距離進行測量,則要求模塊的測量角度越小越好,否則容易影響模塊的正常使用。