adafruit-ano-rotary-navigation-encoder-to-i2c-stemma-qt-adapter
adafruit-ano-rotary-navigation-encoder-to-i2c-stemma-qt-adapter
Adapter
Created by Liz Clark
https://learn.adafruit.com/adafruit-ano-rotary-navigation-encoder-to-i2c-stemma-qt-adapter
Overview 3
Pinouts 5
• Power Pins
• I2C Logic Pins
• Address Jumpers
• Interrupt Pin and LED
• UPDI Pin
• Power LED
• ANO Encoder Pins
Python Docs 13
Arduino 13
• Wiring
• Library Installation
• Example Code
Arduino Docs 17
Downloads 17
• Files
• Schematic and Fab Print
The ANO rotary encoder wheel is a funky user interface element, reminiscent of the
original clicking scroll wheel interface on the first iPods (https://adafru.it/Vbn). It's a
nifty kit, but the pin-out is a little odd - and there are a ton of pins needed to connect
to the rotary encoder and 5 button switches.
This Stemma QT breakout makes all that frustration go away - solder in the ANO
Directional Navigation and Scroll Wheel Rotary Encoder (not included) (http://adafru.it/
5001). The onboard microcontroller is programmed with our seesaw firmware and will
track all pulses and pins for you and then save the incremental value for querying at
any time over I2C. Plug it in with a Stemma QT cable for instant rotary goodness, with
any kind of microcontroller from an Arduino UNO up to a Raspberry Pi to one of our
QT Py's.
Power with 3 to 5V DC, and then use 3 or 5V logic I2C data. The INT pin can be
configured to pulse low whenever rotation or push-buttoning is detected so you do
not have to spam-read the I2C port to detect motion. It's also easy to add this
breakout to a breadboard - with six 0.1"-spaced breakout pads - if you so choose.
Four solder jumpers can be used to change the I2C address - up to 16 can share one
I2C bus! If you happen to need more, it's possible to set the I2C address with a
This is just the assembled and programmed 'seesaw' PCB for the ANO encoder, the
encoder is NOT included! Pick one up here (http://adafru.it/5001). Some soldering is
required to attach the encoder to the backing.
Pinouts
Power Pins
• VIN - This is the power pin. To power the board, give it the same power as the
logic level of your microcontroller - e.g. for a 3V microcontroller like a Feather
RP2040, use 3V, or for a 5V microcontroller like Arduino, use 5V.
• GND - This is common ground for power and logic.
• SCL - I2C clock pin, connect to your microcontroller I2C clock line. There's a 10K
pullup on this pin.
• SDA - I2C data pin, connect to your microcontroller I2C data line. There's a 10K
pullup on this pin.
• STEMMA QT (https://adafru.it/Ft4) - These connectors allow you to connect to
development boards with STEMMA QT / Qwiic connectors or to other things
with various associated accessories (https://adafru.it/JRA).
Address Jumpers
On the back of the board are four address jumpers, labeled A0, A1, A2 and A3, above
the breakout pads along the bottom of the board. These jumpers allow you to chain
up to 16 of these boards on the same pair of I2C clock and data pins. To do so, you
cut the jumpers "open" by separating the two pads.
If you happen to need more than 16, it's possible to set the I2C address with a special
address-change command that is saved to the onboard non-volatile EEPROM
memory.
The default I2C address is 0x49. The other address options can be calculated by
"adding" the A0/A1/A2/A3 to the base of 0x49.
A0 sets the lowest bit with a value of 1, A1 sets the next bit with a value of 2, A2 sets
the next bit with a value of 4 and A3 sets the next bit with a value of 8. The final
address is 0x49 + A3 + A2 + A1 + A0 which would be 0x58.
The table below shows all possible addresses, and whether the pin(s) should be high
(closed) or low (open).
UPDI Pin
• UPDI - This is the single-pin Unified Program and Debug Interface. This pin is for
external programming or on-chip-debugging for the ATtiny816 running the seesa
w firmware (https://adafru.it/VdL). We have a page in the ATtiny Breakouts with
seesaw Learn Guide (https://adafru.it/18ED) detailing how to reprogram these
chips with your own firmware (at your own risk). We don't provide any support
for custom builds of seesaw - we think this is cool and useful for the Maker
community.
Power LED
• Power LED - On the back of the board, above the STEMMA connector on the
right, is the power LED, labeled on. It is the green LED.
You can use this adapter with any CircuitPython microcontroller board or with a
computer that has GPIO and Python thanks to Adafruit_Blinka, our CircuitPython-for-
Python compatibility library (https://adafru.it/BSN).
Here's the Raspberry Pi wired with I2C using the STEMMA connector:
Once that's done, from your command line run the following command:
If your default Python is version 3 you may need to run 'pip' instead. Just make sure
you aren't trying to use CircuitPython on Python 2.x, it isn't supported!
Thankfully, we can do this in one go. In the example below, click the Download
Project Bundle button below to download the necessary libraries and the code.py file
in a zip file. Extract the contents of the zip file, and copy the entire lib folder and
the code.py file to your CIRCUITPY drive.
Your CIRCUITPY/lib folder should contain the following folders and file:
• adafruit_bus_device/
• adafruit_seesaw/
• adafruit_pixelbuf.mpy
Python Usage
Once you have the library pip3 installed on your computer, copy or download the
following example to your computer, and run the following, replacing code.py with
whatever you named the file:
python3 code.py
i2c_arm_baudrate=400000
If running Python: The console output will appear wherever you are running Python.
import board
from adafruit_seesaw import seesaw, rotaryio, digitalio
seesaw.pin_mode(1, seesaw.INPUT_PULLUP)
seesaw.pin_mode(2, seesaw.INPUT_PULLUP)
seesaw.pin_mode(3, seesaw.INPUT_PULLUP)
seesaw.pin_mode(4, seesaw.INPUT_PULLUP)
seesaw.pin_mode(5, seesaw.INPUT_PULLUP)
select = digitalio.DigitalIO(seesaw, 1)
select_held = False
up = digitalio.DigitalIO(seesaw, 2)
up_held = False
left = digitalio.DigitalIO(seesaw, 3)
left_held = False
down = digitalio.DigitalIO(seesaw, 4)
down_held = False
right = digitalio.DigitalIO(seesaw, 5)
right_held = False
encoder = rotaryio.IncrementalEncoder(seesaw)
last_position = None
while True:
position = encoder.position
if position != last_position:
last_position = position
print(f"Position: {position}")
for b in range(5):
if not buttons[b].value and button_states[b] is False:
button_states[b] = True
print(f"{button_names[b]} button pressed")
In the simple test example, the code confirms that you have connected the ANO
rotary encoder to I2C adapter by checking the seesaw firmware for the product ID
number. After that, in the loop, the rotary encoder position is printed to the serial
console. Additionally, if a button is pressed or released that is also printed to the
serial console.
Python Docs
Python Docs (https://adafru.it/18EG)
Arduino
Using the ANO rotary encoder to I2C adapter with Arduino involves wiring up the I2C
adapter to your Arduino-compatible microcontroller, installing the
Adafruit_Seesaw (https://adafru.it/BrV) library and running the provided example
code.
Wiring
Wire as shown for a 5V board like an Uno. If you are using a 3V board, like an Adafruit
Feather, wire the board's 3V pin to the adapter VIN.
Here is an Adafruit Metro wired up to the adapter using the STEMMA QT connector:
Library Installation
You can install the Adafruit_Seesaw library for Arduino using the Library Manager in
the Arduino IDE.
Click the Manage Libraries ... menu item, search for Adafruit_Seesaw, and select the
Adafruit seesaw Library library:
If the "Dependencies" window does not come up, then you already have the
dependencies installed.
If the dependencies are already installed, you must make sure you update
them through the Arduino Library Manager before loading the example!
Example Code
/*
* This example shows how to read from a seesaw encoder module.
* The available encoder API is:
* int32_t getEncoderPosition();
int32_t getEncoderDelta();
void enableEncoderInterrupt();
void disableEncoderInterrupt();
*/
#include "Adafruit_seesaw.h"
#define SS_SWITCH_SELECT 1
#define SS_SWITCH_UP 2
#define SS_SWITCH_LEFT 3
Adafruit_seesaw ss;
int32_t encoder_position;
void setup() {
Serial.begin(115200);
while (!Serial) delay(10);
if (! ss.begin(SEESAW_ADDR)) {
Serial.println("Couldn't find seesaw on default address");
while(1) delay(10);
}
Serial.println("seesaw started");
uint32_t version = ((ss.getVersion() >> 16) & 0xFFFF);
if (version != 5740){
Serial.print("Wrong firmware loaded? ");
Serial.println(version);
while(1) delay(10);
}
Serial.println("Found Product 5740");
ss.pinMode(SS_SWITCH_UP, INPUT_PULLUP);
ss.pinMode(SS_SWITCH_DOWN, INPUT_PULLUP);
ss.pinMode(SS_SWITCH_LEFT, INPUT_PULLUP);
ss.pinMode(SS_SWITCH_RIGHT, INPUT_PULLUP);
ss.pinMode(SS_SWITCH_SELECT, INPUT_PULLUP);
Serial.println("Turning on interrupts");
ss.enableEncoderInterrupt();
ss.setGPIOInterrupts((uint32_t)1 << SS_SWITCH_UP, 1);
void loop() {
if (! ss.digitalRead(SS_SWITCH_UP)) {
Serial.println("UP pressed!");
}
if (! ss.digitalRead(SS_SWITCH_DOWN)) {
Serial.println("DOWN pressed!");
}
if (! ss.digitalRead(SS_SWITCH_SELECT)) {
Serial.println("SELECT pressed!");
}
if (! ss.digitalRead(SS_SWITCH_LEFT)) {
Serial.println("LEFT pressed!");
}
if (! ss.digitalRead(SS_SWITCH_RIGHT)) {
Serial.println("RIGHT pressed!");
}
Upload the sketch to your board and open up the Serial Monitor (Tools -> Serial
Monitor) at 115200 baud. You'll see the seesaw firmware recognized by the code.
Then, when you press any of the buttons or turn the encoder it will print to the Serial
Monitor. You'll also see the interrupt LED light up with each encoder turn.
Arduino Docs
Arduino Docs (https://adafru.it/SdQ)
Downloads
Files
• ATtiny816 Datasheet (https://adafru.it/18EI)
• ANO Rotary Encoder Datasheet (https://adafru.it/Vbp)
• EagleCAD PCB files on GitHub (https://adafru.it/18EK)
• 3D models on GitHub (https://adafru.it/18EM)
• Fritzing object in the Adafruit Fritzing Library - back view, no encoder (https://
adafru.it/18EQ)
• Fritzing object in the Adafruit Fritzing Library - front view, with encoder (https://
adafru.it/18ES)