Home
JAQForum Ver 24.01
Log In or Join  
Active Topics
Local Time 11:02 22 Feb 2026 Privacy Policy
Jump to

Notice. New forum software under development. It's going to miss a few functions and look a bit ugly for a while, but I'm working on it full time now as the old forum was too unstable. Couple days, all good. If you notice any issues, please contact me.

Forum Index : Microcontroller and PC projects : Adafruit I2C rotary encoder w/ RGB LED

Author Message
karlelch

Guru

Joined: 30/10/2014
Location: Germany
Posts: 315
Posted: 06:18am 21 Feb 2026
Copy link to clipboard 
Print this post

Hi

for a radio project, I needed a rotary encoder and found this one: I2C rotary encoder w/ RGB LED . If someone is interested, here is the code to use it.

Best
Thomas

' Test program for Adafruit I2C QT Rotary Encoder with Seesaw
' -----------------------------------------------------------------------
Option BASE 0
Option EXPLICIT
Option DEFAULT None

' -----------------------------------------------------------------------
' Definitions
' -----------------------------------------------------------------------
Const ENC_ADDR          = &H36               ' Encoder's I2C address
Const ENC_PIN_SDA       = MM.Info(PinNo GP0) ' SDA pin
Const ENC_PIN_SCL       = MM.Info(PinNo GP1) ' SCL pin
Const ENC_I2C_FREQ      = 1000

' Seesaw Base Registers
Const ENC_REG_STATUS    = &H00
Const ENC_REG_GPIO      = &H01
Const ENC_REG_NEOPIXEL  = &H0E
Const ENC_REG_ENCODER   = &H11

' Status Functions
Const ENC_STATUS_HW_ID  = &H01
Const ENC_STATUS_SWRST  = &H7F

' GPIO Functions
Const ENC_GPIO_DIRCLR   = &H03 ' Set to Input
Const ENC_GPIO_BULK     = &H04 ' Read all GPIO
Const ENC_GPIO_SET      = &H05 ' Set Output High
Const ENC_GPIO_PULLEN   = &H0B ' Pull-up Enable

' Encoder Functions
Const ENC_INTENSET      = &H10
Const ENC_POSITION      = &H30
Const ENC_DELTA         = &H40

' NeoPixel Functions
Const ENC_NEO_PIN       = &H01
Const ENC_NEO_SPEED     = &H02
Const ENC_NEO_BUF_LEN   = &H03
Const ENC_NEO_BUF_WRITE = &H04
Const ENC_NEO_SHOW      = &H05

' Hardware Config
Const ENC_BTN_PIN       = 24   ' Button is on Pin 24
Const ENC_NEO_PIN_NUM   = 6    ' NeoPixel is on Pin 6

' Encoder data type
Type TRotaryEncoder
 position As Integer
 btn As Integer
End Type

' -----------------------------------------------------------------------
Dim encData As TRotaryEncoder
Dim Integer wheelPos

Print "Initializing I2C Rotary Encoder..."

' Setup I2C
SetPin ENC_PIN_SDA, ENC_PIN_SCL, I2C
I2C OPEN ENC_I2C_FREQ, 500

' Initialize rotary encoder via seesaw
SeesawEncoder.init()

Print "Running. Press Ctrl-C to stop."

' Main loop
Do
 encData = SeesawEncoder()

 ' Update LED based on position or button
 If encData.btn Then
   ' Button Pressed: White
   SeesawEncoder.setLED(255, 255, 255)
 Else
   ' Button Released: Color Wheel based on position
   ' Map position to 0-255 for color wheel
   wheelPos = (encData.position *10) Mod 255
   If wheelPos < 0 Then Inc wheelPos, 255
   SeesawEncoder.setLEDWheel(wheelPos)
 EndIf

 ' Print Status
 Print @(0,0) "Position: " Str$(encData.position, 6) "  ";
 Print "Button: ";
 If encData.btn = 0 Then Print "PRESSED " Else Print "RELEASED";
 Print "   "

 Pause 50
Loop
End

