Download PDF Parts List View on YouTube Download Code

Introduction

Rotary encoders are one of those components that can really elevate your project’s user interface. They give you that satisfying tactile feedback when scrolling through menus or adjusting values, making your projects feel more professional and intuitive to use. But here’s the challenge – traditional rotary encoders can be a bit tricky to work with. They require multiple GPIO pins, careful debouncing, and tight timing requirements to read reliably.

Enter the Adafruit I2C Rotary Encoder – and this is a real game-changer! This clever little module packages a rotary encoder, a pushbutton switch, and an RGB NeoPixel LED into a single unit that communicates over I2C. What does that mean for you? Well, you can add multiple encoders to your project using just two wires (plus power and ground), freeing up your precious GPIO pins for other tasks. And the best part? The tricky debouncing and timing stuff is all handled for you by the module’s built-in microcontroller.

In this article, we’ll dive deep into the Adafruit I2C Rotary Encoder. We’ll examine its specifications, understand how it works, and put it through its paces with two practical projects. First, we’ll build a hierarchical menu system for controlling an RGB LED – perfect for learning how to create intuitive navigation interfaces. Then we’ll have some fun building an Etch-A-Sketch drawing application using two encoders. Along the way, you’ll learn techniques that you can apply to all sorts of projects.

The Adafruit I2C Rotary Encoder is available from Adafruit Industries and comes in various colors. You can find complete documentation and additional resources at https://learn.adafruit.com/adafruit-i2c-qt-rotary-encoder.

Adafruit Seesaw I2C Encoder

What Makes It Special?

The Adafruit I2C Rotary Encoder is built on the “Seesaw” platform, Adafruit’s innovative approach to creating I2C-connected peripherals. You might be wondering – what’s with the name “Seesaw”? Well, it’s actually quite clever! These modules use an ATSAMD09 microcontroller running custom firmware that acts as a bridge between I2C and various sensors and controls. It “sees” the hardware and provides “saw” (serial) access to it – hence, Seesaw! This architecture allows Adafruit to create a whole family of I2C devices with consistent programming interfaces, making them easy to use together in your projects.

The encoder module packs several features into one compact package:

  • Rotary Encoder: A 24-position rotary encoder with excellent mechanical feel
  • Pushbutton Switch: Integrated into the encoder shaft for selection and confirmation
  • RGB NeoPixel: A built-in addressable RGB LED for visual feedback
  • STEMMA QT/Qwiic Connector: For easy, solder-free daisy-chaining
  • Configurable I2C Address: Allows up to eight encoders on the same bus

Pinout and Connections

The encoder breakout board features the following connections:

STEMMA QT/Qwiic Connector (4-pin JST SH):

  • VCC (3.3V or 5V)
  • GND
  • SDA (I2C Data)
  • SCL (I2C Clock)

Additional Pads:

  • Same I2C and power connections as solder pads
  • A0, A1, A2: Address configuration pads
  • INT: Interrupt output (optional, active low)

The board works with both 3.3V and 5V logic levels, making it compatible with a wide range of microcontrollers. The STEMMA QT connectors use a standard JST SH 1mm pitch connector, which is compatible with SparkFun’s Qwiic system – so if you have Qwiic cables lying around, they’ll work perfectly!

Configuring the I2C Address

One of the most useful features of the Seesaw encoder is the ability to change its I2C address. This is what allows you to connect multiple encoders to the same I2C bus – you can have up to eight encoders working together! The default address is 0x36, but you can modify it by bridging the address pads on the back of the board.

Here’s how the addressing works:

Pads Bridged I2C Address
None (default) 0x36
A0 0x37
A1 0x38
A0 + A1 0x39
A2 0x3A
A0 + A2 0x3B
A1 + A2 0x3C
A0 + A1 + A2 0x3D

To bridge a pad, simply add a small solder blob across the two pads on the back of the board. This creates a connection that the Seesaw firmware detects at startup, adjusting the I2C address accordingly.

Important Note: Address 0x3C is commonly used by SSD1306 OLED displays, so you’ll want to avoid that address if you’re using one of these popular displays in your project.

How a Rotary Encoder Works

Before we dive deeper into using the Seesaw encoder, it’s worth taking a moment to understand how rotary encoders actually work. Unlike potentiometers, which provide variable resistance, rotary encoders are digital devices that detect rotational movement via two output signals.

A typical rotary encoder has two output pins (often labeled A and B) that produce quadrature signals – square waves that are 90 degrees out of phase with each other. As you rotate the shaft, these signals transition in a specific pattern. When you turn the encoder clockwise, output A transitions before output B. When you turn it counter-clockwise, output B transitions before A. By monitoring both signals and their timing, a microcontroller can determine not only that rotation has occurred, but also which direction you’re turning and how far the shaft has rotated.

