How to write single bit to slave using i2c

All ESP32 boards running MicroPython.
Target audience: MicroPython users with an ESP32 board.
Post Reply
JDRBoston
Posts: 21
Joined: Mon Feb 19, 2018 9:43 pm

How to write single bit to slave using i2c

Post by JDRBoston » Sun Aug 25, 2019 2:53 pm

I am trying to read pressure and temperature data from a Honeywell SSC Series i2c pressure sensor. I would greatly appreciate your help in figuring out how to send a single bit to the device on the i2c bus so that I can get it to respond by sending data frames back.

I am using an ESP32 running micropython. The pressure sensor acts as a slave on i2c bus, in my case with an address of 40 / 0x28. After the sensor detects its 7-bit address on the i2c bus, it wants to detect a single 1 bit sent from the master before it will acknowledge and then send 8-bit data frames.

My circuit and i2c bus seem to be adequate because I am able to detect the pressure device and another device on the bus using scan(). But I cannot figure out how to send a single bit, and not a byte, using the writeto() function. I've read though the machine library docs and this discussion board but I haven't been able to find out how this is done. During a web search, I did find an example where people were able to send a single bit and get meaningful data from this pressure sensor using the Arduino command "Wire.write(1)" But I haven't been able to get this to work using micropython. I tried stuffing an extra bit at the end of the address (in other words, addressing the slave as 0x51 = 0b1010001 instead of 0x28 = 0b101000 but that didn't work (in retrospect, the probably shouldn't work the way the devices respond to addresses on the bus). I tried i2c.writeto(40, 1) but I got "TypeError: object with buffer protocol required".

I would appreciate advice. I apologize I'm not clear in my question or the solution to my question would be obvious to most programmers. I am learning as I go and greatly appreciate what I have been taught by experimenting with micropython and reading your entries on this board.

Thank you!

OutoftheBOTS_
Posts: 847
Joined: Mon Nov 20, 2017 10:18 am

Re: How to write single bit to slave using i2c

Post by OutoftheBOTS_ » Sun Aug 25, 2019 8:44 pm

As far as I am aware the I2C standard only works with full bytes.

rpr
Posts: 99
Joined: Sat Oct 27, 2018 5:17 pm

Re: How to write single bit to slave using i2c

Post by rpr » Sun Aug 25, 2019 9:05 pm

What happens if you send i2c.writeto(40,b'1')?

User avatar
jimmo
Posts: 2754
Joined: Tue Aug 08, 2017 1:57 am
Location: Sydney, Australia
Contact:

Re: How to write single bit to slave using i2c

Post by jimmo » Sun Aug 25, 2019 11:41 pm

JDRBoston wrote:
Sun Aug 25, 2019 2:53 pm
After the sensor detects its 7-bit address on the i2c bus, it wants to detect a single 1 bit sent from the master before it will acknowledge and then send 8-bit data frames.
I went looking for a datasheet and found https://sensing.honeywell.com/i2c-comms ... 0may12.pdf which may not be your sensor but I think explains what you're describing. Relevant quote below.

"To read out a compensated pressure reading, the master
generates a START condition and sends the sensor slave
address followed by a read bit (shown in Figure 2). "

In i2c, addresses are seven bits, which are turned into 8-bit bus addressses ( `(addr << 1)|1` for read, `(addr<<1)` for write). Some I2C libraries hide this from your (you always work with the seven-bit address, and depending whether you're doing a read or a write operation, the library adjusts the address appropriately), others make you work with the read and write addresses separately. MicroPython is the former.

So in your case, you just want to read directly from the read address -- i2c.readfrom(0x28, N) -- under the hood, this does all the low level details (start bit, 8-bit read address, ack bits, stop bit, etc). N is the number of bytes you want -- it looks like you can just choose how many bytes to read between 2 and 4 depending on whether you want temperature too? The device will supply anywhere between 2 and 4 bytes. (Under the hood, while the i2c transaction stays open and the master keeps clocking the scl line, the device just supplies more).

This seems to be really common for I2C datasheets -- written by someone who is wonderfully familiar with I2C at an electrical level but not realising that not many people actually uses it at that level.
rpr wrote:
Sun Aug 25, 2019 9:05 pm
What happens if you send i2c.writeto(40,b'1')?
This neither sends a single bit nor a 1. It'll send the ascii value for '1' which is 0x31.

JDRBoston
Posts: 21
Joined: Mon Feb 19, 2018 9:43 pm

Re: How to write single bit to slave using i2c

Post by JDRBoston » Mon Aug 26, 2019 12:28 am

Thank you, jimmy, rpm, and OutoftheBOTS._ I greatly appreciate your responses!

jimmo, you are right - that is the data sheet that I was using. In my application, I am using a Honeywell SSCDANN150PG2A3, which is a vented gauge sensor in a 8-pin DIN package that measures 0 - 150PSI applied to a port and supplies encoded pressure and temperature values over i2c. Your explanation about the address shifting and addition of the 1 bit now makes great sense. Importantly, your solution was right on! I tired simply requesting the data from the device using i2.readfrom(address, no_bytes) and I got some data frames from the device that made sense. Also, when I applied some uncalibrated pressures, the data frames showed an increment. Thank you, again!!

rpr
Posts: 99
Joined: Sat Oct 27, 2018 5:17 pm

Re: How to write single bit to slave using i2c

Post by rpr » Thu Aug 29, 2019 12:00 am

jimmo wrote:
Sun Aug 25, 2019 11:41 pm
rpr wrote:
Sun Aug 25, 2019 9:05 pm
What happens if you send i2c.writeto(40,b'1')?
This neither sends a single bit nor a 1. It'll send the ascii value for '1' which is 0x31.
@jimmo -- thank you.

Post Reply