' =======================================================================
' Rotary encoder function
' -----------------------------------------------------------------------
Sub SeesawEncoder.init()
 ' Initialize rotary encoder
  Local Integer idBuf(1), addr = ENC_ADDR
  Print "Initializing Seesaw rotary encoder ..."

 ' Reset Seesaw to ensure clean state
 I2C WRITE ENC_ADDR, 0, 3, ENC_REG_STATUS, ENC_STATUS_SWRST, &HFF
 Pause 500

 ' Check HW ID (Should be &H55)
 I2C WRITE ENC_ADDR, 1, 2, ENC_REG_STATUS, ENC_STATUS_HW_ID
 Pause 5
 I2C READ ENC_ADDR, 0, 1, idBuf()
 Print "| Seesaw harware ID: ";Hex$(idBuf(0))

 ' Configure Button (Pin 24) AND Encoder (Pins 12, 13)
 ' Pin 24 is in Byte 0 (Bits 31-24): Bit 0 -> &H01
 ' Pins 12, 13 are in Byte 2 (Bits 15-8):
 '   Pin 12 (Bit 4) -> &H10
 '   Pin 13 (Bit 5) -> &H20
 ' Combined Mask: &H01, &H00, &H30, &H00
 '
 ' Set Direction to INPUT
 I2C WRITE addr, 0,6, ENC_REG_GPIO, ENC_GPIO_DIRCLR, &H01,&H00,&H30,&H00
 Pause 10
 ' Enable Pull-up
 I2C WRITE addr, 0,6, ENC_REG_GPIO, ENC_GPIO_PULLEN, &H01,&H00,&H30,&H00
 Pause 10
 ' Set Pull-up High
 I2C WRITE addr, 0,6, ENC_REG_GPIO, ENC_GPIO_SET, &H01,&H00,&H30,&H00

 ' Enable Encoder Interrupts
 I2C WRITE addr, 0,3, ENC_REG_ENCODER, ENC_INTENSET, &H01
 Pause 10

 ' Configure NeoPixel
 ' Set Pin
 I2C WRITE addr, 0,3, ENC_REG_NEOPIXEL, ENC_NEO_PIN, ENC_NEO_PIN_NUM
 Pause 10
 ' Set Speed (1 = 800kHz)
 I2C WRITE addr, 0,3, ENC_REG_NEOPIXEL, ENC_NEO_SPEED, 1
 Pause 10
 ' Set Buffer Length (3 bytes for 1 pixel)
 ' Length is 2 bytes big endian: 0, 3
 I2C WRITE addr, 0,4, ENC_REG_NEOPIXEL, ENC_NEO_BUF_LEN, 0,3
 Pause 10

 ' Reset Encoder Position to 0
 I2C WRITE addr, 0,6, ENC_REG_ENCODER, ENC_POSITION, 0,0,0,0
End Sub

' - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Function SeesawEncoder() As TRotaryEncoder
 ' Return state of encoder and button
 Local Integer rBuf(3), v

 ' Read 4 bytes from Encoder Position register
 ' Use Option 0 (Stop) to let the chip process during the pause
 I2C WRITE ENC_ADDR, 0,2, ENC_REG_ENCODER, ENC_POSITION
 Pause 10
 I2C READ ENC_ADDR, 0,4, rBuf()
 v = (rBuf(0) << 24) Or (rBuf(1) << 16) Or (rBuf(2) << 8) Or rBuf(3)
 If (rBuf(0) And &H80) Then
   Inc v, -&H100000000
 EndIf
 SeesawEncoder.position = v

 ' Read button state
 ' (Pin 24 corresponds to bit 0 of the first byte (rBuf(0));
 '  logic is inverted (Pull-up): 0=Pressed, 1=Released)
 I2C WRITE ENC_ADDR, 0, 2, ENC_REG_GPIO, ENC_GPIO_BULK
 Pause 10
 I2C READ ENC_ADDR, 0, 4, rBuf()
 SeesawEncoder.btn = Not(rBuf(0) And &H01)
End Function


Sub SeesawEncoder.setLED(r%, g%, b%)
 ' Set RGB LED
 ' Write buffer: Offset(2 bytes), Data(G, R, B) and show
 ' (Note: NeoPixels are typically GRB)
 I2C WRITE ENC_ADDR, 0,7, ENC_REG_NEOPIXEL, ENC_NEO_BUF_WRITE, 0,0,g%,r%,b%
 I2C WRITE ENC_ADDR, 0,2, ENC_REG_NEOPIXEL, ENC_NEO_SHOW
End Sub


Function SeesawEncoder.setLEDWheel(wPos%) As Integer
 ' Set RGB LED color by color wheel value
 Local Integer r, g, b
 wPos% = 255 -wPos%
 If wPos% < 85 Then
   r = 255 -wPos% *3
   g = 0
   b = wPos% *3
 ElseIf wPos% < 170 Then
   Inc wPos%, -85
   r = 0
   g = wPos% *3
   b = 255 -wPos% *3
 Else
   Inc wPos%, -170
   r = wPos% *3
   g = 255 -wPos% *3
   b = 0
 EndIf
 SeesawEncoder.setLED(r, g, b)
End Sub

' -----------------------------------------------------------------------
 
Print this page


To reply to this topic, you need to log in.

The Back Shed's forum code is written, and hosted, in Australia.
© JAQ Software 2026