![]() |
Forum Index : Microcontroller and PC projects : I2CPort
Page 1 of 2 ![]() ![]() |
|||||
Author | Message | ||||
jman![]() Guru ![]() Joined: 12/06/2011 Location: New ZealandPosts: 711 |
Hi I am having an issue with I2CPort CFunction the following code using standard I2C commands works as expected I2C open 100, 100 I2C write INA219_ADDRESS, 0, 1, Register I2C read INA219_ADDRESS, 0, 2, GetData() With the folowing code r=I2CPort(1, 15, 16, INA219_ADDRESS, 1, Register) r=I2CPort(2, 15, 16, INA219_ADDRESS, 2, GetData()) The output is totaly incorrect with GetData(0) always 127 and GetData(1) always 255 no matter what the value of Register. r returns 1 indicating the I2C commands were succesfull So is the issue with I2CPort or I2CPort does not like the INA219 or i am i missing something Regards Jman |
||||
goc30![]() Guru ![]() Joined: 12/04/2017 Location: FrancePosts: 435 |
Hi have-you seen adafruit_ina library ? https://learn.adafruit.com/adafruit-ina219-current-sensor-breakout?view=all in exemple, lib send 1word (0xffff) in begin sequence void Adafruit_INA219::wireWriteRegister (uint8_t reg, uint16_t value) { _i2c->beginTransmission(ina219_i2caddr); #if ARDUINO >= 100 _i2c->write(reg); // Register _i2c->write((value >> 8) & 0xFF); // Upper 8-bits _i2c->write(value & 0xFF); // Lower 8-bits #else _i2c->send(reg); // Register _i2c->send(value >> 8); // Upper 8-bits _i2c->send(value & 0xFF); // Lower 8-bits #endif _i2c->endTransmission(); } |
||||
GoodToGo!![]() Senior Member ![]() Joined: 23/04/2017 Location: AustraliaPosts: 188 |
Hey jman, Have you managed to get the INA219 working on a standard I2C port? I ported the adafruit code to micromite a while ago. Have a look at Fruit of the Shed - INA219 code for an example.... Hope the above helps, GTG! ![]() ...... Don't worry mate, it'll be GoodToGo! |
||||
Geoffg![]() Guru ![]() Joined: 06/06/2011 Location: AustraliaPosts: 3292 |
It should work. I don't have a INA219 to test with but I did a lot of testing when I developed the CFunction and it never showed something so catastrophic as this. Geoff Geoff Graham - http://geoffg.net |
||||
jman![]() Guru ![]() Joined: 12/06/2011 Location: New ZealandPosts: 711 |
I am using the port of the Adafruit library from GTG located here http://www.fruitoftheshed.com/MMBasic.INA219-Current-Sensor.ashx and this works perfectly using the standard I2C the issue ONLY occurs when using the I2CPort CFunction. Orginal code '---------------------------------------------------------------- ' I2C read and write routines '---------------------------------------------------------------- Sub ReadRegister(Register, Value) 'Reads a 16 bit value over I2C Local GetData(1) I2C write INA219_ADDRESS, 0, 1, Register I2C read INA219_ADDRESS, 0, 2, GetData() Value = ((GetData(0) <<8) Or GetData(1)) End Sub Sub WriteRegister(Register, Value) 'Writes a 16 bit value (2 x 8 bit) in a regis Local MSB,LSB MSB = Value >> 8 LSB = Value And &hff Local WriteData(2)=(Register, MSB, LSB) I2C write INA219_ADDRESS, 0, 3, WriteData() End Sub I2CPort Code '---------------------------------------------------------------- ' I2C read and write routines '---------------------------------------------------------------- Sub ReadRegister(Register, Value) 'Reads a 16 bit value over I2C Local GetData(1),r r=I2CPort(1, 18, 17, INA219_ADDRESS, 1, Register) r=I2CPort(2, 18, 17, INA219_ADDRESS, 2, GetData()) Value = ((GetData(0) <<8) Or GetData(1)) End Sub Sub WriteRegister(Register, Value) 'Writes a 16 bit value (2 x 8 bit) in a regis Local MSB,LSB,r MSB = Value >> 8 LSB = Value And &hff Local WriteData(2)=(Register, MSB, LSB) r=I2CPort(1, 18, 17, INA219_ADDRESS, 3, WriteData()) End Sub @GoodToGo! If you have a spare INA219 could you be so kind as to test the I2CPort CFunction and post the results Many Thanks Jman |
||||
Geoffg![]() Guru ![]() Joined: 06/06/2011 Location: AustraliaPosts: 3292 |
Ah, all the arguments to I2CPort must be integers. Including the data to send and the array receiving the data. I bet that is it. Geoff Geoff Graham - http://geoffg.net |
||||
GoodToGo!![]() Senior Member ![]() Joined: 23/04/2017 Location: AustraliaPosts: 188 |
Yep, I'm getting the same results. All variables are Integers and they are sending ok. Just the return results are up the creek. I'll continue testing...... EDIT. Everything getting read from the INA219 are "1"'s. The module has onboard 10k pullup's on the SDA and SCK lines, I wonder if that coupled with the weak pullup's in the MM that the CFUNCTION invokes are the cause? GTG! ![]() ...... Don't worry mate, it'll be GoodToGo! |
||||
TassyJim![]() Guru ![]() Joined: 07/08/2011 Location: AustraliaPosts: 6283 |
What do you have set for INA219_ADDRESS Some of the options involve connecting the address setting pins to SDA or SCL which might cause grief. Jim VK7JH MMedit |
||||
GoodToGo!![]() Senior Member ![]() Joined: 23/04/2017 Location: AustraliaPosts: 188 |
const INA219_ADDRESS = &h40 '&b1000000 = (A0,A1=GND) This is the default address with the solder pads open. If I select a different address there is no response. So the address is ok. The routine works fine using the normal MM I2C port, just not using the CFunction. GTG! ![]() ...... Don't worry mate, it'll be GoodToGo! |
||||
GoodToGo!![]() Senior Member ![]() Joined: 23/04/2017 Location: AustraliaPosts: 188 |
Some results on the normal I2C port using the below amendment to the Fruit of the Shed code:- '---------------------------------------------------------------- ' I2C read and write routines '---------------------------------------------------------------- sub ReadRegister (Register, Value) 'Reads a 16 bit value over I2C local GetData(1), r i2c write INA219_ADDRESS, 0, 1, Register i2c read INA219_ADDRESS, 0, 2, GetData() print "Register = " +str$(register) 'r = I2CPort(1, 15, 16, INA219_ADDRESS, 1, Register) 'r = I2CPort(2, 15, 16, INA219_ADDRESS, 2, GetData()) print bin$(GetData(0)) + " " + bin$(GetData(1)) Value = ((GetData(0) <<8) or GetData(1)) print bin$(value) end sub sub WriteRegister (Register, Value) 'Writes a 16 bit value (2 x 8 bit) in a register over I2C local MSB, LSB, r MSB = Value >> 8 LSB = Value and &hff Local WriteData(2)=(Register, MSB, LSB) print "WD(0)= " +bin$(WriteData(0)) print "WD(1)= " +bin$(WriteData(1)) print "WD(2)= " +bin$(WriteData(2)) i2c write INA219_ADDRESS, 0, 3, Register, MSB, LSB 'r = I2CPort(1, 15, 16, INA219_ADDRESS, 3, WriteData()) end sub Now using the Cfunction by commenting/uncommenting the appropriate lines above:- As you can see, all "1"'s. One thing to note, that using the Cfunction is resulting in a s-l-o-w response. I wonder if it's timing out? Cheers, GTG! ![]() ...... Don't worry mate, it'll be GoodToGo! |
||||
Geoffg![]() Guru ![]() Joined: 06/06/2011 Location: AustraliaPosts: 3292 |
This is strange, if it was timing out I2CPort would have returned zero indicating an error. But then why is it slow? I2CPort is the master so it controls the clock (100KHz) so that cannot be the issue. Perhaps the INA219 is slow to respond but is less than the timeout (which is 5ms). The I2C command uses the PIC32 hardware while I2CPort is bitbanged in software. Perhaps something (signal levels, timing, noise, etc) is marginal and the hardware I2C is better at handling it. Geoff Graham - http://geoffg.net |
||||
GoodToGo!![]() Senior Member ![]() Joined: 23/04/2017 Location: AustraliaPosts: 188 |
I wonder if this has something to do with it? The normal MM I2C timeout is a minimum 100ms. I normally start the I2c with "I2C OPEN 100, 100". The INA219 datasheet mentions "The INA219 includes a 28-ms timeout on its interface to prevent locking up an SMBus". The thing can interface with either I2c or SMBus using the same pins. Is it possible that the larger timeout to make it compatible with SMBus is causing issues with the CFunction? Your thoughts? GTG! ![]() ...... Don't worry mate, it'll be GoodToGo! |
||||
jman![]() Guru ![]() Joined: 12/06/2011 Location: New ZealandPosts: 711 |
And some more food for thought Screenshots of the write and we can see the timing is not the same. The working write is below the bit in RED is 10.1us The NON working write the bit in RED is 9.988ms Export of the trace in txt format, seems odd the reads are missing from the NON working one Working Time [s],Packet ID,Address,Data,Read/Write,ACK/NAK 0.621046166666667,0,'128','5',Write,ACK 0.621140333333333,0,'128','16',Write,ACK 0.6212345,0,'128','0',Write,ACK 0.637430666666667,1,'128','0',Write,ACK 0.637524833333333,1,'128',<,Write,ACK 0.637619,1,'128','207',Write,ACK 0.640441,2,'128','4',Write,ACK 0.640916833333333,,'129','0',Read,ACK 0.641014083333333,,'129','3',Read,NAK Not Working Time [s],Packet ID,Address,Data,Read/Write,ACK/NAK 0.902392583333333,0,'128','5',Write,ACK 0.992295416666667,0,'128','16',Write,ACK 1.08219,0,'128','0',Write,ACK 1.30808975,1,'128','0',Write,ACK 1.39799591666667,1,'128',<,Write,ACK 1.48789825,1,'128','207',Write,ACK 1.70038208333333,2,'128','4',Write,ACK So it seems the timming is an issue Regards Jman |
||||
Geoffg![]() Guru ![]() Joined: 06/06/2011 Location: AustraliaPosts: 3292 |
The I2c and SMBus are essentially the same thing so it is hard to see how that is the problem. The 28-ms timeout also could not be the issue - from the data sheet: SMBus timeout in the INA219 resets the interface any time SCL or SDA is low for over 28 ms. I believe we need to get a logic analyser on to this. EDIT: JMan beat me to it. Geoff Graham - http://geoffg.net |
||||
Geoffg![]() Guru ![]() Joined: 06/06/2011 Location: AustraliaPosts: 3292 |
The screenshots don't help - I presume that the red patch is the transfer but it is unreadable. The difference in "the trace in txt format" is that that the two reads at the end are missing. Otherwise the listings are identical. We need some correlation between what your program was doing and the trace. Can you modify your program to print the arguments to every write and read? Comparing that to the trace might shed some light on the issue. Geoff Graham - http://geoffg.net |
||||
Frank N. Furter Guru ![]() Joined: 28/05/2012 Location: GermanyPosts: 949 |
@Jman, did you tried another pullup? In the data sheet a pullup of 3.3K is recommended... Frank |
||||
matherp Guru ![]() Joined: 11/12/2012 Location: United KingdomPosts: 10315 |
The symptoms you are seeing are consistent with the CFunction thinking the clock is being stretched - this would explain the slow response but no error. The Cfunction code implements clock stretching properly which many hardware implementations don't. I would double check you don't have a dry joint on the clock pullup and as Frank suggests go with a more aggressive pullup - say 2K7 |
||||
jman![]() Guru ![]() Joined: 12/06/2011 Location: New ZealandPosts: 711 |
Hi The frirst thing i did prior to the orginal post was to replace the 10k pullups with 4k7 ones these have now been replaced with 2k7 pullups and we still have the issue. I will do a few more takes with the logic analyzer and post the results Regards Jman |
||||
jman![]() Guru ![]() Joined: 12/06/2011 Location: New ZealandPosts: 711 |
Some more info from the logic analyzer Working read Non working read Working export Time [s],Packet ID,Address,Data,Read/Write,ACK/NAK 0.567969875,0,'128','5',Write,ACK 0.568064,0,'128','16',Write,ACK 0.56815825,0,'128','0',Write,ACK 0.57616525,1,'128','0',Write,ACK 0.576259375,1,'128',<,Write,ACK 0.576353625,1,'128','207',Write,ACK 0.58779375,2,'128','4',Write,ACK 0.58826975,,'129','0',Read,ACK 0.588367,,'129','4',Read,NAK Not the non working one has NO ack after the setup to read but instead has a second setup to read ? NON Working export the read is missing :( Time [s],Packet ID,Address,Data,Read/Write,ACK/NAK 0.784313625,0,'128','5',Write,ACK 0.8742155,0,'128','16',Write,ACK 0.964119375,0,'128','0',Write,ACK 1.181285875,1,'128','0',Write,ACK 1.271188875,1,'128',<,Write,ACK 1.36108075,1,'128','207',Write,ACK 1.5783975,2,'128','4',Write,ACK Regards Jman |
||||
GoodToGo!![]() Senior Member ![]() Joined: 23/04/2017 Location: AustraliaPosts: 188 |
Finally got around to trying this on my logic analyser. (Saleae knock off) The first thing I noticed is that the I2c clock for the MM port is 100KHz. However the CFunction appears to be 100Hz! ![]() Using the dedicated I2C port:- Using the Cfunction:- Attached are the analyser files (in LOGICDATA format) for anyone to have a look at. 2018-03-19_154535_I2C_INA219_Logicdata_files.zip The clockspeed explains why it's slow I guess...... Thoughts? GTG! ![]() ...... Don't worry mate, it'll be GoodToGo! |
||||
Page 1 of 2 ![]() ![]() |
![]() |
![]() |
The Back Shed's forum code is written, and hosted, in Australia. | © JAQ Software 2025 |