Here’s the beautiful part – the Seesaw firmware handles all of this complexity for you! It monitors encoder signals, manages debouncing, and provides a simple position counter accessible via I2C. This counter increments or decrements based on rotation direction, giving you a straightforward way to track rotational input without worrying about the low-level signal timing.

The encoder in the Adafruit module has 24 detents (click positions) per full rotation, providing sufficient resolution for menu navigation and value adjustment.

The Seesaw Ecosystem

The I2C Rotary Encoder is just one member of Adafruit’s growing Seesaw family. Other Seesaw products include:

  • Seesaw Soil Sensor: Measures moisture and temperature
  • Seesaw Arcade Buttons: Multiple buttons on one I2C address
  • Mini TFT with Joystick: Display and analog input combined
  • Seesaw NeoKey: Mechanical keyboard switches with NeoPixels

All of these devices share the same Adafruit_Seesaw library and programming patterns, making it easy to mix and match different input types in your projects. Once you’ve learned to work with one Seesaw device, you can quickly integrate others – the API is consistent across the whole family.

Using the I2C Encoder

The best way to get started with the I2C Rotary Encoder is to run through some of Adafruit’s example sketches. These examples are included with the Adafruit_Seesaw library, which you can install through the Arduino Library Manager.

Installing the Library

To install the required library:

  • Open the Arduino IDE
  • Go to Sketch → Include Library → Manage Libraries
  • Search for “Adafruit Seesaw”
  • Click Install on Adafruit Seesaw Library (this will also install dependencies like Adafruit_BusIO)

You can also find the library source code and additional examples on GitHub at https://github.com/adafruit/Adafruit_Seesaw.

Example 1: Basic Encoder Demo

The encoder_basic example demonstrates the fundamental operation of a single encoder. You’ll find this sketch under File → Examples → Adafruit Seesaw → encoder → encoder_basic.

What It Does:

This example initializes one encoder at the default address (0x36) and continuously monitors both the rotary encoder position and the pushbutton state. As you rotate the encoder, you’ll see the position value change in the Serial Monitor. Turning clockwise increments the value, while counter-clockwise rotation decrements it. The position is stored as a 32-bit signed integer, so it can handle a wide range of values without wrapping around.

The example also demonstrates button reading. Note that the button is active LOW – it reads as 0 when pressed and 1 when released. That’s why you’ll see !encoder.digitalRead(SS_SWITCH) in the code – the exclamation mark inverts the logic for more intuitive understanding.

NeoPixel Control:

One of the coolest features is the built-in NeoPixel LED. The example sketch includes a “Wheel” function that cycles through rainbow colors as you turn the encoder. This provides immediate visual feedback and shows you how to control the LED. The NeoPixel is addressed through the Seesaw interface using the seesaw_neopixel.h library – you don’t need separate GPIO pins for it!

Example 2: Multiple Encoders

The multiple_encoders example shows you how to work with two (or more) encoders on the same I2C bus. You’ll find this under File → Examples → Adafruit Seesaw → encoder → multiple_encoders.

What It Does:

This sketch initializes two encoders – one at the default address (0x36) and another at address 0x37 (with the A0 pad bridged). Each encoder is set up with its own NeoPixel color: the first encoder shows blue, and the second shows red. As you turn each encoder independently, you’ll see its position values update separately in the Serial Monitor.

This example demonstrates an important concept: each encoder is completely independent. They maintain their own position counters, button states, and NeoPixel colors. You simply create separate object instances and initialize them with different I2C addresses. This is the foundation for more complex projects, such as our Etch-A-Sketch, where we’ll use two encoders to control X- and Y-axis movement.

Building a Menu System

Now that we understand how the encoder works, let’s build something practical – a hierarchical menu system! This project will use a single I2C rotary encoder to navigate through menus and control the color and pattern of an RGB LED. It’s the perfect example of how rotary encoders excel at menu navigation.

What You’ll Need

  • Seeeduino XIAO RP2040 microcontroller
  • SSD1306 OLED display (128×64 pixels, I2C)
  • Adafruit I2C Rotary Encoder (default address 0x36)
  • STEMMA QT cables (or jumper wires if you prefer soldering)

The XIAO RP2040 is a great choice for this project because it’s compact, has built-in I2C support, and even includes an onboard NeoPixel LED that we can use as our RGB display. Both the OLED and encoder connect to the same I2C bus, making the wiring incredibly simple!

How the Menu System Works

Our menu system uses a state machine approach with three different states: Main Menu, Color Submenu, and Pattern Submenu. The encoder rotation lets you scroll through menu options, and pressing the encoder button selects an item or returns to the previous menu. It’s a classic hierarchical navigation pattern that you’ve probably used in countless devices.

Menu Structure

