找回密碼
 立即注冊(cè)

QQ登錄

只需一步,快速開始

搜索
查看: 4329|回復(fù): 0
打印 上一主題 下一主題
收起左側(cè)

使用Processing+Arduino寫的類似雷達(dá)掃描效果

[復(fù)制鏈接]
跳轉(zhuǎn)到指定樓層
樓主
今天給大家?guī)淼氖怯肞rocessing+Arduino做的一個(gè)類似雷達(dá)掃描的效果。
先看效果圖

前不久看到過一個(gè)國(guó)外的人做的一個(gè)雷達(dá)掃描效果,用的是arduino + processing 做的。processing來顯示雷達(dá)掃描效果以及障礙物、arduino用來控制舵機(jī)和超聲波測(cè)距模塊。所以就有樣學(xué)樣的做了一個(gè)。
需要的東西:
arduino uno板子一塊
超聲波測(cè)距模塊一個(gè)
小型舵機(jī)一個(gè)
杜邦線若干。
固定超聲波測(cè)距模塊到舵機(jī)上。大家可以用超聲波模塊的支架或者自己動(dòng)手用硬紙片和膠水粘貼的方式
舵機(jī)是用的180度的舵機(jī)。
思路就是 在arduino里 控制舵機(jī)。從0度 到180度。每次增加1度角度 如果當(dāng)前角度到了180度。則從下次開始。每次角度減1
效果就是 舵機(jī)從左向右慢慢旋轉(zhuǎn)、轉(zhuǎn)到右側(cè)、再?gòu)挠覀?cè)慢慢向左旋轉(zhuǎn)。來回的這樣。就像是一個(gè)雷達(dá)在掃描前方的180度范圍內(nèi)的障礙物。
每次角度改變之后、同時(shí)超聲波測(cè)距一次、 全局變量保存當(dāng)前的角度和當(dāng)前角度的前方的距離。
流程是 改變舵機(jī)角度 +-1度 -> 超聲波測(cè)距 -> 像串口發(fā)送當(dāng)前的角度和超聲波測(cè)距得到的距離。 角度是從0~180度 距離是從 2~ 300~400 厘米(cm) 左右 這個(gè)要看具體的超聲波測(cè)距模塊的參數(shù)。
processing 接受到串口的數(shù)據(jù)。解析出來角度和距離。 將這個(gè)數(shù)據(jù)。放入數(shù)組中的對(duì)應(yīng)角度下標(biāo)值為這個(gè)角度的距離。
然后processing每次循環(huán)。都重新繪制界面。繪制當(dāng)前角度的掃描扇形 取出數(shù)組中所有的數(shù)據(jù)。 再轉(zhuǎn)換一下比例。再計(jì)算一下障礙物的坐標(biāo)。繪制障礙物。
流程就是這樣。具體的實(shí)現(xiàn)?梢钥纯闯绦蚶锩。
processing的效果大概是這樣的。


arduino程序方面。
首先。每次讓舵機(jī)轉(zhuǎn)動(dòng)1度。從0~180 當(dāng)?shù)?80時(shí)。再反向轉(zhuǎn)回去。就是從180度再每次減少1度。

部分代碼:

//當(dāng)前角度

int mAngleNum = 0;

//當(dāng)前是正向旋轉(zhuǎn)還是反向旋轉(zhuǎn)

char mFront = 0;


//設(shè)置舵機(jī)當(dāng)前的角度

mServo.write(180 - mAngleNum);


if( mFront == 0 )

  {

    mAngleNum ++;

    if( mAngleNum > 180 )

    {

      mFront = 1;

    }

  }

  else

  {

    mAngleNum --;

    if( mAngleNum < 0 )

    {

      mFront = 0;

    }

  }


這里。實(shí)現(xiàn)了從 180度開始。每次減少1度。直到0度。然后開始從0度往180度增加。每次增加1度。

然后接下來。我們就需要 在每次舵機(jī)旋轉(zhuǎn)的時(shí)候。我們進(jìn)行超聲波測(cè)距。


//當(dāng)前距離

int mDistance = 0;

//超聲波測(cè)距引腳

const int mTrigPin = 2;

const int mEchoPin = 3;

pinMode(mTrigPin, OUTPUT);

// 要檢測(cè)引腳上輸入的脈沖寬度,需要先設(shè)置為輸入狀態(tài)

pinMode(mEchoPin, INPUT);

// 產(chǎn)生一個(gè)10us的高脈沖

digitalWrite(mTrigPin, LOW);

delayMicroseconds(2);

digitalWrite(mTrigPin, HIGH);

delayMicroseconds(10);

digitalWrite(mTrigPin, LOW);

mDistance = pulseIn(mEchoPin, HIGH) / 58.0; //將回波時(shí)間換算成cm

