element14 Community
element14 Community
    Register Log In
  • Site
  • Search
  • Log In Register
  • Community Hub
    Community Hub
    • What's New on element14
    • Feedback and Support
    • Benefits of Membership
    • Personal Blogs
    • Members Area
    • Achievement Levels
  • Learn
    Learn
    • Ask an Expert
    • eBooks
    • element14 presents
    • Learning Center
    • Tech Spotlight
    • STEM Academy
    • Webinars, Training and Events
    • Learning Groups
  • Technologies
    Technologies
    • 3D Printing
    • FPGA
    • Industrial Automation
    • Internet of Things
    • Power & Energy
    • Sensors
    • Technology Groups
  • Challenges & Projects
    Challenges & Projects
    • Design Challenges
    • element14 presents Projects
    • Project14
    • Arduino Projects
    • Raspberry Pi Projects
    • Project Groups
  • Products
    Products
    • Arduino
    • Avnet Boards Community
    • Dev Tools
    • Manufacturers
    • Multicomp Pro
    • Product Groups
    • Raspberry Pi
    • RoadTests & Reviews
  • About Us
  • Store
    Store
    • Visit Your Store
    • Choose another store...
      • Europe
      •  Austria (German)
      •  Belgium (Dutch, French)
      •  Bulgaria (Bulgarian)
      •  Czech Republic (Czech)
      •  Denmark (Danish)
      •  Estonia (Estonian)
      •  Finland (Finnish)
      •  France (French)
      •  Germany (German)
      •  Hungary (Hungarian)
      •  Ireland
      •  Israel
      •  Italy (Italian)
      •  Latvia (Latvian)
      •  
      •  Lithuania (Lithuanian)
      •  Netherlands (Dutch)
      •  Norway (Norwegian)
      •  Poland (Polish)
      •  Portugal (Portuguese)
      •  Romania (Romanian)
      •  Russia (Russian)
      •  Slovakia (Slovak)
      •  Slovenia (Slovenian)
      •  Spain (Spanish)
      •  Sweden (Swedish)
      •  Switzerland(German, French)
      •  Turkey (Turkish)
      •  United Kingdom
      • Asia Pacific
      •  Australia
      •  China
      •  Hong Kong
      •  India
      •  Korea (Korean)
      •  Malaysia
      •  New Zealand
      •  Philippines
      •  Singapore
      •  Taiwan
      •  Thailand (Thai)
      • Americas
      •  Brazil (Portuguese)
      •  Canada
      •  Mexico (Spanish)
      •  United States
      Can't find the country/region you're looking for? Visit our export site or find a local distributor.
  • Translate
  • Profile
  • Settings
Raspberry Pi
  • Products
  • More
Raspberry Pi
Blog Pico PIO state machine implements a peripheral: Rotary Decoder substeps example
  • Blog
  • Forum
  • Documents
  • Quiz
  • Events
  • Polls
  • Files
  • Members
  • Mentions
  • Sub-Groups
  • Tags
  • More
  • Cancel
  • New
Join Raspberry Pi to participate - click to join for free!
Featured Articles
Announcing Pi
Technical Specifications
Raspberry Pi FAQs
Win a Pi
GPIO Pinout
Raspberry Pi Wishlist
Comparison Chart
Quiz
  • Share
  • More
  • Cancel
Group Actions
  • Group RSS
  • More
  • Cancel
Engagement
  • Author Author: Jan Cumps
  • Date Created: 25 Mar 2025 7:31 PM Date Created
  • Views 2495 views
  • Likes 8 likes
  • Comments 5 comments
Related
Recommended
  • raspberry
  • pico
  • pico_eurocard
  • PIO

Pico PIO state machine implements a peripheral: Rotary Decoder substeps example

Jan Cumps
Jan Cumps
25 Mar 2025

