Tu123
    • Create new note
    • Create a note from template
      • Sharing URL Link copied
      • /edit
      • View mode
        • Edit mode
        • View mode
        • Book mode
        • Slide mode
        Edit mode View mode Book mode Slide mode
      • Customize slides
      • Note Permission
      • Read
        • Only me
        • Signed-in users
        • Everyone
        Only me Signed-in users Everyone
      • Write
        • Only me
        • Signed-in users
        • Everyone
        Only me Signed-in users Everyone
      • Engagement control Commenting, Suggest edit, Emoji Reply
    • Invite by email
      Invitee

      This note has no invitees

    • Publish Note

      Share your work with the world Congratulations! 🎉 Your note is out in the world Publish Note

      Your note will be visible on your profile and discoverable by anyone.
      Your note is now live.
      This note is visible on your profile and discoverable online.
      Everyone on the web can find and read all notes of this public team.
      See published notes
      Unpublish note
      Please check the box to agree to the Community Guidelines.
      View profile
    • Commenting
      Permission
      Disabled Forbidden Owners Signed-in users Everyone
    • Enable
    • Permission
      • Forbidden
      • Owners
      • Signed-in users
      • Everyone
    • Suggest edit
      Permission
      Disabled Forbidden Owners Signed-in users Everyone
    • Enable
    • Permission
      • Forbidden
      • Owners
      • Signed-in users
    • Emoji Reply
    • Enable
    • Versions and GitHub Sync
    • Note settings
    • Note Insights
    • Engagement control
    • Transfer ownership
    • Delete this note
    • Save as template
    • Insert from template
    • Import from
      • Dropbox
      • Google Drive
      • Gist
      • Clipboard
    • Export to
      • Dropbox
      • Google Drive
      • Gist
    • Download
      • Markdown
      • HTML
      • Raw HTML
Menu Note settings Versions and GitHub Sync Note Insights Sharing URL Create Help
Create Create new note Create a note from template
Menu
Options
Engagement control Transfer ownership Delete this note
Import from
Dropbox Google Drive Gist Clipboard
Export to
Dropbox Google Drive Gist
Download
Markdown HTML Raw HTML
Back
Sharing URL Link copied
/edit
View mode
  • Edit mode
  • View mode
  • Book mode
  • Slide mode
Edit mode View mode Book mode Slide mode
Customize slides
Note Permission
Read
Only me
  • Only me
  • Signed-in users
  • Everyone
Only me Signed-in users Everyone
Write
Only me
  • Only me
  • Signed-in users
  • Everyone
