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
  • 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 Pi Pico Display and Rotary Encoder
  • Blog
  • Forum
  • Documents
  • Quiz
  • Events
  • Polls
  • Files
  • Members
  • Mentions
  • Sub-Groups
  • Tags
  • More
  • Cancel
  • New
Raspberry Pi requires membership for participation - click to join
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: shabaz
  • Date Created: 10 Oct 2021 10:53 PM Date Created
  • Views 22664 views
  • Likes 4 likes
  • Comments 7 comments
Related
Recommended
  • python
  • circuitpython
  • incremental encoder
  • raspberry pi pico
  • dm8ba10
  • rotary encoder
  • pi pico

Pi Pico Display and Rotary Encoder

shabaz
shabaz
10 Oct 2021

  • Introduction
  • Working with the Pi Pico and CircuitPython
  • Circuit
  • Code
    • Main code
    • update_rotval function
    • update_speedrange function
  • Summary

 

Introduction

This short blog post covers how I got a display and rotary encoderrotary encoder functioning with the Pi PicoPi Pico. The information here could be useful for many scenarios where a value needs to be dialed in, for instance, to control motor speed or to adjust the frequency of a circuit. My current use case was to control frequency.

 

The 1-minute video here demonstrates the project.

You don't have permission to edit metadata of this video.
Edit media
x
image
Upload Preview
image

 

A slightly unusual LCD was used – it's a DM8BA10 10-digit 16-segment starburst with decimals display from Aliexpress. I liked it because it looks a little retro (at least when the blue backlight is switched off). I used a rotary encoder from Alpsrotary encoder from Alps.

image

 

Another slightly different thing (for me) was to use Python for this entire project. It's my first CircuitPython program, and it was an opportunity to explore how usable it is for microcontroller projects. I concluded that while it is interesting, I didn't have as much control over the hardware as I would have liked, and I frequently wished I was using C/C++. However, I also learned to appreciate just what a paradigm shift it can be to develop rapidly without needing to compile code, and in a language that is accessible for many more users than just traditional engineers. That was important to me because I wish to use this code for a simple radio project, where not all users may be familiar with traditional development methods and C programming.

 

Working with the Pi Pico and CircuitPython

After I purchased a Pi Pico, I downloaded the latest CircuitPython binary release (.UF2 file) and then held down the only button on the Pi Pico and plugged it into my PC's USB port, and then released the button. This only needs to be done once. The Pi Pico appears as USB storage space, and I dragged the CircuitPython binary release file onto it. Within seconds, the Pi Pico was running CircuitPython (and it's possible to use a USB serial port to interactively type Python commands, but I didn't do that).

 

Next, I wrote my Python code in a text editor, frequently saving it and dragging the code into the USB storage space. The code runs immediately each time I do that. Any text editor can be used, but the Mu editor has built-in code-checking capability, and a built-in serial port console which is handy for debug print statements.

image

 

Circuit

The diagram below shows the connections. The only slightly unusual thing is that one of the outputs from the rotary encoder makes its way to two pins on the Pi Pico; it was required to overcome a limitation with the code, explained later.

 

The LCD module has a serial interface that looks like SPI, but I didn't use the Pi's SPI interface because the LCD expects fairly slow data, and of a length that doesn't sit on an 8-bit boundary, and I wasn't sure if the SPI capability in the Pi Pico would have been happy with these things.

image

 

The display doesn't need to be illuminated depending on preference; disconnect the LED+ connection on the display to run it without the backlight.

image

 

This project is powered either from the USB connection on the Pi Pico or via a 5V supply connected to J1 in the circuit below. J1 and D1 can be removed if not required.

image

The Pi Pico pinout is shown here for reference; the green values are the GPIO numbers.

image

 

The DM8BA10 display total current consumption is about 200 uA at 5V with the backlight connection disconnected, or 16 mA with the backlight turned on. With the code described below, the Pi Pico current consumption is approximately 24 mA at 5V.

 

Code

The code is a single Python file. The information in this section is not necessary to use the project but will be useful if changes to the code are desired.

 

Serial commands are sent in order to control the display. Each character on the display has 16 segments of starburst arrangement, and there is a list in the code called LCD_CHARBITS that maps ASCII characters to the appropriate LCD segments that need turning on. The code currently only implements 0-9, A-Z and a small handful of other ASCII characters. The bitmap diagram is shown here. For example, the character C as in the diagram would be represented in the code using the hexadecimal value 0xA381.

image

 

