<th id="ddiqb"><progress id="ddiqb"></progress></th>

      <dfn id="ddiqb"><form id="ddiqb"></form></dfn>

      1. <tfoot id="ddiqb"></tfoot>

        公司資訊
        熱銷產(chǎn)品
        最新發(fā)布
        更多內(nèi)容

        用接近開關(guān)測算電機速度,輕松實現(xiàn)精確控制

        • 時間:2024-06-27 12:30:56
        • 點擊:0

        在工業(yè)生產(chǎn)和自動化控制系統(tǒng)中,電機速度的精確測量和控制對于提高生產(chǎn)效率和保證產(chǎn)品質(zhì)量至關(guān)重要。本文將介紹如何利用接近開關(guān)這一簡單而有效的傳感器來實現(xiàn)電機速度的精確測量和控制。

        一、什么是接近開關(guān)?

        接近開關(guān)是一種具有高靈敏度、非接觸式檢測功能的傳感器,當目標物體靠近或離開傳感器時,能夠產(chǎn)生電信號輸出。在電機速度測量中,接近開關(guān)可以安裝在電機的旋轉(zhuǎn)軸上,實時監(jiān)測電機轉(zhuǎn)速,從而實現(xiàn)對電機速度的精確控制。

        二、如何用接近開關(guān)測算電機速度?

        1. 準備工具和材料

        為了使用接近開關(guān)測量電機速度,我們需要準備以下工具和材料:

        - 一臺帶有編碼器的電機

        - 一個接近開關(guān)傳感器

        - 一塊微控制器(如Arduino)

        - 一根杜邦線

        - 一個電源適配器

        - 一些基本的電子元件(如電阻和電容)

        2. 連接電路

        將接近開關(guān)傳感器的信號線、電源線和地線分別連接到微控制器的相應(yīng)引腳上。具體連接方式如下:

        - 將接近開關(guān)的VCC接到微控制器的5V引腳

        - 將接近開關(guān)的GND接到微控制器的GND引腳

        - 將接近開關(guān)的OUT接到微控制器的一個數(shù)字輸入引腳(如D2)

        - 為電機供電,并將電機的另一端接到微控制器的另一個數(shù)字輸入引腳(如D3)

        - 在需要測量電機速度的地方添加一個霍爾效應(yīng)轉(zhuǎn)速傳感器或者直流電壓計,將其信號線接到微控制器的一個模擬輸入引腳(如A0)。

        3. 編寫程序

        我們需要為微控制器編寫一個簡單的程序,用于讀取接近開關(guān)和霍爾效應(yīng)轉(zhuǎn)速傳感器的數(shù)據(jù),并計算出電機的實際速度。以下是一個簡單的示例代碼:

        ```c

        #include

        const int nearSwitchPin = 2; // 接近開關(guān)引腳連接到D2

        const int motorPin1 = A3; // 電機速度信號輸入引腳1連接到D3

        const int motorPin2 = A4; // 電機速度信號輸入引腳2連接到D4(霍爾效應(yīng)轉(zhuǎn)速傳感器信號輸入引腳)

        const float kp = 5.0; // 比例系數(shù),根據(jù)實際情況調(diào)整

        const float ki = 0.5; // 積分系數(shù),根據(jù)實際情況調(diào)整

        float errorSum = 0; // 誤差累積值

        float lastError = 0; // 上一次的誤差值

        float integral = 0; // 積分值

        float targetSpeed = 1000; // 目標轉(zhuǎn)速(rpm)

        float currentSpeed = 0; // 當前電機轉(zhuǎn)速(rpm)

        float outputSpeed = 0; // 輸出電機控制信號(PWM占空比)

        void setup() {

        pinMode(nearSwitchPin, INPUT);

        pinMode(motorPin1, INPUT_PULLUP);

        pinMode(motorPin2, INPUT);

        }

        void loop() {

        int nearState = digitalRead(nearSwitchPin); // 讀取接近開關(guān)狀態(tài)

        float currentSpeedFloat = analogRead(motorPin2) * (5.0 * (1.0 + (3.3 * VREF)/(65536.0 * 110))) * (5.0 * (1.0 + (3.3 * VREF)/(65536.0 * 110))); // 讀取霍爾效應(yīng)轉(zhuǎn)速傳感器數(shù)據(jù)并轉(zhuǎn)換為rpm單位(假設(shè)VREF為5V)

        currentSpeed = currentSpeedFloat * (60.0 * (1.0 + (3.3 * VREF)/(65536.0 * 110))) * (60.0 * (1.0 + (3.3 * VREF)/(65536.0 * 110))); // 將當前轉(zhuǎn)速轉(zhuǎn)換為rpm單位(假設(shè)VREF為5V)

        if (nearState == HIGH) { // 如果接近開關(guān)被觸發(fā)(即電機轉(zhuǎn)動到位)

        int encoderValue = pulseIn(motorPin1, HIGH); // 通過脈沖寬度調(diào)制方法獲取編碼器計數(shù)(假設(shè)編碼器已連接至D3引腳)

        encoderValue = encoderValue * CLOCK_PRESCALER + PULSE_OVERHEAD; // 根據(jù)時鐘分頻系數(shù)和脈沖延遲時間修正計數(shù)值(CLOCK_PRESCALER和PULSE_OVERHEAD需根據(jù)實際情況進行設(shè)置)

        int distance = encoderValue * GEAR_RATIO; // 根據(jù)齒輪比計算實際距離變化量(GEAR_RATIO需根據(jù)實際情況進行設(shè)置)

        int targetDistance = distance * SPEED_CHANGER_FACTOR; // 根據(jù)目標速度計算需要達到的實際距離(SPEED_CHANGER_FACTOR需根據(jù)實際情況進行設(shè)置)

        int actualDistance = currentSpeedInt * ROTATION_PERIOD; // 根據(jù)當前速度和每分鐘轉(zhuǎn)數(shù)計算實際距離(ROTATION_PERIOD需根據(jù)實際情況進行設(shè)置)

        int error = targetDistance - actualDistance; // 計算偏差值

        int integralPart = integral + error; // 積分累加值增加偏差值

        float derivative = error - lastError; // 計算導(dǎo)數(shù)值(當前偏差值與上一次偏差值之差)

        int outputSignal = saturate((KP * error + KI * integralPart + derivative), INT_MIN, INT_MAX); // 根據(jù)比例、積分、微分調(diào)節(jié)公式計算輸出信號(飽和處理以防止輸出信號超出整數(shù)范圍)

        outputSpeed = map(outputSignal, INT_MIN, INT_MAX, 0, 255); // 將輸出信號映射到PWM占空比范圍(例如:0%對應(yīng)0%,255%對應(yīng)100%)

        analogWritePWM(motorPin2, outputSpeed); // 將輸出信號寫入PWM通道以控制電機轉(zhuǎn)速(假設(shè)已經(jīng)配置好了PWM功能)

        deltaAngle = angleToTicks(distance); // 根據(jù)距離變化量計算脈沖寬度調(diào)制脈寬對應(yīng)的脈沖數(shù)(假設(shè)已經(jīng)實現(xiàn)了angleToTicks函數(shù))

        int ticks = abs((pulseInLow(motorPin1, HIGH))+(pulseInLow(motorPin2, HIGH))); // 通過脈沖寬度調(diào)制方法讀取編碼器的累計脈沖數(shù)(假設(shè)已經(jīng)實現(xiàn)了pulseInLow函數(shù)) dco=ticks/deltaAngle; dco=map(dco,INT_MIN+1,INT_MAX-1,TARGET_TICKS+1,TARGET_TICKS*SPEED); dco=map(dco,TARGET_TICKS+1,TARGET_TICKS*SPEED+1,TARGET_TICKS+1,TARGET_TICKS*SPEED); dco=map(dco,TARGET_TICKS+1,TARGET_TICKS*SPEED+1,TARGET_TICKS+1,TARGET_TICKS*SPEED); dco/=(TARGET_TICKS*SPEED); dco*=TARGET_TICKS/((TARGET_TICKS-dco)*SPEED); dco*=TARGET_TICKS/((TARGET_TICKS-dco)*SPEED); dco/=(TARGET_TICKS*(SPEED-dco)); dco*=TARGET_TICKS*(SPEED-dco); dco/=(TARGET_TICKS*(SPEED-dco)); dco*=TARGET_TICKS*(SPEED-dco); dco/=(TARGET_TICKS*(SPEED-dco)); dco*=TARGET_TICKS*(SPEED-dco); uint8_t _targetTicks=ticks/deltaAngle; _targetTicks=map(_targetTicks,INT_MIN+1,INT_MAX-1,TARGET_TICKS+1,TARGET_TICKS*SPEED); _targetTicks=map(_targetTicks,TARGET_TICKS+1,TARGET_TICKS*SPEED+1,TARGET_TICKS+1,TARGET_TICKS*SPEED); _targetTicks=map(_targetTicks,TARGET_TICKS+1,TARGET_TICKS*SPEED+1,TARGET_TICKS+1,TARGET_TICKS*SPEED); _targetTicks=(uint8)(roundf((float)(abs((ticks/deltaAngle)))/(float)(TARGET_TICKS*(SPEED-dco))))); _targetTicks=map((uint8)(roundf((float)(abs((ticks/deltaAngle)))/(float)(TARGET_TICKS*(SPEED-d

        推薦產(chǎn)品