搡BBBB推BBBB推BBBB,老牛A片在线精品免费观看,国产在线观看无遮挡无码Av多人,国产一国产一本到免费,国产一级a毛一级a看免费视频

激光測距傳感器自制方法大公開!讓你輕松DIY

  • 時間:2024-06-16 00:25:06
  • 點擊:0

在科技日新(xin)月(yue)異的(de)(de)時代(dai),越(yue)來(lai)越(yue)多的(de)(de)智能設備走進我們(men)(men)的(de)(de)生活(huo)(huo)。今天(tian),我們(men)(men)要分享的(de)(de)是一種非(fei)常實用(yong)的(de)(de)設備——激光測(ce)距(ju)傳感器的(de)(de)自(zi)制方(fang)法。通過這個方(fang)法,你(ni)不僅可以(yi)節(jie)省(sheng)購買成(cheng)本,還(huan)可以(yi)發揮自(zi)己的(de)(de)創造力,為你(ni)的(de)(de)家(jia)居生活(huo)(huo)增添更多樂(le)趣。下(xia)面就讓我們(men)(men)一起來(lai)了解一下(xia)吧!

一、所需材料

1. 激光測距傳感器(qi)

2. Arduino開發板(ban)(如Arduino UNO)

3. 杜邦線若干

4. 面包板

5. 其他電(dian)(dian)子(zi)元件(如(ru)電(dian)(dian)阻、電(dian)(dian)容等)

6. 外殼(ke)(用于安裝(zhuang)傳(chuan)感(gan)器和(he)電路板)

二、制作步驟

1. 準(zhun)(zhun)備(bei)工作:首先,我們(men)需(xu)要準(zhun)(zhun)備(bei)一(yi)(yi)(yi)個面包板(ban),將Arduino開(kai)發(fa)板(ban)放在(zai)面包板(ban)上,然后(hou)在(zai)開(kai)發(fa)板(ban)周圍(wei)固定一(yi)(yi)(yi)圈杜(du)邦線,以便(bian)焊接其他電子(zi)元(yuan)件。接下來(lai),準(zhun)(zhun)備(bei)一(yi)(yi)(yi)個外殼,可以是一(yi)(yi)(yi)個簡單的紙盒或者購買一(yi)(yi)(yi)個專門的外殼。

2. 接線(xian):將激(ji)光(guang)測距(ju)傳感器(qi)的(de)VCC接到(dao)面包(bao)板(ban)上(shang)(shang)的(de)5V電源(yuan)插座,將GND接到(dao)面包(bao)板(ban)上(shang)(shang)的(de)GND插座,將OUT接到(dao)Arduino的(de)數字引腳(如D3)。此外,還(huan)需要(yao)連接上(shang)(shang)限(xian)位開(kai)關(guan)和驅動(dong)電機的(de)引腳。

3. 編(bian)程(cheng):使用Arduino IDE編(bian)寫程(cheng)序,控制激(ji)光測距(ju)傳(chuan)感器的輸出信號。當(dang)(dang)激(ji)光距(ju)離小于(yu)設定值(zhi)時,限位開(kai)(kai)關觸發,電(dian)機(ji)啟動;當(dang)(dang)激(ji)光距(ju)離大(da)于(yu)設定值(zhi)時,限位開(kai)(kai)關關閉,電(dian)機(ji)停(ting)止。以下是一個簡單的示(shi)例代碼:

