Help with Omron IR sensor I2C
T Chap
Posts: 4,223
I could use an extra set of eyes. The LCD works well displaying values most of the time with the code as shown, but randomly $FF will pop up in some or all locations. I put in an extra STOP at line 4 of the i2c code, this is not in the manual, but without it the display shows FF about 50% of the time.
On page 14 in the manual, it discusses a WAIT REQUEST that is required by the master. I get FF values randomly that show up at 2 seconds to 15 seconds intervals. Cycle times tested are 1/10 of a second to 1 per second.
Minimal I2c Driver
Thanks for any suggestions.
Example in product info:
tPTAT = 256*readbuff[1] + readbuff[0]; 'internal temp ref
tP[0] = 256*readbuff[3] + readbuff[2];
tP[1] = 256*readbuff[5] + readbuff[4];
tP[2] = 256*readbuff[7] + readbuff[6];
tP[3] = 256*readbuff[9] + readbuff[8];
tP[4] = 256*readbuff[11] + readbuff[10];
tP[5] = 256*readbuff[13] + readbuff[12];
tP[6] = 256*readbuff[15] + readbuff[14];
tP[7] = 256*readbuff[17] + readbuff[16];
tP[8] = 256*readbuff[19] + readbuff[18];
tP[9] = 256*readbuff[21] + readbuff[20];
tP[10] = 256*readbuff[23] + readbuff[22];
tP[11] = 256*readbuff[25] + readbuff[24];
tP[12] = 256*readbuff[27] + readbuff[26];
tP[13] = 256*readbuff[29] + readbuff[28];
tP[14] = 256*readbuff[31] + readbuff[30];
tP[15] = 256*readbuff[33] + readbuff[32];
tPEC = readbuff[34]; 'this is CRC
http://www.omron.com/ecb/products/sensor/special/mems/pdf/AN-D6T-01EN_r2.pdf
On page 14 in the manual, it discusses a WAIT REQUEST that is required by the master. I get FF values randomly that show up at 2 seconds to 15 seconds intervals. Cycle times tested are 1/10 of a second to 1 per second.
Minimal I2c Driver
Thanks for any suggestions.
Word irval[16], omronref Byte omron[35] PUB ReadOMron | u , v i2c2.i2cStart(i2cSCL2) i2c2.i2cWrite(i2cSCL2, OmronWrite) '0x14 this is a write=0 1 is read i2c2.i2cWrite(i2cSCL2, $4C ) i2c2.i2cStop(i2cSCL2) 'without this stop, gets 50% $FF values i2c2.i2cStart(i2cSCL2) i2c2.i2cWrite(i2cSCL2, OmronRead) u~ repeat 34 ' get first 34 bytes omron[u] := i2c2.i2cRead(i2cSCL2, 0) 'Read : 15h u++ w(2_000) '2000 is almost no FF <<<<<<<<<<<<<<<<<<<< added this waitcnt to see what happens, improves greatly omron[35] := i2c2.i2cRead(i2cSCL2, 1) ' read last byte i2c2.i2cStop(i2cSCL2) omronref := omron[0] + omron[1] << 8 cls go0 ser.hex(3, omronref, 2) ser.str(3, string(" ")) u := 2 v := 0 repeat 8 'view only first x pixels of 16 irval[v] := omron[u] + omron[u+1] << 8 'lsb+msb ser.hex(3, irval[v], 2) ser.str(3, string(" ")) u := u+2 v++
Example in product info:
tPTAT = 256*readbuff[1] + readbuff[0]; 'internal temp ref
tP[0] = 256*readbuff[3] + readbuff[2];
tP[1] = 256*readbuff[5] + readbuff[4];
tP[2] = 256*readbuff[7] + readbuff[6];
tP[3] = 256*readbuff[9] + readbuff[8];
tP[4] = 256*readbuff[11] + readbuff[10];
tP[5] = 256*readbuff[13] + readbuff[12];
tP[6] = 256*readbuff[15] + readbuff[14];
tP[7] = 256*readbuff[17] + readbuff[16];
tP[8] = 256*readbuff[19] + readbuff[18];
tP[9] = 256*readbuff[21] + readbuff[20];
tP[10] = 256*readbuff[23] + readbuff[22];
tP[11] = 256*readbuff[25] + readbuff[24];
tP[12] = 256*readbuff[27] + readbuff[26];
tP[13] = 256*readbuff[29] + readbuff[28];
tP[14] = 256*readbuff[31] + readbuff[30];
tP[15] = 256*readbuff[33] + readbuff[32];
tPEC = readbuff[34]; 'this is CRC
http://www.omron.com/ecb/products/sensor/special/mems/pdf/AN-D6T-01EN_r2.pdf
Comments
Where is the datasheet for it??
Is the sensor "D6T-44L / D6T-8L Thermal sensor"? Because it states that "clock stretching must be on".
A search of the forum indicates that the minimal I2C driver doesn't support clock stretching. You will need to one of the more advanced I2C drivers that support "clock stretching".
Of course that is if the issue is with "clock stretching".
http://microsite.omroncomponents.com/assets/ApplicationNote_IR%20Sensor_(ES)a.pdf
I've run across a couple of devices that use stretching (Sensirion SHT21 RH/T, SPD610 pressure, MAX1236 ADC). For those devices, the stretching happens at a specific point in a Read operation. That point happens to be immediately after the DevID+read is sent and ACK'd, and scl has been driven low to allow the slave to set the first bit of the result. The master then releases scl but the slave holds it low. When ready with the conversion result, the slave releases scl, and that transition clocks in the first data bit. Subsequent bits and bytes are not stretched.
AFAIK, stretching protocol is not spelled out in detail in the i2c spec, so how to implement it seems to be at the discretion of the device manufacturer. The description in the Omron data sheet is okay, but left me wondering if its stretch might occur before the ACK instead of after it, and if it is needed for all bytes, or what. I recall in another thread where where Chris Gadd found an example of a port expander that had the stretch before the ACK between clocks 8 and 9.
Since FF is never a valid response and only occurs once in a while, it is not a problem to ignore any FF response since worst case is I have to wait 250ms to get the next valid response which is not a problem.
For future searchers looking up Omron D6T 4x4, here is my starting point test code using an LCD on port 3 to watch about half of the 16 "windows":
Here from the 2007 i2c spec:
<<On the byte level, a device may be able to receive bytes of data at a fast rate, but needs more time to store a received byte or prepare another byte to be transmitted. Slaves can then hold the SCL line LOW after reception and acknowledgment of a byte to force the master into a wait state until the slave is ready for the next byte transfer in a type of handshake procedure." >>
I wonder if the wait should be extended beyond clkfreq/I2CDelayS. I2CDelayS = 10_000 'clock stretch delay
Now that you pointed this out, I can test tomorrow by increasing the wait time. 80_000_000/10_000 = 8000 is not a very big wait.
In the diagram attached in the post above, it shows a) a Fixed Wait LOW from the Master pulling down SCL at the ACK. But in the basic i2c driver, the wait time the SCL is held low is only for the next 2 instructions until the dira[SCL]~ occurs. Would this be considered long enough for the device to see the LOW and then itself drive the SCL low? I am wondering if the device does not have time to respond with it's own SCL LOW before the master releases the SCL, which is causing the glitches. Tomorrow I will test with a wait period inserted to see what happens.
The next question is, does the Fixed Low SCL period follow the SDA ACK LOW?
waitcnt(500+cnt) would be only 6.25µs at an 80MHz clock, not enough to be unequivocal.
I see the Digikey product page has a nice video about applications of the product, and a link to OMRON material. But I couldn't navigate to anything about the P6T on the OMRON site. I sent in an FAE support request. Can you do the same? I'lll probably purchase one of these for a hot-spot detection project.
Can you post the whole i2c driver?
The object has been renamed to basic i2c driver but on the obex it was called Basic i2c Driver TM.
This is the latest version of the basic i2c driver I have been tweaking. It will sometimes go 1 minute with no glitch, but sometimes it glitches at 5 seconds. I have tried this with all different types of waitcnt's, 10000,1000, 100. 10, and 5. It doesn't seem to make a difference.
If you want, pm an address and I will have digi drop one in the mail today to you.
Thanks for the i2c object. I hadn't looked at that one before. TM: Tim Moores' modification of James Burrows' modification of Mike Green's version 1.1. Tim mentions slowing it down for 100kHz and adding the clock stretching. For reference, it now appears in OBEX as HMC6343 i2c Driver. Tweaking these drivers can be pretty maddening, at least that's been my experience with a few specific devices!
So is this indicative of the error being on the part of the master or device?
Yes, the clock is the responsibility of the master, but the slave can hold. I see that the modified Read and Write methods now use open logic that assumes pullup resistors on both sda and scl. So the slave could possibly be stretching the clock at that point so that a pulse generated by the Prop is not getting through. It is hard to see from the code how that could come about, but there is a lot of tweaking of code going on, I guess. The Start and Stop methods are still driving both the sda and scl pins to outputs. The D6T document says it is going to stretch the clock, not clear whether before or after the ACK, and during all of the bytes, or at only specific ones (such as before the repeated start).
When and if you start messing with this device, if you get into figuring out the CRC method please post what you come up with. There are some examples in the app notes but they are in C or some other format that I haven't been able to interpret yet.
Thanks for the D6T sensor. I think it will be useful for a project I have here, maybe also something for other forumistas. Linking to your other thread, the interface is worked out.
I have this Molex crimp tool that works ok on the JST crimp pins.
With the new code I am getting no errors, works perfectly.
A short video showing off the Omron sensor. Propeller driven new haven 4.3 LCD.
Seems the video isn't available anymore. Didn't get a chance to see it...