INA3221 Cargar baterías Solar

Hola foro, hace unos días me llegaron los módulos INA3221, para fuente única de alimentación, ahora me llegaron para tres fuentes independientes, ya probé ambos y funcionan con sus respectivas características. El código con el que cuento esta diseñado para los módulos ACS712 Y FZ0430. La función PWM no ha funcionado como debería, en ocasiones no detiene la carga de la batería de ácido plomo.
Mi problema es que no se como modificar el código, para que la información que ahora llega por los pines analógicos, y los INA3221 la envían vía I2C
Nota: la falla puede estar en la batería.

//https://forum.arduino.cc/t/fz0430-lecturas-incorrectas-en-2-de-4/998825/63

#include <Arduino.h>
#define bulk_voltage_max         12.200
#define bulk_voltage_min         12.100
#define absorption_voltage       12.300
#define absorption_max_current    0.266
#define absorption_min_current    0.166
#define float_voltage            12.600
#define float_voltage_max        12.400
#define float_voltage_min        12.450
#define float_max_current         0.120
#define battery_min_voltage      10.000
#define solar_min_voltage        14.200
#define charging_current          0.300
#define PWM_out                   6
#define load_enable               2
#define solar_current_in          A0
#define solar_voltage_in          A1
#define battery_voltage_in        A2
#define LCD_refresh_rate       1000
int rele8 = 8;
int rele9 = 9;
int rele10 = 10;
int rele11 = 11;
int Current;
const unsigned long TIEMPO_LECTURAS = 3000UL;
byte BULK = 0;
byte ABSORPTION = 1;
byte FLOAT = 2;
byte mode = 0;
float bat_voltage = 0;
int pwm_value = 3;
float solar_current = 0;
float current_factor = 0.100;
float solar_voltage = 0;
float solar_power = 0.0;
String load_status = "OFF";
int pwm_percentage = 0;
unsigned int before_millis = 0;
unsigned int now_millis = 0;
String mode_str = "BULK";

float R1 = 30000.0;
float R2 = 7500.0;
float R3 = 30000.0;
float R4 = 7500.0;
float R5 = 30000.0;
float R6 = 7500.0;
float ref_voltage0 = 5.0;
float ref_voltage1 = 5.0;
float ref_voltage2 = 5.0;
int adc_value0 = 0;
int adc_value1 = 0;
int adc_value2 = 0;
unsigned long tiempolecturas;
struct Bateria {
  int sensor;
  float adc_voltage;
  float in_voltage;
  float ref_voltage;
  float max, min;
  int rele;
  float R1, R2;
};
Bateria bateria[3] = {
  {A5, 0.0, 0.0, 5.0, 16.10, 15.80,  rele9, R1, R2},
  {A4, 0.0, 0.0, 5.0, 12.70, 12.40, rele10, R3, R4},
  {A3, 0.0, 0.0, 5.0,  8.90,  8.20, rele11, R5, R6}
};
void leoBateria(int id) {  // si se cargan
  bateria[id].adc_voltage  = (analogRead(bateria[id].sensor) * bateria[id].ref_voltage) / 1024.0;
  bateria[id].in_voltage = bateria[id].adc_voltage / (bateria[id].R2 / (bateria[id].R1 + bateria[id].R2));
  if (bateria[id].in_voltage > bateria[id].max) {
    digitalWrite(bateria[id].rele, HIGH);
  }
  if (bateria[id].in_voltage < bateria[id].min) {
    digitalWrite(bateria[id].rele, LOW);
  }
}

// mostrame un codigo viejo tuyo donde estaban estos codigos repetidos