Here’s how the menu hierarchy is organized:

Main Menu:

  • Color – Opens the color selection submenu
  • Pattern – Opens the pattern selection submenu

Color Submenu:

  • Eight color choices: Red, Green, Blue, Yellow, Cyan, Magenta, White, and Off
  • Pressing the button applies the selected color and returns to the main menu

Pattern Submenu:

  • Solid – LED stays on continuously
  • Slow Blink – Blinks every second
  • Fast Blink – Blinks every 250ms
  • Pulse – Smooth breathing effect
  • Rainbow – Cycles through the color spectrum

Key Code Features

Here is the code for our Menu System:

Let’s take a closer look at how it works.

State Machine:

The code uses an enum called MenuState to track which menu you’re currently viewing. This makes the navigation logic clean and easy to understand. When you press the button, the code checks the current state and either enters a submenu or applies a selection and returns to the main menu.

Wrap-Around Navigation:

When you reach the end of a menu list and continue rotating, the selection wraps around to the beginning. This circular navigation feels natural and prevents you from getting “stuck” at the end of a list. The code handles this with simple modulo arithmetic.

Visual Feedback:

The encoder’s built-in NeoPixel changes color to match your selected color choice, providing instant visual confirmation. The OLED display shows the current menu with a “> ” indicator next to the selected item, making it clear where you are in the navigation.

Non-Blocking Pattern Updates:

The LED patterns (blinking, pulsing, rainbow) update without using delay() commands. Instead, the code uses millis() to check elapsed time. This keeps the interface responsive – you can always navigate the menu, even while a pattern is running.

Critical I2C Initialization:

One important detail in the code: Wire.begin() must be called before initializing the OLED display and encoder. This was a lesson learned through debugging – if you initialize I2C devices before calling Wire.begin(), you’ll end up with a blank display!

Build an Etch-A-Sketch

Now for the fun part – let’s build a digital Etch-A-Sketch! This project uses two I2C rotary encoders to create a drawing application with all sorts of features you’d never get with a mechanical toy. We’ll have color selection, adjustable line width, backlight control, and even the ability to save and load your settings.

What You’ll Need

  • ESP32-C6 DevKitC microcontroller
  • ILI9341 TFT display (320×240 pixels, SPI)
  • Two Adafruit I2C Rotary Encoders (addresses 0x36 and 0x37)
  • STEMMA QT cables

The ESP32-C6 provides plenty of processing power and has separate I2C and SPI interfaces, letting us connect the encoders and display without conflicts. Remember to bridge the A0 pad on one encoder to change its address to 0x37!

How the Etch-A-Sketch Works

Our digital Etch-A-Sketch improves on the classic toy in several ways. The left encoder controls horizontal movement, while the right encoder controls vertical movement – just like the original. We’ve added multiple operating modes you can cycle through by pressing the left encoder button. Each mode gives you different functionality:

Operating Modes:

  • Draw Mode (Red NeoPixel): Both encoders control X and Y movement
  • Color Mode (Current color NeoPixel): Left encoder cycles through 9 colors
  • Width Mode (Orange NeoPixel): Left encoder adjusts line width from 1 to 10 pixels
  • Brightness Mode (Yellow NeoPixel): Left encoder adjusts display backlight

Additional Features:

  • Press the right encoder button to clear the screen
  • Press both buttons simultaneously to enter Save/Load mode
  • A status bar at the bottom shows current color, line width, backlight percentage, and mode
  • A crosshair cursor shows your drawing position

Key Code Features

Here is the code for the Etch-a-Sketch:

Dual-Encoder Coordination:

The code maintains separate position trackers for each encoder (encX_position and encY_position). When in Draw mode, any change in either encoder moves the cursor and draws a line. The movement is scaled by 2 pixels per encoder click, which provides a good balance between precision and speed.

Thick Line Drawing:

When the line width exceeds 1 pixel, the code uses Bresenham’s line algorithm combined with filled circles to create smooth, thick lines. Each point along the line is filled with a circle at the current width, creating a paintbrush effect that looks much better than simple thick lines.

Cursor Management:

The cursor is implemented as a small crosshair that’s always visible in Draw mode but blinks in other modes. Before any screen update, the cursor is erased by drawing it in black, then redrawn after the update. This prevents the cursor from leaving artifacts as it moves around the screen.

NeoPixel Mode Indicators:

The left encoder’s NeoPixel changes color based on the current mode: red for Draw, the current selected color for Color mode, orange for Width, and yellow for Brightness. This provides instant visual feedback on what the encoder will control. The right encoder always stays blue to indicate its role as the Y-axis controller.

Persistent Settings with NVS:

The ESP32’s Non-Volatile Storage (NVS) system saves your last used color, line width, and backlight brightness. When you press both encoder buttons, you can choose to save your current settings or load previously saved ones. The encoders flash green when saving and yellow when loading, providing clear confirmation.

