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.