float get_solar_voltage(int n_samples) {
  float voltage = 0;
  for (int i = 0; i < n_samples; i++)   {
    voltage += (analogRead(solar_voltage_in) * (5.0 / 1023.0) * 4.860);
  }
  voltage = voltage / n_samples;
  if (voltage < 0) {
    voltage = 0;
  }
  return (voltage);
}
float get_battery_voltage(int n_samples) {
  float voltage = 0;
  for (int i = 0; i < n_samples; i++)  {
    voltage += (analogRead(battery_voltage_in) * (5.0 / 1023.0) * 4.757);
  }
  voltage = voltage / n_samples;
  if (voltage < 0) {
    voltage = 0;
  }
  return (voltage);
}
float get_solar_current(int n_samples) {
  float Sensor_voltage;
  float current = 0;
  for (int i = 0; i < n_samples; i++)   {
    Sensor_voltage = analogRead(solar_current_in) * (5.0 / 1023.0);
    current = current + (Sensor_voltage - 2.51503) / current_factor;
  }
  current = current / n_samples;
  if (current < 0) {
    current = 0;
  }
  return (current);
}
float in_voltage(float x, float in_min, float in_max, float out_min, float out_max) {
  return (x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min;
}
void setup() {
  Serial.begin(9600);
  pinMode(rele8, OUTPUT);
  pinMode(rele9, OUTPUT);
  pinMode(rele10, OUTPUT);
  pinMode(rele11, OUTPUT);
  pinMode(solar_voltage_in, INPUT);
  pinMode(solar_current_in, INPUT);
  pinMode(battery_voltage_in, INPUT);
  pinMode(PWM_out, OUTPUT);
  digitalWrite(PWM_out, LOW);
  pinMode(load_enable, OUTPUT);
  digitalWrite(load_enable, LOW);
  Serial.begin(9600);
  before_millis = millis();
  
}
void loop() {
  if (millis() - tiempolecturas > 3000UL) {
    if (Current > 0.100) {
      digitalWrite(rele8, HIGH);
    }
    if (Current < 0.300) {
      digitalWrite(rele8, LOW);
    }
    solar_voltage = get_solar_voltage(15);
    bat_voltage   = get_battery_voltage(15);
    solar_current = get_solar_current(15);
    solar_power = bat_voltage * solar_current;
    pwm_percentage = map(pwm_value, 0, 255, 0, 100);
    now_millis = millis();
    if (now_millis - before_millis > LCD_refresh_rate)  {
      before_millis = now_millis;
      Serial.print("Volt. Fuente  :");
      Serial.println(solar_voltage, 3);
      Serial.print("Volt. Bateria :");
      Serial.println(bat_voltage, 3);
      Serial.print("pwm           :");
      Serial.println(pwm_percentage);
      Serial.print("Bat. AMP      :");
      Serial.println(solar_current, 3);
      Serial.println(load_status);
    }
    if (bat_voltage < battery_min_voltage) {
      digitalWrite(load_enable, LOW);
      load_status  = "OFF";
    }
    else {
      digitalWrite(load_enable, HIGH);
      load_status  = "ON";
    }
    // BATERIA 1
    leoBateria(0);
    // BATERIA 2
    leoBateria(1);
    // BATERIA 3
    leoBateria(2);

    /////   FLOAT       /////////
    if (mode == FLOAT) {
      if (bat_voltage < float_voltage_min) {
        mode = BULK;
        mode_str = "BULK";
      }
      else {
        if (solar_current > float_max_current) {
          mode = BULK;
          mode_str = "BULK";
        }
        else {
          if (bat_voltage > float_voltage) {
            pwm_value--;
            pwm_value = constrain(pwm_value, 0, 255);
          }
          else {
            pwm_value++;
            pwm_value = constrain(pwm_value, 0, 255);
          }
        }
        analogWrite(PWM_out, pwm_value);
      }
    }
    else {
      if (bat_voltage < bulk_voltage_min) {
        mode = BULK;
        mode_str = "BULK";
      }
      else if (bat_voltage > bulk_voltage_max) {
        mode_str = "ABSORPTION";
        mode = ABSORPTION;
      }

      /////////   BULK    ////////////
      if (mode == BULK) {
        if (solar_current > charging_current) {
          pwm_value--;
          pwm_value = constrain(pwm_value, 0, 255);
        }
        else {
          pwm_value++;
          pwm_value = constrain(pwm_value, 0, 255);
        }
        analogWrite(PWM_out, pwm_value);
      }
      ////////  ABSORPTION  ///////
      if (mode == ABSORPTION) {
        if (solar_current > absorption_max_current) {
          pwm_value--;
          pwm_value = constrain(pwm_value, 0, 255);
        }
        else {
          if (bat_voltage > absorption_voltage) {
            pwm_value++;
            pwm_value = constrain(pwm_value, 0, 255);
          }
          else {
            pwm_value--;
            pwm_value = constrain(pwm_value, 0, 255);
          }
          if (solar_current < absorption_min_current) {
            mode = FLOAT;
            mode_str = "FLOAT";
          }
        }
        analogWrite(PWM_out, pwm_value);
      }
    }
    for (int i = 0; i < 3; i++) {
      Serial.print("sensor " + String(i) + "      :");
      Serial.print(bateria[i].in_voltage,  3);
      Serial.println(" V");
    }
    tiempolecturas = millis();
  }
}

Saludos.

Modulo 1 tres canales independientes.

3 canales

Modulo 2 fuente única.

Me gustaría su opinión, para decidir con que modulo trabajar.
Saludos.

Hola foro, este código funciona con con cualquiera de los dos módulos.

//https://forum.arduino.cc/t/fixing-the-ina3221-breakout-board/526947/6
//   SDL_Arduino_INA3221 Library Test Code
//   SDL_Arduino_INA3221.cpp Arduino code - runs in continuous mode
//   Version 1.1
//   SwitchDoc Labs   January 31, 2015
//
//
// This was designed for SunAirPlus - Solar Power Controller - www.switchdoc.com
//



#include <Wire.h>
#include <SDL_Arduino_INA3221.h>

SDL_Arduino_INA3221 ina3221;

// the three channels of the INA3221 named for SunAirPlus Solar Power Controller channels (www.switchdoc.com)
#define LIPO_BATTERY_CHANNEL 1
#define SOLAR_CELL_CHANNEL 2
#define OUTPUT_CHANNEL 3

void setup(void) 
{
  
Serial.begin(57600);
Serial.println("SDA_Arduino_INA3221_Test");

Serial.println("Measuring voltage and current with ina3221 ...");
ina3221.begin();
}

void loop(void) 
{

Serial.println("------------------------------");
float shuntvoltage1 = 0;
float busvoltage1 = 0;
float current_mA1 = 0;
float loadvoltage1 = 0;


busvoltage1 = ina3221.getBusVoltage_V(LIPO_BATTERY_CHANNEL);
shuntvoltage1 = ina3221.getShuntVoltage_mV(LIPO_BATTERY_CHANNEL);
current_mA1 = -ina3221.getCurrent_mA(LIPO_BATTERY_CHANNEL);  // minus is to get the "sense" right.   - means the battery is charging, + that it is discharging
loadvoltage1 = busvoltage1 + (shuntvoltage1 / 1000);

Serial.print("LIPO_Battery Bus Voltage:   "); Serial.print(busvoltage1); Serial.println(" V");
Serial.print("LIPO_Battery Shunt Voltage: "); Serial.print(shuntvoltage1); Serial.println(" mV");
Serial.print("LIPO_Battery Load Voltage:  "); Serial.print(loadvoltage1); Serial.println(" V");
Serial.print("LIPO_Battery Current 1:       "); Serial.print(current_mA1); Serial.println(" mA");
Serial.println("");

float shuntvoltage2 = 0;
float busvoltage2 = 0;
float current_mA2 = 0;
float loadvoltage2 = 0;

busvoltage2 = ina3221.getBusVoltage_V(SOLAR_CELL_CHANNEL);
shuntvoltage2 = ina3221.getShuntVoltage_mV(SOLAR_CELL_CHANNEL);
current_mA2 = -ina3221.getCurrent_mA(SOLAR_CELL_CHANNEL);
loadvoltage2 = busvoltage2 + (shuntvoltage2 / 1000);

Serial.print("Solar Cell Bus Voltage 2:   "); Serial.print(busvoltage2); Serial.println(" V");
Serial.print("Solar Cell Shunt Voltage 2: "); Serial.print(shuntvoltage2); Serial.println(" mV");
Serial.print("Solar Cell Load Voltage 2:  "); Serial.print(loadvoltage2); Serial.println(" V");
Serial.print("Solar Cell Current 2:       "); Serial.print(current_mA2); Serial.println(" mA");
Serial.println("");

float shuntvoltage3 = 0;
float busvoltage3 = 0;
float current_mA3 = 0;
float loadvoltage3 = 0;

busvoltage3 = ina3221.getBusVoltage_V(OUTPUT_CHANNEL);
shuntvoltage3 = ina3221.getShuntVoltage_mV(OUTPUT_CHANNEL);
current_mA3 = ina3221.getCurrent_mA(OUTPUT_CHANNEL);
loadvoltage3 = busvoltage3 + (shuntvoltage3 / 1000);

Serial.print("Output Bus Voltage 3:   "); Serial.print(busvoltage3); Serial.println(" V");
Serial.print("Output Shunt Voltage 3: "); Serial.print(shuntvoltage3); Serial.println(" mV");
Serial.print("Output Load Voltage 3:  "); Serial.print(loadvoltage3); Serial.println(" V");
Serial.print("Output Current 3:       "); Serial.print(current_mA3); Serial.println(" mA");
Serial.println("");

delay(2000);
}

Solo entrega información en el monitor Serial, no cumple ninguna función.
Saludos.

Primer enfoque, dime si trabaja bien

#include <Arduino.h>
#include <Wire.h>
#include <SDL_Arduino_INA3221.h>

SDL_Arduino_INA3221 ina3221;

// the three channels of the INA3221 named for SunAirPlus Solar Power Controller channels (www.switchdoc.com)
#define LIPO_BATTERY_CHANNEL    1 // verifica esto
#define SOLAR_CELL_CHANNEL      2
#define OUTPUT_CHANNEL          3

#define bulk_voltage_max         12.200
#define bulk_voltage_min         12.100
#define absorption_voltage       12.300
#define absorption_max_current    0.266
#define absorption_min_current    0.166
#define float_voltage            12.600
#define float_voltage_max        12.400
#define float_voltage_min        12.450
#define float_max_current         0.120
#define battery_min_voltage      10.000
#define solar_min_voltage        14.200
#define charging_current          0.300
#define PWM_out                   6
#define load_enable               2
#define solar_current_in          A0
#define solar_voltage_in          A1
#define battery_voltage_in        A2
#define LCD_refresh_rate       1000
int rele8 = 8;
int rele9 = 9;
int rele10 = 10;
int rele11 = 11;
int Current;
const unsigned long TIEMPO_LECTURAS = 3000UL;
byte BULK = 0;
byte ABSORPTION = 1;
byte FLOAT = 2;
byte mode = 0;
float bat_voltage = 0;
int pwm_value = 3;
float solar_current = 0;
float current_factor = 0.100;
float solar_voltage = 0;
float solar_power = 0.0;
String load_status = "OFF";
int pwm_percentage = 0;
unsigned int before_millis = 0;
unsigned int now_millis = 0;
String mode_str = "BULK";

float R1 = 30000.0;
float R2 = 7500.0;
float R3 = 30000.0;
float R4 = 7500.0;
float R5 = 30000.0;
float R6 = 7500.0;
float ref_voltage0 = 5.0;
float ref_voltage1 = 5.0;
float ref_voltage2 = 5.0;
int adc_value0 = 0;
int adc_value1 = 0;
int adc_value2 = 0;
unsigned long tiempolecturas;
struct Bateria {
  int sensor;
  float adc_voltage;
  float in_voltage;
  float ref_voltage;
  float max, min;
  int rele;
  float R1, R2;
};
Bateria bateria[3] = {
  {A5, 0.0, 0.0, 5.0, 16.10, 15.80,  rele9, R1, R2},
  {A4, 0.0, 0.0, 5.0, 12.70, 12.40, rele10, R3, R4},
  {A3, 0.0, 0.0, 5.0,  8.90,  8.20, rele11, R5, R6}
};

void leoBateria(int id) {  // si se cargan
  bateria[id].adc_voltage  = (analogRead(bateria[id].sensor) * bateria[id].ref_voltage) / 1024.0;
  bateria[id].in_voltage = bateria[id].adc_voltage / (bateria[id].R2 / (bateria[id].R1 + bateria[id].R2));
  if (bateria[id].in_voltage > bateria[id].max) {
    digitalWrite(bateria[id].rele, HIGH);
  }
  if (bateria[id].in_voltage < bateria[id].min) {
    digitalWrite(bateria[id].rele, LOW);
  }
}

float get_solar_voltage(int n_samples) {
  float busvoltage1 = ina3221.getBusVoltage_V(LIPO_BATTERY_CHANNEL);
  return (busvoltage1);
}
float get_battery_voltage(int n_samples) {
  float shuntvoltage1 = ina3221.getShuntVoltage_mV(LIPO_BATTERY_CHANNEL);
  return (shuntvoltage1);
}

float get_solar_current(int n_samples) {
  float current_mA1 = -ina3221.getCurrent_mA(LIPO_BATTERY_CHANNEL);  // minus is to get the "sense" right.   - means the battery is charging, + that it is discharging
  return (current_mA1);
}

float in_voltage(float x, float in_min, float in_max, float out_min, float out_max) {
  return (x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min;
}

void setup() {
  Serial.begin(9600);
  pinMode(rele8, OUTPUT);
  pinMode(rele9, OUTPUT);
  pinMode(rele10, OUTPUT);
  pinMode(rele11, OUTPUT);
  pinMode(solar_voltage_in, INPUT);
  pinMode(solar_current_in, INPUT);
  pinMode(battery_voltage_in, INPUT);
  pinMode(PWM_out, OUTPUT);
  digitalWrite(PWM_out, LOW);
  pinMode(load_enable, OUTPUT);
  digitalWrite(load_enable, LOW);
  Serial.println("SDA_Arduino_INA3221_ Inicializado");
  ina3221.begin();

  before_millis = millis();
  
}
void loop() {
  if (millis() - tiempolecturas > 3000UL) {
    if (Current > 0.100) {
      digitalWrite(rele8, HIGH);
    }
    if (Current < 0.300) {
      digitalWrite(rele8, LOW);
    }
    solar_voltage = get_solar_voltage(15);
    bat_voltage   = get_battery_voltage(15);
    solar_current = get_solar_current(15);
    solar_power = bat_voltage * solar_current;
    pwm_percentage = map(pwm_value, 0, 255, 0, 100);
    now_millis = millis();
    if (now_millis - before_millis > LCD_refresh_rate)  {
      before_millis = now_millis;
      Serial.print("Volt. Fuente  :");
      Serial.println(solar_voltage, 3);
      Serial.print("Volt. Bateria :");
      Serial.println(bat_voltage, 3);
      Serial.print("pwm           :");
      Serial.println(pwm_percentage);
      Serial.print("Bat. AMP      :");
      Serial.println(solar_current, 3);
      Serial.println(load_status);
    }
    if (bat_voltage < battery_min_voltage) {
      digitalWrite(load_enable, LOW);
      load_status  = "OFF";
    }
    else {
      digitalWrite(load_enable, HIGH);
      load_status  = "ON";
    }
    // BATERIA 1
    leoBateria(0);
    // BATERIA 2
    leoBateria(1);
    // BATERIA 3
    leoBateria(2);

    /////   FLOAT       /////////
    if (mode == FLOAT) {
      if (bat_voltage < float_voltage_min) {
        mode = BULK;
        mode_str = "BULK";
      }
      else {
        if (solar_current > float_max_current) {
          mode = BULK;
          mode_str = "BULK";
        }
        else {
          if (bat_voltage > float_voltage) {
            pwm_value--;
            pwm_value = constrain(pwm_value, 0, 255);
          }
          else {
            pwm_value++;
            pwm_value = constrain(pwm_value, 0, 255);
          }
        }
        analogWrite(PWM_out, pwm_value);
      }
    }
    else {
      if (bat_voltage < bulk_voltage_min) {
        mode = BULK;
        mode_str = "BULK";
      }
      else if (bat_voltage > bulk_voltage_max) {
        mode_str = "ABSORPTION";
        mode = ABSORPTION;
      }

      /////////   BULK    ////////////
      if (mode == BULK) {
        if (solar_current > charging_current) {
          pwm_value--;
          pwm_value = constrain(pwm_value, 0, 255);
        }
        else {
          pwm_value++;
          pwm_value = constrain(pwm_value, 0, 255);
        }
        analogWrite(PWM_out, pwm_value);
      }
      ////////  ABSORPTION  ///////
      if (mode == ABSORPTION) {
        if (solar_current > absorption_max_current) {
          pwm_value--;
          pwm_value = constrain(pwm_value, 0, 255);
        }
        else {
          if (bat_voltage > absorption_voltage) {
            pwm_value++;
            pwm_value = constrain(pwm_value, 0, 255);
          }
          else {
            pwm_value--;
            pwm_value = constrain(pwm_value, 0, 255);
          }
          if (solar_current < absorption_min_current) {
            mode = FLOAT;
            mode_str = "FLOAT";
          }
        }
        analogWrite(PWM_out, pwm_value);
      }
    }
    for (int i = 0; i < 3; i++) {
      Serial.print("sensor " + String(i) + "      :");
      Serial.print(bateria[i].in_voltage,  3);
      Serial.println(" V");
    }
    tiempolecturas = millis();
  }
}




void loop(void) 
{

Serial.println("------------------------------");


Serial.print("LIPO_Battery Bus Voltage:   "); Serial.print(busvoltage1); Serial.println(" V");
Serial.print("LIPO_Battery Shunt Voltage: "); Serial.print(shuntvoltage1); Serial.println(" mV");
Serial.print("LIPO_Battery Load Voltage:  "); Serial.print(loadvoltage1); Serial.println(" V");
Serial.print("LIPO_Battery Current 1:       "); Serial.print(current_mA1); Serial.println(" mA");
Serial.println("");

float shuntvoltage2 = 0;
float busvoltage2 = 0;
float current_mA2 = 0;
float loadvoltage2 = 0;

busvoltage2 = ina3221.getBusVoltage_V(SOLAR_CELL_CHANNEL);
shuntvoltage2 = ina3221.getShuntVoltage_mV(SOLAR_CELL_CHANNEL);
current_mA2 = -ina3221.getCurrent_mA(SOLAR_CELL_CHANNEL);
loadvoltage2 = busvoltage2 + (shuntvoltage2 / 1000);

Serial.print("Solar Cell Bus Voltage 2:   "); Serial.print(busvoltage2); Serial.println(" V");
Serial.print("Solar Cell Shunt Voltage 2: "); Serial.print(shuntvoltage2); Serial.println(" mV");
Serial.print("Solar Cell Load Voltage 2:  "); Serial.print(loadvoltage2); Serial.println(" V");
Serial.print("Solar Cell Current 2:       "); Serial.print(current_mA2); Serial.println(" mA");
Serial.println("");

float shuntvoltage3 = 0;
float busvoltage3 = 0;
float current_mA3 = 0;
float loadvoltage3 = 0;

busvoltage3 = ina3221.getBusVoltage_V(OUTPUT_CHANNEL);
shuntvoltage3 = ina3221.getShuntVoltage_mV(OUTPUT_CHANNEL);
current_mA3 = ina3221.getCurrent_mA(OUTPUT_CHANNEL);
loadvoltage3 = busvoltage3 + (shuntvoltage3 / 1000);

Serial.print("Output Bus Voltage 3:   "); Serial.print(busvoltage3); Serial.println(" V");
Serial.print("Output Shunt Voltage 3: "); Serial.print(shuntvoltage3); Serial.println(" mV");
Serial.print("Output Load Voltage 3:  "); Serial.print(loadvoltage3); Serial.println(" V");
Serial.print("Output Current 3:       "); Serial.print(current_mA3); Serial.println(" mA");
Serial.println("");

delay(2000);
}

Hola @Surbyte, no quería copilar,
cambie esto

void loop(void)

por esto

void ina (void)

Y copilo, lo subí fui al monitor Serial, y daba las lecturas, de los pines analógicos de A0 hasta A5, pero no da las lecturas del ina3221, I2C comente los analógicos A4 y A5 pensando que eso interfería, pero siguió sin dar las lecturas I2C, pase todo lo que estaba en el void ina (void) al void loop () y ya me dio las lecturas del I2C, comente todos sensores FZ0430 y ACS712. Intente apagar o encender el rele del pin digital 2, controlado por corriente y no lo conseguí después de muchos intentos. Al rato que llegue un teléfono con cámara subo la maqueta, con la que planeo hacer las pruebas y se den una idea, ahora estoy con el INA3221 de tres canales independientes, solo me falta confirmar su capacidad máxima de amperios que soporta, el INA219 soporta 3.2 A. y este parece que solo soporta 1.1 por canal que serian 3.3A usando los tres canales, de momento estoy usando ventiladores de raspberry de 20mA para fundir nada.
Saludos.

No me di cuenta y al final del código posteado en post#5 quedó con el ejemplo del INA3221 que no borré totalmente, de ahí el error.

Ahora que me familiaricé con tu descubrimiento INA3221, porque conocia el INA219 pero no esta versión de 3 canales, ya se donde modificar y qué modificar.

Diré obviedades, tiene 3 canales asi que la idea es que conectas algo a alguno de ellos.
Antes tenias

#define solar_current_in          A0
#define solar_voltage_in          A1
#define battery_voltage_in        A2

Y ahora tienes la posibildad de leer para cada 1 varias cosas. Asi que el canal 1 medira la tensión y la corriente solar.
El canal 2 leerá la tensión de bateria y su corriente.

Código que compila. Espero funcione. No hace falta tomar 15 muestras según creo.

#include <Wire.h>
#include <SDL_Arduino_INA3221.h>

SDL_Arduino_INA3221 ina3221;

// the three channels of the INA3221 named for SunAirPlus Solar Power Controller channels (www.switchdoc.com)
#define SOLAR_CHANNEL             1 
#define BATTERY_CHANNEL           2

#define bulk_voltage_max         12.20
#define bulk_voltage_min         12.10
#define absorption_voltage       12.30
#define absorption_max_current    0.266
#define absorption_min_current    0.166
#define float_voltage            12.60
#define float_voltage_max        12.40
#define float_voltage_min        12.45
#define float_max_current         0.12
#define battery_min_voltage      10.00
#define solar_min_voltage        14.20
#define charging_current          0.30
#define PWM_out                   6
#define load_enable               2
#define LCD_refresh_rate       1000

int rele8 = 8;
int rele9 = 9;
int rele10 = 10;
int rele11 = 11;
int Current;
const unsigned long TIEMPO_LECTURAS = 3000UL;
byte BULK = 0;
byte ABSORPTION = 1;
byte FLOAT = 2;
byte mode = 0;
float bat_voltage = 0;
int pwm_value = 3;
float solar_current = 0;
float current_factor = 0.100;
float solar_voltage = 0;
float solar_power = 0.0;
String load_status = "OFF";
int pwm_percentage = 0;
unsigned int before_millis = 0;
unsigned int now_millis = 0;
String mode_str = "BULK";

float R1 = 30000.0;
float R2 = 7500.0;
float R3 = 30000.0;
float R4 = 7500.0;
float R5 = 30000.0;
float R6 = 7500.0;
float ref_voltage0 = 5.0;
float ref_voltage1 = 5.0;
float ref_voltage2 = 5.0;
int adc_value0 = 0;
int adc_value1 = 0;
int adc_value2 = 0;
unsigned long tiempolecturas;
struct Bateria {
  int sensor;
  float adc_voltage;
  float in_voltage;
  float ref_voltage;
  float max, min;
  int rele;
  float R1, R2;
};
Bateria bateria[3] = {
  {A5, 0.0, 0.0, 5.0, 16.10, 15.80,  rele9, R1, R2},
  {A4, 0.0, 0.0, 5.0, 12.70, 12.40, rele10, R3, R4},
  {A3, 0.0, 0.0, 5.0,  8.90,  8.20, rele11, R5, R6}
};

void leoBateria(int id) {  // si se cargan
  bateria[id].adc_voltage  = (analogRead(bateria[id].sensor) * bateria[id].ref_voltage) / 1024.0;
  bateria[id].in_voltage = bateria[id].adc_voltage / (bateria[id].R2 / (bateria[id].R1 + bateria[id].R2));
  if (bateria[id].in_voltage > bateria[id].max) {
    digitalWrite(bateria[id].rele, HIGH);
  }
  if (bateria[id].in_voltage < bateria[id].min) {
    digitalWrite(bateria[id].rele, LOW);
  }
}

float get_bus_voltage(int canal) {
  float busvoltage = ina3221.getBusVoltage_V(canal);
  return busvoltage;
}

float get_current(int canal) {
  float current_mA = -ina3221.getCurrent_mA(canal);  // minus is to get the "sense" right.   - means the battery is charging, + that it is discharging
  return current_mA;
}

float in_voltage(float x, float in_min, float in_max, float out_min, float out_max) {
  return (x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min;
}

void setup() {
  Serial.begin(9600);
  pinMode(rele8, OUTPUT);
  pinMode(rele9, OUTPUT);
  pinMode(rele10, OUTPUT);
  pinMode(rele11, OUTPUT);
  
  pinMode(PWM_out, OUTPUT);
  digitalWrite(PWM_out, LOW);
  pinMode(load_enable, OUTPUT);
  digitalWrite(load_enable, LOW);
  Serial.println("SDA_Arduino_INA3221_ Inicializado");
  ina3221.begin();

  before_millis = millis();
  
}
void loop() {
  if (millis() - tiempolecturas > 3000UL) {
    if (Current > 0.100) {
      digitalWrite(rele8, HIGH);
    }
    if (Current < 0.300) {
      digitalWrite(rele8, LOW);
    }
    solar_voltage = get_bus_voltage(SOLAR_CHANNEL);
    bat_voltage   = get_bus_voltage(BATTERY_CHANNEL);
    solar_current = get_current(SOLAR_CHANNEL);
    battery_current = get_current(BATTERY_CHANNEL);
    
    solar_power = bat_voltage * solar_current;
    pwm_percentage = map(pwm_value, 0, 255, 0, 100);
    
    now_millis = millis();
    if (now_millis - before_millis > LCD_refresh_rate)  {
      before_millis = now_millis;
      Serial.print("Volt. Fuente  :");
      Serial.println(solar_voltage, 3);
      Serial.print("Fuente. AMP      :");
      Serial.println(solar_current, 3);
      Serial.print("Volt. Bateria :");    
      Serial.println(bat_voltage, 3);
      Serial.print("Bat. AMP      :");    // agregué esta lectura
      Serial.println(battery_current, 3); // agregué esta información que no te confunda.     
      Serial.print("pwm           :");
      Serial.println(pwm_percentage);
      Serial.print("Bat. AMP      :");
      Serial.println(solar_current, 3);
      Serial.println(load_status);
    }
    if (bat_voltage < battery_min_voltage) {
      digitalWrite(load_enable, LOW);
      load_status  = "OFF";
    }
    else {
      digitalWrite(load_enable, HIGH);
      load_status  = "ON";
    }
    // BATERIA 1
    leoBateria(0);
    // BATERIA 2
    leoBateria(1);
    // BATERIA 3
    leoBateria(2);

    /////   FLOAT       /////////
    if (mode == FLOAT) {
      if (bat_voltage < float_voltage_min) {
        mode = BULK;
        mode_str = "BULK";
      }
      else {
        if (solar_current > float_max_current) {
          mode = BULK;
          mode_str = "BULK";
        }
        else {
          if (bat_voltage > float_voltage) {
            pwm_value--;
            pwm_value = constrain(pwm_value, 0, 255);
          }
          else {
            pwm_value++;
            pwm_value = constrain(pwm_value, 0, 255);
          }
        }
        analogWrite(PWM_out, pwm_value);
      }
    }
    else {
      if (bat_voltage < bulk_voltage_min) {
        mode = BULK;
        mode_str = "BULK";
      }
      else if (bat_voltage > bulk_voltage_max) {
        mode_str = "ABSORPTION";
        mode = ABSORPTION;
      }

      /////////   BULK    ////////////
      if (mode == BULK) {
        if (solar_current > charging_current) {
          pwm_value--;
          pwm_value = constrain(pwm_value, 0, 255);
        }
        else {
          pwm_value++;
          pwm_value = constrain(pwm_value, 0, 255);
        }
        analogWrite(PWM_out, pwm_value);
      }
      ////////  ABSORPTION  ///////
      if (mode == ABSORPTION) {
        if (solar_current > absorption_max_current) {
          pwm_value--;
          pwm_value = constrain(pwm_value, 0, 255);
        }
        else {
          if (bat_voltage > absorption_voltage) {
            pwm_value++;
            pwm_value = constrain(pwm_value, 0, 255);
          }
          else {
            pwm_value--;
            pwm_value = constrain(pwm_value, 0, 255);
          }
          if (solar_current < absorption_min_current) {
            mode = FLOAT;
            mode_str = "FLOAT";
          }
        }
        analogWrite(PWM_out, pwm_value);
      }
    }
    for (int i = 0; i < 3; i++) {
      Serial.print("sensor " + String(i) + "      :");
      Serial.print(bateria[i].in_voltage,  3);
      Serial.println(" V");
    }
    tiempolecturas = millis();
  }
}

Hola @Surbyte, yo pensaba en algo asi, ahora solo le agregue el rele digital 2 falta agregar los reles 8 y 9 y integrar el pwm.

#include <Arduino.h>
#include <Wire.h>
#include <SDL_Arduino_INA3221.h>

SDL_Arduino_INA3221 ina3221;
#define LIPO_BATTERY_CHANNEL    1 // verifica esto // ahora estoy usando un pequeño banco de vaterias de litio (12 piezas de 18650)
#define SOLAR_CELL_CHANNEL      2
#define OUTPUT_CHANNEL          3

#define bulk_voltage_max         4.600
#define bulk_voltage_min         4.100
#define absorption_voltage       4.700
#define absorption_max_current   0.022
#define absorption_min_current   0.016
#define float_voltage            4.750
#define float_voltage_max        4.900
#define float_voltage_min        4.850
#define float_max_current        0.012
#define battery_min_voltage      3.900
#define solar_min_voltage        4.990
#define charging_current         0.018
#define PWM_out                   6
#define load_enable               2

#define LCD_refresh_rate       1000
int current_mA3;
int rele8 = 8;
int rele9 = 9;
int rele10 = 10;
int rele11 = 11;
int Current;
int busvoltage1;
int shuntvoltage1;
int loadvoltage1;
int current_mA1;

const unsigned long TIEMPO_LECTURAS = 3000UL;
byte BULK = 0;
byte ABSORPTION = 1;
byte FLOAT = 2;
byte mode = 0;
float bat_voltage = 0;
int pwm_value = 3;
float solar_current = 0;
float current_factor = 0.100;
float solar_voltage = 0;
float solar_power = 0.0;
String load_status = "OFF";
int pwm_percentage = 0;
unsigned int before_millis = 0;
unsigned int now_millis = 0;
String mode_str = "BULK";

unsigned long tiempolecturas;
struct Bateria {
  int sensor;
  float adc_voltage;
  float in_voltage;
  float ref_voltage;
  float max, min;
  int rele;
  float R1, R2;
};

void leoBateria(int id) {  // si se cargan

}
float get_solar_voltage(int n_samples) {
  float busvoltage1 = ina3221.getBusVoltage_V(LIPO_BATTERY_CHANNEL);
  return (busvoltage1);
}
float get_battery_voltage(int n_samples) {
  float shuntvoltage1 = ina3221.getShuntVoltage_mV(LIPO_BATTERY_CHANNEL);
  return (shuntvoltage1);
}

float get_solar_current(int n_samples) {
  float current_mA1 = -ina3221.getCurrent_mA(LIPO_BATTERY_CHANNEL);
  return (current_mA1);
}

float in_voltage(float x, float in_min, float in_max, float out_min, float out_max) {
  return (x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min;
}

void setup() {
  Serial.begin(9600);
  pinMode(rele8, OUTPUT);
  pinMode(rele9, OUTPUT);
  pinMode(rele10, OUTPUT);
  pinMode(rele11, OUTPUT);

  pinMode(PWM_out, OUTPUT);
  digitalWrite(PWM_out, LOW);
  pinMode(load_enable, OUTPUT);
  digitalWrite(load_enable, LOW);
  Serial.println("SDA_Arduino_INA3221_ Inicializado");
  ina3221.begin();

  before_millis = millis();

}
void loop() {
  if (millis() - tiempolecturas > 3000UL) {
    if (current_mA3  > 0.019) {
      digitalWrite(rele8, HIGH);
    }
    if (current_mA3  < 0.016) {
      digitalWrite(rele8, LOW);
    }

    pwm_percentage = map(pwm_value, 0, 55, 0, 100);
    now_millis = millis();
    if (now_millis - before_millis > LCD_refresh_rate)  {
      before_millis = now_millis;


      Serial.println("------------------------------");


      Serial.print("LIPO_Battery Bus Voltage:   "); Serial.print(busvoltage1); Serial.println(" V");
      Serial.print("LIPO_Battery Shunt Voltage: "); Serial.print(shuntvoltage1); Serial.println(" mV");
      Serial.print("LIPO_Battery Load Voltage:  "); Serial.print(loadvoltage1); Serial.println(" V");
      Serial.print("LIPO_Battery Current 1:       "); Serial.print(current_mA1); Serial.println(" mA");
      Serial.println("");

      float shuntvoltage2 = 0;
      float busvoltage2 = 0;
      float current_mA2 = 0;
      float loadvoltage2 = 0;

      busvoltage2 = ina3221.getBusVoltage_V(SOLAR_CELL_CHANNEL);
      shuntvoltage2 = ina3221.getShuntVoltage_mV(SOLAR_CELL_CHANNEL);
      current_mA2 = -ina3221.getCurrent_mA(SOLAR_CELL_CHANNEL);
      loadvoltage2 = busvoltage2 + (shuntvoltage2 / 1000);

      Serial.print("Solar Cell Bus Voltage 2:   "); Serial.print(busvoltage2); Serial.println(" V");
      Serial.print("Solar Cell Shunt Voltage 2: "); Serial.print(shuntvoltage2); Serial.println(" mV");
      Serial.print("Solar Cell Load Voltage 2:  "); Serial.print(loadvoltage2); Serial.println(" V");
      Serial.print("Solar Cell Current 2:       "); Serial.print(current_mA2); Serial.println(" mA");
      Serial.println("");

      float shuntvoltage3 = 0;
      float busvoltage3 = 0;
      float current_mA3 = 0;
      float loadvoltage3 = 0;

      busvoltage3 = ina3221.getBusVoltage_V(OUTPUT_CHANNEL);
      shuntvoltage3 = ina3221.getShuntVoltage_mV(OUTPUT_CHANNEL);
      current_mA3 = ina3221.getCurrent_mA(OUTPUT_CHANNEL);
      loadvoltage3 = busvoltage3 + (shuntvoltage3 / 1000);

      Serial.print("Output Bus Voltage 3:   "); Serial.print(busvoltage3); Serial.println(" V");
      Serial.print("Output Shunt Voltage 3: "); Serial.print(shuntvoltage3); Serial.println(" mV");
      Serial.print("Output Load Voltage 3:  "); Serial.print(loadvoltage3); Serial.println(" V");
      Serial.print("Output Current 3:       "); Serial.print(current_mA3); Serial.println(" mA");
      Serial.println("");

    }
    if (bat_voltage < battery_min_voltage) {
      digitalWrite(load_enable, LOW);
      load_status  = "OFF";
    }
    else {
      digitalWrite(load_enable, HIGH);
      load_status  = "ON";
    }
    // BATERIA 1
    leoBateria(0);
    // BATERIA 2
    leoBateria(1);
    // BATERIA 3
    leoBateria(2);

    /////   FLOAT       /////////
    if (mode == FLOAT) {
      if (bat_voltage < float_voltage_min) {
        mode = BULK;
        mode_str = "BULK";
      }
      else {
        if (solar_current > float_max_current) {
          mode = BULK;
          mode_str = "BULK";
        }
        else {
          if (bat_voltage > float_voltage) {
            pwm_value--;
            pwm_value = constrain(pwm_value, 0, 55);
          }
          else {
            pwm_value++;
            pwm_value = constrain(pwm_value, 0, 55);
          }
        }
        analogWrite(PWM_out, pwm_value);
      }
    }
    else {
      if (bat_voltage < bulk_voltage_min) {
        mode = BULK;
        mode_str = "BULK";
      }
      else if (bat_voltage > bulk_voltage_max) {
        mode_str = "ABSORPTION";
        mode = ABSORPTION;
      }

      /////////   BULK    ////////////
      if (mode == BULK) {
        if (solar_current > charging_current) {
          pwm_value--;
          pwm_value = constrain(pwm_value, 0, 255);
        }
        else {
          pwm_value++;
          pwm_value = constrain(pwm_value, 0, 255);
        }
        analogWrite(PWM_out, pwm_value);
      }
      ////////  ABSORPTION  ///////
      if (mode == ABSORPTION) {
        if (solar_current > absorption_max_current) {
          pwm_value--;
          pwm_value = constrain(pwm_value, 0, 125);
        }
        else {
          if (bat_voltage > absorption_voltage) {
            pwm_value++;
            pwm_value = constrain(pwm_value, 0, 125);
          }
          else {
            pwm_value--;
            pwm_value = constrain(pwm_value, 0, 255);
          }
          if (solar_current < absorption_min_current) {
            mode = FLOAT;
            mode_str = "FLOAT";
          }
        }
        analogWrite(PWM_out, pwm_value);
      }
    }
    tiempolecturas = millis();
  }
}

Maqueta carga baterías.

Esta maqueta la use para probar el código de tres baterías con carga PWM ahora la idea es usar el INA3221 para suplir los sensores ACS712 y FZ0430 ahora le agregue un INA 3221 para hacer pruebas.
Saludos.

Revisaste el código que te pasé antes?

Hola @Surbyte, si lo estuve revisando, solo declare (int battery_current;) y copilo, pero el monitor serial no da datos del ina3221, solo los pines analógicos ya establecidos en el código base, el PWM se mantenía en 46 pulsos sin importar el voltaje que suministre a la batería.
Saludos.

Ultimo punto de vista.

#include <Wire.h>
#include <SDL_Arduino_INA3221.h>

SDL_Arduino_INA3221 ina3221;

// the three channels of the INA3221 named for SunAirPlus Solar Power Controller channels (www.switchdoc.com)
#define SOLAR_CHANNEL             1  
#define BATTERY_CHANNEL           2
#define BATTERY2_CHANNEL          3  


#define bulk_voltage_max         12.20
#define bulk_voltage_min         12.10
#define absorption_voltage       12.30
#define absorption_max_current    0.266
#define absorption_min_current    0.166
#define float_voltage            12.60
#define float_voltage_max        12.40
#define float_voltage_min        12.45
#define float_max_current         0.12
#define battery_min_voltage      10.00
#define solar_min_voltage        14.20
#define charging_current          0.30
#define PWM_out                   6
#define load_enable               2
#define LCD_refresh_rate       1000

int rele8   =  8;
int rele9   =  9;
int rele10  = 10;
int rele11  = 11;
int Current;

enum   {
  BULK, // enfriando
  ABSORPTION,  // calentando
  FLOAT
} estado;

estado mode                 = BULK;
String mode_str[3]          = {"BULK","ABSORPTION", "FLOAT"};

int pwm_value               = 3;
float bat_voltage           = 0;
float solar_current         = 0;
float battery_current       = 0;
float current_factor        = 0.100;
float solar_voltage         = 0;
float solar_power           = 0.0;
String load_status          = "OFF";
int pwm_percentage          = 0;
unsigned int before_millis  = 0;
unsigned int now_millis     = 0;
String mode_str             = "BULK";
unsigned long tiempolecturas;

struct Bateria {
  float in_voltage;
  float max, min;
  int rele;
};

Bateria bateria[3] = {
  {0.0, 16.10, 15.80,  rele9},
  {0.0, 12.70, 12.40, rele10},
  {0.0,  8.90,  8.20, rele11}
};

void leoBateria(int id) {  // si se cargan
  int tmp = id-1;
  bateria[tmp].in_voltage = get_bus_voltage(tmp);

  if (bateria[tmp].in_voltage > bateria[tmp].max) {
      digitalWrite(bateria[tmp].rele, HIGH);
  }
  if (bateria[tmp].in_voltage < bateria[tmp].min) {
      digitalWrite(bateria[tmp].rele, LOW);
  }
}

float get_bus_voltage(int canal) {
  float busvoltage = ina3221.getBusVoltage_V(canal);
  return busvoltage;
}

float get_current(int canal) {
  float current_mA = -ina3221.getCurrent_mA(canal);  // minus is to get the "sense" right.   - means the battery is charging, + that it is discharging
  return current_mA;
}

float in_voltage(float x, float in_min, float in_max, float out_min, float out_max) {
  return (x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min;
}

void setup() {
  Serial.begin(9600);
  pinMode(rele8, OUTPUT);
  pinMode(rele9, OUTPUT);
  pinMode(rele10, OUTPUT);
  pinMode(rele11, OUTPUT);
  
  pinMode(PWM_out, OUTPUT);
  digitalWrite(PWM_out, LOW);
  pinMode(load_enable, OUTPUT);
  digitalWrite(load_enable, LOW);
  Serial.println("SDA_Arduino_INA3221_ Inicializado");
  ina3221.begin();

  before_millis = millis();
}

void loop() {
  if (millis() - tiempolecturas > 3000UL) {
    if (Current > 0.100) {
      digitalWrite(rele8, HIGH);
    }
    if (Current < 0.300) {
      digitalWrite(rele8, LOW);
    }
    solar_voltage = get_bus_voltage(SOLAR_CHANNEL);
    bat_voltage   = get_bus_voltage(BATTERY2_CHANNEL);
    solar_current = -get_current(SOLAR_CHANNEL);
    battery_current = -get_current(BATTERY2_CHANNEL);

    solar_power = bat_voltage * solar_current;
    pwm_percentage = map(pwm_value, 0, 255, 0, 100);
    
    now_millis = millis();
    if (now_millis - before_millis > LCD_refresh_rate)  {
      before_millis = now_millis;
      Serial.print("Volt. Fuente  :");
      Serial.println(solar_voltage, 3);
      Serial.print("Fuente. AMP   :");
      Serial.println(solar_current, 3);
      Serial.print("Volt. Bateria :");    
      Serial.println(bat_voltage, 3);
      Serial.print("Bat. AMP      :");    
      Serial.println(battery_current, 3);      
      Serial.print("pwm           :");
      Serial.println(pwm_percentage);
      Serial.print("Bat. AMP      :");
      Serial.println(solar_current, 3);
      Serial.println(load_status);
    }
    if (bat_voltage < battery_min_voltage) {
      digitalWrite(load_enable, LOW);
      load_status  = "OFF";
    }
    else {
      digitalWrite(load_enable, HIGH);
      load_status  = "ON";
    }
   
    // BATERIA 1
    leoBateria(SOLAR_CHANNEL);
    // BATERIA 2
    leoBateria(BATTERY_CHANNEL);
    // BATERIA 3
    leoBateria(BATTERY2_CHANNEL); 

    /////   FLOAT       /////////
    if (mode == FLOAT) {
      if (bat_voltage < float_voltage_min) {
        mode = BULK;
      }
      else {
        if (solar_current > float_max_current) {
          mode = BULK;
        }
        else {
          if (bat_voltage > float_voltage) {
            pwm_value--;
            pwm_value = constrain(pwm_value, 0, 255);
          }
          else {
            pwm_value++;
            pwm_value = constrain(pwm_value, 0, 255);
          }
        }
        analogWrite(PWM_out, pwm_value);
      }
    }
    else {
      if (bat_voltage < bulk_voltage_min) {
        mode = BULK;
      }
      else if (bat_voltage > bulk_voltage_max) {
        mode = ABSORPTION;
      }

      /////////   BULK    ////////////
      if (mode == BULK) {
        if (solar_current > charging_current) {
          pwm_value--;
          pwm_value = constrain(pwm_value, 0, 255);
        }
        else {
          pwm_value++;
          pwm_value = constrain(pwm_value, 0, 255);
        }
        analogWrite(PWM_out, pwm_value);
      }
      ////////  ABSORPTION  ///////
      if (mode == ABSORPTION) {
        if (solar_current > absorption_max_current) {
          pwm_value--;
          pwm_value = constrain(pwm_value, 0, 255);
        }
        else {
          if (bat_voltage > absorption_voltage) {
            pwm_value++;
            pwm_value = constrain(pwm_value, 0, 255);
          }
          else {
            pwm_value--;
            pwm_value = constrain(pwm_value, 0, 255);
          }
          if (solar_current < absorption_min_current) {
            mode = FLOAT;
          }
        }
        analogWrite(PWM_out, pwm_value);
      }
    }
    for (int i = 0; i < 3; i++) {
      Serial.print("sensor " + String(i) + "      :");
      Serial.print(bateria[i].in_voltage,  3);
      Serial.println(" V");
    }
    tiempolecturas = millis();
  }
}

Hola @Surbyte, ya revise el código, esta muy desordenado el Monitor Serial,(lo estoy corrigiendo) da voltajes 3 canales corriente 2 canales y esta mezclada la información creo que debe ser como el original que da los tres parámetros por canal.
Nota: una disculpa, que no e venido al foro por problemas de energía eléctrica, en el pueblo que vivo, 4 días sin nada y 2 de forma intermitente, ahora en lugar de 110 vac solo llegan 90 vac espero y se resuelva en estos días.

Hola @Surbyte, ya estuve haciendo cambios al código, ya copila ahora el monitor Serial ya debe dar los datos con otro orden, solo tengo problemas con enum de momento lo comente. //String mode_str = BULK;

//https://forum.arduino.cc/t/ina3221-cargar-baterias-solar/1007627/4
//https://forum.arduino.cc/t/fixing-the-ina3221-breakout-board/526947/6
// www.switchdoc.com

#include <Wire.h>
#include <SDL_Arduino_INA3221.h>
SDL_Arduino_INA3221 ina3221;
#define LIPO_BATTERY_CHANNEL 1
#define SOLAR_CELL_CHANNEL 2
#define OUTPUT_CHANNEL 3
#define bulk_voltage_max         12.20
#define bulk_voltage_min         12.10
#define absorption_voltage       12.30
#define absorption_max_current    0.266
#define absorption_min_current    0.166
#define float_voltage            12.60
#define float_voltage_max        12.40
#define float_voltage_min        12.45
#define float_max_current         0.12
#define battery_min_voltage      10.00
#define solar_min_voltage        14.20
#define charging_current          0.30
#define PWM_out                   6
#define load_enable               2
#define LCD_refresh_rate       1000

int rele8   =  8;
int rele9   =  9;
int rele10  = 10;
int rele11  = 11;
int Current;

enum   {
  BULK,
  ABSORPTION,
  FLOAT
} estado;

float mode                  = BULK;
String mode_str[3]          = {"BULK", "ABSORPTION", "FLOAT"};
int pwm_value               = 3;
float bat_voltage           = 0;
float solar_current         = 0;
float battery_current       = 0;
float current_factor        = 0.100;
float solar_voltage         = 0;
float solar_power           = 0.0;
String load_status          = "OFF";
int pwm_percentage          = 0;
unsigned int before_millis  = 0;
unsigned int now_millis     = 0;
//String mode_str             = BULK;
unsigned long tiempolecturas;
struct Bateria {
  float in_voltage;
  float max, min;
  int rele;
};
Bateria bateria[3] = {
  {0.0, 16.10, 15.80,  rele9},
  {0.0, 12.70, 12.40, rele10},
  {0.0,  8.90,  8.20, rele11}
};
void leoBateria(int id) {
  int tmp = id - 1;
  bateria[tmp].in_voltage = get_bus_voltage(tmp);

  if (bateria[tmp].in_voltage > bateria[tmp].max) {
    digitalWrite(bateria[tmp].rele, HIGH);
  }
  if (bateria[tmp].in_voltage < bateria[tmp].min) {
    digitalWrite(bateria[tmp].rele, LOW);
  }
}

float get_bus_voltage(int canal) {
  float busvoltage = ina3221.getBusVoltage_V(canal);
  return busvoltage;
}

float get_current(int canal) {
  float current_mA = -ina3221.getCurrent_mA(canal);
  return current_mA;
}

float in_voltage(float x, float in_min, float in_max, float out_min, float out_max) {
  return (x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min;
}


void setup(void)
{
  Serial.begin(9600);
  Serial.println("SDA_Arduino_INA3221_Test");
  Serial.println("Measuring voltage and current with ina3221 ...");
  pinMode(rele8, OUTPUT);
  pinMode(rele9, OUTPUT);
  pinMode(rele10, OUTPUT);
  pinMode(rele11, OUTPUT);
  pinMode(PWM_out, OUTPUT);
  digitalWrite(PWM_out, LOW);
  pinMode(load_enable, OUTPUT);
  digitalWrite(load_enable, LOW);
  Serial.println("SDA_Arduino_INA3221_ Inicializado");
  ina3221.begin();
  before_millis = millis();
}
void loop(void)
{
  if (millis() - tiempolecturas > 3000UL) {
    Serial.println("------------------------------");
    float shuntvoltage1 = 0;
    float busvoltage1 = 0;
    float current_mA1 = 0;
    float loadvoltage1 = 0;
    if (current_mA1 > 0.800 ) {
      digitalWrite(rele8, HIGH);
    }
    if (current_mA1 < 0.100) {
      digitalWrite(rele8, LOW);
    }

    busvoltage1 = ina3221.getBusVoltage_V(LIPO_BATTERY_CHANNEL);
    shuntvoltage1 = ina3221.getShuntVoltage_mV(LIPO_BATTERY_CHANNEL);
    current_mA1 = -ina3221.getCurrent_mA(LIPO_BATTERY_CHANNEL);
    loadvoltage1 = busvoltage1 + (shuntvoltage1 / 1000);
    solar_power = bat_voltage * solar_current;
    pwm_percentage = map(pwm_value, 0, 255, 0, 100);
    now_millis = millis();
    if (now_millis - before_millis > LCD_refresh_rate)  {
      before_millis = now_millis;
      Serial.print("LIPO_Battery Bus Voltage:   "); Serial.print(busvoltage1); Serial.println(" V");
      Serial.print("LIPO_Battery Shunt Voltage: "); Serial.print(shuntvoltage1); Serial.println(" mV");
      Serial.print("LIPO_Battery Load Voltage:  "); Serial.print(loadvoltage1); Serial.println(" V");
      Serial.print("LIPO_Battery Current 1:       "); Serial.print(current_mA1); Serial.println(" mA");
      Serial.println("");

       if (busvoltage1 > 12.00) {
      digitalWrite(rele9, HIGH);
    }
    if (busvoltage1 < 12.60) {
      digitalWrite(rele9, LOW);
    }

      float shuntvoltage2 = 0;
      float busvoltage2 = 0;
      float current_mA2 = 0;
      float loadvoltage2 = 0;

      busvoltage2 = ina3221.getBusVoltage_V(SOLAR_CELL_CHANNEL);
      shuntvoltage2 = ina3221.getShuntVoltage_mV(SOLAR_CELL_CHANNEL);
      current_mA2 = -ina3221.getCurrent_mA(SOLAR_CELL_CHANNEL);
      loadvoltage2 = busvoltage2 + (shuntvoltage2 / 1000);
      solar_power = bat_voltage * solar_current;
      pwm_percentage = map(pwm_value, 0, 255, 0, 100);
      now_millis = millis();
      if (now_millis - before_millis > LCD_refresh_rate)  {
        before_millis = now_millis;
        Serial.print("Solar Cell Bus Voltage 2:   "); Serial.print(busvoltage2); Serial.println(" V");
        Serial.print("Solar Cell Shunt Voltage 2: "); Serial.print(shuntvoltage2); Serial.println(" mV");
        Serial.print("Solar Cell Load Voltage 2:  "); Serial.print(loadvoltage2); Serial.println(" V");
        Serial.print("Solar Cell Current 2:       "); Serial.print(current_mA2); Serial.println(" mA");
        Serial.println("");

         if (busvoltage2 > 12.70) {
      digitalWrite(rele10, HIGH);
    }
    if (busvoltage2 < 12.90) {
      digitalWrite(rele10, LOW);
    }

        float shuntvoltage3 = 0;
        float busvoltage3 = 0;
        float current_mA3 = 0;
        float loadvoltage3 = 0;

        busvoltage3 = ina3221.getBusVoltage_V(OUTPUT_CHANNEL);
        shuntvoltage3 = ina3221.getShuntVoltage_mV(OUTPUT_CHANNEL);
        current_mA3 = ina3221.getCurrent_mA(OUTPUT_CHANNEL);
        loadvoltage3 = busvoltage3 + (shuntvoltage3 / 1000);
        solar_power = bat_voltage * solar_current;
        pwm_percentage = map(pwm_value, 0, 255, 0, 100);
        now_millis = millis();
        if (now_millis - before_millis > LCD_refresh_rate)  {
          before_millis = now_millis;

          Serial.print("Output Bus Voltage 3:   "); Serial.print(busvoltage3); Serial.println(" V");
          Serial.print("Output Shunt Voltage 3: "); Serial.print(shuntvoltage3); Serial.println(" mV");
          Serial.print("Output Load Voltage 3:  "); Serial.print(loadvoltage3); Serial.println(" V");
          Serial.print("Output Current 3:       "); Serial.print(current_mA3); Serial.println(" mA");
          Serial.println("");

           if (busvoltage3 > 8.90) {
      digitalWrite(rele11, HIGH);
    }
    if (busvoltage3 < 8.20) {
      digitalWrite(rele11, LOW);
    }
          /////   FLOAT       /////////
          if (mode == FLOAT) {
            if (bat_voltage < float_voltage_min) {
              mode = BULK;
              //mode_str = "BULK";
            }
            else {
              if (solar_current > float_max_current) {
                mode = BULK;
                //mode_str = "BULK";
              }
              else {
                if (bat_voltage > float_voltage) {
                  pwm_value--;
                  pwm_value = constrain(pwm_value, 0, 255);
                }
                else {
                  pwm_value++;
                  pwm_value = constrain(pwm_value, 0, 255);
                }
              }
              analogWrite(PWM_out, pwm_value);
            }
          }
          else {
            if (bat_voltage < bulk_voltage_min) {
              mode = BULK;
              //mode_str = "BULK";
            }
            else if (bat_voltage > bulk_voltage_max) {
              //        mode_str = "ABSORPTION";
              mode = ABSORPTION;
            }

            /////////   BULK    ////////////
            if (mode == BULK) {
              if (solar_current > charging_current) {
                pwm_value--;
                pwm_value = constrain(pwm_value, 0, 255);
              }
              else {
                pwm_value++;
                pwm_value = constrain(pwm_value, 0, 255);
              }
              analogWrite(PWM_out, pwm_value);
            }
            ////////  ABSORPTION  ///////
            if (mode == ABSORPTION) {
              if (solar_current > absorption_max_current) {
                pwm_value--;
                pwm_value = constrain(pwm_value, 0, 255);
              }
              else {
                if (bat_voltage > absorption_voltage) {
                  pwm_value++;
                  pwm_value = constrain(pwm_value, 0, 255);
                }
                else {
                  pwm_value--;
                  pwm_value = constrain(pwm_value, 0, 255);
                }
                if (solar_current < absorption_min_current) {
                  mode = FLOAT;
                }
              }
              analogWrite(PWM_out, pwm_value);
            }
          }
        }
      }
    }
  }
}

Nota: también comente esto ( //mode_str = "BULK":wink: me imagino que esto afecta, no e podido hacer pruebas, espero en unas horas hacer lo.
Saludos.

Intenta poner todos los elementos de la misma longitud.

Hola @Surbyte, ya intente alienar los renglones, sobre todo los del monitor Serial, espero y ahora este mas cómodo para verse.

//https://forum.arduino.cc/t/ina3221-cargar-baterias-solar/1007627/4
//https://forum.arduino.cc/t/fixing-the-ina3221-breakout-board/526947/6
// www.switchdoc.com

#include <Wire.h>
#include <SDL_Arduino_INA3221.h>
SDL_Arduino_INA3221 ina3221;
#define LIPO_BATTERY_CHANNEL     1
#define SOLAR_CELL_CHANNEL       2
#define OUTPUT_CHANNEL           3
#define bulk_voltage_max         12.20
#define bulk_voltage_min         12.10
#define absorption_voltage       12.30
#define absorption_max_current   0.266
#define absorption_min_current   0.166
#define float_voltage            12.60
#define float_voltage_max        12.40
#define float_voltage_min        12.45
#define float_max_current        0.12
#define battery_min_voltage      10.00
#define solar_min_voltage        14.20
#define charging_current         0.30
#define PWM_out                  6
#define load_enable              2
#define LCD_refresh_rate         1000

int rele8   =  8;
int rele9   =  9;
int rele10  = 10;
int rele11  = 11;
int Current;

enum   {
  BULK,
  ABSORPTION,
  FLOAT
} estado;

float mode                  = BULK;
String mode_str[3]          = {"BULK", "ABSORPTION", "FLOAT"};
int pwm_value               = 3;
float bat_voltage           = 0;
float solar_current         = 0;
float battery_current       = 0;
float current_factor        = 0.100;
float solar_voltage         = 0;
float solar_power           = 0.0;
String load_status          = "OFF";
int pwm_percentage          = 0;
unsigned int before_millis  = 0;
unsigned int now_millis     = 0;
//String mode_str           = BULK;
//const unsigned long INTERVALO_ENTRE_LECTURAS = 2500UL;
const unsigned long TIEMPO_LECTURAS = 2500UL;
struct Bateria {
  float in_voltage;
  float max, min;
  int rele;
};
Bateria bateria[3] = {
  {0.0, 16.10, 15.80,  rele9},
  {0.0, 12.70, 12.40, rele10},
  {0.0,  8.90,  8.20, rele11}
};
unsigned long tiempolecturas;
void leoBateria(int id) {
  int tmp = id - 1;
  bateria[tmp].in_voltage = get_bus_voltage(tmp);

  if (bateria[tmp].in_voltage > bateria[tmp].max) {
    digitalWrite(bateria[tmp].rele, HIGH);
  }
  if (bateria[tmp].in_voltage < bateria[tmp].min) {
    digitalWrite(bateria[tmp].rele, LOW);
  }
}
float get_bus_voltage(int canal) {
  float busvoltage = ina3221.getBusVoltage_V(canal);
  return busvoltage;
}
float get_current(int canal) {
  float current_mA = -ina3221.getCurrent_mA(canal);
  return current_mA;
}
float in_voltage(float x, float in_min, float in_max, float out_min, float out_max) {
  return (x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min;
}

void setup(void)
{
  Serial.begin  (9600);
  Serial.println("SDA_Arduino_INA3221_Test");
  Serial.println("Medicion voltaje corriente ina3221 ...");
  pinMode       (rele8, OUTPUT);
  pinMode       (rele9, OUTPUT);
  pinMode       (rele10, OUTPUT);
  pinMode       (rele11, OUTPUT);
  pinMode       (PWM_out, OUTPUT);
  digitalWrite  (PWM_out, LOW);
  pinMode       (load_enable, OUTPUT);
  digitalWrite  (load_enable, LOW);
  Serial.println("Iniciando INA3221");
  ina3221.begin ();
  before_millis = millis();
}
void loop(void)
{
  if (millis() - tiempolecturas > 2500UL) {
    Serial.println("------------------------------");
    float shuntvoltage1 = 0;
    float busvoltage1   = 0;
    float current_mA1   = 0;
    float loadvoltage1  = 0;
    if (current_mA1     > 0.800 ) {
      digitalWrite(rele8, HIGH);
    }
    if (current_mA1    < 0.100) {
      digitalWrite(rele8, LOW);
    }
    busvoltage1 = ina3221.getBusVoltage_V(LIPO_BATTERY_CHANNEL);
    shuntvoltage1 = ina3221.getShuntVoltage_mV(LIPO_BATTERY_CHANNEL);
    current_mA1 = -ina3221.getCurrent_mA(LIPO_BATTERY_CHANNEL);
    loadvoltage1 = busvoltage1 + (shuntvoltage1 / 1000);
    solar_power = bat_voltage * solar_current;
    pwm_percentage = map(pwm_value, 0, 255, 0, 100);
    now_millis = millis();
    Serial.print("LIPO_Battery Bus Voltage:   ");
    Serial.print(busvoltage1);
    Serial.println(" V");
    Serial.print("LIPO_Battery Shunt Voltage: ");
    Serial.print(shuntvoltage1);
    Serial.println(" mV");
    Serial.print("LIPO_Battery Load Voltage:  ");
    Serial.print(loadvoltage1);
    Serial.println(" V");
    Serial.print("LIPO_Battery Current 1:       ");
    Serial.print(current_mA1);
    Serial.println(" mA");
    Serial.println("");
    if (busvoltage1 > 12.00) {
      digitalWrite(rele9, HIGH);
    }
    if (busvoltage1 < 12.60) {
      digitalWrite(rele9, LOW);
    }
    Serial.println("------------------------------");
    float shuntvoltage2 = 0;
    float busvoltage2 = 0;
    float current_mA2 = 0;
    float loadvoltage2 = 0;
    busvoltage2 = ina3221.getBusVoltage_V(SOLAR_CELL_CHANNEL);
    shuntvoltage2 = ina3221.getShuntVoltage_mV(SOLAR_CELL_CHANNEL);
    current_mA2 = -ina3221.getCurrent_mA(SOLAR_CELL_CHANNEL);
    loadvoltage2 = busvoltage2 + (shuntvoltage2 / 1000);
    solar_power = bat_voltage * solar_current;
    pwm_percentage = map(pwm_value, 0, 255, 0, 100);
    before_millis = now_millis;
    Serial.print("Solar Cell Bus Voltage 2:   ");
    Serial.print(busvoltage2);
    Serial.println(" V");
    Serial.print("Solar Cell Shunt Voltage 2: ");
    Serial.print(shuntvoltage2);
    Serial.println(" mV");
    Serial.print("Solar Cell Load Voltage 2:  ");
    Serial.print(loadvoltage2);
    Serial.println(" V");
    Serial.print("Solar Cell Current 2:       ");
    Serial.print(current_mA2);
    Serial.println(" mA");
    Serial.println("");
    if (busvoltage2 > 12.70) {
      digitalWrite(rele10, HIGH);
    }
    if (busvoltage2 < 12.90) {
      digitalWrite(rele10, LOW);
    }
    Serial.println("------------------------------");
    float shuntvoltage3 = 0;
    float busvoltage3 = 0;
    float current_mA3 = 0;
    float loadvoltage3 = 0;
    busvoltage3 = ina3221.getBusVoltage_V(OUTPUT_CHANNEL);
    shuntvoltage3 = ina3221.getShuntVoltage_mV(OUTPUT_CHANNEL);
    current_mA3 = ina3221.getCurrent_mA(OUTPUT_CHANNEL);
    loadvoltage3 = busvoltage3 + (shuntvoltage3 / 1000);
    solar_power = bat_voltage * solar_current;
    pwm_percentage = map(pwm_value, 0, 255, 0, 100);
    before_millis = now_millis;
    Serial.print("Output Bus Voltage 3:   ");
    Serial.print(busvoltage3);
    Serial.println(" V");
    Serial.print("Output Shunt Voltage 3: ");
    Serial.print(shuntvoltage3);
    Serial.println(" mV");
    Serial.print("Output Load Voltage 3:  ");
    Serial.print(loadvoltage3);
    Serial.println(" V");
    Serial.print("Output Current 3:       ");
    Serial.print(current_mA3);
    Serial.println(" mA");
    Serial.println("");
    if (busvoltage3 > 8.90) {
      digitalWrite(rele11, HIGH);
    }
    if (busvoltage3 < 8.20) {
      digitalWrite(rele11, LOW);
    }
    /////   FLOAT       /////////
    if (mode == FLOAT) {
      if (bat_voltage < float_voltage_min) {
        mode = BULK;
        //mode_str = "BULK";
      }
      else {
        if (solar_current > float_max_current) {
          mode = BULK;
          //mode_str = "BULK";
        }
        else {
          if (bat_voltage > float_voltage) {
            pwm_value--;
            pwm_value = constrain(pwm_value, 0, 255);
          }
          else {
            pwm_value++;
            pwm_value = constrain(pwm_value, 0, 255);
          }
        }
        analogWrite(PWM_out, pwm_value);
      }
    }
    else {
      if (bat_voltage < bulk_voltage_min) {
        mode = BULK;
        //mode_str = "BULK";
      }
      else if (bat_voltage > bulk_voltage_max) {
        //        mode_str = "ABSORPTION";
        mode = ABSORPTION;
      }
      /////////   BULK    ////////////
      if (mode == BULK) {
        if (solar_current > charging_current) {
          pwm_value--;
          pwm_value = constrain(pwm_value, 0, 255);
        }
        else {
          pwm_value++;
          pwm_value = constrain(pwm_value, 0, 255);
        }
        analogWrite(PWM_out, pwm_value);
      }
      ////////  ABSORPTION  ///////
      if (mode == ABSORPTION) {
        if (solar_current > absorption_max_current) {
          pwm_value--;
          pwm_value = constrain(pwm_value, 0, 255);
        }
        else {
          if (bat_voltage > absorption_voltage) {
            pwm_value++;
            pwm_value = constrain(pwm_value, 0, 255);
          }
          else {
            pwm_value--;
            pwm_value = constrain(pwm_value, 0, 255);
          }
          if (solar_current < absorption_min_current) {
            mode = FLOAT;
          }
        }
        analogWrite(PWM_out, pwm_value);
      }
    }
    tiempolecturas = millis();
  }
}

Saludos.
Nota: lo puedes subir a cualquier Arduino, y abrir el monitor Serial y ver el orden, (toda la información aparece en ceros), pero con orden.

Ya está definida

String mode_str[3]  = {"BULK", "ABSORPTION", "FLOAT"};

por eso

String mode_str  = BULK,

genera error por intento de redefinición.

Lo solucionas simplemente cambiándole el nombre.

No se que uso le darías esa variable pero ten en cuenta que solo estaría almacenando "0", "1" o "2".

Saludos

Hola @anon90500195, dime como lo soluciono porque, (String mode_str = BULK,) esta comentado varias veces, (creo que 4 veces) todo el problema empezó con esto
(estado mode = BULK;) en el post#12 me daba error, y lo modifique por esto (estado = BULK;) después me dio el error que me comentas.
Saludos.

Ya te dije, cámbiale el nombre.

Lo gracioso de la situación que planteas es que estás gastando energía en corregir un error con una variable que finalmente no se usa.

Hola @anon90500195, seguí tu consejo y elimine la variable que no se usa. Quiero agregar una pantalla LCD al programa el LCD 4x20 es insuficiente para ver los datos, pensaba en una LCD grafic, tengo una que 128x64 vía SPI pero nunca la e usado, y no tengo ni la menor idea de como incluirla en el código, me podrías recomendar algún enlace que me ayude a incluir la en el código.
Saludos

Hola @silvia96. Si es SPI es fácil conectarla pero antes hay que asegurarse qeu funciona sin problemas, asi que identifica su driver o controlador. Busca la librería, prueba los ejemplos en sketch separados y luego si todo funcinoa bien integra a tu proyecto.
Danos datos.