The Pico has a set of PIO co-processors. They are real-time controllers that can execute logic with deterministic timing. Ideal to run strict-timed sequences and state machines. And to implement extra peripherals (like a quadrature decoder here).
The PIO engine is not easy to program, not easy to learn. But there are some great examples out there. I'm reviewing Sub-Step Quadrature Encoder from SDK pico-examples.
In this post: test the example, using the rotary encoder on shabaz' PICO-EUROCARD

image

This is an interesting case. Most quadrature decoder examples (such as this one) count steps per time. Works great in many cases, but has its issues. This one takes a different approach. It calculates the time per step, and derives speed from that.

The code uses a PIO state machine to read the encoder's activity and translate it into the info we need.

Adapt to PICO-EUROCARD rotary encoder

The Raspberry Pico code uses pin 10 and 11 as rotary encoder pins A and B. On the eurocard, the controller is attached to pins 6 and 7. In the example you have to change 1 line of code:

 int main(void)
 {
     substep_state_t state;
 
     // base pin to connect the A phase of the encoder. the B phase must be
     // connected to the next pin
     // const uint PIN_A = 10;
     const uint PIN_A = 6;

That's it :). Build and test.

Testing

To test this, you just need to connect a terminal program to the debugger. Then wiggle the encoder ...

image

An alternative decoding solution that fits when the common technique isn't granular enough. 

Thank you for reading.

  • Sign in to reply
  • DAB
    DAB 6 months ago

    Nice project Jan.

    • Cancel
    • Vote Up 0 Vote Down
    • Sign in to reply
    • More
    • Cancel
  • Jan Cumps
    Jan Cumps 6 months ago

    Stepper motor time. I found an example to control a stepper via  PIO. I want to try that out first, then see if I can make it do ramp-up ramp-down.

    image

    • Cancel
    • Vote Up 0 Vote Down
    • Sign in to reply
    • More
    • Cancel
  • Jan Cumps
    Jan Cumps 6 months ago

    The design has a calibration function.

    Suggestion is to create test code that runs the motor stable at 50%, then call that function. It will then return the phase sizes of the encoder.

    These values can then be used in the real firmware to have optimal coverage over the whole speed range.

    • Cancel
    • Vote Up 0 Vote Down
    • Sign in to reply
    • More
    • Cancel
  • Jan Cumps
    Jan Cumps 6 months ago in reply to shabaz

    The example readme says that each PIO can handle 4 encoders - the restricting factor is the count of state machines that can run on the PIO.

    > Does the code increment/decrement the count based on the calculated speed too?
    As far as I can see: no. That's a discrete value - the real steps.

    • Cancel
    • Vote Up 0 Vote Down
    • Sign in to reply
    • More
    • Cancel
  • shabaz
    shabaz 6 months ago

    Nice.. That's really neat that the rotary encoder handling is all delegated to the PIO. Since there are two, this could also be interesting for motors with encoders, e.g. robotics, dedicate a Pi Pico per pair of motors for instance.

    Does the code increment/decrement the count based on the calculated speed too? (e.g. handy if you're using the rotary encoder as a user interface control, incrementing say frequency from 0 to 1 MHz in steps of 1 Hz when moved slowly, but in steps of 100 Hz when rotated a bit quicker, and so on).

    • Cancel
    • Vote Up 0 Vote Down
    • Sign in to reply
    • More
    • Cancel
element14 Community

element14 is the first online community specifically for engineers. Connect with your peers and get expert answers to your questions.

  • Members
  • Learn
  • Technologies
  • Challenges & Projects
  • Products
  • Store
  • About Us
  • Feedback & Support
  • FAQs
  • Terms of Use
  • Privacy Policy
  • Legal and Copyright Notices
  • Sitemap
  • Cookies

An Avnet Company © 2025 Premier Farnell Limited. All Rights Reserved.

Premier Farnell Ltd, registered in England and Wales (no 00876412), registered office: Farnell House, Forge Lane, Leeds LS12 2NE.

ICP 备案号 10220084.

Follow element14

  • X
  • Facebook
  • linkedin
  • YouTube