Skip to content
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

How to read I2C data without sending a command? #129

Open
ea7kir opened this issue Dec 6, 2021 · 26 comments
Open

How to read I2C data without sending a command? #129

ea7kir opened this issue Dec 6, 2021 · 26 comments

Comments

@ea7kir
Copy link

ea7kir commented Dec 6, 2021

Raspberry Pi 4B, RASPIO 64 bit Bullseye Lite, Swift Version 5.5

For example, to read the Status Register of an SHT31 (datasheet page 13)

Screenshot 2021-12-06 at 15 09 56

would require...

i2c.writeByte(0x44, command: 0xF3, value: 0x2D)
let data = i2c.readData(0x44) // would return 6 bytes, but this is not possible.

It would also be helpful to be able to send word commands like this...

i2c.writeWord(0x44, command: 0xF32D)

Any help with this would be most helpful, because I'm completely stuck.

@uraimo
Copy link
Owner

uraimo commented Dec 6, 2021

Hi, that diagram looks identical to the SHT20 one, try doing two readByte in sequence like Sam did, or 3 if you want the CRC (useless imho).
That readData expects that the data is sent with an array format and I suppose that's not what the sensor does.

@ea7kir
Copy link
Author

ea7kir commented Dec 6, 2021 via email

@uraimo
Copy link
Owner

uraimo commented Dec 6, 2021

Hmm, 16bits commands are not even allowed by the protocol, I wonder if 8+8 could work, have you tried something like this:

i2c.writeByte(0x44, command: 0xF3, value: 0x2D)
let value = i2c.readWord(0x44, command: 0xF3)
let crc = i2c.readByte(0x44, command: 0xF3) //optional

Also, with that "would return 6 bytes, but this is not possible." did you mean that when you ran that you got 6 bytes? Did you try decoding the value and see if it matched what you expected?

You could also try asking on the swift-arm Slack to check if someone else has already tried something similar, I don't know how active it is lately.

For the DS18B20 if you can't get the i2c version to work I wrote a library for the 1-Wire version of the sensor (should be its native protocol).

@ea7kir
Copy link
Author

ea7kir commented Dec 7, 2021 via email

@curuvar
Copy link
Contributor

curuvar commented Dec 7, 2021 via email

@ea7kir
Copy link
Author

ea7kir commented Dec 7, 2021 via email

@ea7kir
Copy link
Author

ea7kir commented Dec 7, 2021 via email

@uraimo
Copy link
Owner

uraimo commented Dec 7, 2021

Is there any chance you'll be able to work on this in the foreseeable future?

DS18B20 fixed for Swift 5.x.

@ea7kir
Copy link
Author

ea7kir commented Dec 7, 2021 via email

@ea7kir
Copy link
Author

ea7kir commented Dec 8, 2021 via email

@uraimo
Copy link
Owner

uraimo commented Dec 8, 2021

Yes, the RaspberryPi output for the list of 1wire slaves could very likely now contain a newline.
Trimmed in 1.3.9.

@ea7kir
Copy link
Author

ea7kir commented Dec 8, 2021 via email

@uraimo
Copy link
Owner

uraimo commented Dec 8, 2021

@uraimo
Copy link
Owner

uraimo commented Dec 8, 2021

2.0.4

@ea7kir
Copy link
Author

ea7kir commented Dec 8, 2021 via email

@ea7kir
Copy link
Author

ea7kir commented Dec 13, 2021

Googling for SHT31, I found this

https://github.com/torvalds/linux/blob/master/drivers/hwmon/sht3x.c

And I appear to have this in my Raspberry Pi OS.

sudo find / -name sht3x*
/usr/lib/modules/5.10.63-v8+/kernel/drivers/hwmon/sht3x.ko

There's also one for my INA226

