![](templates/subSilver/images/CCSLogo.jpg) |
![CCS C Software and Maintenance Offers](templates/subSilver/images/forumAd6.jpg) |
View previous topic :: View next topic |
Author |
Message |
miskol
Joined: 01 Feb 2011 Posts: 16
|
PIC18F26k22 communication with INA219B |
Posted: Thu Jan 28, 2016 11:32 am |
|
|
Hi,
i'm trying to communicate PIC18F26k22 with INA219B. I used supply 3.3V connected to Vshunt+ and Vshunt- connected to LED with series resistor 330ohm which goes to common GND.
Unfortunately it doesnt work, OLED shows reading of 255 for both VShunt and VBus value.
my OLED definitely works, i got it to show the input voltage correctly.
Below is my coding:
Code: |
#include <main.h>
#include <mColed.c>
#include <float.h>
#USE SPI (MASTER, SPI1, ENABLE=PIN_B3, MODE=0, BITS=8, STREAM=SPI_1)
#use I2C (MASTER, I2C2, SLOW)
//float Rshunt = 0.001;
float adc = 0; float VBatt = 0;
char data1,data2;
unsigned int VSina = 0; unsigned int VBina = 0;
//INA219
BYTE INA219_CONFIGURATION = 0x00; // configuration register
BYTE INA219_SHUNT_VOLTAGE = 0x01; // shunt voltage register
BYTE INA219_BUS_VOLTAGE = 0x02; // bus voltage register
BYTE INA219_POWER = 0x03; // power register
BYTE INA219_CURRENT = 0x04; // current register
BYTE INA219_CALIBRATION = 0x05; // calibration register
BYTE INA219_I2C_ADDRESS = 0x40; // I2C address
void ADCupdate(void);
void OLED_display(void);
void OLED_start(void);
void main()
{
setup_adc_ports(sAN0, VSS_VDD);
setup_adc(ADC_CLOCK_INTERNAL|ADC_TAD_MUL_0);
OLED_start(); //display OLED
// INA219 initialize; bus 16V, shunt 320mV, 12-bit continuous Vshunt Vbus
i2c_start();
i2c_write(INA219_I2C_ADDRESS); // I2C slave address 0x40
i2c_write(INA219_CONFIGURATION); // INA219 config reg
i2c_write(0x19); // bus 16V, shunt 320mV, 12-bit continuous Vshunt Vbus
i2c_write(0x9F); //
i2c_stop();
// LSB 1m A/bit
i2c_start();
i2c_write(INA219_I2C_ADDRESS); // I2C slave address 0x40
i2c_write(INA219_CALIBRATION); // INA219 calibration reg
i2c_write(0x10); // 1m A/bit, 20m W/bit
i2c_write(0x00);
i2c_stop();
while(TRUE)
{
//TODO: User Code
i2c_start();
i2c_write(INA219_I2C_ADDRESS); // I2C slave address 0x40
i2c_write(INA219_SHUNT_VOLTAGE); // command register to read VShunt
i2c_stop(); delay_ms(1); // delay for ADC converts
i2c_start();
i2c_write(INA219_I2C_ADDRESS); // I2C slave address 0x40
data1 = i2c_read(1); // read INA219 MSB with master Acknowledge
data2 = i2c_read(1); // read INA219 LSB with master Acknowledge
i2c_stop();
VSina = make16(data1,data2); // combine MSB LSB, raw value for VShunt
i2c_start();
i2c_write(INA219_I2C_ADDRESS); // I2C slave address 0x40
i2c_write(INA219_BUS_VOLTAGE); // command register to read VBus
i2c_stop(); delay_ms(1); // delay for ADC converts
i2c_start();
i2c_write(INA219_I2C_ADDRESS); // I2C slave address 0x40
data1 = i2c_read(1); // read INA219 MSB with master Acknowledge
data2 = i2c_read(1); // read INA219 LSB with master Acknowledge
i2c_stop();
VBina = make16(data1,data2); // combine MSB LSB, raw value for VBus
//VBina = (VBina >> 3);
OLED_display();
}
}
void OLED_start(void) {
OUTPUT_HIGH(RES); init_OLED(); //reset_display();
show_bitmap(3); delay_ms(1000); // display image1
OLED_init(); OLED_clear(); OLED_write(OLED);
}
void OLED_display(void) {
char txt[100];
ADCupdate(); OLED_clear();
sprintf(txt,"%3.2f",VBatt); OLED_text(73,0,txt,2); // display Voltage input
txt = "V"; OLED_text(117,0,txt,2);
sprintf(txt,"%u",VBina); OLED_text(73,17,txt,2); // display VBus
sprintf(txt,"%u",VSina); OLED_text(73,34,txt,2); // display VShunt
OLED_write(OLED);
}
void ADCupdate(void) {
set_adc_channel(0); delay_us(10); adc = read_adc(); VBatt = ((adc/65535)*3.3); VBatt = ((VBatt * 8.4) / 3.17); adc = 0; delay_us(10);
}
|
Please help, thank you. |
|
![](templates/subSilver/images/spacer.gif) |
temtronic
Joined: 01 Jul 2010 Posts: 9177 Location: Greensville,Ontario
|
|
Posted: Thu Jan 28, 2016 12:02 pm |
|
|
3 comments
1) I don't see where you set the clock speed of the PIC.
2) what are the pullup resistors for the I2C bus ?
3)I've never seen
setup_adc(ADC_CLOCK_INTERNAL_TAD_MUL_0);
used for any ADC except while in sleep mode.
from the datasheet....When the device frequency is greater than 1 MHz, the FRC clock source is only recommended if the
conversion will be performed during Sleep.
and I assume you're using a device frequency > 1MHz.
Jay |
|
![](templates/subSilver/images/spacer.gif) |
miskol
Joined: 01 Feb 2011 Posts: 16
|
|
Posted: Thu Jan 28, 2016 12:08 pm |
|
|
temtronic wrote: | 3 comments
1) I don't see where you set the clock sped of the PIC.
2) what are the pullup resistors for the I2C bus ?
3)I've never seen
setup_adc(ADC_CLOCK_INTERNAL_TAD_MUL_0);
used for any ADC except while in sleep mode
from the datasheet....When the device frequency is greater than 1 MHz, the FRC clock source is only recommended if the
conversion will be performed during Sleep.
and I assume you're using a device fequncy > 1MHz.
Jay |
Hi, TQ for your help.
1) PIC clock speed is 64MHz.
2) pull-up resistors are 2.49K ohm.
3) noted with thanks. |
|
![](templates/subSilver/images/spacer.gif) |
Ttelmah
Joined: 11 Mar 2010 Posts: 19378
|
|
Posted: Thu Jan 28, 2016 12:43 pm |
|
|
Classic problem.
Texas list I2C addresses as the 7bit address.
The seven bit address is the top seven bits of the byte sent by the PIC (and every other controller), followed by the direction bit.
So to turn the Texas address into an address for use on the bus, you have to multiply it by 2.
Assuming you have A0 and A1 grounded, the chips write address is 0x80...
It's _read_ address is 0x81.
You are also not sending the read bit (trying to use the same address both for read and write)....
Last edited by Ttelmah on Thu Jan 28, 2016 12:47 pm; edited 1 time in total |
|
![](templates/subSilver/images/spacer.gif) |
temtronic
Joined: 01 Jul 2010 Posts: 9177 Location: Greensville,Ontario
|
|
Posted: Thu Jan 28, 2016 12:45 pm |
|
|
re 2) pullups. Might be too high, I use 1K2R though check with peripheral datasheet to see what they recommend.
re I2C
copy the I2C scanner program from the code library, it's at the top. Use it to confirm the PIC sees the peripheral.
Jay |
|
![](templates/subSilver/images/spacer.gif) |
miskol
Joined: 01 Feb 2011 Posts: 16
|
|
Posted: Thu Jan 28, 2016 1:47 pm |
|
|
Ttelmah wrote: | Classic problem.
Texas list I2C addresses as the 7bit address.
The seven bit address is the top seven bits of the byte sent by the PIC (and every other controller), followed by the direction bit.
So to turn the Texas address into an address for use on the bus, you have to multiply it by 2.
Assuming you have A0 and A1 grounded, the chips write address is 0x80...
It's _read_ address is 0x81.
You are also not sending the read bit (trying to use the same address both for read and write).... |
TQ very much, finally i'm getting something now ![Very Happy](images/smiles/icon_biggrin.gif) |
|
![](templates/subSilver/images/spacer.gif) |
miskol
Joined: 01 Feb 2011 Posts: 16
|
|
Posted: Thu Jan 28, 2016 1:49 pm |
|
|
temtronic wrote: | re 2) pullups. Might be too high, I use 1K2R though check with peripheral datasheet to see what they recommend.
re I2C
copy the I2C scanner program from the code library, it's at the top. Use it to confirm the PIC sees the peripheral.
Jay |
TQ, i've used the scanner program, edited it to display on my OLED and yes it shows 80 for the address and number of i2c chips found is 1. very nice very useful code
earlier i used 4.7K ohm resistors, figured it could be too high then i changed to 2.49K ohm and now i changed it to nearest that i have which is 1K ohm. |
|
![](templates/subSilver/images/spacer.gif) |
Ttelmah
Joined: 11 Mar 2010 Posts: 19378
|
|
Posted: Fri Jan 29, 2016 4:54 am |
|
|
Just to add on the bus resistors, it's a case of 'current/time'. Some values will be different for a 3.3v bus than a 5v bus.
On the I2C bus, you have the current that the pull down drivers can generate. This is required to be a minimum of 3mA at 0.4v. So straight away without considering anything else, the _minimum_ resistor that can be used 'generically', is 1150R at 5v (normally quoted as 1.2KR), and 725R at 3.3v (750R normally quoted). Note how much smaller the 3.3v value is.
Separately, you then have how fast the resistor can pull the bus back 'up' when the drivers switch off. The rise time on I2C, is the time taken for the rail to go from 0.3*Vdd to 0.7*Vdd (again in the spec), and this depends on the resistor, and the bus capacitance. The rise time is specified to be 1uS maximum for standard mode, and 0.3uSec maximum for fast mode. V(t) is calculated as Vdd * (1-e^(-t/RC)), so:
V(T1) = 0.3 * 3.3
Then solving:
3.3 * (1-e^(-t/RC))
for T1, gives:
0.99 = 3.3 * (1-e^(t1/RC)
0.3 = 1-e^(t1/RC)
-0.7 = -e^(t1/RC)
ln(0.7) = t1/RC
t1 = 0.35667*RC
Now the neat thing is if you study this, that the voltage terms cancel throughout, so you get the same result for all different supply voltages. Try 5v and you get the same answer. Then do the same for the 0.7*Vcc (T2) term, and you get:
t2 = 1.20397*RC
Now since we want the time 'between' these (T2-T1), this solves as:
Trise = (1.20397-0.35667)*RC
0.8473*RC - you'll find this in most I2C data sheets.
Then if you are using a bus with 400pF maximum capacitance, you can calculate 'Rmax' for 'standard mode' as:
1/R = 0.8473 * 400pF * 1/1E-6
Gives R=2950R
Do the same for 'fast mode', and you have R = 885R
The first interesting thing about this is that a 5V master can't actually then drive a fast mode bus with 400R capacitance. Since Rmin is greater than the resistance actually required. The quoted maximum bus capacitance for fast mode at 5v, using standard drivers is actually just under 300pF. However many devices actually generate more than the 3mA current, so higher capacitance busses can often be driven OK, but it is a warning that some devices may then have problems. You can also see that using (for instance) 4K7R, will only be OK at this speed up to about 75pF capacitance. Always make a rough estimate of your likely 'worst case' capacitance and choose resistors that will have a little margin at this.
Separately there is 'high speed' mode, but on this active pull up's (rise time accelerators) become required, since otherwise the allowable bus capacitance would just be so low.
This all becomes really important when using a lot of devices on long busses.
In your case, if the bus is short and only has the one device, your bus capacitance, is most likely only a few 10's of pF. 2K49R, will be fine even on fast mode, up to 142pF on the bus. |
|
![](templates/subSilver/images/spacer.gif) |
zamzam23
Joined: 25 Aug 2010 Posts: 47
|
the working code |
Posted: Thu Mar 16, 2017 10:17 pm |
|
|
hi,
Can you share the last working code for ina219 ? I need read voltage and current with this module. |
|
![](templates/subSilver/images/spacer.gif) |
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
Powered by phpBB © 2001, 2005 phpBB Group
|