```cpp

#include

const int distancePin = 3; // 激光測距傳感(gan)器連接的數字引(yin)腳(jiao)

const int limitSwitchPin = A0; // 限位開(kai)關連接的模(mo)擬引腳(jiao)

const int motorPin = 9; // 電機(ji)驅(qu)動器連接的數字引腳(jiao)

Servo myservo; // 創(chuang)建一(yi)個舵機對象

int targetDistance = 10; // 目標距(ju)離,可以根據需要調整(zheng)

int currentDistance; // 當前距離(li)

bool isLimitSwitchOpen = false; // 限位開(kai)關是(shi)否打(da)開(kai)的標(biao)志

void setup() {

pinMode(distancePin, INPUT); // 設置(zhi)激光測(ce)距傳感器引腳(jiao)為輸入模式

pinMode(limitSwitchPin, INPUT); // 設置限位(wei)開關引腳為輸入模式

myservo.attach(motorPin); // 將舵機連接到電機驅動器

}

void loop() {

currentDistance = analogRead(distancePin); // 讀取(qu)激(ji)光測距傳感器(qi)的輸出值(單位:厘米(mi))

if (currentDistance < targetDistance && !isLimitSwitchOpen) { // 當距離小于目標距離且限位開關未觸發時

myservo.write(90); // 電(dian)機轉(zhuan)動到(dao)最右邊(bian)的位置

} else if (currentDistance > targetDistance && isLimitSwitchOpen) { // 當距離(li)大于目標距離(li)且限位開(kai)關已觸(chu)發時(shi)

myservo.write(0); // 電機(ji)轉動到最左邊的位(wei)置

} else if (currentDistance > targetDistance && isLimitSwitchOpen == false) { // 當距(ju)離大于目(mu)標(biao)距(ju)離且(qie)限位開關未觸發時(即到達(da)目(mu)標(biao)位置)

delay(500); // 等待500毫(hao)秒,讓電機有時間停止

myservo.write(0); // 將舵機設置為初始位置(最左邊)

} else if (currentDistance <= targetDistance && isLimitSwitchOpen == true) { // 當距離小于等于目標距離且限位開關已觸發時(即未到達目標位置)

int stepsToTarget = map(currentDistance, 0, targetDistance + 1, -90, 180); // 計算到達目標位置需要轉動的角度范圍(wei)(單位:度)

int currentSteps = map(myservo.read(), 0, 180, 0, stepsToTarget); // 根據當(dang)前舵(duo)機(ji)角度(du)計算還(huan)需(xu)要轉動的角度(du)范圍(單位(wei):度(du))

int newSteps = min(currentSteps + stepSpeed * (analogRead(limitSwitchPin) == HIGH), stepsToTarget); // 根據限位開(kai)關狀態更(geng)新還需(xu)要轉(zhuan)動的(de)角(jiao)度(du)范圍(單位:度(du))

int stepsToTake = abs(newSteps - currentSteps); // 需要轉動的(de)步數

int direction = newSteps < currentSteps; // 是向前還是向后轉動方向的標志

int delayTime = direction == true ? delayBeforeForwarding * stepsToTake * stepSpeed * (stepsToTake * stepSpeed >= stepsToTarget + delayAfterForwarding * stepSpeed) + delayBetweenForwardingAndBackwarding * (stepsToTake % (stepsToTarget + delayBetweenForwardingAndBackwarding)) * stepSpeed : delayBeforeBackwarding * stepsToTake * stepSpeed * (stepsToTake * stepSpeed <= stepsToTarget + delayAfterBackwarding * stepSpeed) + delayBetweenBackwardingAndForwarding * (stepsToTake % (stepsToTarget + delayBetweenBackwardingAndForwarding)) * stepSpeed; // 根據新的步數和方向計算延時時間(單位:毫秒)

int delayCount = delayTime; // 需(xu)要(yao)延(yan)時的次數,用于微調延(yan)時時間

int lastDirection = direction; // 為了判(pan)斷(duan)是否需要調整轉(zhuan)向方向,記錄上一(yi)次的轉(zhuan)向方向

int counter = delayTime; // 為了判斷是否已(yi)經(jing)完成延時,記(ji)錄當前延時次數

while (delayCount > counter && counter >= delayStartValue) { // 當延(yan)(yan)時(shi)(shi)時(shi)(shi)間大(da)于(yu)等于(yu)開(kai)始(shi)延(yan)(yan)時(shi)(shi)的值(zhi)且延(yan)(yan)時(shi)(shi)次數大(da)于(yu)等于(yu)開(kai)始(shi)延(yan)(yan)時(shi)(shi)的值(zhi)時(shi)(shi)執(zhi)行循環(huan)體

int angle = map(direction == true ? currentSteps + counter * stepSpeed * lastDirection == newSteps * lastDirection == false && counter % (stepsToTarget + delayBetweenForwardingAndBackwarding) == false && counter % (stepsToTarget + delayBetweenBackwardingAndForwarding) == false && counter >= delayBeforeForwarding * stepSpeed && counter <= delayAfterForwarding * stepSpeed && lastDirection != true && counter >= delayBetweenForwardingAndBackwarding && counter <= delayBetweenBackwardingAndForwarding || counter >= stepsToTarget + delayBeforeBackwarding * stepSpeed && counter <= stepsToTarget + delayAfterBackwarding * stepSpeed && lastDirection == true && counter >= delayBetweenBackwardingAndForwarding && counter <= delayBetweenBackwardingAndForwarding || counter >= stepsToTarget + delayBeforeForwarding * stepSpeed && counter <= stepsToTarget + delayAfterForwarding * stepSpeed && lastDirection == false && counter >= delayBetweenForwardingAndBackwarding && counter <= delayBetweenForwardingAndBackwarding || counter >= stepsToTarget + delayBeforeBackwarding * stepSpeed && counter <= stepsToTarget + delayAfterBackwarding * stepSpeed && lastDirection == true && counter >= delayBetweenBackwardingAndForwarding && counter <= delayBetweenBackwardingAndForwarding || counter >= stepsToTarget + delayBeforeForwarding * stepSpeed && counter <= stepsToTarget + delayAfterForwarding * stepSpeed && lastDirection == false && counter >= delayBetweenForwardingAndBackwarding && counter <= delayBetweenForwardingAndBackwarding || lastDirection != direction && counter >= delayBetweenReverse*stepSpeed && counter <= delayAfterReverse*stepSpeed, true, false) * stepSpeed; // 根據當前轉向方向和延時時間計算舵機轉動的角度范圍(單位:度)

int servoAngle = map(angle + getRotationOffset(), minDegrees, maxDegrees, minPositionDeg, maxPositionDeg); // 根據舵機轉動的范圍(wei)(wei)映射到實際(ji)的角度范圍(wei)(wei)(單位:度)

int positionInc = map((direction == true && servoAngle > minPositionDeg), true, false)[0] == true || map((direction == false && servoAngle < maxPositionDeg), true, false)[0] == true || map((lastDirection != direction), true, false)[0] == true; // 根據轉向方向判斷是否需要增加或減少舵機的角度范圍(單位:布爾值)

int positionDecayFactor = map((lastDirection != direction), true, false)[0]; // 根據轉(zhuan)向(xiang)(xiang)方向(xiang)(xiang)確定(ding)衰(shuai)減因(yin)子(用(yong)于調整舵機轉(zhuan)動速(su)度(du))

int positionDecayDelayCounter = map((lastDirection != direction), true, false)[0]; // 根(gen)據轉向方(fang)向記(ji)錄衰減延遲計數器(用于微調(diao)延時時間)

int speedAdjustment = positionInc == true || positionDecayFactor == true || lastDirection != direction || positionDecayDelayCounter < decayDelayCounter; // 根據上述條件判斷是否需要調整舵機的轉動速度和方向或進行衰減延遲處理(布爾值列表)

String command = ""; // 根(gen)據上述條件生成控(kong)制(zhi)命(ming)令(ling)字符串(僅在需要調整舵機(ji)的(de)轉動速度和方向(xiang)或進(jin)行衰減延(yan)遲處理時使用)

String servoCmd = ""; // 根據上述條件生(sheng)成(cheng)舵機控(kong)制命令字符串(僅在需要調(diao)整(zheng)舵機的(de)轉(zhuan)動速(su)度和方向(xiang)或進行(xing)衰減延遲

推薦產品