Mixed Bus Architecture:

This project demonstrates an important concept – you can use different communication protocols simultaneously. The TFT display uses SPI for high-speed graphics, while the encoders use I2C. The ESP32 handles both buses independently with no conflicts. This is one of the advantages of using microcontrollers with dedicated hardware peripherals.

Conclusion

The Adafruit I2C Rotary Encoder really is a game-changer for Arduino projects. By combining a rotary encoder, pushbutton, and RGB LED in a single I2C package, it dramatically simplifies both the hardware and software design of interactive projects. No more worrying about debouncing, no more eating up GPIO pins, no more complex timing code – it all just works!

What We’ve Learned

Throughout this article, we’ve covered a lot of ground:

  • How the Seesaw platform works and why it’s called “Seesaw”
  • Rotary encoder principles and quadrature signal detection
  • I2C address configuration using solder pads
  • Building hierarchical menu systems with state machines
  • Creating responsive, non-blocking user interfaces
  • Managing multiple encoders on one I2C bus
  • Integrating encoders with displays (both OLED and TFT)
  • Using NeoPixels for intuitive visual feedback
  • Implementing save/load functionality with non-volatile storage

Future Project Ideas

The techniques we’ve demonstrated can be applied to countless other projects. Here are some ideas to get you thinking:

Audio Projects:

  • Multi-band equalizer with separate encoders for each frequency band
  • Software-defined radio tuner with frequency and volume controls
  • MIDI controller with multiple parameter controls

Robotics:

  • Tank drive robot with independent left/right motor control
  • Pan-tilt camera platform controller
  • Robotic arm joint position control

Home Automation:

  • Smart thermostat with temperature and schedule controls
  • Smart lighting controller with hue, saturation, and brightness adjustment
  • Garden irrigation timer with zone and duration settings

Design Tips for Your Projects

When incorporating I2C rotary encoders into your own projects, keep these principles in mind:

  • Plan Your I2C Addresses: Before ordering hardware, map out all I2C devices and their addresses to avoid conflicts.
  • Use Visual Feedback: The built-in NeoPixel is valuable – use it to indicate modes, confirm actions, or show status.
  • Think in Modes: A single encoder can control many parameters through mode switching.
  • Keep Menus Shallow: Deep menu hierarchies frustrate users – aim for 2-3 levels maximum.
  • Use Wrap-around: Circular navigation feels more natural than hitting boundaries.
  • Update Displays Efficiently: Only redraw changed elements to maintain smooth operation.

Final Thoughts

The I2C Rotary Encoder represents a significant evolution in hobby electronics. By offloading encoder reading to a dedicated microcontroller and providing I2C access, Adafruit has created a building block that makes complex interfaces accessible to makers at all levels.

The two projects in this article – the hierarchical menu system and the Etch-A-Sketch – demonstrate just a fraction of what’s possible. The real power of these encoders lies in their flexibility: they’re equally at home in simple volume controls and sophisticated multi-parameter interfaces.

As you design your own projects, remember that good user interfaces are invisible – they feel natural and intuitive, allowing users to focus on their task rather than fighting with controls. The I2C Rotary Encoder, with its combination of tactile feedback, precise control, and visual indication, gives you the tools to create interfaces that delight rather than frustrate.

Whether you’re building a one-off project or designing a product, the Adafruit I2C Rotary Encoder deserves a place in your toolkit. Its combination of simplicity, capability, and polish makes it a joy to work with – and that joy translates directly into better projects.

Now it’s your turn to experiment. What will you build?

Parts List

Here are some components you’ll need to complete the experiments in this article. Please note that some of these links may be affiliate links, and DroneBot Workshop may receive a commission on your purchases. This does not increase the cost to you and is a method of supporting this ad-free website.

  • Adafruit I2C Rotary Encoder – Available from Adafruit Industries
  • Seeeduino XIAO RP2040 – Compact microcontroller with built-in NeoPixel
  • ESP32-C6 DevKitC – Modern ESP32 with WiFi 6
  • SSD1306 OLED Display – 128×64 pixel I2C display
  • ILI9341 TFT Display – 320×240 pixel color display
  • STEMMA QT Cables – For easy encoder connections

 

Resources

Adafruit I2C Rotary Encoder – Adafruit’s guide to using the I2C Rotary Encoders

Code – All the code used in this article, packed into a nice ZIP file

PDF Version – A PDF version of this article, also in a ZIP file.

 

Working with the Adafruit I2C Rotary Encoder

1 Comment
Oldest
Newest
Inline Feedbacks
View all comments
Richard
20 days ago

the pdf is not working. This seems to be true on many of the tutorials. No pdf, despite the icon for it at the beginning.