|
Forum Index : Microcontroller and PC projects : Adafruit I2C rotary encoder w/ RGB LED
| Author | Message | ||||
| karlelch Guru Joined: 30/10/2014 Location: GermanyPosts: 315 |
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 ' ----------------------------------------------------------------------- |
||||
| The Back Shed's forum code is written, and hosted, in Australia. | © JAQ Software 2026 |