The code has printing functions for numbers and text, for instance:

 

lcd_printtext("HI THERE") 
lcd_printint(42)

 

Main code

The main code initializes the display, and then loops forever, waiting on either the rotary encoder to be rotated or for the push-button to be pressed. It's trivially simple, the diagram below and the source code snippet show this.

image

image

 

update_rotval function

If the encoder is rotated, then the CircuitPython rotaryio library provides a count value, and within the update_rotval function, the difference between that and the previously captured value can be added to the displayed number. The countio library is simultaneously used to see how fast the encoder was rotated. The countio library cannot use the same pins as the encoder, and so one of the encoder pins is wired to another GPIO pin, purely for speed determination using the countio library. Based on the speed, a multiplier is used to create 'acceleration' for adjusting the count value. All of this is handled in the update_rotval function.

 

update_speedrange function

I wanted to use this project for a very wide range of values (tens of millions) and with a stiff rotary encoder, even the acceleration feature might be insufficient. I also wanted to allow the user to be able to optionally adjust in 1 kHz and 1 MHz increment. In the end, I decided that a single button would be used to select Hz, kHz, or MHz increments, and the display would briefly indicate this each time the button is pressed. The digitalio library is used to read the button status, change the step to 1, 1000, or 1000000, and briefly display the setting ("HZ", "K" or "M" on the display). This is all handled in the update_speedrange function.

 

The button feature, plus the acceleration feature, together make for an adequate user interface for this purpose. If a very large range of values is not needed, then the button can be removed from the circuit.

 

To actually use the rotational value to do something (e.g. set a motor speed, or set the frequency output for a signal generator), code will need to be written to send (say) I2C or SPI instructions containing the value, to the downstream device that will take action on it.

 

Summary

It was possible to implement a usable control and display method with the Pi Pico and Python, specifically CircuitPython, in this example. The code is on GitHub and is easily modifiable. The diagram showing the bit mapping for the LCD segments can be used to extend the displayable characters and symbols.

 

There's no doubt in my mind that I would have architected and coded things differently, and better, had I worked in C/C++. CircuitPython, as it stands today, cannot realistically be used for working with all possible peripherals, internal and external to the microcontroller, in as precise a manner as with C/C++ and any associated libraries. However, I think the Python implementation in some cases may be 'good enough' and I hope and wish CircuitPython becomes more mature. From my perspective, I will use CircuitPython for the situations where I'd like non-engineers to feel more comfortable, and in that case, I feel CircuitPython can be a good option.

 

Thanks for reading.

  • Sign in to reply
  • shabaz
    shabaz over 3 years ago

    I have ported the code now to MicroPython, I'll put that up on GitHub at some point, and then I'm going to continue with that, and probably not maintain the CircuitPython version.

    • Cancel
    • Vote Up 0 Vote Down
    • Sign in to reply
    • More
    • Cancel
  • shabaz
    shabaz over 3 years ago in reply to fmilburn

    Hi Frank,

     

    I'm curious to see how hard/easy it is to create custom libraries in C for CircuitPython, but despite that, as you say, the lack of support at Python-level for interrupt or even multiple threads is limiting. I might try to port the code to MicoPython and see how the main loop can improve. I do like the concept of using Python for simplifying embedded apps, but it would be nice if more powerful capabilities were supported too for allowing better design of those applications.

    • Cancel
    • Vote Up 0 Vote Down
    • Sign in to reply
    • More
    • Cancel
  • fmilburn
    fmilburn over 3 years ago

    Hi Shabaz,

     

    I really like that display and thanks for posting the code!

    • Cancel
    • Vote Up 0 Vote Down
    • Sign in to reply
    • More
    • Cancel
  • fmilburn
    fmilburn over 3 years ago in reply to shabaz

    My main issue with Circuit Python is that it doesn't support interrupts, or at least it didn't in the past.  Apparently, Adafruit writes their libraries in C and then puts them in a wrapper for Circuit Python: no interrupts? · Issue #19 · adafruit/Adafruit_CircuitPython_TSL2561 · GitHub

    • Cancel
    • Vote Up 0 Vote Down
    • Sign in to reply
    • More
    • Cancel
  • genebren
    genebren over 3 years ago in reply to shabaz

    There is always more to learn.  If it allows for a fast prototype or easy test beds, then there is value.  I have enjoyed the Ardunio for quick development and some neat libraries, but I always find myself going back to C, bare metal on a ATmega where I have full control of the device and I don't have to guess on interactions between libraries and resources.

    • 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