You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
I'm trying to use a peripheral from Adafruit which communicates over I2C. The same setup works fine with their Arduino library. I copied the protocol from there, and I can't see anything wrong with my implementation, but it doesn't work via Nesper 🤷♂️ I've tried messing with the clock speed, different pins, different pullups, etc. I can tell there's some communication happening, because any other address hangs the system (wish I had an oscilloscope), but all I get is 0xFF back for every byte for every register I try.
Any ideas? Am I doing something wrong?
import nesper/timers
import nesper/i2cs
import nesper
#constTAG*: cstring="input"SCL_PIN=gpio_num_t(22)
SDA_PIN=gpio_num_t(23)
SEESAW_ADC_BASE=0x09'u8SEESAW_GPIO_BASE=0x01'u8SEESAW_ADC_CHANNEL_OFFSET=0x07'u8SEESAW_GPIO_DIRSET_BULK=0x02'u8SEESAW_GPIO_DIRCLR_BULK=0x03'u8SEESAW_GPIO_BULK=0x04'u8SEESAW_GPIO_BULK_SET=0x05'u8SEESAW_GPIO_BULK_CLR=0x06'u8SEESAW_GPIO_BULK_TOGGLE=0x07'u8SEESAW_GPIO_INTENSET=0x08'u8SEESAW_GPIO_INTENCLR=0x09'u8SEESAW_GPIO_INTFLAG=0x0A'u8SEESAW_GPIO_PULLENSET=0x0B'u8SEESAW_GPIO_PULLENCLR=0x0C'u8BUTTON_RIGHT=6BUTTON_DOWN=7BUTTON_LEFT=9BUTTON_UP=10BUTTON_SEL=14
button_mask: uint32= (1shlBUTTON_RIGHT) or (1shlBUTTON_DOWN) or
(1shlBUTTON_LEFT) or (1shlBUTTON_UP) or (1shlBUTTON_SEL)
let port1 =newI2CMaster(port =I2C_NUM_0,
sda_io_num =SDA_PIN, ## !< GPIO number for I2C sda signal
scl_io_num =SCL_PIN, ## !< GPIO number for I2C scl signal
clk_speed =100_000.Hertz,
sda_pullup_en =false, ## !< Internal GPIO pull mode for I2C sda signal
scl_pullup_en =false, ## !< Internal GPIO pull mode for I2C scl signal
intr_alloc_flags = {})
procseesawWrite(bs: seq[uint8]) =var cmd = port1.newCmd()
cmd.start()
cmd.writeTo(0x49)
for b in bs:
cmd.writeByte(b)
cmd.stop()
port1.submit(cmd, 10.Millis)
procseesawRead(bs: seq[uint8], size: uint): seq[uint8] =result=newSeq[uint8](size)
seesawWrite(bs)
delayMillis(1)
var readCmd = port1.newCmd()
readCmd.start()
readCmd.readFrom(0x49)
readCmd.read(result, ACK)
readCmd.stop()
port1.submit(readCmd, 10.Millis)
procinitInput*() =let maskcmd =@[uint8(button_mask shr24), uint8(button_mask shr16),
uint8(button_mask shr8), uint8(button_mask and0xFF)]
seesawWrite(@[SEESAW_GPIO_BASE, SEESAW_GPIO_DIRCLR_BULK] & maskCmd)
seesawWrite(@[SEESAW_GPIO_BASE, SEESAW_GPIO_PULLENSET] & maskCmd)
seesawWrite(@[SEESAW_GPIO_BASE, SEESAW_GPIO_BULK_SET] & maskCmd)
seesawWrite(@[SEESAW_GPIO_BASE, SEESAW_GPIO_INTENSET] & maskCmd)
procprintButtons*() =echo(seesawRead(@[SEESAW_GPIO_BASE, SEESAW_GPIO_BULK], 8))
echo(seesawRead(@[SEESAW_ADC_BASE, SEESAW_ADC_CHANNEL_OFFSET], 2))
The text was updated successfully, but these errors were encountered:
The esp-lib has given me lots of headaches with I2C. It looks like you have sda_pullup_en and scl_pullup_en disabled. NVM, you said you tried out different configurations.
There's a few things to try. I had a lot of difficulty with I2C on esp-lib which is what Nesper wraps around. AFAICT, it's with the esp-lib itself and not the Nesper wrappers. The Arduino libraries define a pretty sane set of defaults for dealing with NACK and ACK's while the esp-lib version are much lower level.
I actually moved to using esp-idf-lib I2C drivers in my latest Nesper projects because it was more reliable. They wrap the ACK/NACK's for you and it works for most proper I2C devices. You can see an example on the devel branch here.
the clock speed is set to 100_000.Hertz which is a bit slow for some devices, they sometimes prefer 400_000.Hertz
sometimes the ACK vs LAST_NACK can be the difference. Most devices do a NACK on the final read byte
similar thing for the last writeByte where you may need to do a writeByte(ack=false)
Also, you might consider trying Nephyr as it supports a lot of ESP32 features but is much more stable. It's what I'm using these days for new projects. :-)
Though for Nesper I'd recommend the esp-idf-lib I2C driver as the way to go.
I'm trying to use a peripheral from Adafruit which communicates over I2C. The same setup works fine with their Arduino library. I copied the protocol from there, and I can't see anything wrong with my implementation, but it doesn't work via Nesper 🤷♂️ I've tried messing with the clock speed, different pins, different pullups, etc. I can tell there's some communication happening, because any other address hangs the system (wish I had an oscilloscope), but all I get is
0xFF
back for every byte for every register I try.Any ideas? Am I doing something wrong?
The text was updated successfully, but these errors were encountered: