树莓派外设开发之超声波
樹莓派超聲波測距
-
樹莓派Gpio引腳圖:
注意:這里代碼中使用的是wiringPi編碼,圖中GPIO 針腳定義為根據BCM編碼定義
-
超聲波模塊介紹:
接線參考:模塊除了兩個電源引腳外,還有Trig,Echo引腳,這兩個引腳分別接我們開發板的16號端口和
18號端口(物理引腳)
超聲波時序
-
蜂鳴器模塊
1.GND 接地引腳(接樹莓派14號物理引腳)
2.I/O 輸入輸出引腳(接樹莓派11號物理引腳——GPIO 17)
? 3.VCC 接電源引腳(接樹莓派4號物理引腳)
- 相關函數介紹:
使用wiringPi時,你必須在執行任何操作前初始化樹莓派,否則程序不能正常工作。可以調用下表函數之一進行初始化,它們都會返回一個int , 返回 -1 表示初始化失敗。
| int wiringPiSetupGpio (void) | 返回執行狀態,-1表示失敗 | 當使用這個函數初始化樹莓派引腳時,程序中使用的是BCM GPIO 引腳編號表。需要root權限 |
時間控制函數:
| unsigned int micros (void) | 這個函數返回 一個 從你的程序執行 wiringPiSetup 初始化函數(或者wiringPiSetupGpio ) 到 當前時間 經過的 微秒數。 返回類型是unsigned int,最大可記錄 大約71分鐘的時長。 |
| void delay (unsigned int howLong) | 將當前執行流暫停 指定的毫秒數。因為Linux本身是多線程的,所以實際暫停時間可能會長一些。參數是unsigned int 類型,最大延時時間可達49天 |
| void delayMicroseconds (unsigned int howLong) | 將執行流暫停 指定的微秒數(1000微秒 = 1毫秒 = 0.001秒)。 因為Linux本身是多線程的,所以實際暫停時間可能會長一些。參數是unsigned int 類型,最大延時時間可達71分鐘 |
- **gettimeofday(struct timeval tv, struct timezone tz);
gettimeofday函數是Linux系統下標準C函數,在Windows下使用會返回-1錯誤,這個函數返回的是1970年1月1日00:00:00到現在經過的秒數,函數的正常傳入時需要用到兩個參數。其參數tv是保存獲取時間結果的結構體,參數tz用于保存時區結果:struct timezone{int tz_minuteswest;int tz_dsttime;}timezone 參數若不使用則傳入NULL即可,這里還有一個小故事:timeval中的tv_sec是time_t類型的,即long的類型。在32位下為4個字節,能夠表示的最大正整數是2147483647,而這個表示的時間最大能到2038-01-19 03:14:07 (UTC),超過了之后就變為-2147483648,溢出回1901-12-13 20:45:54(UTC),這就是linux2038年的問題。而64位系統下的time_t類型即long類型長度為8個字節,可以用到更多年,這么長的時間完全不用擔心溢出的問題。
代碼如下:
#include <wiringPi.h> #include <stdio.h> #include <sys/time.h> #include <signal.h> #include <stdlib.h>#define Trig 4 //wiringPi庫引腳 #define Echo 5 #define Buzzer 0void ultraInit(void) {pinMode(Echo, INPUT); //設置端口為輸入pinMode(Trig, OUTPUT); //設置端口為輸出pinMode(Buzzer, OUTPUT); //設置端口為輸出digitalWrite(Buzzer, HIGH);//初始化蜂鳴器輸出高電平 }float disHandle(void) {struct timeval tv1; //timeval是time.h中的預定義結構體 其中包含兩個一個是秒,一個是微秒/*struct timeval{time_t tv_sec; //Seconds.suseconds_t tv_usec; //Microseconds.};*/struct timeval tv2;float dis; long start, stop;digitalWrite(Trig, LOW);delayMicroseconds(2);digitalWrite(Trig, HIGH);delayMicroseconds(10); //發出觸發信號digitalWrite(Trig, LOW);while(!(digitalRead(Echo) == 1));gettimeofday(&tv1, NULL); //獲取發出超聲波時間while(!(digitalRead(Echo) == 0));gettimeofday(&tv2, NULL); //獲取接收到超聲波的時間start = tv1.tv_sec * 1000000 + tv1.tv_usec; //微秒級的時間stop = tv2.tv_sec * 1000000 + tv2.tv_usec;dis = (float)(stop - start) / 1000000 * 34000 / 2; //求出距離return dis; }void sighandle(int signum) {digitalWrite(Buzzer, HIGH);printf("quit\n");exit(0); }int main(void) {float dis;signal(SIGINT, sighandle); //信號處理函數,SIGINT信號在用戶鍵入INTR字符(通常是Ctrl-C)時發出if(wiringPiSetup() == -1){ //初始化樹莓派引腳printf("setup wiringPi failed !");return 1;}ultraInit();while(1){dis = disHandle();if(dis < 15){digitalWrite(Buzzer, LOW);printf("distance = %0.2f cm warning! \n",dis);}else{digitalWrite(Buzzer, HIGH);printf("distance = %0.2f cm\n",dis);}delay(500);}return 0; }開始測距當距離小于設定值時,蜂鳴器報警,結束按CTRL+C,利用信號處理函數輸出高電平,并退出。
執行結果:
按Ctrl+c結束后總結
以上是生活随笔為你收集整理的树莓派外设开发之超声波的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: DELL poweredge T630装
- 下一篇: proe5.0零件图添加文字问题