Home
JAQForum Ver 24.01
Log In or Join  
Active Topics
Local Time 06:55 02 Aug 2025 Privacy Policy
Jump to

Notice. New forum software under development. It's going to miss a few functions and look a bit ugly for a while, but I'm working on it full time now as the old forum was too unstable. Couple days, all good. If you notice any issues, please contact me.

Forum Index : Microcontroller and PC projects : I2CPort

     Page 1 of 2    
Author Message
jman

Guru

Joined: 12/06/2011
Location: New Zealand
Posts: 711
Posted: 07:30am 16 Mar 2018
Copy link to clipboard 
Print this post

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: France
Posts: 435
Posted: 10:31am 16 Mar 2018
Copy link to clipboard 
Print this post

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();
}
Edited by goc30 2018-03-17
 
GoodToGo!

Senior Member

Joined: 23/04/2017
Location: Australia
Posts: 188
Posted: 12:00pm 16 Mar 2018
Copy link to clipboard 
Print this post

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: Australia
Posts: 3292
Posted: 12:56pm 16 Mar 2018
Copy link to clipboard 
Print this post

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 Zealand
Posts: 711
Posted: 07:13pm 16 Mar 2018
Copy link to clipboard 
Print this post

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: Australia
Posts: 3292
Posted: 10:01pm 16 Mar 2018
Copy link to clipboard 
Print this post

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: Australia
Posts: 188
Posted: 12:36am 17 Mar 2018
Copy link to clipboard 
Print this post

  jman said  
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 successful


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! Edited by GoodToGo! 2018-03-18
...... Don't worry mate, it'll be GoodToGo!
 
TassyJim

Guru

Joined: 07/08/2011
Location: Australia
Posts: 6283
Posted: 01:12am 17 Mar 2018
Copy link to clipboard 
Print this post

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: Australia
Posts: 188
Posted: 02:22am 17 Mar 2018
Copy link to clipboard 
Print this post

  TassyJim said   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


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: Australia
Posts: 188
Posted: 02:38am 17 Mar 2018
Copy link to clipboard 
Print this post

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

  Quote  > run
WD(0)= 101
WD(1)= 10000
WD(2)= 0
WD(0)= 0
WD(1)= 111100
WD(2)= 11001111
Register = 1
0 11
11
Register = 2
100110 11111010
10011011111010
Register = 4
0 110
110
Register = 2
100110 11111010
10011011111010
Register = 1
0 101
101
Register = 3
0 10
10
Bus Voltage: 4.988V
Shunt Voltage: 0.03mV
Supply Voltage: 4.98805V
Current: 1mA
Power: 4mW
Calc. Power: 4.988mW


Now using the Cfunction by commenting/uncommenting the appropriate lines above:-
  Quote  run
WD(0)= 101
WD(1)= 10000
WD(2)= 0
WD(0)= 0
WD(1)= 111100
WD(2)= 11001111
Register = 1
1111111 11111111
111111111111111
Register = 2
1111111 11111111
111111111111111
Register = 4
1111111 11111111
111111111111111
Register = 2
1111111 11111111
111111111111111
Register = 1
1111111 11111111
111111111111111
Register = 3
1111111 11111111
111111111111111
Bus Voltage: 16.38V
Shunt Voltage: 327.67mV
Supply Voltage: 16.7077V
Current: 3277mA
Power: 65534mW
Calc. Power: 53677.3mW


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! Edited by GoodToGo! 2018-03-18
...... Don't worry mate, it'll be GoodToGo!
 
Geoffg

Guru

Joined: 06/06/2011
Location: Australia
Posts: 3292
Posted: 05:55am 17 Mar 2018
Copy link to clipboard 
Print this post

  GoodToGo! said  One thing to note, that using the Cfunction is resulting in a s-l-o-w response. I wonder if it's timing out?

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: Australia
Posts: 188
Posted: 06:17am 17 Mar 2018
Copy link to clipboard 
Print this post

  Geoffg said  Perhaps the INA219 is slow to respond but is less than the timeout (which is 5ms.)


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 Zealand
Posts: 711
Posted: 06:58am 17 Mar 2018
Copy link to clipboard 
Print this post

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: Australia
Posts: 3292
Posted: 07:13am 17 Mar 2018
Copy link to clipboard 
Print this post

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.Edited by Geoffg 2018-03-18
Geoff Graham - http://geoffg.net
 
Geoffg

Guru

Joined: 06/06/2011
Location: Australia
Posts: 3292
Posted: 07:40am 17 Mar 2018
Copy link to clipboard 
Print this post

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: Germany
Posts: 949
Posted: 10:08am 17 Mar 2018
Copy link to clipboard 
Print this post

@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 Kingdom
Posts: 10315
Posted: 11:09am 17 Mar 2018
Copy link to clipboard 
Print this post

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 Zealand
Posts: 711
Posted: 08:35pm 17 Mar 2018
Copy link to clipboard 
Print this post

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 Zealand
Posts: 711
Posted: 09:11pm 17 Mar 2018
Copy link to clipboard 
Print this post

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: Australia
Posts: 188
Posted: 05:47am 19 Mar 2018
Copy link to clipboard 
Print this post

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    
Print this page
The Back Shed's forum code is written, and hosted, in Australia.
© JAQ Software 2025