ls -l /usr/lib/modules/5.10.63-v8+/kernel/drivers/hwmon/
total 212
-rw-r--r-- 1 root root 14832 Nov 18 17:22 ds1621.ko
-rw-r--r-- 1 root root 19128 Nov 18 17:22 gpio-fan.ko
-rw-r--r-- 1 root root  9848 Nov 18 17:22 iio_hwmon.ko
-rw-r--r-- 1 root root 22144 Nov 18 17:22 ina2xx.ko
-rw-r--r-- 1 root root 13168 Nov 18 17:22 jc42.ko
-rw-r--r-- 1 root root 29520 Nov 18 17:22 lm75.ko
-rw-r--r-- 1 root root 10736 Nov 18 17:22 raspberrypi-hwmon.ko
-rw-r--r-- 1 root root 16352 Nov 18 17:22 rpi-poe-fan.ko
-rw-r--r-- 1 root root 10680 Nov 18 17:22 sht21.ko
-rw-r--r-- 1 root root 21080 Nov 18 17:22 sht3x.ko
-rw-r--r-- 1 root root 13688 Nov 18 17:22 shtc1.ko
-rw-r--r-- 1 root root 11992 Nov 18 17:22 tmp102.ko

So my question is, how can I access these through SwiftyGPIO?

@ea7kir
Copy link
Author

ea7kir commented Dec 15, 2021

To read the SHT31 status register...

Screenshot 2021-12-15 at 16 34 30

Trying this

i2c.writeByte(0x44, command: 0xF3, value: 0x2D)
let _ = i2c.readData(0x44, command: 0x2D)

and I get this

I2C read failed: Protocol error
Aborted

Notice where the S and P bits are in the diagram. I appears the whole operation needs to execute as one command. I've tried everything suggested and everything I can think of. Can SwiftyGPIO can do this in a way I've overlooked? Please can someone come to my aid?

@ea7kir
Copy link
Author

ea7kir commented Dec 15, 2021

Similar situation with an INA266.

@curuvar
Copy link
Contributor

curuvar commented Dec 16, 2021 via email

@ea7kir
Copy link
Author

ea7kir commented Dec 16, 2021

It's good to know I'm not the only one and that @curuvar has a possible solution. I kind of get it, but I'd much prefer to have this functionality integrated within SwiftyGPIO, so I hope @uraimo is following this and will be able to can the find the time to see if his library can be extended.

As with so many many others, I'm humbly grateful to @uraimo for his undoubted talent and dedication, So in return I wish to offer this small piece of code that could slot into the 1-wire class.

public func isReachable(_ slaveId: String) -> Bool {
	let pathname = "/sys/bus/w1/devices/" + slaveId + "/w1_slave"
	return open(pathname, O_RDONLY | O_SYNC) > 0 ? true : false
}

@curuvar
Copy link
Contributor

curuvar commented Dec 16, 2021 via email

@ea7kir
Copy link
Author

ea7kir commented Dec 16, 2021

I cleaned to the function to get rid of the warnings and added it to my Safer i2c https://github.com/uraimo/SwiftyGPIO/pull/125/files# pull request.

As I've said before, I'm no expert (especially with GitHub), but this looks good to me. So how/when will I be able to try it?

@ea7kir
Copy link
Author

ea7kir commented Dec 16, 2021

@curuvar, I changed Package.swift to https://github.com/curuvar/SwiftyGPIO.git and get v1.3.15, but writeAndRead and tryWriteAndRead are missing.

@curuvar
Copy link
Contributor

curuvar commented Dec 16, 2021 via email

@ea7kir
Copy link
Author

ea7kir commented Dec 17, 2021

The change are not in my main branch yet. If you change your dependency line to: .package( url: "https://github.com/curuvar/SwiftyGPIO.git", branch: "Safe-I2C" ), You should get the added call.

Thank you @curuvar.

Your Safe-I2C branch is working for me. So far I've only tested the SHT31 with the writeAndRead function. It can read the status register (verified by toggling the heater). It can read the 6 bytes containing the temperature and humidity (currently ignoring CRC) and these will successfully translate to centigrade and a relative humidity percentage. So I'm up and running and very happy.

I begin to understand why people do forks, but now appear to have 4 options...

  1. track your branch
  2. track your master (if/when you merge the branch)
  3. track @uraimo (if/when he merges your branch)
  4. create my own fork (if/when I better understand GitHub - and from who?)

Any of which will mean having to constantly check GitHub to see who's winning.

Comments will be most appreciated.

@ea7kir ea7kir closed this as completed Dec 17, 2021
@ea7kir ea7kir reopened this Dec 17, 2021
@curuvar
Copy link
Contributor

curuvar commented Dec 17, 2021 via email

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants