-
Notifications
You must be signed in to change notification settings - Fork 195
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
Blank I2C output ESP32 simple program #910
Comments
Code looks fine. Worth to try is using the pins we use in the examples (32,33). If that changes things for you it's probably a bug on our side (since 21,22 are the default pins, they should also work) If that doesn't work you might want to use a logic analyzer (for the clock speeds of I2C a very cheap one is more than enough) and see what is happening on the wires |
@bjoernQ I'm also experiencing issues with I2C async version.
I've experiening issues with the IMU I2Csensor as well, though I'm not sure if it's only the esp-hal impl or a driver crate bug included in there, see PR #862 |
Thanks! Oh, I somehow missed #862 - need to look into that |
Thanks! There's definitely something broken in I2C but I'm far from my equipment so can't provide you with further info. |
@bjoernQ I've acquired a logic analyzer and got it working with saleae's Logic2 however I'm not 100% sure what I should be looking for 😅 I've written a simple program to request the IR data every second and then attached the logic analyzer to the SDA and SCL pins. Please see the schematic, screenshot and code below. SchematicThis is how I've wired the analyzer to the circuit (I had to add a diode in order for the circuit to run... not sure if this can cause any issues). graph TD;
subgraph ESP32
GPIO21
GPIO22
GND_ESP
3V3
end
GPIO21 --- SDA
GPIO22 --- SCL
GND_ESP --- GND_MLX
3V3 --- VCC
subgraph MLX90614
SDA
SCL
GND_MLX
VCC
end
GND_MLX --- GND_LOGIC
SDA --- CH0
SCL --- DIODE_1N4148 --- CH1
subgraph DIODE_1N4148
end
subgraph LOGIC_ANALYZER
GND_LOGIC
CH0
CH1
end
Logic Analyzer CaptureI can see some communication on the wires but am not sure what a correct/incorrect patterns looks like Program#![no_std]
#![no_main]
use esp32_hal::{
clock::ClockControl, entry, gpio::IO, i2c::I2C, peripherals::Peripherals, prelude::*, Delay,
};
use esp_backtrace as _;
use esp_println::println;
#[entry]
fn main() -> ! {
// Initialize peripherals
let peripherals = Peripherals::take();
let system = peripherals.SYSTEM.split();
let clocks = ClockControl::boot_defaults(system.clock_control).freeze();
let io = IO::new(peripherals.GPIO, peripherals.IO_MUX);
// Initialize I2C specific pins
let sda = io.pins.gpio21;
let scl = io.pins.gpio22;
// Open I2C0
let mut i2c = I2C::new(peripherals.I2C0, sda, scl, 100u32.kHz(), &clocks);
// Delay configuration
let mut delay = Delay::new(&clocks);
println!("Scanning for devices...");
// Scan for devices
if let Ok(_) = i2c.write(0x5A, &[0x07]) {
// 0x04 is the command to read the raw sensor data
let to_send: [u8; 1] = [0x04];
loop {
let mut data = [0u8; 3];
i2c.write_read(0x5A, &to_send, &mut data).ok();
println!("Sent: 0x{:02X}, Received: {:02x?}", 0x00, data);
delay.delay_ms(1000u32);
}
}
loop {}
} Thank you for the help 🙏 |
Great you got a logic analyzer. Will definitely be helpful in the future. Seems like for whatever reason the clock signal looks "interesting". The Saleae software also contains a protocol decoder which you could use to make more sense of the signals but, in this case, SCL already looks suspicious. Would be good if you could use different pin (32 or 33) as SDA and compare what the logic analyzer captures |
As I mentioned in #862, it's possible to simulate similar problem, by connecting ungrounded wire to PIN 8, or by touching the board. It seems that I2C clocks are simply thrown out of balance. Workaround: Decrease frequency of I2C to 2 kHz. |
Possible suspect 1esp-hal/esp-hal-common/src/i2c.rs Lines 1498 to 1515 in 6005f92
icm42670 crate exampleIt's used both in async and current block Api for the crate:
Will try with lowered frequency next |
I'm investigating this issue on the Rust board. |
Thank you everyones help! After much trial and error I was able to capture better samples of the i2c communication. I believe the issue is related to the esp-hal/esp-hal-common/src/i2c.rs Lines 1496 to 1512 in ece40ab
Working Example CaptureLooking at a capture of working The write:
then without a
for completeness the full command flow is
|
awesome thank you! I just pulled it down and got similar results. However it appears that you're changes are for async i2c and I am currently not using Do you know if these changes will work in the sync case? Also quick note but it appears there is still a |
I haven't tested my implementation but decided to share it because you commented on the issue. And no I don't believe you can do this in the blocking version. In async you can wait for two futures too complete in parallel. |
@elpiel got it, thank you for sharing I really appreciate the information and am going to use the code to help debug the issue further 🙏 |
@drbh the time between write and read seem to be huge. Are you running in release mode? This is how it looks like for me (other i2c device so it looks different) Maybe the MLX90614 just doesn't like the long pause between write and read |
Is this resolved? Can we close this issue? |
@bjoernQ unfortunately I still cannot read data from the MLX90614, you were right I was originally compiling in debug. Building release did improve the timing (shown below) but I still get a response of The only difference between the arduino and rust logic output seems to be the number of transactions sent over the bus. I believe this is due to It may make sense to close this issue since I cannot confirm that the issue is related to Thanks for all of the help! |
I think I am experiencing the same, or very similar issue. Please let me know if I should open another issue elsewhere. I am using different boards (esp32-s3 and esp32-c6 DevKitC-1) targeting a different I2C device (Adafruit Atecc608A, not that it seems to matter yet at this point) though. When I try a slightly adapted version of @drbh s code (chip has a config zone that can be locked, don't wont to write random commands and ruin the chip), the program gets stuck after 2 iterations of the for loop: #![no_std]
#![no_main]
use esp32s3_hal::{clock::ClockControl, prelude::*, timer::TimerGroup, Delay, IO};
use esp_backtrace as _;
use esp_println::println;
use esp32s3_hal::i2c::I2C;
#[entry]
fn main() -> ! {
esp_println::logger::init_logger(log::LevelFilter::Info);
let peripherals = Peripherals::take();
let system = peripherals.SYSTEM.split();
let clocks = ClockControl::boot_defaults(system.clock_control).freeze();
// Set up SCL & SDA
let io = IO::new(peripherals.GPIO, peripherals.IO_MUX);
let scl = io.pins.gpio1;
let sda = io.pins.gpio2;
// Construct I2C
let mut i2c = I2C::new(peripherals.I2C0, scl, sda, 100u32.kHz(), &clocks);
let mut delay = Delay::new(&clocks);
for addr in 0..=127 {
println!("Scanning Address {}", addr as u8);
// Scan Address
let res = i2c.read(addr as u8, &mut [0]);
// Check and Print Result
match res {
Ok(_) => println!("Device Found at Address {}", addr as u8),
Err(err) => println!("No Device Found: {:?}", err),
}
}
loop {
println!("Loop...");
delay.delay_ms(500u32);
}
} Output of stuck program:
I expected that it would run through the for-loop and get back with one device found. I didn't expect the reads to get hung up in any case. I tried
(I am new to embedded, I hope this counts as minimal example, my original goal is to get this library supported on my hardware but when trying to wake up the chip, the program either get's stuck or fails here https://github.com/BlackbirdHQ/at-cryptoauth-rs/blob/46db006c2da43e82bba4508e79e9db41bf84ce94/src/datalink.rs#L122) |
This doesn't seem to be related to the issue here and probably it's better to create a separate issue for it |
This issue has grown stale, and I'm not sure there's anything actionable here, so gonna go ahead and close this. Everybody involved, please feel free to open a new issue if you are still experiencing any problems. |
Thank you for the awesome library. I am having issues connecting a MLX90614 (on a breakout board with 4.7K pull-up resistors on sda and scl) to my ESP32.
I've been able to validate that the device works via the Ardunio IDE using this library and this program.
However I cannot seem to get a useful response when trying to communicate with the I2C bus via
esp-hal
I've tried to manually
write_read
at the address0x5A
and always get a response of[ff, ff, ff]
.Additionally I've attempted to scan for all I2C devices and send all 1 byte messages and always get a response of
[00, 00, 00]
or[ff, ff, ff]
. Please see the example code below.I am an embedded newbie so its very likely I'm doing something (or everything) completely wrong. Is there a better/correct way to read data from an I2C bus?
The text was updated successfully, but these errors were encountered: