2017-03-22 5 views
0

SO J'ai calculé la valeur de registre d'étalonnage basée sur this:Comment calibrer le capteur ti INA219? (en C)

Ma valeur de résistance de shunt est de 0,01 ohms. Mes courants sont éteints, même si je l'étalonner en fonction de ma valeur shunt

Tous les courants montrent les mauvaises valeurs (Par exemple, il est censé montrer 7,8mA et il montre 1mA

Après mon code:

#include <unistd.h> 
#include <stdlib.h> 
#include <stdio.h> 
#include <errno.h> 
#include <endian.h> 
#include <string.h> 
#include <time.h> 
#include <getopt.h> 
#include <sys/types.h> 
#include <sys/stat.h> 
#include <sys/ioctl.h> 
#include <fcntl.h> 
#include <linux/i2c-dev.h> 

#define CONFIG_REG   0 
#define SHUNT_REG   1 
#define BUS_REG    2 
#define POWER_REG   3 
#define CURRENT_REG   4 
#define CALIBRATION_REG  5 


#define INA_ADDRESS1   0x40 
#define INA_ADDRESS2   0x41 



int interval = 60; 
int i2c_bus = 1; 
int i2c_address1 = INA_ADDRESS1; 
int i2c_address2 = INA_ADDRESS2; 

int handle; 

int i2c_read(void *buf, int len) 
{ 
    int rc = 0; 

    if (read(handle, buf, len) != len) 
    { 
     printf("I2C read failed: %s\n", strerror(errno)); 
     rc = -1; 
    } 

    return 0; 
} 


int i2c_write(void *buf, int len) 
{ 
    int rc = 0; 

    if (write(handle, buf, len) != len) 
    { 
     printf("I2C write failed: %s\n", strerror(errno)); 
     rc = -1; 
    } 

    return rc; 
} 

int register_read(unsigned char reg, unsigned short *data) 
{ 
    int rc = -1; 
    unsigned char bite[ 4 ]; 

    bite[ 0 ] = reg; 
    if (i2c_write(bite, 1) == 0) 
    { 
     if (i2c_read(bite, 2) == 0) 
     { 
      *data = (bite[ 0 ] << 8) | bite[ 1 ]; 
      rc = 0; 
     } 
    } 

    return rc; 
} 

int register_write(unsigned char reg, unsigned short data) 
{ 
    int rc = -1; 
    unsigned char bite[ 4 ]; 

    bite[ 0 ] = reg; 
    bite[ 1 ] = (data >> 8) & 0xFF; 
    bite[ 2 ] = (data & 0xFF); 

    if (i2c_write(bite, 3) == 0) 
    { 
     rc = 0; 
    } 

    return rc; 
} 


int get_voltage(float *mv) 
{ 
    short bus; 

    if (register_read(BUS_REG, (unsigned short*)&bus) != 0) 
    { 
     return -1; 
    } 

    *mv = (float)((bus & 0xFFF8) >> 1); 
    return 0; 
} 


int get_current(float *ma) 
{ 
    short shunt; 

    if (register_read(SHUNT_REG, &shunt) != 0) 
    { 
     return -1; 
    } 

    *ma = (float)shunt/10; 
    return 0; 
} 


void show_current(void) 
{ 
    float ma; 

    if (get_current(&ma)) 
    { 
     fprintf(stderr, "Error reading current\n"); 
     return; 
    } 
} 


void show_voltage(void) 
{ 
    float mv; 

    if (get_voltage(&mv)) 
    { 
     fprintf(stderr, "Error reading voltage\n"); 
     return; 
    } 
    printf("%4.0f\n", mv); 
} 


void show_voltage_current(void) 
{ 
    float mv, ma; 

    if (get_current(&ma) || get_voltage(&mv)) 
    { 
     fprintf(stderr, "Error reading voltage/current\n"); 
     return; 
    } 


    else 
    { 
     printf("Load Voltage: %g Current: %4.1fmA\n", (mv/1000), (ma)); 

    } 
} 


int main(int argc, char *argv[]) 
{ 
    char filename[ 20 ]; 
    register_write(CALIBRATION_REG, 4096); 



    snprintf(filename, 19, "/dev/i2c-%d", i2c_bus); 
    handle = open(filename, O_RDWR); 
    if (handle < 0) 
    { 
     fprintf(stderr, "Error opening bus %d: %s\n", i2c_bus, strerror(errno)); 
     exit(1); 
    } 

    if (ioctl(handle, I2C_SLAVE, i2c_address1) < 0) 
    { 
     fprintf(stderr, "Error setting address %02X: %s\n", i2c_address1, strerror(errno)); 
     exit(1); 
    } 

     show_voltage_current(); 
     sleep(1); 


    if (ioctl(handle, I2C_SLAVE, i2c_address2) < 0) 
    { 
     fprintf(stderr, "Error setting address %02X: %s\n", i2c_address2, strerror(errno)); 
     exit(1); 


     show_voltage_current(); 
     sleep(1); 
    } 
    return 0; 
} 

Répondre

0

Regardez https://github.com/flav1972/ArduinoINA219 comme référence.

Vous devez définir des registres d'état et d'étalonnage avant les valeurs actuelles/électriques seront fiables

Essayez de changer le courant attendu d'au moins 1/4 du courant maximum et n'oubliez pas de régler la tension de dérivation valide.

Sur mon conseil d'essai si je définis le pensais courant que 1.6A et max_current 16A J'ai mal fait, mais si je change pour résultat 4A semble ok

a marché pour moi: Rshunt = 0,1 R, Vbus = 16V, Imax = 1,6A, Iexp = 1,6A, Rshunt = 0,01R, Vbus = 16V, Imax = 16A, Iexp = 4.16A