Manufactura industrial
Internet industrial de las cosas | Materiales industriales | Mantenimiento y reparación de equipos | Programación industrial |
home  MfgRobots >> Manufactura industrial >  >> Manufacturing Technology >> Proceso de manufactura

Centro de Energía Solar Todo en Uno: Controlador de Carga, Inversor, Power Bank y Lámpara LED

Componentes y materiales

Microchip Technology Atmega8
× 1
Convertidor Buck
× 1
SparkFun LED - 3W Aluminio PCB (Paquete de 5, Blanco Cálido)
× 1
Pantalla Nokia 5110
× 1
Disipador de calor SparkFun
× 1
MOSFET Canal N SparkFun
× 4
MOSFET Canal P SparkFun
× 1
Panel Solar 40 Vatios o menos para sistema de 12V
× 1
Batería de Ion-Litio SparkFun - Celda 18650
× 1
Módulo DC-DC 0.9V-5V a USB 5V DC Boost Step-up Power Supply
× 1
Centro de Energía Solar Todo en Uno: Controlador de Carga, Inversor, Power Bank y Lámpara LED
Transistor NPN de Uso General
× 1
Transformador con Toma Central 12-0-12/220
× 1
Centro de Energía Solar Todo en Uno: Controlador de Carga, Inversor, Power Bank y Lámpara LED
1N4007 – Diodo de Alta Tensión y Corriente
× 1
Centro de Energía Solar Todo en Uno: Controlador de Carga, Inversor, Power Bank y Lámpara LED
Header Macho 36 Posiciones 1 Fila - Largo (0.1")
× 1
Centro de Energía Solar Todo en Uno: Controlador de Carga, Inversor, Power Bank y Lámpara LED
Interruptor Deslizante
× 1
Centro de Energía Solar Todo en Uno: Controlador de Carga, Inversor, Power Bank y Lámpara LED
Pulsador SparkFun 12mm
× 1
Centro de Energía Solar Todo en Uno: Controlador de Carga, Inversor, Power Bank y Lámpara LED
Arduino Proto Shield
× 1
Placa Strip/Vero/Proto 8x11 cm
× 1
Centro de Energía Solar Todo en Uno: Controlador de Carga, Inversor, Power Bank y Lámpara LED
Arduino UNO
× 1
Centro de Energía Solar Todo en Uno: Controlador de Carga, Inversor, Power Bank y Lámpara LED
Arduino Nano R3
× 1
Centro de Energía Solar Todo en Uno: Controlador de Carga, Inversor, Power Bank y Lámpara LED
Arduino Mega 2560
× 1
Diodo Schottky Baja Tensión 5822
× 1
Centro de Energía Solar Todo en Uno: Controlador de Carga, Inversor, Power Bank y Lámpara LED
Condensador 10 µF
× 1
Centro de Energía Solar Todo en Uno: Controlador de Carga, Inversor, Power Bank y Lámpara LED
Condensador 100 nF
× 1

Herramientas y máquinas necesarias

Centro de Energía Solar Todo en Uno: Controlador de Carga, Inversor, Power Bank y Lámpara LED
Soldador (genérico)
Taladro
Centro de Energía Solar Todo en Uno: Controlador de Carga, Inversor, Power Bank y Lámpara LED
Pistola de pegamento caliente (genérica)

Aplicaciones y servicios en línea

Centro de Energía Solar Todo en Uno: Controlador de Carga, Inversor, Power Bank y Lámpara LED
Arduino IDE
AutoDesk 123D

Acerca de este proyecto

Sobre este proyecto

Tengo algunos paneles solares, baterías de 12 Voltios, transformadores y algunas cosas más por ahí desde hace un tiempo pidiendo a gritos que les diera un buen uso. Así nació este dispositivo: una solución fotovoltaica pequeña y completa en una sola placa. Revisemos primero qué hace cada cosa, ¿de acuerdo?

Este dispositivo que hice tiene todas estas características, las dos últimas son soportadas independientemente por la batería de ion-litio a bordo. Con un panel solar (hasta 100 Vatios), una batería de plomo-ácido de 12 Voltios y un transformador, se pueden utilizar todas las opciones.

Versión Proto en Uno

La primera versión se desarrolló en una placa Uno con hardware mínimo y opciones mínimas. La pantalla Nokia se montó directamente y se desarrolló un shield de MOSFETs para soportar la carga/descarga de la batería. No hay control de menú, no hay inversor, no hay carga PWM y ¡funciones geniales! Solo carga on/off y mostrando niveles de voltaje de batería y panel. Hace el trabajo pero no tiene encanto.

Centro de Energía Solar Todo en Uno: Controlador de Carga, Inversor, Power Bank y Lámpara LED

Versión Completa en Protoboard

Luego desarrollé esta nueva con las siguientes características:

Menú controlado por 2 botones/interruptores basado en desplazamiento y selección, mostrando opciones e información de estado en la pantalla Nokia 5110. ¡Muy guay! La parte trasera está aislada con pegamento caliente para protección contra cortocircuitos contra objetos metálicos.

Hay algunas características convenientes más como interruptor on/off para la retroiluminación de la pantalla, separar el buck para operación independiente desconectándolo de la batería interna.

Centro de Energía Solar Todo en Uno: Controlador de Carga, Inversor, Power Bank y Lámpara LED
Centro de Energía Solar Todo en Uno: Controlador de Carga, Inversor, Power Bank y Lámpara LED
Centro de Energía Solar Todo en Uno: Controlador de Carga, Inversor, Power Bank y Lámpara LED
Centro de Energía Solar Todo en Uno: Controlador de Carga, Inversor, Power Bank y Lámpara LED

Accediendo al menú en la pantalla Nokia 5110 con el botón de usuario se muestra aquí:

¡Aprendamos algo técnico!

El controlador de carga puede ser de tipos On/Off, PWM o MPPT. On/Off es la forma más simple (mi versión 1 - imagen arriba) de controlador que no limita la corriente de carga a medida que el voltaje de la batería se acerca a su voltaje de carga completa.

Mientras que PWM disminuye gradualmente la corriente de carga a medida que la batería se llena. El controlador PWM tiene los siguientes beneficios:

Pero el PWM no puede obtener la mayor parte de la energía eléctrica de los paneles solares fotovoltaicos, porque arrastra al panel a operar cerca del voltaje de la batería. MPPT es la solución a este problema, que básicamente es un convertidor buck-boost DC a DC ajustable, puede convertir la mayor parte de la energía solar comparado con el controlador PWM.

Los inversores pueden ser de tipos onda cuadrada, onda senoidal modificada y onda senoidal pura. El inversor de onda cuadrada es muy simple en diseño y suficiente para pequeñas cargas DC como lámparas AC, lámparas CFL, ventiladores de mesa, soldadores, pero no recomendado para motores inductivos, equipos delicados/fuentes de alimentación debido a la distorsión armónica.

La onda senoidal modificada es una especie de onda senoidal retardada creada a partir de ondas cuadradas, mejor que los inversores de onda cuadrada simples. Los inversores de onda senoidal son los mejores para todo tipo de cargas pero complejos de diseñar en hardware, algoritmo de software difícil de operar y caros de fabricar.

Un regulador buck es un convertidor DC-DC reductor, aquí he usado un módulo buck para cargar la batería de ion-litio de 4.2V que alimenta el controlador (Arduino + pantalla), power bank USB independiente, lámpara LED a bordo.

Centro de Energía Solar Todo en Uno: Controlador de Carga, Inversor, Power Bank y Lámpara LED

Ahora, el power bank USB básicamente es un boost DC-DC que puede convertir un rango de voltajes por debajo de 5 (como rango de 3.3 a 4.2 voltios) de una batería de ion-litio o LiPo a 5 voltios, que es el voltaje del bus USB que puede cargar dispositivos móviles.

También tiene un convertidor buck para cargar esa batería. En mi proyecto, el módulo buck toma algo de energía del panel para cargar la batería interna (a bordo).

Funcionamiento del hardware

Antes de entrar en detalles, revisa esta imagen de todo lo conectado alrededor del dispositivo:

Centro de Energía Solar Todo en Uno: Controlador de Carga, Inversor, Power Bank y Lámpara LED

El sistema tiene varios componentes de hardware para servir a diferentes propósitos. Por supuesto, el cerebro es el microcontrolador AVR Atmega8A (se puede usar Atmega328P con cambios menores, discutido abajo) que está programado en Arduino.

Centro de Energía Solar Todo en Uno: Controlador de Carga, Inversor, Power Bank y Lámpara LED

Un Atmega8A nuevo se graba con el bootloader Arduino Optiboot8, puedes comprar un Arduino Mini/Atmega328 con bootloader para evitar el lío.

El controlador, pantalla, lámpara LED y power bank se alimentan desde la batería de ion-litio a bordo. Dos botones momentáneos táctiles son para acceder al menú en la pantalla, lo que permite al usuario operar diferentes funciones del dispositivo. Los interruptores están desacoplados por hardware a través de condensadores de suavizado conectados en paralelo.

Un interruptor deslizante permite encender/apagar el dispositivo según sea necesario.

Centro de Energía Solar Todo en Uno: Controlador de Carga, Inversor, Power Bank y Lámpara LED

La función de carga solar se realiza mediante un MOSFET tipo P controlado por un circuito de control basado en transistor 2N2222 que es controlado mediante PWM desde el microcontrolador. El PWM se controla basado en el nivel de voltaje de la batería externa. La corriente de los paneles solares fluye a través del MOSFET tipo P a la batería de plomo-ácido. Cuando la batería está completamente cargada, el MOSFET se apaga desde el microcontrolador. Después de que la carga se apaga, el voltaje de la batería comienza a caer gradualmente, cuando alcanza 13.6 voltios la carga se reanuda de nuevo con bajo ciclo de trabajo para mantener la carga de flotación.

La carga DC de 12 Voltios se controla a través de un MOSFET tipo N controlando su pin Gate desde el microcontrolador.

Centro de Energía Solar Todo en Uno: Controlador de Carga, Inversor, Power Bank y Lámpara LED

La lámpara LED a bordo también es impulsada a través de un NMOS. El Gate de este MOSFET es controlado por PWM para ajuste de brillo del LED.

Centro de Energía Solar Todo en Uno: Controlador de Carga, Inversor, Power Bank y Lámpara LED

El bloque inversor consiste en 2 MOSFETs tipo N que se encienden/apagan alternativamente para simular CA. Al agregar un transformador con toma central externo, se puede realizar una alimentación CA de onda cuadrada.

Centro de Energía Solar Todo en Uno: Controlador de Carga, Inversor, Power Bank y Lámpara LED

La siguiente figura explica la acción del inversor:

Centro de Energía Solar Todo en Uno: Controlador de Carga, Inversor, Power Bank y Lámpara LED

Al permitir que la corriente fluya a través de la toma central de la bobina de un transformador elevador en dirección opuesta alternativamente usando MOSFETs, se puede crear voltaje CA en el secundario. Esto sucede porque cuando el MOSFET superior está encendido y el inferior apagado, la corriente fluye hacia arriba. Pero cuando el MOSFET superior está apagado y el inferior encendido, la corriente fluye hacia abajo.

Ambos MOSFETs deben conmutarse al doble de la frecuencia de CA. Revisa la siguiente imagen para entenderlo:

Centro de Energía Solar Todo en Uno: Controlador de Carga, Inversor, Power Bank y Lámpara LED

Para crear 50 Hz CA, se aplica una onda cuadrada alterna en el lado de baja tensión del transformador con toma central 12-0-12V/220V. 50 Hz significa 20 ms para cada onda.

Por eso 20ms/2 = 10 ms o 100 veces conmutar las señales de Gate aplicadas a los MOSFETs que impulsan el transformador (MOSFETs del inversor).

Centro de Energía Solar Todo en Uno: Controlador de Carga, Inversor, Power Bank y Lámpara LED
Centro de Energía Solar Todo en Uno: Controlador de Carga, Inversor, Power Bank y Lámpara LED
Centro de Energía Solar Todo en Uno: Controlador de Carga, Inversor, Power Bank y Lámpara LED

¡Advertencia! El voltaje CA es letal para los humanos, puede causar muerte/lesiones. ¡Nunca toques el lado de alta tensión del transformador con la mano desnuda!

Si no se usa la función inversor, la opción 2XDC Load permite usar dos cargas DC de 12 voltios más en la terminal del inversor.

Magia del software

Se proporcionan dos conjuntos de código, uno es el código completo en una sola pestaña de Arduino, otro es el código en pestañas según funciones separadas.

He generalizado grupos de tareas en una sola función.

Por ejemplo:

Get_ADCVal() medirá los voltajes de Panel, Batería Interna y Batería Externa, tomará 20 muestras, promediará esos valores y actualizará la variable que contiene la información de voltaje.

Context_Control() hará la Interacción de Usuario, Control de Acción, Actualización de Info en Pantalla, actividades relacionadas.

Charging_Control(), Discharging_Control(), Load_Control() son funciones de fondo que actúan como LAZO CERRADO para el sistema, monitorean el nivel de voltaje de la batería, controlan la función Auto Load, control de protección sobrecarga/descarga profunda, etc.

Las entradas de usuario se recogen a través de interruptores momentáneos impulsados por interrupciones. Cuando se presionan estos interruptores, se ejecutan las ISR relacionadas con INT0/INT1. Dos variables volátiles dp y ds cambian. Otra tercera variable level junto con dp (puntero de pantalla ->) y ds (selector de contenido de pantalla) permite al usuario navegar por menú/submenú y realizar acciones según sea necesario.

El Temporizador 1 de 16 bits de AVR está configurado para generar Interrupción por Desbordamiento de Temporizador cada 10 ms y voltea PIN_INVP y PIN_INVN cuando la función Inversor está Activa.

Todas las funciones Lcd_....() tienen que ver con el control de la pantalla.

Atmega8A vs Atmega328P (Uno)

El sistema se puede actualizar fácilmente para funcionar con Atmega328P/Uno haciendo los siguientes cambios en el código. Buscar y reemplazar:

TIMSK con TIMSK1
#define ADC_VREF 2.69 con #define ADC_VREF 1.11
#define ADCVDIV_R1 22 con #define ADCVDIV_R1 8.2

En la parte de hardware necesitas usar una resistencia de 8.2K en lugar de 22K para escalar los voltajes de panel y batería al rango de medición del ADC.

Videos de acción

Normalmente no leo solo palabras sobre algún proyecto, en su lugar voy por el video primero. Si eres como yo, disfruta los videos:

Alcance de mejora

Me quedé sin espacio Flash en Atmega8A. No pude añadir algunas características críticas como:

Si tienes planes para hacer algo como esto, ¡no olvides añadir algunas de estas características!

Atmega328P(Uno) o Arduino Mega podrían ser mejores candidatos para incluir todas estas opciones.

De todos modos, hace el trabajo, estoy contento con él.

Recursos adicionales

Código

Código en Una Sola Pestaña Arduino
#define PIN_SCE 12
#define PIN_RESET 13
#define PIN_DC 8
#define PIN_SDIN 7
#define PIN_SCLK 6
#define PIN_INVP 4
#define PIN_INVN 5
#define PIN_LOAD 9 // carga dc 12v
#define PIN_LAMP 10 // LUZ LED BLANCA
#define PIN_BATTPWM 11 // Controla PMOS para Carga Batería Ext
#define PIN_BATTint_Sense A2
#define PIN_SOLAR_Sense A0
#define PIN_BATText_Sense A3
#define ADC_VREF 2.695 // voltaje ref interno, alrededor de 1.11V para Arduino Uno aka Atmega328P, aquí mi Atmega8A da esto!
#define ADCVDIV_R1 22 // 22 K divisor de voltaje resistencia inferior
#define ADCVDIV_R2 175 // 175 K divisor de voltaje resistencia superior
//const uint8_t skulljoke[] PROGMEM ={2,} ; // PIN 2 & 3 USADOS COMO INTERRUPTOR
// PIN 0 & 1 COMO PROGRAMACIÓN
// PIN RESET COMO
#define LCD_C LOW
#define LCD_D HIGH
#define LCD_X 84
#define LCD_Y 48
uint8_t x=0;
uint8_t level=0;
uint8_t blinker=0;
boolean Load_Auto_Enable=0;
float maxADC_Voltage=0.0;
float BattInt_Voltage=0.0;
float BattExt_Voltage=0.0;
float PV_Voltage=0.0;
volatile int y=0;
volatile uint8_t dp =0;
volatile uint8_t ds =0;
volatile boolean cycle=0;
volatile uint8_t cdc_level =0;
//int i;
void setup(void) {
  LcdInitialise();
  LcdClear();
  LcdString("*ARDUBOY PV*");
  LcdString(" CONTROLADOR,");
  LcdString("AC INVERSOR,");
  LcdString("POWER BANK, ");
  LcdString("LAMP THING!!");
  delay(3000);
  analogReference(INTERNAL);
  maxADC_Voltage=(ADC_VREF/ADCVDIV_R1)*(ADCVDIV_R1+ADCVDIV_R2);
  pinMode(PIN_LOAD,OUTPUT);
  digitalWrite(PIN_LOAD,LOW);
  pinMode(2, INPUT_PULLUP);
  attachInterrupt(0, SW1, FALLING);// Interrupción para Interruptor 1
  pinMode(3, INPUT_PULLUP);
  attachInterrupt(1, SW2, FALLING);// Interrupción para Interruptor 2
}
void loop(void) {
  Get_ADCVal();
  Context_Control();
  Charging_Control();
  Discharging_Control();
  Load_Control();
  LcdClear();;
}
///////////// ADC ///////////////
void Get_ADCVal(void) {
  int I=0;
  int J=0;
  int K=0;
  for(x=0;x<20;x++) {
    I=I+analogRead(PIN_BATTint_Sense);
    J=J+analogRead(PIN_BATText_Sense);
    K=K+analogRead(PIN_SOLAR_Sense);
  }
  // voltaje promedio
  BattInt_Voltage=I/20.0;
  BattExt_Voltage=J/20.0;
  PV_Voltage=K/20.0;
  BattInt_Voltage=maxADC_Voltage*BattInt_Voltage/1023.0;
  BattExt_Voltage=maxADC_Voltage*BattExt_Voltage/1023.0;
  PV_Voltage=maxADC_Voltage*PV_Voltage/1023.0;
}
//////////// Pantalla y Control //////////////
void Context_Control(void) {
  if(ds==0) {show_menu();}
  if(ds==1 && dp == 0) {show_info(); delay(100);} //LcdClear();Get_ADCVal();}
  ///////////////////////Entra al 1er Submenú////////////////////////////
  if(ds==1 && dp == 1) {
    level=1; dp=0;
    while(level==1) {
      int temp=ds;
      LcdClear(); show_load_ctrl();delay(250);
      if (dp==0){ if(ds!=temp){Load_Auto_Enable=0;digitalWrite(PIN_LOAD,LOW);}}
      if (dp==1){if(ds!=temp){Load_Auto_Enable=0; digitalWrite(PIN_LOAD,HIGH);}}
      if (dp==2){ if(ds!=temp){Load_Auto_Enable=1;}}
      if (dp==3){show_load_ctrl();delay(250);level=0;dp=0;ds=0;}
    }
  }
  //////////////////////Entra al 2do Submenú//////////////////////////////
  if(ds==1 && dp == 2) {
    level=2; dp=0;
    while(level==2) {
      int temp=ds;
      show_inv_ctrl();delay(250);
      LcdClear();
      if (dp==0){ if(ds!=temp){Timer1_Init();}}
      if (dp==1){ if(ds!=temp){Timer1_DeInit();}}
      if (dp==2){ if(ds!=temp){Timer1_DeInit();digitalWrite(PIN_INVP,1);digitalWrite(PIN_INVN,1);}}
      if (dp==3){show_inv_ctrl();delay(250);level=0;dp=0;ds=0;}
    }
  }
  /////////////////////////////////////////////////////////
  ////////////////Entra al 3er Submenú/////////////////////////////
  if(ds==1 && dp == 3) {
    level=3; dp=0;
    while(level==3) {
      int temp=ds;
      LcdClear(); show_led_ctrl();delay(250);
      if (dp==0){blinker=0;if(ds!=temp) {if(y<=255){y=y+15;analogWrite(PIN_LAMP,y);}}}
      if (dp==1){blinker=0;if(ds!=temp) {if(y>=0){y=y-15;analogWrite(PIN_LAMP,y);}}}
      if (dp==2){if(ds!=temp) {blinker^=1;analogWrite(PIN_LAMP,127);delay(250);analogWrite(PIN_LAMP,0);}}
      if (dp==3){show_led_ctrl();delay(250);level=0;dp=0;ds=0;}
    }
  }
  /////////////////////////////////////////////////////////
  // {show_inv_ctrl();}
  // {show_led_ctrl();}
  //}
  if(blinker==1) {analogWrite(PIN_LAMP,0);}
  delay(250);
  if(blinker==1) {analogWrite(PIN_LAMP,127);}
}
/////////////////////////// Texto del Menú para mostrar en pantalla Nokia 5110 /////////////////
void show_menu(void) {
  LcdXY(0,dp); LcdString("->");
  LcdXY(15,0); LcdString("Sys Info");
  LcdXY(15,1); LcdString("DC Load+");
  LcdXY(15,2); LcdString("AC Load~");
  LcdXY(15,3); LcdString("LED Lamp");
}
void show_info(void) {
  LcdXY(0,0); LcdString("Bat_I="); LcdNumtoString(BattInt_Voltage); LcdString("v");
  LcdXY(0,1); LcdString("Bat_E="); LcdNumtoString(BattExt_Voltage); LcdString("v");
  LcdXY(0,2); LcdString("Sol_P="); LcdNumtoString(PV_Voltage); LcdString("v");
  LcdXY(0,3);
  if(BattExt_Voltage >8.0) {LcdString("Bat Conn OK");} else {LcdString("Conecta Bat");}
  if (PV_Voltage > 10.5 && cdc_level!=3 && cdc_level!=0) {LcdString("Cargando:ON ");} else {LcdString("Cargando:OFF");}
  if (TCNT1 >=45535 ) {LcdString("Inversor:ON");} else {LcdString("Inversor:OFF");}
}
void show_load_ctrl(void) {
  LcdXY(0,dp); LcdString("->");
  LcdXY(15,0); LcdString("Carga Off");
  LcdXY(15,1); LcdString("Carga On");
  LcdXY(15,2); LcdString("Carga Auto");
  LcdXY(15,3); LcdString("Volver");
  LcdXY(0,4); LcdString("Debe Conectar");
  LcdString("Carga DC 12V");
}
void show_inv_ctrl(void) {
  LcdXY(0,dp); LcdString("->");
  LcdXY(15,0); LcdString("AC Inv On");
  LcdXY(15,1); LcdString("AC Inv Off");
  LcdXY(15,2); LcdString("2XDC Load");
  LcdXY(15,3); LcdString("Volver");
  LcdXY(0,4); LcdString("2XDC Load,NO");
  LcdXY(0,5); LcdString("TRANSFORMADOR!");
}
void show_led_ctrl(void) {
  LcdXY(0,dp); LcdString("->");
  LcdXY(15,0); LcdString("LED ++");
  LcdXY(15,1); LcdString("LED --");
  LcdXY(15,2); LcdString("LED Parp");
  LcdXY(15,3); LcdString("Volver");
  LcdXY(0,4); LcdString("LED DESHABIL");
  LcdXY(0,5); LcdString("Cuando INVR On");
}
///////////////// Interrupciones ISRs ////////////////
void SW1() {
  dp++; if(dp>3){dp=0;}
}
void SW2() {
  ds^=1;
}
ISR(TIMER1_OVF_vect) {
  noInterrupts();
  TCNT1 = 45535; // TCNT1 = 25535;
  cycle^=1;
  if(cycle==0); {
    digitalWrite(PIN_INVP,HIGH);
    delayMicroseconds(1); // banda muerta
    digitalWrite(PIN_INVN,LOW);
    delayMicroseconds(1);
  }
  if(cycle==1) {
    digitalWrite(PIN_INVP,LOW);
    delayMicroseconds(1); // banda muerta
    digitalWrite(PIN_INVN,HIGH);
    delayMicroseconds(1);
  }
  interrupts();
}
/////////////Funciones Nokia 5110 ////////////
static const byte ASCII[][5] = {
  {0x00, 0x00, 0x00, 0x00, 0x00}, // 20
  {0x00, 0x00, 0x5f, 0x00, 0x00}, // 21 !
  {0x00, 0x07, 0x00, 0x07, 0x00}, // 22 "
  {0x14, 0x7f, 0x14, 0x7f, 0x14}, // 23 #
  {0x24, 0x2a, 0x7f, 0x2a, 0x12}, // 24 $
  {0x23, 0x13, 0x08, 0x64, 0x62}, // 25 %
  {0x36, 0x49, 0x55, 0x22, 0x50}, // 26 &
  {0x00, 0x05, 0x03, 0x00, 0x00}, // 27 '
  {0x00, 0x1c, 0x22, 0x41, 0x00}, // 28 (
  {0x00, 0x41, 0x22, 0x1c, 0x00}, // 29 )
  {0x14, 0x08, 0x3e, 0x08, 0x14}, // 2a *
  {0x08, 0x08, 0x3e, 0x08, 0x08}, // 2b +
  {0x00, 0x50, 0x30, 0x00, 0x00}, // 2c ,
  {0x08, 0x08, 0x08, 0x08, 0x08}, // 2d -
  {0x00, 0x60, 0x60, 0x00, 0x00}, // 2e .
  {0x20, 0x10, 0x08, 0x04, 0x02}, // 2f /
  {0x3e, 0x51, 0x49, 0x45, 0x3e}, // 30 0
  {0x00, 0x42, 0x7f, 0x40, 0x00}, // 31 1
  {0x42, 0x61, 0x51, 0x49, 0x46}, // 32 2
  {0x21, 0x41, 0x45, 0x4b, 0x31}, // 33 3
  {0x18, 0x14, 0x12, 0x7f, 0x10}, // 34 4
  {0x27, 0x45, 0x45, 0x45, 0x39}, // 35 5
  {0x3c, 0x4a, 0x49, 0x49, 0x30}, // 36 6
  {0x01, 0x71, 0x09, 0x05, 0x03}, // 37 7
  {0x36, 0x49, 0x49, 0x49, 0x36}, // 38 8
  {0x06, 0x49, 0x49, 0x29, 0x1e}, // 39 9
  {0x00, 0x36, 0x36, 0x00, 0x00}, // 3a :
  {0x00, 0x56, 0x36, 0x00, 0x00}, // 3b ;
  {0x08, 0x14, 0x22, 0x41, 0x00}, // 3c <
  {0x14, 0x14, 0x14, 0x14, 0x14}, // 3d =
  {0x00, 0x41, 0x22, 0x14, 0x08}, // 3e >
  {0x02, 0x01, 0x51, 0x09, 0x06}, // 3f ?
  {0x32, 0x49, 0x79, 0x41, 0x3e}, // 40 @
  {0x7e, 0x11, 0x11, 0x11, 0x7e}, // 41 A
  {0x7f, 0x49, 0x49, 0x49, 0x36}, // 42 B
  {0x3e, 0x41, 0x41, 0x41, 0x22}, // 43 C
  {0x7f, 0x41, 0x41, 0x22, 0x1c}, // 44 D
  {0x7f, 0x49, 0x49, 0x49, 0x41}, // 45 E
  {0x7f, 0x09, 0x09, 0x09, 0x01}, // 46 F
  {0x3e, 0x41, 0x49, 0x49, 0x7a}, // 47 G
  {0x7f, 0x08, 0x08, 0x08, 0x7f}, // 48 H
  {0x00, 0x41, 0x7f, 0x41, 0x00}, // 49 I
  {0x20, 0x40, 0x41, 0x3f, 0x01}, // 4a J
  {0x7f, 0x08, 0x14, 0x22, 0x41}, // 4b K
  {0x7f, 0x40, 0x40, 0x40, 0x40}, // 4c L
  {0x7f, 0x02, 0x0c, 0x02, 0x7f}, // 4d M
  {0x7f, 0x04, 0x08, 0x10, 0x7f}, // 4e N
  {0x3e, 0x41, 0x41, 0x41, 0x3e}, // 4f O
  {0x7f, 0x09, 0x09, 0x09, 0x06}, // 50 P
  {0x3e, 0x41, 0x51, 0x21, 0x5e}, // 51 Q
  {0x7f, 0x09, 0x19, 0x29, 0x46}, // 52 R
  {0x46, 0x49, 0x49, 0x49, 0x31}, // 53 S
  {0x01, 0x01, 0x7f, 0x01, 0x01}, // 54 T
  {0x3f, 0x40, 0x40, 0x40, 0x3f}, // 55 U
  {0x1f, 0x20, 0x40, 0x20, 0x1f}, // 56 V
  {0x3f, 0x40, 0x38, 0x40, 0x3f}, // 57 W
  {0x63, 0x14, 0x08, 0x14, 0x63}, // 58 X
  {0x07, 0x08, 0x70, 0x08, 0x07}, // 59 Y
  {0x61, 0x51, 0x49, 0x45, 0x43}, // 5a Z
  {0x00, 0x7f, 0x41, 0x41, 0x00}, // 5b [
  {0x02, 0x04, 0x08, 0x10, 0x20}, // 5c \
  {0x00, 0x41, 0x41, 0x7f, 0x00}, // 5d ]
  {0x04, 0x02, 0x01, 0x02, 0x04}, // 5e ^
  {0x40, 0x40, 0x40, 0x40, 0x40}, // 5f _
  {0x00, 0x01, 0x02, 0x04, 0x00}, // 60 `
  {0x20, 0x54, 0x54, 0x54, 0x78}, // 61 a
  {0x7f, 0x48, 0x44, 0x44, 0x38}, // 62 b
  {0x38, 0x44, 0x44, 0x44, 0x20}, // 63 c
  {0x38, 0x44, 0x44, 0x48, 0x7f}, // 64 d
  {0x38, 0x54, 0x54, 0x54, 0x18}, // 65 e
  {0x08, 0x7e, 0x09, 0x01, 0x02}, // 66 f
  {0x0c, 0x52, 0x52, 0x52, 0x3e}, // 67 g
  {0x7f, 0x08, 0x04, 0x04, 0x78}, // 68 h
  {0x00, 0x44, 0x7d, 0x40, 0x00}, // 69 i
  {0x20, 0x40, 0x44, 0x3d, 0x00}, // 6a j
  {0x7f, 0x10, 0x28, 0x44, 0x00}, // 6b k
  {0x00, 0x41, 0x7f, 0x40, 0x00}, // 6c l
  {0x7c, 0x04, 0x18, 0x04, 0x78}, // 6d m
  {0x7c, 0x08, 0x04, 0x04, 0x78}, // 6e n
  {0x38, 0x44, 0x44, 0x44, 0x38}, // 6f o
  {0x7c, 0x14, 0x14, 0x14, 0x08}, // 70 p
  {0x08, 0x14, 0x14, 0x18, 0x7c}, // 71 q
  {0x7c, 0x08, 0x04, 0x04, 0x08}, // 72 r
  {0x48, 0x54, 0x54, 0x54, 0x20}, // 73 s
  {0x04, 0x3f, 0x44, 0x40, 0x20}, // 74 t
  {0x3c, 0x40, 0x40, 0x20, 0x7c}, // 75 u
  {0x1c, 0x20, 0x40, 0x20, 0x1c}, // 76 v
  {0x3c, 0x40, 0x30, 0x40, 0x3c}, // 77 w
  {0x44, 0x28, 0x10, 0x28, 0x44}, // 78 x
  {0x0c, 0x50, 0x50, 0x50, 0x3c}, // 79 y
  {0x44, 0x64, 0x54, 0x4c, 0x44}, // 7a z
  {0x00, 0x08, 0x36, 0x41, 0x00}, // 7b {
  {0x00, 0x00, 0x7f, 0x00, 0x00}, // 7c |
  {0x00, 0x41, 0x36, 0x08, 0x00}, // 7d }
  {0x10, 0x08, 0x08, 0x10, 0x08}, // 7e ~
  {0x78, 0x46, 0x41, 0x46, 0x78}  // 7f
};
void LcdCharacter(char character) {
  LcdWrite(LCD_D, 0x00);
  for (int index = 0; index < 5; index++) {
    LcdWrite(LCD_D, ASCII[character - 0x20][index]);
  }
  LcdWrite(LCD_D, 0x00);
}
void LcdClear(void) {
  for (int index = 0; index < LCD_X * LCD_Y / 8; index++) {
    LcdWrite(LCD_D, 0x00);
  }
}
void LcdInitialise(void) {
  pinMode(PIN_SCE, OUTPUT);
  pinMode(PIN_RESET, OUTPUT);
  pinMode(PIN_DC, OUTPUT);
  pinMode(PIN_SDIN, OUTPUT);
  pinMode(PIN_SCLK, OUTPUT);
  digitalWrite(PIN_RESET, LOW);
  digitalWrite(PIN_RESET, HIGH);
  LcdWrite(LCD_C, 0x21); // Comandos Extendidos LCD.
  LcdWrite(LCD_C, 0xA0); // Establecer Vop LCD (Contraste).
  //0xB1
  LcdWrite(LCD_C, 0x04); // Establecer coeficiente Temp.
  //0x04
  LcdWrite(LCD_C, 0x14); // Modo bias LCD 1:48.
  //0x13
  LcdWrite(LCD_C, 0x20); // Comandos Básicos LCD
  LcdWrite(LCD_C, 0x0C); // LCD en modo normal.
}
void LcdString(char *characters) {
  while (*characters) {
    LcdCharacter(*characters++);
  }
}
void LcdWrite(byte dc, byte data) {
  // analogWrite(PIN_BL, 127);
  digitalWrite(PIN_DC, dc);
  digitalWrite(PIN_SCE, LOW);
  shiftOut(PIN_SDIN, PIN_SCLK, MSBFIRST, data);
  digitalWrite(PIN_SCE, HIGH);
}
void LcdXY(int x,int y) {
  LcdWrite(LCD_C,0x80|x);
  LcdWrite(LCD_C,0x40|y);
}
void LcdNumtoString(float number) {
  char string[8];
  LcdString(dtostrf(number,5,2, string));
}
///////////////// Funciones de Control de Bucle en Segundo Plano //////////////
// Este código habilitará automáticamente la carga externa cuando el sol se pone usando PV como Sensor de Luz
void Load_Control(void) {
  if (Load_Auto_Enable == 1 && PV_Voltage < 4.5 && cdc_level > 0) {digitalWrite(PIN_LOAD,HIGH);}
  if (Load_Auto_Enable == 1 && PV_Voltage >10.5 || cdc_level==0) {digitalWrite(PIN_LOAD,LOW);}
}
void Charging_Control (void) {
  // Nivel BattExt_Voltage 14.3 Carga off, 13.5 o menos Carga on, 10.8 Carga off, 12.5 Carga on
  // esta siguiente condición previene los intentos de carga durante la noche % noche PV es 0 volt!
  if (PV_Voltage > 10.5 && BattExt_Voltage >8.0) {
    if (BattExt_Voltage <= 12.5) { analogWrite(PIN_BATTPWM,255); cdc_level = 0; }
    if (BattExt_Voltage > 12.5 && BattExt_Voltage <=12.9) { analogWrite(PIN_BATTPWM,200); cdc_level = 1; }
    if (BattExt_Voltage > 12.9 && BattExt_Voltage <=13.3) { analogWrite(PIN_BATTPWM,160); cdc_level = 1; }
    if (BattExt_Voltage > 13.3 && BattExt_Voltage <=13.6) { analogWrite(PIN_BATTPWM,120); cdc_level = 2; }
    if (BattExt_Voltage > 13.6 && BattExt_Voltage <=13.9 && cdc_level == 2) { analogWrite(PIN_BATTPWM,80); cdc_level = 2; }
    if (BattExt_Voltage > 13.9 && BattExt_Voltage <=14.3 && cdc_level == 2) { analogWrite(PIN_BATTPWM,40); cdc_level = 2; }
    // Bloqueo por Sobrevoltaje, mientras cdc_level es 3, NO Carga! La carga reanuda cuando cdc es 2 que es debajo de 13.5v
    if (BattExt_Voltage > 14.3) { analogWrite(PIN_BATTPWM,0); cdc_level = 3; }
  } else {analogWrite(PIN_BATTPWM,0);cdc_level = 3;}
}
/// Bloqueo por Subvoltaje
void Discharging_Control (void) {
  if (BattExt_Voltage <= 10.8) {
    cdc_level = 0;
    {digitalWrite(PIN_LOAD,LOW);}
    Timer1_DeInit();
  }
}
///////////////// Funciones del Temporizador 2 ////////////////
// Esta parte del código está escrita en estilo AVR
void Timer1_Init(void) {
  noInterrupts(); // deshabilita todas las interrupciones
  pinMode(PIN_INVP,OUTPUT);
  pinMode(PIN_INVN,OUTPUT);
  TCCR1A = 0;
  TCCR1B = 0;
  /* ========================================
  50 Hz CA significa 20 ms Onda que se forma por 2, pulsos de 10 ms desde pines PIN_INVP y PIN_INVN
  así que ambos pines deberían conmutar a 100 Hz!
  Ahora 100 Hz = .01 seg
  Reloj del Sistema Arduino 16 MHz = 16000000 ciclos en 0.01 seg tenemos 160000 ciclos
  usando prescaler de 8 (CS11) hace que el temporizador cuente 160000/8 = 20000 ticks del temporizador
  Como el temporizador 2 es Contador Ascendente de 16 bits y Desborda en valor 65635
  necesitamos empezar a contar desde 65535-20000 = desde 45535 valor hasta 65535
  así TCNT1 empieza en 45535 ..luego tick tick tick ... 46000 .... 50000 .............. 65536 !!!
  Boom Interrupción por Desbordamiento de Temporizador y conmutar los pines de control del inversor en ISR
  y empezar a contar desde 45535 Otra Vez !!! (Esto ocurre en Segundo Plano)
  ======================================== */
  TCNT1 = 45535; //TCNT1 = 25535;
  TCCR1B |= (1 << CS11); // prescaler 8
  TIMSK |= (1 << TOIE1); // habilita interrupción por comparación de temporizador
  interrupts();
}
void Timer1_DeInit(void) {
  noInterrupts(); // deshabilita todas las interrupciones
  TCCR1A = 0;
  TCCR1B = 0;
  TCNT1 = 0;
  // TIMSK &= (0 << TOIE1); // deshabilita interrupción por comparación de temporizador
  digitalWrite(PIN_INVP,LOW);
  digitalWrite(PIN_INVN,LOW);
  interrupts();
}
Código CompletoC/C++

Código Organizado y Legible

No hay vista previa (solo descarga).
BootloadersC/C++
No hay vista previa (solo descarga).

Esquemas

Centro de Energía Solar Todo en Uno: Controlador de Carga, Inversor, Power Bank y Lámpara LED

Proceso de manufactura

  1. Lámparas Halógenas: Tecnología, Historia y Futuro – Perspectiva Experta
  2. Lámpara de Lava: Historia, Diseño y Secretos de Fabricación
  3. Sistemas de calefacción solar: de soluciones pasivas a activas para calefacción sostenible del hogar
  4. Circuitos integrados (CI): chips compactos y potentes que impulsan la electrónica moderna
  5. Células solares: de los primeros experimentos a la fotovoltaica moderna – tecnología, producción y perspectivas
  6. Semáforo Inteligente: Iluminación Vial Adaptativa con IoT
  7. Mando USB para juegos DIY con Arduino – Construye tu propio gamepad de alto rendimiento
  8. Disfraz de nube DIY: Tira LED, Arduino Nano y componentes SparkFun
  9. Rastreador Solar V2.0 – Sistema Avanzado DIY de Seguimiento Solar
  10. Aprovechamiento de la energía solar: guía completa para una energía limpia y fiable
  11. Qué es un Inversor Solar: Cómo Convierte la Energía Solar en Electricidad Utilizable