I2C_IO Help Please?

Anything QL Software or Programming Related.
User avatar
t0nyt
QL Wafer Drive
Posts: 1140
Joined: Wed Nov 22, 2023 6:46 pm
Location: UK

I2C_IO Help Please?

Post by t0nyt »

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


User avatar
t0nyt
QL Wafer Drive
Posts: 1140
Joined: Wed Nov 22, 2023 6:46 pm
Location: UK

Re: I2C_IO Help Please?

Post by t0nyt »

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


User avatar
NormanDunbar
Forum Moderator
Posts: 2506
Joined: Tue Dec 14, 2010 9:04 am
Location: Buckie, Scotland
Contact:

Re: I2C_IO Help Please?

Post by NormanDunbar »

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:
  1. Set up the write address of the sensor by shifting its 7 bit address left 1 bit and clearing bit zero.
  2. Send a start to the bus.
  3. Write the write address to the bus.
  4. If you get an ACK, the device is listening.
  5. Write your config to the bus, the sensor will read each byte and should return an ACK.
  6. 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.
  7. Write the read address of the sensor by shifting its 7 bit address one bit left and setting bit zero to a 1.
  8. You should get an ACK, if so, the device is ready.
  9. 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.
  10. Terminate the transaction by sending a stop to the bus.
ACK = acknowledge.
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! :D )


You can create an I2C scanner by running a loop from zero to 127. For each address in the loop:
  1. Set up the write address of the sensor by shifting the current address left 1 bit and clearing bit zero.
  2. Send a start to the bus.
  3. Write the write address to the bus.
  4. If you get an ACK, the device is listening. Report "Device found at " + 7 bit address. Send a stop.
  5. 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.
User avatar
XorA
Site Admin
Posts: 1733
Joined: Thu Jun 02, 2011 11:31 am
Location: Shotts, North Lanarkshire, Scotland, UK

Re: I2C_IO Help Please?

Post by XorA »

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)


User avatar
t0nyt
QL Wafer Drive
Posts: 1140
Joined: Wed Nov 22, 2023 6:46 pm
Location: UK

Re: I2C_IO Help Please?

Post by t0nyt »

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


User avatar
t0nyt
QL Wafer Drive
Posts: 1140
Joined: Wed Nov 22, 2023 6:46 pm
Location: UK

Re: I2C_IO Help Please?

Post by t0nyt »

XorA 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)
Thanks, I’ve been really struggling to understand what i2c_io actually wants but will be doing some more tests tomorrow

Many thanks
Tony


User avatar
NormanDunbar
Forum Moderator
Posts: 2506
Joined: Tue Dec 14, 2010 9:04 am
Location: Buckie, Scotland
Contact:

Re: I2C_IO Help Please?

Post by NormanDunbar »

PS. The official NXP User Manual for I2C is at https://www.nxp.com/docs/en/user-guide/UM10204.pdf.

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.
Derek_Stewart
Font of All Knowledge
Posts: 4854
Joined: Mon Dec 20, 2010 11:40 am
Location: Sunny Runcorn, Cheshire, UK

Re: I2C_IO Help Please?

Post by Derek_Stewart »

Hi,

Here is a disassemble of I2C_IO with DISA:
I2C_IO_dis.zip
(780 Bytes) Downloaded 7 times

not commented, but you can see what is going on with the command.


Regards, Derek
User avatar
t0nyt
QL Wafer Drive
Posts: 1140
Joined: Wed Nov 22, 2023 6:46 pm
Location: UK

Re: I2C_IO Help Please?

Post by t0nyt »

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


User avatar
t0nyt
QL Wafer Drive
Posts: 1140
Joined: Wed Nov 22, 2023 6:46 pm
Location: UK

Re: I2C_IO Help Please?

Post by t0nyt »

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


Post Reply