Only me Signed-in users Everyone
Engagement control Commenting, Suggest edit, Emoji Reply
  • Invite by email
    Invitee

    This note has no invitees

  • Publish Note

    Share your work with the world Congratulations! 🎉 Your note is out in the world Publish Note

    Your note will be visible on your profile and discoverable by anyone.
    Your note is now live.
    This note is visible on your profile and discoverable online.
    Everyone on the web can find and read all notes of this public team.
    See published notes
    Unpublish note
    Please check the box to agree to the Community Guidelines.
    View profile
    Engagement control
    Commenting
    Permission
    Disabled Forbidden Owners Signed-in users Everyone
    Enable
    Permission
    • Forbidden
    • Owners
    • Signed-in users
    • Everyone
    Suggest edit
    Permission
    Disabled Forbidden Owners Signed-in users Everyone
    Enable
    Permission
    • Forbidden
    • Owners
    • Signed-in users
    Emoji Reply
    Enable
    Import from Dropbox Google Drive Gist Clipboard
       owned this note    owned this note      
    Published Linked with GitHub
    Subscribed
    • Any changes
      Be notified of any changes
    • Mention me
      Be notified of mention me
    • Unsubscribe
    Subscribe
    # STM32 - Encoder ## " Encoder " 是啥,能吃嗎 (˘・з・˘) - Encoder(編碼器)是馬達控制重要的感測器 - 將位置資訊轉換為電子訊號的感測器 (sensor) - 可以用於追蹤機器人的 **速度** 及 **位置** 資訊 ::: info 利用 **定時** 讀取 Encoder 的訊號我們便可以得知馬達的 **轉速**,進而推導出機器的 **速度** or **位置** ::: ::: success 有點類似 **<font color='SkyBlue'>打點計時器**</font> 的原理 ::: <details> <summary>為什麼會需要知道馬達的轉速 (๑•́ ₃ •̀๑)</summary> - 我們下達命令給馬達的同時,我們也需要追蹤他有沒有乖乖的照我們的指示去做! - 利用 Encoder 才能得知馬達 **現實的狀態**! - 有了 Encoder 我們便可以利用 **回授** 的概念讓我們更穩定的控制我們的機器 - **回授**:觀測 **輸出** 的資訊 以調整 **輸入** 的狀況 ![image](https://hackmd.io/_uploads/ryU5UHkKA.png) </details> --- ## Encoder 是怎麼運作的 (•ω•́ ) - 我們這次使用的是 **增量型** **旋轉** **光學** 編碼器(encoder) - **增量型** 代表這個 encoder 所測得的資料是 **相對** 的! - 馬達是以轉動為輸出,所以觀測他使用的是 **旋轉** 編碼器 - **光學** 代表他是利用 **感測光是否穿過狹縫** 判斷待測物轉幾圈 ![image](https://hackmd.io/_uploads/S1lO2S1YR.png) <details> <summary>Encoder 有相當多種的種類,我們可以依照不同需求進行挑選</summary> - 依輸出資料型態區分:絕對型、增量型 - 依觀測資料型態區分:旋轉型、直線型 - 依運作原理區分:機械式、電容式、電磁式、光學式 ::: info 有興趣可以自己上網查或是問 chatGPT! ::: </details> - 這次使用的編碼器中,會有 **兩片** 狹縫 **間隔相同** 的環,每當 Encoder 感測到狹縫就會發出電子訊號 - 因為這些狹縫是規律的,他們之間的 **間隔一樣** ,透過 **知道他經過幾個狹縫** 我們便可以計算出他轉了幾圈 <details> <summary>那這樣一片就可以知道轉速了,為什會需要兩片 ಠ_ಠ</summary> - 兩片的狹縫是 **錯開** 的,他們之間會差半格,藉此我們才能知道旋轉的方向! ![Incremental_directional_encoder](https://hackmd.io/_uploads/r1Ldls8cA.gif) ::: info 順時針轉 & 逆時針轉 會先讀到不同片的環! ::: </details> --- ## 要怎麼使用他 ▼・ᴥ・▼ - <font color='Salmon'>Encoder 使用概念</font> - STM32 Timer 內建的 **<font color='SkyBlue'>Encoder Mode</font>** 會幫我們計算 Encoder 經過幾個狹縫 - 利用 **<font color='SkyBlue'>中斷</font>** 每隔一段時間(約 1-10 ms)去讀取 Encoder 累計的數值 - 利用 **<font color='SkyBlue'>累計的數值</font>** 及 **<font color='SkyBlue'>間隔時間</font>**,推導出那段時間的平均轉速 - 因為間隔時間很短,所以可以近似於瞬時速度 - 把 Encoder **<font color='SkyBlue'>數值歸零</font>**,重頭開始累積經過的狹縫數 - 重複進行,就可以一直取得馬達的速度了! --- ### Encoder 的參數 在開始使用 Encoder 之前,我們會需要先了解一些有關他的參數,這些參數與 **減速箱**、**編碼器** 及 **取樣週期** 相關 1. **counter**(計數器):Encoder <font color='RePurple'>讀到幾個狹縫</font> - 我們可以透過 STM32 Timer 內建的 counter 讀取 - 經過一個完整的狹縫組合,counter會 **<font color='red'>+/- 4</font>** ![Screenshot from 2024-07-25 14-38-35](https://hackmd.io/_uploads/B1ilQuyFC.png) - 正轉 counter 遞增,反轉 counter 遞減 2. **reduction_ratio**(減速比):<font color='SkyBlue'>Encoder</font> 轉速 / <font color='BlackPink'>馬達軸</font> 轉速 - 可以翻閱 [減速箱型錄](http://sohomotor.com/Product.html) 找到! 3. **resolution**(解析度):Encoder 一圈的 <font color='0xffff'>狹逢數 </font> - 可以翻閱 [Encoder型錄](http://sohomotor.com/Product_02.html) 找到! - 解析度越大,讀取的數值越精確 4. **time_span**(時間間隔):<font color='LightGreen'>間隔多少時間</font> 讀取一次 Encoder 的值 - 看你 **多久進一次中斷**! - 取樣的週期越短,計算出的數值越精確 --- ### 計算公式 利用上面的概念及參數,我們可以推得以下公式以計算馬達轉幾圈&轉速 - turns(旋轉圈數): $$ turns = \frac{counter}{4 \cdot reduction\_ratio \cdot resolution},Unit:[rev] $$ - speed(轉速) $$ speed = \frac{turns}{time\_span},Unit:[\frac{rev}{sec}] $$ --- ### Timer 初始化設定 - Project.ioc -> Timers -> Combined Channels -> Encoder Mode ::: info 有些 Timer 沒有 Encoder Mode! ::: ![Screenshot from 2024-07-25 14-45-48](https://hackmd.io/_uploads/B1lHqjkFC.png) - Configuration -> Parameter Settings -> Encoder -> Encoder Mode -> Tl1 and T12 ![Screenshot from 2024-07-25 14-50-19](https://hackmd.io/_uploads/SyGzqjyY0.png) --- ### 電路 Encoder 總共有4條線,其中兩條是提供 Encoder 電源(5V & GND),令外兩條是 輸出電子訊號 ![image](https://hackmd.io/_uploads/rJIZzs8cR.png) 5V & GND 當然就是接到開發板上的 5V & GND 另外兩條則需要到 .ioc 中看剛剛的 timer 是哪兩個腳位在接收訊號 <details> <summary>Project.ioc -> Timers -> Configuration -> GPIO Settings</summary> ![Screenshot from 2024-07-25 14-55-39](https://hackmd.io/_uploads/B1Adqi1FA.png) </details> ::: info 這兩條線的順序決定了 **馬達正反轉方向** ::: --- ### 控制函式 - 啟用 Timer ```Cpp= HAL_TIM_Encoder_Start(&htimx, TIM_CHANNEL_a); HAL_TIM_Encoder_Start(&htimx, TIM_CHANNEL_b); ``` <details> <summary>跟之前的好像 o(*゚▽゚*)o</summary> - x:剛剛開的是 **幾號 Timer** - a,b:Timer 使用到 **幾號 Channel** - 剛剛 Configuration 的 GPIO 那邊找的到,通常為 1 & 2 ![Screenshot from 2024-07-25 15-13-06](https://hackmd.io/_uploads/rkqPjOyYR.png) ::: warning 函式要放在 **MX_TIMx_Init();** 後面! ::: </details> - 讀取 Encoder Counter 的值 ```Cpp= __HAL_TIM_GetCounter(&htimx); ``` ::: warning 前面是 **兩個** 底線歐! ::: - 把 Encoder 的值歸零 ```Cpp= __HAL_TIM_SetCounter(&htimx, 0); ``` - 完整程式(加入公式&中斷) ```Cpp= #define reduction_ratio ?? #define resolution ??? #define time_span ????? // 建立變數紀錄 Encoder counter 的值 short enc = 0; // 建立變數紀錄 轉速 的值 double speed = 0; // 進中斷讀取 void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim){ if(htim->Instance == TIMy){ // 紀錄 counter 值 enc = __HAL_TIM_GetCounter(&htimx); // 計算轉速 speed = (double)enc/(4*reduction_ratio*resolution)/time_span; // 把 counter 值歸零,供下次計算 __HAL_TIM_SetCounter(&htimx, 0); } } ``` ::: success Encoder 也學完了 (*´∀`)~♥ 接下來來學 [STM32 - PID controller](/DEztrnehTAuggldbisGKhQ) 吧! ::: --- ## 實做練習 ### Basic - 請試著在 現場表達式 讀取 **馬達轉速** - 本次使用的馬達 **減速比** = 24 **解析度** = 256 --- ### Advanced - 請試著在 現場表達式 讀取 **馬達角度** - 角度以 0度-360度 表示 ::: info 可能會要對公式做一點修改,並做一些邊界條件的判斷! ::: --- ### 範例程式 <details> <summary>Basic</summary> ```Cpp= #define reduction_ratio ?? #define resolution ??? #define time_span ????? // 建立變數紀錄 Encoder counter 的值 short enc = 0; // 建立變數紀錄 轉速 的值 double speed = 0; // 進中斷讀取 void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim){ if(htim->Instance == TIMy){ // 紀錄 counter 值 enc = __HAL_TIM_GetCounter(&htimx); // 計算轉速 speed = (double)enc/(4*reduction_ratio*resolution)/time_span; // 把 counter 值歸零,供下次計算 __HAL_TIM_SetCounter(&htimx, 0); } } ``` </details> <details> <summary>Advanced</summary> ```Cpp= #define reduction_ratio ?? #define resolution ??? #define time_span ????? // 建立變數紀錄 Encoder counter 的值 short enc = 0; // 建立變數紀錄 角度(deg) 的值 double angle = 0; // 進中斷讀取 void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim){ if(htim->Instance == TIMy){ // 紀錄 counter 值 enc = __HAL_TIM_GetCounter(&htimx); // 計算轉速 angle += (double)enc/(4*reduction_ratio*resolution)*360; // 如果超過360度,從 0 開始重算 if(angle > 360) angle -= 360; if(angle < 0) angle += 360; // 把 counter 值歸零,供下次計算 __HAL_TIM_SetCounter(&htimx, 0); } } ``` </details>

    Import from clipboard

    Paste your markdown or webpage here...

    Advanced permission required

    Your current role can only read. Ask the system administrator to acquire write and comment permission.

    This team is disabled

    Sorry, this team is disabled. You can't edit this note.

    This note is locked

    Sorry, only owner can edit this note.

    Reach the limit

    Sorry, you've reached the max length this note can be.
    Please reduce the content or divide it to more notes, thank you!

    Import from Gist

    Import from Snippet

    or

    Export to Snippet

    Are you sure?

    Do you really want to delete this note?
    All users will lose their connection.

    Create a note from template

    Create a note from template

    Oops...
    This template has been removed or transferred.
    Upgrade
    All
    • All
    • Team
    No template.

    Create a template

    Upgrade

    Delete template

    Do you really want to delete this template?
    Turn this template into a regular note and keep its content, versions, and comments.

    This page need refresh

    You have an incompatible client version.
    Refresh to update.
    New version available!
    See releases notes here
    Refresh to enjoy new features.
    Your user state has changed.
    Refresh to load new user state.

    Sign in

    Forgot password

    or

    By clicking below, you agree to our terms of service.

    Sign in via Facebook Sign in via Twitter Sign in via GitHub Sign in via Dropbox Sign in with Wallet
    Wallet ( )
    Connect another wallet

    New to HackMD? Sign up

    Help

    • English
    • 中文
    • Français
    • Deutsch
    • 日本語
    • Español
    • Català
    • Ελληνικά
    • Português
    • italiano
    • Türkçe
    • Русский
    • Nederlands
    • hrvatski jezik
    • język polski
    • Українська
    • हिन्दी
    • svenska
    • Esperanto
    • dansk

    Documents

    Help & Tutorial

    How to use Book mode

    Slide Example

    API Docs

    Edit in VSCode

    Install browser extension

    Contacts

    Feedback

    Discord

    Send us email

    Resources

    Releases

    Pricing

    Blog

    Policy

    Terms

    Privacy

    Cheatsheet

    Syntax Example Reference
    # Header Header 基本排版
    - Unordered List
    • Unordered List
    1. Ordered List
    1. Ordered List
    - [ ] Todo List
    • Todo List
    > Blockquote
    Blockquote
    **Bold font** Bold font
    *Italics font* Italics font
    ~~Strikethrough~~ Strikethrough
    19^th^ 19th
    H~2~O H2O
    ++Inserted text++ Inserted text
    ==Marked text== Marked text
    [link text](https:// "title") Link
    ![image alt](https:// "title") Image
    `Code` Code 在筆記中貼入程式碼
    ```javascript
    var i = 0;
    ```
    var i = 0;
    :smile: :smile: Emoji list
    {%youtube youtube_id %} Externals
    $L^aT_eX$ LaTeX
    :::info
    This is a alert area.
    :::

    This is a alert area.

    Versions and GitHub Sync
    Get Full History Access

    • Edit version name
    • Delete

    revision author avatar     named on  

    More Less

    Note content is identical to the latest version.
    Compare
      Choose a version
      No search result
      Version not found
    Sign in to link this note to GitHub
    Learn more
    This note is not linked with GitHub
     

    Feedback

    Submission failed, please try again

    Thanks for your support.

    On a scale of 0-10, how likely is it that you would recommend HackMD to your friends, family or business associates?

    Please give us some advice and help us improve HackMD.

     

    Thanks for your feedback

    Remove version name

    Do you want to remove this version name and description?

    Transfer ownership

    Transfer to
      Warning: is a public team. If you transfer note to this team, everyone on the web can find and read this note.

        Link with GitHub

        Please authorize HackMD on GitHub
        • Please sign in to GitHub and install the HackMD app on your GitHub repo.
        • HackMD links with GitHub through a GitHub App. You can choose which repo to install our App.
        Learn more  Sign in to GitHub

        Push the note to GitHub Push to GitHub Pull a file from GitHub

          Authorize again
         

        Choose which file to push to

        Select repo
        Refresh Authorize more repos
        Select branch
        Select file
        Select branch
        Choose version(s) to push
        • Save a new version and push
        • Choose from existing versions
        Include title and tags
        Available push count

        Pull from GitHub

         
        File from GitHub
        File from HackMD

        GitHub Link Settings

        File linked

        Linked by
        File path
        Last synced branch
        Available push count

        Danger Zone

        Unlink
        You will no longer receive notification when GitHub file changes after unlink.

        Syncing

        Push failed

        Push successfully