這里。我們就是測(cè)試當(dāng)前的距離。然后同時(shí)每次改變角度。都測(cè)試一次當(dāng)前距離。我們每次改變角度、測(cè)試距離之后。都把我們的當(dāng)前角度和距離。送給processing 讓processing知道我們的當(dāng)前狀態(tài)。然后。processing 方面。我們需要一直不停的接受 arduino傳遞過來的當(dāng)前硬件的狀態(tài)數(shù)據(jù)(就是當(dāng)前的角度和當(dāng)前前方的距離)我這里設(shè)計(jì)的是。只測(cè)試前方180度的1.5m范圍內(nèi)的障礙物。好了。我們繼續(xù)。我們?cè)趐rocessing中。一直去查找數(shù)據(jù)。每次找到數(shù)據(jù)后。都把數(shù)據(jù)進(jìn)行組裝以及拆分。原因就是。我們傳遞的數(shù)據(jù)比較多。不是單一的數(shù)據(jù)。所以我們要區(qū)分我們具體每個(gè)數(shù)據(jù)。同時(shí)還要區(qū)分。多個(gè)數(shù)據(jù)的連續(xù)和間斷問題。就是如何去讀取和解析一個(gè)完整的數(shù)據(jù)包(包含當(dāng)前角度和當(dāng)前距離的一段數(shù)據(jù)) 首先我們需要在draw()里 每次都要讀取數(shù)據(jù)。當(dāng)然這里每次讀取的都是一個(gè)int類型的數(shù)據(jù)。其實(shí)他是一個(gè)byte或者說是一個(gè)字節(jié)。也就是8個(gè)二進(jìn)制 也同樣是一個(gè)C語言里的char 還同樣是一個(gè)ASCII 當(dāng)然關(guān)于是否是unsigned之類的就先不說了。我們只要知道read()一次 讀取出來的是個(gè)8個(gè)二進(jìn)制位表示出來的數(shù)據(jù) 就夠了。當(dāng)然他是用int類型來存放的

if ( myPort.available() > 0) {

  val = myPort.read();      }。我們這里沒有真的用數(shù)據(jù)包的方式去處理的。而是用每次read之后。我把數(shù)據(jù)存放在181個(gè)int的數(shù)組中。因?yàn)榻嵌仁菑?到180度。有181個(gè)數(shù)據(jù).....然后。在draw() 中。每次都清空畫布。然后重新繪制背景、然后繪制當(dāng)前掃描效果的扇形。然后繪制當(dāng)前的障礙物。畫布設(shè)置:int mWidth = 600;

int mHeight = 300;

設(shè)置300的原因是方便計(jì)算。我準(zhǔn)備掃描1.5米以內(nèi)的同時(shí)180度的范圍。所以可以設(shè)置成 寬度 1.5m * 2 = 150cm * 2 = 300cm, 高度1.5m = 150cm 。也可以設(shè)置成這個(gè)數(shù)據(jù)的一倍。就是 600cm, 300cm 或者兩倍。三倍。由于屏幕寬度高度的原因。我就設(shè)置成了600,300。然后,我們每次繪制出來畫布。就開始根據(jù)當(dāng)前角度。來繪制一個(gè)半透明的內(nèi)部填充的扇形。我吧當(dāng)前角度 放到了扇形的中間。最后。根據(jù)181個(gè)int的數(shù)組。吧181個(gè)角度的障礙物的距離。繪制到屏幕上。當(dāng)然 超出100cm或者少于5cm的都沒有繪制。當(dāng)然大家也可以自己回去改成 150cm 10cm之類的。

下面發(fā)一下繪制障礙物的具體代碼:

  1. for( int i = 0; i < 181; i ++ )
  2.   {
  3.     int a, b, distance;
  4.     distance = a = b = mDistanceArr[i];

  5.     if( i - 1 >= 0 )
  6.       a = mDistanceArr[ i - 1 ];
  7.     if( i + 1 <= 180 )
  8.       b = mDistanceArr[ i + 1 ];
  9.     if( distance < 5 || distance > mMaxDistance ) continue;
  10.     if( a < 5 || a > mMaxDistance ) a = distance;
  11.     if( b < 5 || b > mMaxDistance ) b = distance;

  12.     distance = (a + b + distance) / 3;

  13.     if( distance < 5 || distance >= mMaxDistance ) continue;
  14.     //distance = 60 angle = 45;
  15.     //mWidth / 2;
  16.     float scale = mWidthHalf / mMaxDistance;

  17.     int tmpDistance = (int)(distance * scale);


  18.     int px = (int)(mWidthHalf - tmpDistance * cos(i * PI/180));
  19.     int yy = (int)(tmpDistance * sin(i * PI/180));
  20.     int py = 300 - yy;
  21.     println("scale:" + scale + " angle:" + i + " sin():" + sin(i * PI/180) + " distance:" + distance + " tmpDistance:" + tmpDistance + " x:" + px + " yy:" + yy + " py:" + py);

  22.     ellipse(px, py, 30, 30);
  23.   }
復(fù)制代碼



Y~@MA3@]21_TG0[C3SQDV`X.png (25.39 KB, 下載次數(shù): 161)

Y~@MA3@]21_TG0[C3SQDV`X.png

C]_G{P[4@C1UVUNAQB6$6BJ.png (25.56 KB, 下載次數(shù): 97)

C]_G{P[4@C1UVUNAQB6$6BJ.png

評(píng)分

參與人數(shù) 1黑幣 +50 收起 理由
admin + 50 共享資料的黑幣獎(jiǎng)勵(lì)!

查看全部評(píng)分

分享到:  QQ好友和群QQ好友和群 QQ空間QQ空間 騰訊微博騰訊微博 騰訊朋友騰訊朋友
收藏收藏1 分享淘帖 頂 踩
回復(fù)

使用道具 舉報(bào)

本版積分規(guī)則

手機(jī)版|小黑屋|51黑電子論壇 |51黑電子論壇6群 QQ 管理員QQ:125739409;技術(shù)交流QQ群281945664

Powered by 單片機(jī)教程網(wǎng)

快速回復(fù) 返回頂部 返回列表