diff --git a/examples/seesaw/rotary-encoder/main.go b/examples/seesaw/rotary-encoder/main.go new file mode 100644 index 000000000..fcd4571a8 --- /dev/null +++ b/examples/seesaw/rotary-encoder/main.go @@ -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) + } +} diff --git a/examples/seesaw/main.go b/examples/seesaw/soil-sensor/main.go similarity index 100% rename from examples/seesaw/main.go rename to examples/seesaw/soil-sensor/main.go diff --git a/seesaw/encoder.go b/seesaw/encoder.go new file mode 100644 index 000000000..dbb7222cc --- /dev/null +++ b/seesaw/encoder.go @@ -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[:]) +} diff --git a/seesaw/registers.go b/seesaw/registers.go index 3d1ebe75a..abebdf1b6 100644 --- a/seesaw/registers.go +++ b/seesaw/registers.go @@ -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 +) diff --git a/smoketest.sh b/smoketest.sh index f21e2be55..a5b93656e 100755 --- a/smoketest.sh +++ b/smoketest.sh @@ -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