I2C_IO Help Please?
I2C_IO Help Please?
I've been trying to get an I2C "HTU-21D Temperature/Humidity sensor" working with Minerva Mk2 as it seemed like a simple "read" device to start with (LCD was write only)
But no matter what I've tried so far I only get an xmit error (or other errors depending on what I try). I know the sensor is fine as I got it working straight away on a non-QL system
I was wondering if anyone has I2C/I2C_IO_BIN experience and could shed any light on the problem please?
According to the HTU-21D data sheet the correct sequence to read humidity is
CHR$(HEX('80')) write device '40' shifted left 1 bit
CHR$(HEX('E5')) Humidity Measurement
CHR$(HEX('81')) read device '40' shifted left 1 bit + 1
Returns MSB+LSB+CHKSUM
But converting this to an I2C_IO command isn't working:
X$=CHR$('80') & CHR$(HEX('E5')) & CHR$(0) & CHR$(HEX('81')) & CHR$(3) & CHR$(156) & CHR$(255)
R$=I2C_IO(X$,3,HEX('40'),1)
10011100
10SRBPA0 = 156 NO START/READ/USES BUFFER/SEND STOP
I've no idea what the ",1)" parameter is supposed to do in the I2C_IO command or whether the "CHR$(0)" (also tried CHR$(1)) is even mean't to be there but doesn't work when removed either
I must be missing something, mainly my understanding I guess (have read all the documents/examples I can find to no avail so far)
Any thoughts please?
Many thanks
Tony
But no matter what I've tried so far I only get an xmit error (or other errors depending on what I try). I know the sensor is fine as I got it working straight away on a non-QL system
I was wondering if anyone has I2C/I2C_IO_BIN experience and could shed any light on the problem please?
According to the HTU-21D data sheet the correct sequence to read humidity is
CHR$(HEX('80')) write device '40' shifted left 1 bit
CHR$(HEX('E5')) Humidity Measurement
CHR$(HEX('81')) read device '40' shifted left 1 bit + 1
Returns MSB+LSB+CHKSUM
But converting this to an I2C_IO command isn't working:
X$=CHR$('80') & CHR$(HEX('E5')) & CHR$(0) & CHR$(HEX('81')) & CHR$(3) & CHR$(156) & CHR$(255)
R$=I2C_IO(X$,3,HEX('40'),1)
10011100
10SRBPA0 = 156 NO START/READ/USES BUFFER/SEND STOP
I've no idea what the ",1)" parameter is supposed to do in the I2C_IO command or whether the "CHR$(0)" (also tried CHR$(1)) is even mean't to be there but doesn't work when removed either
I must be missing something, mainly my understanding I guess (have read all the documents/examples I can find to no avail so far)
Any thoughts please?
Many thanks
Tony
Re: I2C_IO Help Please?
Well I’ve determined i2c_io doesn’t work in the way I thought it did. It’s not literal
Tomorrow I’ll try and get my head around the first command byte as this seems to be the key
Tomorrow I’ll try and get my head around the first command byte as this seems to be the key
- NormanDunbar
- Forum Moderator
- Posts: 2508
- Joined: Tue Dec 14, 2010 9:04 am
- Location: Buckie, Scotland
- Contact:
Re: I2C_IO Help Please?
I2C devices usually have a 7 bit address. This gets converted to an 8 bit address which is different for reading and writing.
In an I2C transaction, where you must first write to a sensor and then read data back, you must:
NACK = Not Acknowledge.
Every action that occurs on the bus should return a status byte which identifies any problems, if errors occurred, or indicates success otherwise.
I have just finished writing a chapter or two on I2C, in Assembly Language, for the third in my trilogy of Arduino internals books, so this is burned into my memory now. (And will remain there until age causes it to be flushed out to leave room for something else to fit in!
)
You can create an I2C scanner by running a loop from zero to 127. For each address in the loop:
DISCLAIMER I don't have I2C running on anything apart from my Arduino's and other microcontrollers. I have written a lot of I2C code for those, but never for the QL. However, having said that, I am willing to offer whatever assistance I can.
Cheers,
Norm.
In an I2C transaction, where you must first write to a sensor and then read data back, you must:
- Set up the write address of the sensor by shifting its 7 bit address left 1 bit and clearing bit zero.
- Send a start to the bus.
- Write the write address to the bus.
- If you get an ACK, the device is listening.
- Write your config to the bus, the sensor will read each byte and should return an ACK.
- Start a new read transaction by sending a start -- do not send a stop, although on a QL it probably makes no difference, there's only one controller.
- Write the read address of the sensor by shifting its 7 bit address one bit left and setting bit zero to a 1.
- You should get an ACK, if so, the device is ready.
- Read each byte of data from the sensor, returning an ACK for all except the final byte, where you return an NACK to the sensor.
- Terminate the transaction by sending a stop to the bus.
NACK = Not Acknowledge.
Every action that occurs on the bus should return a status byte which identifies any problems, if errors occurred, or indicates success otherwise.
I have just finished writing a chapter or two on I2C, in Assembly Language, for the third in my trilogy of Arduino internals books, so this is burned into my memory now. (And will remain there until age causes it to be flushed out to leave room for something else to fit in!

You can create an I2C scanner by running a loop from zero to 127. For each address in the loop:
- Set up the write address of the sensor by shifting the current address left 1 bit and clearing bit zero.
- Send a start to the bus.
- Write the write address to the bus.
- If you get an ACK, the device is listening. Report "Device found at " + 7 bit address. Send a stop.
- If you got a NACK, try the next address. No need to send a stop.
DISCLAIMER I don't have I2C running on anything apart from my Arduino's and other microcontrollers. I have written a lot of I2C code for those, but never for the QL. However, having said that, I am willing to offer whatever assistance I can.
Cheers,
Norm.
Why do they put lightning conductors on churches?
Author of Arduino Software Internals
Author of Arduino Interrupts
No longer on Twitter, find me on https://mastodon.scot/@NormanDunbar.
Author of Arduino Software Internals
Author of Arduino Interrupts
No longer on Twitter, find me on https://mastodon.scot/@NormanDunbar.
- XorA
- Site Admin
- Posts: 1733
- Joined: Thu Jun 02, 2011 11:31 am
- Location: Shotts, North Lanarkshire, Scotland, UK
Re: I2C_IO Help Please?
Take all the addresses out of the cmd$
X$ = CHR$(HEX('E5'))
Your R$ is correct I think.
Your telling the I2C_IO command the device address, so you don't also put in the the CMD. Also why are you putting the return value expected in the command your sending?
(i2c is most of my professional work, although I never use it on QL)
X$ = CHR$(HEX('E5'))
Your R$ is correct I think.
Your telling the I2C_IO command the device address, so you don't also put in the the CMD. Also why are you putting the return value expected in the command your sending?
(i2c is most of my professional work, although I never use it on QL)
Re: I2C_IO Help Please?
Many thanks Norm
With all my reading I think I understand how the I2c protocol works, though your description is a great resource for me thanks and makes everything clear in my head
I’ve realised my roadblock has been not understanding correctly how i2c_io works, but I think I’ve nearly got it sussed now. The first command byte is what I have to get right to tell it to send correctly as per your description
Will get back to you
Many thanks
Tony
With all my reading I think I understand how the I2c protocol works, though your description is a great resource for me thanks and makes everything clear in my head
I’ve realised my roadblock has been not understanding correctly how i2c_io works, but I think I’ve nearly got it sussed now. The first command byte is what I have to get right to tell it to send correctly as per your description
Will get back to you
Many thanks
Tony
Re: I2C_IO Help Please?
Thanks, I’ve been really struggling to understand what i2c_io actually wants but will be doing some more tests tomorrowXorA wrote: Wed Sep 03, 2025 8:12 pm Take all the addresses out of the cmd$
X$ = CHR$(HEX('E5'))
Your R$ is correct I think.
Your telling the I2C_IO command the device address, so you don't also put in the the CMD. Also why are you putting the return value expected in the command your sending?
(i2c is most of my professional work, although I never use it on QL)
Many thanks
Tony
- NormanDunbar
- Forum Moderator
- Posts: 2508
- Joined: Tue Dec 14, 2010 9:04 am
- Location: Buckie, Scotland
- Contact:
Re: I2C_IO Help Please?
PS. The official NXP User Manual for I2C is at https://www.nxp.com/docs/en/user-guide/UM10204.pdf.
Cheers,
Norm.
Cheers,
Norm.
Why do they put lightning conductors on churches?
Author of Arduino Software Internals
Author of Arduino Interrupts
No longer on Twitter, find me on https://mastodon.scot/@NormanDunbar.
Author of Arduino Software Internals
Author of Arduino Interrupts
No longer on Twitter, find me on https://mastodon.scot/@NormanDunbar.
-
- Font of All Knowledge
- Posts: 4854
- Joined: Mon Dec 20, 2010 11:40 am
- Location: Sunny Runcorn, Cheshire, UK
Re: I2C_IO Help Please?
Hi,
Here is a disassemble of I2C_IO with DISA:
not commented, but you can see what is going on with the command.
Here is a disassemble of I2C_IO with DISA:
not commented, but you can see what is going on with the command.
Regards, Derek
Re: I2C_IO Help Please?
Thanks all
So far the only return values I get returned are all &FF
Will take a break from this for a while as it's doing my head in
So far the only return values I get returned are all &FF
Will take a break from this for a while as it's doing my head in
Re: I2C_IO Help Please?
Thought I’d try my current code with a bmp280
Didn’t get &FF this time, just a mix of &80 and &00
That doesn’t look right either
Didn’t get &FF this time, just a mix of &80 and &00
That doesn’t look right either