INA 219 DC Current Sensor - C language
John Kauffman
Posts: 653
Before I re-invent the wheel, has anyone written a C library/example for the INA 219 DC Current Sensor?
(multiple names for future searchers)
DC Current Sensor
INA 219
INA219
part 29130
Thanks.
(multiple names for future searchers)
DC Current Sensor
INA 219
INA219
part 29130
Thanks.
Comments
Right. I'm thinking conversion from Arduino to Propeller C will be easier than from Spin.
Thanks.
I think only one line is a problem. For i2c_in() I believe that I am asking for data from the wrong memory address on the INA but can't figure out the correct location from the other examples. Nor am I getting it from the datasheet.
This is proof of concept: no checks for INA219 present, modify calibration, etc.
I've attached C file. It is verbose as I tried to indicate what I was doing and compare with similar examples. INA219 ver03.c
At bottom comments I've copied entire programs for reference:
Plax SPIN example (works)
Arduino (works)
C language I2C example w/EEPROM (works).
Datasheet here: http://www.parallax.com/sites/default/files/downloads/29130-INA219-DC-Current-Sensor-INA219B-Datasheet.pdf
i2c_in(eeBus,0b1010000,0,2,InaData[0],8); // ?? problem here
Per the second parameter ( 0b1010000 ) you are trying to access an eeprom, not the INA 219, whose address you say is 0x40. Should be 0b0100000 in 7-bit format
You are also telling the I2C function that the register address is 2 bytes long. From the data sheet I see only 6 registers so the memAddrCount should be 1.
And in your write up you indicate 5 registers of interest and each register is a 16-bit word but you only defined the InaData array as 4 chars. Should be 10.
Your first register of interest is register 1, you have it starting at 0.
The last parameter is the data byte count to read from the device, which you set to 8. That should be 10 also. Once the array has been filled you will have to
combine each two elements of your array into a 16 bit word.
The read command should probably look like this;
i2c_in(eeBus,0b0100000,1,1,InaData[0],10);
Thanks for breaking down the problems. I cut and paste the suggested i2c_in line and changed array but still got 0. But I'm digging into the meaning of each of your comments and may be able to figure it out. I'm a little confused on the mem addresses but am working on learning it from other examples of i2c_in().
Thanks.
For the information on how to use the i2c_in library function go to the Simple Library Reference. With Simpleide open, click on Help on the Menu bar, (top) and select Simple Library Reference from the drop down, usually the 3rd item. Now click on Simpletools.h near the top under Utility. On the next page scroll down to FUNCTIONS section and continue going down to subheading I2C. Click on the highlighted i2c_in and at the top of the page is a detailed explanation of each parameter.
I dug deeper into the INA219 datasheet and found the device address always has the most significant bit high, meaning that the lowest possible device address will be 0b1000000. The actual address is dependent on what you do with the A0 and A1 pins on the chip. Per Table 2 on page 10 both A0 and A1 must be tied to ground (Vss) to make the device address 0b1000000. So, if you have both pins grounded the instruction should be: Some questions:
Do you have suitable pull up resistors on the SDA and SCL lines? 4.7K to 10K usually works.
Are you combining the high byte and low byte into a single 16 bit variable? When reading 10 bytes starting at register 1 the array will hold register 1 data in InaData[0] high byte and inaData[1] low byte, register 2 in InaData[2] and InaData[3], etc.
I would avoid using float until you have established communication with the device and are able to display non-zero data from the array.
The Device address thing can be confusing - it bit my rear a while ago. The i2c_in() function expects a 7 bit address, in this case 0b1000000 which if converted to 8-bit hex would read 0x40. However, your device will only respond to addresses that has MSB set to 1, meaning that the lowest possible address for this device would be 0x80 for write and 0x81 for read. What i2c_in() does is it takes whatever address you give, shifts it left one bit and adds the LSB, which in 12c is the read/write bit. So, if you provide the address 0b1000000 or 0x40 then everything works out. If, however, you provide 0x80, 12c_in() destroys the address with the left shift.
I hope I haven't confused you further.
Hal
Thanks for breaking it down. I have to get another project done on deadline and then will be back on this.
I hope I haven't confused you further.
You did confuse me further, but that gives me the outline of what to study next to understand it all.
I have studied the Simple Library Reference but was confused on exactly how some terms were use. That is another topic to search on the fora. I think I can get that with some time.
I'll be back. I really appreciate your time.