Skip to content

Add support for seesaw encoders #771

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 2 commits into
base: dev
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
35 changes: 35 additions & 0 deletions examples/seesaw/rotary-encoder/main.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
package main

import (
"machine"
"time"

"tinygo.org/x/drivers/seesaw"
)

// example reading the position of a rotary encoder (4991) powered by a seesaw
// https://learn.adafruit.com/adafruit-i2c-qt-rotary-encoder/arduino
func main() {
// This assumes you are using an Adafruit QT Py RP2040 for its Stemma QT connector
// https://www.adafruit.com/product/4900
i2c := machine.I2C1
i2c.Configure(machine.I2CConfig{
SCL: machine.I2C1_QT_SCL_PIN,
SDA: machine.I2C1_QT_SDA_PIN,
})

dev := seesaw.New(i2c)
dev.Address = 0x36

for {
time.Sleep(time.Second)

pos, err := dev.GetEncoderPosition(0, false)
if err != nil {
println(err)
continue
}

println(pos)
}
}
File renamed without changes.
49 changes: 49 additions & 0 deletions seesaw/encoder.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
package seesaw

import (
"errors"
)

var errInvalidEncoderNumber = errors.New("invalid encoder choice, 0-15 are supported")

// GetEncoderPosition returns the absolute position (or delta since the previous call) of the specified rotary encoder.
func (d *Device) GetEncoderPosition(encoder uint, asDelta bool) (int32, error) {
if encoder >= 16 {
return 0, errInvalidEncoderNumber
}

// The function address' upper nibble is the function, the lower nibble selects which encoder to communicate with
fnAddr := FunctionAddress(encoder)
if asDelta {
fnAddr |= FunctionEncoderDelta
} else {
fnAddr |= FunctionEncoderPosition
}

var buf [4]byte
err := d.Read(ModuleEncoderBase, fnAddr, buf[:])
if err != nil {
return 0, err
}

return int32(buf[0])<<24 | int32(buf[1])<<16 | int32(buf[2])<<8 | int32(buf[3]), nil
}

// SetEncoderPosition calibrate's the encoder's current absolute position to be whatever the provided position is.
func (d *Device) SetEncoderPosition(encoder uint, position int32) error {
if encoder >= 16 {
return errInvalidEncoderNumber
}

// The function address' upper nibble is the function, the lower nibble selects which encoder to communicate with
fnAddr := FunctionEncoderPosition | FunctionAddress(encoder)

buf := [4]byte{
byte(position >> 24),
byte(position >> 16),
byte(position >> 8),
byte(position),
}

return d.Write(ModuleEncoderBase, fnAddr, buf[:])
}
10 changes: 10 additions & 0 deletions seesaw/registers.go
Original file line number Diff line number Diff line change
Expand Up @@ -98,3 +98,13 @@ const (
FunctionKeypadCount FunctionAddress = 0x04
FunctionKeypadFifo FunctionAddress = 0x10
)

// encoder module function address registers
// these are the defaults for encoder 0, change the lower nibble to address other encoders
// see the Device.GetEncoderPosition and SetEncoderPosition methods for examples.
const (
FunctionEncoderIntenset FunctionAddress = 0x10
FunctionEncoderIntenclr FunctionAddress = 0x20
FunctionEncoderPosition FunctionAddress = 0x30
FunctionEncoderDelta FunctionAddress = 0x40
)
2 changes: 1 addition & 1 deletion smoketest.sh
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ tinygo build -size short -o ./build/test.hex -target=p1am-100 ./examples/p1am/ma
tinygo build -size short -o ./build/test.hex -target=pico ./examples/pca9685/main.go
tinygo build -size short -o ./build/test.hex -target=microbit ./examples/pcd8544/setbuffer/main.go
tinygo build -size short -o ./build/test.hex -target=microbit ./examples/pcd8544/setpixel/main.go
tinygo build -size short -o ./build/test.hex -target=feather-rp2040 ./examples/seesaw
tinygo build -size short -o ./build/test.hex -target=feather-rp2040 ./examples/seesaw/soil-sensor
tinygo build -size short -o ./build/test.hex -target=arduino ./examples/servo
tinygo build -size short -o ./build/test.hex -target=pico ./examples/sgp30
tinygo build -size short -o ./build/test.hex -target=pybadge ./examples/shifter/main.go
Expand Down