-
Notifications
You must be signed in to change notification settings - Fork 52
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
API V2 - I2C Review #693
base: main
Are you sure you want to change the base?
API V2 - I2C Review #693
Conversation
… use only one array of pins instead of 2
…publish dio event message, inc. partition sz
…ls into new functions
_msg_i2c_device_event | ||
.i2c_device_events[_msg_i2c_device_event.i2c_device_events_count] | ||
.type = sensor_type; | ||
float value = GetValueFromSensorsEvent(sensor_type, &event); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
not sure all adafruit_sensor value types will always be representable by a float, made me wonder what does a boolean become in float_value representation? Is it just nearly 1 or 0?
I don't thing we have a binary input yet, like a button over i2c, but it's on the roadmap (polling i2c in each loop, as though something was an analog pin over i2c for an ADC, or a button / keypress / rotary encoder change from seesaw device etc)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's a good point. The float is derived from the struct sensors_event_t
in Adafruit_Sensor. However, I do not see any issue adding a bool type to that union (i.e: bool_value
) as the union does not care about the type, only that one is selected, and we are "flagging" that it is a boolean by using a sensor type enum.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do you think this is something we should consider or implement right now?
void I2cHardware::InitBus(bool is_default, const char *sda, const char *scl) { | ||
uint8_t pin_sda, pin_scl; | ||
if (!is_default && (sda == nullptr || scl == nullptr)) { | ||
_bus_status = wippersnapper_i2c_I2cBusStatus_I2C_BUS_STATUS_ERROR_WIRING; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this might be the wrong message, if nullptr then we haven't set the alt bus sda/scl pins, i.e. corrupt protobuf msg from offline config?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not sure what is better here.
What I2cBusStatus
should we set instead? We could also add to I2cBusStatus
:
https://github.com/adafruit/Wippersnapper_Protobuf/blob/api-v2/proto/wippersnapper/i2c.proto#L10
#if defined(PIN_I2C_POWER) | ||
// turn on the I2C power by setting pin to opposite of 'rest state' | ||
pinMode(PIN_I2C_POWER, INPUT); | ||
delay(1); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Does this work reliably, should we increase the time to stablise to 5ms, and could that help for the Feather S2 BME280 situation (I took a peek at support and twiddling gpio7/i2cPower as a component didn't help)? There is also a PIN_I2C_POWER_INVERTED defined as pin7 for the revTft S2 feather (probably same situation) which appears unused in code (v1)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Does this work reliably, should we increase the time to stablise to 5ms,
The code here follows thevariant.cpp
for each board (https://github.com/espressif/arduino-esp32/blob/master/variants/adafruit_feather_esp32s2/variant.cpp#L37). I don't want to modify this to be out-of-sync with this file.
There is also a PIN_I2C_POWER_INVERTED defined as pin7 for the revTft S2 feather (probably same situation) which appears unused in code (v1)
I am confused. For the RevTFT S2, the variant only defines a TFT_I2C_POWER
pin
https://github.com/espressif/arduino-esp32/blob/master/variants/adafruit_feather_esp32s2_reversetft/variant.cpp#L36:37
And we handle it here in the code:
#elif defined(TFT_I2C_POWER) |
_bus_status = wippersnapper_i2c_I2cBusStatus_I2C_BUS_STATUS_ERROR_HANG; | ||
return; | ||
} | ||
_bus->setClock(50000); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I know this is from V1, I wonder if we need this optionally per sensor or something, but I was sure there were a couple with very strict requirements (couple needed 100k in theory and maybe another one had issues except around 20k). Ignore me for now, but if it rings a bell or comes up again then shout.
In my head we were running at 100kHz for everything, but I must have been thinking of circuitpython or something
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The specification was to run at 500kHz for everything on the bus. API v1 did contain a message that sets the I2C bus' frequency (https://github.com/adafruit/Wippersnapper_Protobuf/blob/master/proto/wippersnapper/i2c/v1/i2c.proto#L45) but since we are always sending 500kHz in that message, it got dropped in API v2.
@tyeth Noting that we discussed the following over Slack Huddle: |
The two issues mentioned above have been resolved. |
Test Results6 tests 6 ✅ 1m 5s ⏱️ Results for commit 5ac35f3. ♻️ This comment has been updated with latest results. |
Resolves #640
Pull Request Scope
src/i2c
and refactored all existing drivers to fit the new modified driver base class (drvBase
) withinsrc/i2c/drivers
config.json
file on an SD cardSensorEvent
message, fromsensor.proto
. This message can then be - published to MQTT, logged to sd, and/or published to the serialconfig.json
file into a protobuf message within classws_sd
This pull request only covers "offline mode" functionality, interfaces for publishing back to the MQTT broker have not yet been fully implemented.
Code Review Scope
This pull request adds the following new files within
src/i2c/
and replaces all existing files:I2C Model - Provides interfaces for interacting with messages within the
i2c.proto
APImodel.cpp
model.h
I2C Hardware - Manages low-level i2c bus functionality
hardware.cpp
hardware.h
I2C Controller - Manages high-level functionality for handling I2C messages
controller.cpp
controller.h
There are also refactored drivers the within
src/i2c/drivers/
folder. I do not expect all of the drivers within this folder to be reviewed as a subset was tested for functionality. However,drvBase.h
should be reviewed.Modifies functions within the
ws_sdcard
class:parseConfigFile()
Adds new functions within the
ws_sdcard
class:ParseI2cDeviceAddReplace()
LogI2cDeviceEvent()
(Optional) Hardware Testing
If you'd like to test this on hardware, I suggest building the firmware using PlatformIO. I have tested on: QT Py ESP32-S2 + RTC + SD BFF, Raspberry Pi Pico 2
Notes:
config.json
should reside on the WIPPER drive, not the MicroSD card.rtc
andsd_cs_pin
variables to match the name of the RTC you are using and the pin the MicroSD Card breakout is utilizingExample
config.json
- SHTC3 on default I2C Portshtc3.json
Example
config.json
- MCP9808 connected to PCA9546 MUX on an alternate I2C Portmuxpca-mcp.json
Example
config.json
- BME6xxmuxpca-mcp.json
Example
config.json
- AHT20aht20.json
Example
config.json
- 2x Sensors on one bus, BME280 and TSL2591config-bme280-tsl.json