Fabrication industrielle
Internet des objets industriel | Matériaux industriels | Entretien et réparation d'équipement | Programmation industrielle |
home  MfgRobots >> Fabrication industrielle >  >> Manufacturing Technology >> Processus de fabrication

Hub Solaire Tout-en-Un : Régulateur de Charge, Onduleur, Power Bank et Lampe LED

Composants et Fournitures

Microchip Technology Atmega8
× 1
Convertisseur Buck
× 1
SparkFun LED - 3W PCB Aluminium (Lot de 5, Blanc Chaud)
× 1
Écran Nokia 5110
× 1
Dissipateur Thermique SparkFun
× 1
MOSFET Canal N SparkFun
× 4
MOSFET Canal P SparkFun
× 1
Panneau Solaire 40 Watt ou Moins pour Système 12 V
× 1
SparkFun Batterie Lithium-Ion - Cellule 18650
× 1
Module DC-DC 0,9V-5V vers USB 5V DC Boost Step-up
× 1
Hub Solaire Tout-en-Un : Régulateur de Charge, Onduleur, Power Bank et Lampe LED
Transistor NPN Usage Général
× 1
Transformateur à Prise Centrale 12-0-12/220
× 1
Hub Solaire Tout-en-Un : Régulateur de Charge, Onduleur, Power Bank et Lampe LED
1N4007 – Diode Haute Tension, Fort Courant
× 1
Hub Solaire Tout-en-Un : Régulateur de Charge, Onduleur, Power Bank et Lampe LED
Male-Header 36 Positions 1 Rangée - Long (0,1")
× 1
Hub Solaire Tout-en-Un : Régulateur de Charge, Onduleur, Power Bank et Lampe LED
Interrupteur à Glissière
× 1
Hub Solaire Tout-en-Un : Régulateur de Charge, Onduleur, Power Bank et Lampe LED
Bouton Poussoir SparkFun 12mm
× 1
Hub Solaire Tout-en-Un : Régulateur de Charge, Onduleur, Power Bank et Lampe LED
Arduino Proto Shield
× 1
Plaque Strip/Vero/Proto 8x11 cm
× 1
Hub Solaire Tout-en-Un : Régulateur de Charge, Onduleur, Power Bank et Lampe LED
Arduino UNO
× 1
Hub Solaire Tout-en-Un : Régulateur de Charge, Onduleur, Power Bank et Lampe LED
Arduino Nano R3
× 1
Hub Solaire Tout-en-Un : Régulateur de Charge, Onduleur, Power Bank et Lampe LED
Arduino Mega 2560
× 1
Diode Schottky Basse Tension 5822
× 1
Hub Solaire Tout-en-Un : Régulateur de Charge, Onduleur, Power Bank et Lampe LED
Condensateur 10 µF
× 1
Hub Solaire Tout-en-Un : Régulateur de Charge, Onduleur, Power Bank et Lampe LED
Condensateur 100 nF
× 1

Outils et Machines Nécessaires

Hub Solaire Tout-en-Un : Régulateur de Charge, Onduleur, Power Bank et Lampe LED
Fer à souder (générique)
Perceuse
Hub Solaire Tout-en-Un : Régulateur de Charge, Onduleur, Power Bank et Lampe LED
Pistolet à colle chaude (générique)

Applications et Services en Ligne

Hub Solaire Tout-en-Un : Régulateur de Charge, Onduleur, Power Bank et Lampe LED
Arduino IDE
AutoDesk 123D

À Propos de ce Projet

À Propos de ce Projet

J'ai quelques panneaux solaires, batteries 12 Volts, transformateurs et quelques autres trucs qui traînent depuis un moment, criant qu'il fallait en faire bon usage. Ainsi est né cet appareil - une solution PV complète et compacte sur une seule carte. Passons en revue d'abord ce qui fait quoi, voulez-vous ?

  • Un régulateur de charge est un dispositif qui régule la charge du stockage DC/batterie à partir d'un panneau solaire photovoltaïque et la décharge de la batterie par la charge pour prolonger la durée de vie de la batterie.
  • Un onduleur est un dispositif qui convertit l'électricité sous forme DC en forme AC pour faire fonctionner des charges AC.
  • Une Power Bank fournit une alimentation 5V DC via port USB aux gadgets/appareils mobiles pour une charge portable ou hors réseau.
  • Une lampe d'urgence est une source de lumière LED super brillante qui peut être utilisée lors de coupures de courant, camping, activités de plein air après le crépuscule.

Cet appareil que j'ai fait a toutes ces fonctionnalités, les deux dernières étant supportées indépendamment par la batterie Li-ion embarquée. Avec un panneau solaire (jusqu'à 100 Watt), une batterie plomb-acide 12 Volts et un transformateur — toutes les options peuvent être utilisées.

Version Prototype sur Uno

La première version a été développée sur une carte Uno avec le matériel minimum et les options minimales. L'écran Nokia était monté directement et un shield MOSFET a été développé pour supporter la charge/décharge de la batterie. Il n'y a pas de contrôle de menu, pas d'onduleur, pas de charge PWM et pas de fonctionnalités sympas ! Juste charge on/off et affichage des niveaux de tension batterie et panneau. Ça fait le job mais n'a pas de charme !

Hub Solaire Tout-en-Un : Régulateur de Charge, Onduleur, Power Bank et Lampe LED

Version Complète sur Plaque d'Essai

Ensuite, j'ai développé cette nouvelle version avec les fonctionnalités suivantes :

  • Régulateur de Charge Solaire PWM jusqu'à 100 Watt Panneau
  • Onduleur Mini 60 Watt à Onde Carrée
  • Jusqu'à trois contrôles de charge 12 Volts DC
  • Charge DC primaire supporte les fonctions marche/arrêt auto
  • Power Bank USB Indépendante
  • Module Régulateur Buck
  • Lampe LED Embarquée d'Urgence avec Clignotement et Contrôle de Luminosité

Contrôle de menu à 2 boutons/interrupteurs basé sur défilement et sélection pour le contrôle utilisateur, affichant les options et informations de statut sur l'écran Nokia 5110. Très Cool ! Le dos est isolé à la colle chaude pour protection contre les courts-circuits avec des objets métalliques !

Il y a quelques fonctionnalités pratiques supplémentaires comme un interrupteur marche/arrêt pour le rétroéclairage de l'affichage, séparant le buck pour un fonctionnement indépendant en le déconnectant de la batterie interne.

Hub Solaire Tout-en-Un : Régulateur de Charge, Onduleur, Power Bank et Lampe LED
Hub Solaire Tout-en-Un : Régulateur de Charge, Onduleur, Power Bank et Lampe LED
Hub Solaire Tout-en-Un : Régulateur de Charge, Onduleur, Power Bank et Lampe LED
Hub Solaire Tout-en-Un : Régulateur de Charge, Onduleur, Power Bank et Lampe LED

L'accès au menu sur l'écran Nokia 5110 avec le bouton utilisateur est montré ici :

Apprenons Quelques Choses Techniques !

Le régulateur de charge peut être de type On/Off, PWM ou MPPT. On/Off est la forme la plus simple (ma version 1 - image ci-dessus) de contrôleur qui ne limite pas le courant de charge lorsque la tension de la batterie approche sa tension de charge complète.

Alors que le PWM diminue progressivement le courant de charge à mesure que la batterie se remplit. Le contrôleur PWM a les avantages suivants :

  • Aide à récupérer la capacité de batterie perdue et à désulfater une batterie
  • Augmente la capacité de la batterie à accepter plus de charge
  • Maintient des capacités moyennes de batterie élevées jusqu'à 95 %
  • Égalise les cellules de batterie dérivantes, pour que les cellules internes puissent atteindre le même potentiel
  • Réduit l'échauffement et le dégazage de la batterie, prévenant ainsi la perte d'électrolyte
  • Ralentit le vieillissement et prolonge la durée de vie du système

Mais le PWM ne peut pas extraire la majeure partie de la puissance électrique des panneaux solaires PV, car il force le panneau à fonctionner près de la tension de la batterie. Le MPPT est la solution à ce problème qui est essentiellement un convertisseur buck-boost DC-DC ajustable, il peut convertir la majeure partie de l'énergie solaire comparé au contrôleur PWM.

Les onduleurs peuvent être de type onde carrée, onde sinusoïdale modifiée et onde sinusoïdale pure. L'onduleur à onde carrée est très simple en conception et assez bon pour de petites charges DC comme lampes AC, lampes fluocompactes, ventilateurs de table, fers à souder mais non recommandé pour moteurs inductifs, équipements/dispositifs d'alimentation délicats à cause de la distorsion harmonique.

L'onde sinusoïdale modifiée est une sorte d'onde sinusoïdale retardée créée à partir d'ondes carrées, meilleure que les onduleurs à onde carrée purs. Les onduleurs à onde sinusoïdale pure sont les meilleurs pour tous types de charges mais complexes à concevoir matériellement, algorithme logiciel difficile à faire fonctionner et coûteux à réaliser.

Un régulateur buck est un convertisseur DC-DC abaisseur, ici j'ai utilisé un module buck pour charger la batterie Li-ion 4,2 V qui alimente le contrôleur (Arduino + affichage), la power bank USB indépendante, la lampe LED embarquée.

Hub Solaire Tout-en-Un : Régulateur de Charge, Onduleur, Power Bank et Lampe LED

Maintenant, la power bank USB est essentiellement un convertisseur DC-DC boost qui peut convertir une gamme de tensions en dessous de 5 (comme 3,3 à 4,2 volts) depuis une batterie Li-ion ou LiPo vers 5 volts qui est la tension du bus USB qui peut charger les appareils mobiles.

Elle a aussi un convertisseur buck pour charger cette batterie. Dans mon projet, le module buck prend un peu de jus du panneau pour charger la batterie interne (embarquée).

Fonctionnement du Matériel

Avant d'entrer dans les détails, regardez cette image de tout ce qui est connecté autour de l'appareil :

Hub Solaire Tout-en-Un : Régulateur de Charge, Onduleur, Power Bank et Lampe LED

Le système a divers matériels pour servir différents objectifs. Bien sûr, le cerveau est le microcontrôleur AVR Atmega8A (peut être utilisé Atmega328P avec des modifications mineures, discutées ci-dessous) qui est programmé en Arduino.

Hub Solaire Tout-en-Un : Régulateur de Charge, Onduleur, Power Bank et Lampe LED

Un Atmega8A frais est flashé avec le bootloader Arduino Optiboot8, vous pouvez acheter un Arduino Mini/Atmega328 pré-flashé pour éviter les tracas.

Le contrôleur, l'affichage, la lampe LED et la power bank sont alimentés par la batterie Li-ion embarquée. Deux boutons tactiles momentanés servent à accéder au menu sur l'affichage, ce qui permet à l'utilisateur d'opérer différentes fonctions de l'appareil. Les interrupteurs sont déparasités matériellement par des condensateurs de lissage connectés en parallèle.

Un interrupteur à glissière permet d'allumer/éteindre l'appareil selon les besoins.

Hub Solaire Tout-en-Un : Régulateur de Charge, Onduleur, Power Bank et Lampe LED

La fonction de charge solaire est effectuée par un MOSFET P piloté par un circuit de pilotage basé sur transistor 2N2222 qui est contrôlé par PWM depuis le microcontrôleur. Le PWM est contrôlé en fonction du niveau de tension de la batterie externe. Le courant des panneaux solaires traverse le MOSFET P vers la batterie plomb-acide. Lorsque la batterie est complètement chargée, le MOSFET est éteint par le microcontrôleur. Après l'arrêt de la charge, la tension de la batterie commence à descendre progressivement, quand elle atteint 13,6 volts la charge reprend avec un cycle de travail faible pour maintenir la charge de flottement.

La charge 12 Volts DC est contrôlée par un MOSFET N en contrôlant sa broche Gate depuis le microcontrôleur.

Hub Solaire Tout-en-Un : Régulateur de Charge, Onduleur, Power Bank et Lampe LED

La lampe LED embarquée est aussi pilotée par un MOSFET N. La Gate de ce MOSFET est contrôlée par PWM pour l'ajustement de la luminosité de la LED.

Hub Solaire Tout-en-Un : Régulateur de Charge, Onduleur, Power Bank et Lampe LED

Le bloc onduleur consiste en 2 MOSFETs N qui sont alternativement allumés/éteints pour simuler le AC. En ajoutant un transformateur à prise centrale externe, une alimentation AC à onde carrée peut être réalisée.

Hub Solaire Tout-en-Un : Régulateur de Charge, Onduleur, Power Bank et Lampe LED

La figure suivante explique l'action de l'onduleur :

Hub Solaire Tout-en-Un : Régulateur de Charge, Onduleur, Power Bank et Lampe LED

En permettant au courant de traverser la prise centrale de la bobine d'un transformateur élévateur dans des directions opposées alternativement en utilisant les MOSFETs, une tension AC peut être créée dans le secondaire. Cela se produit parce que lorsque le MOSFET du haut est allumé et le MOSFET du bas éteint, le courant monte. Mais quand le MOSFET du haut est éteint et le MOSFET du bas allumé, le courant descend.

Les deux MOSFETs doivent être basculés à deux fois la fréquence du AC. Regardez l'image suivante pour comprendre :

Hub Solaire Tout-en-Un : Régulateur de Charge, Onduleur, Power Bank et Lampe LED

Pour créer du 50 Hz AC, une onde carrée alternative est appliquée sur le côté bas d'un transformateur 12-0-12V/220V à prise centrale. 50 Hz signifie 20 ms pour chaque onde.

C'est pourquoi 20ms/2 = 10 ms ou 100 fois basculer les signaux Gate appliqués aux MOSFETs pilotant le transformateur (MOSFETs onduleur).

Hub Solaire Tout-en-Un : Régulateur de Charge, Onduleur, Power Bank et Lampe LED
Hub Solaire Tout-en-Un : Régulateur de Charge, Onduleur, Power Bank et Lampe LED
Hub Solaire Tout-en-Un : Régulateur de Charge, Onduleur, Power Bank et Lampe LED

Attention !!! : La Tension AC est Mortelle pour l'Humain, peut causer la mort/blessure ! Ne touchez jamais le côté HT du transformateur à mains nues !

Si la fonction onduleur n'est pas utilisée, l'option 2XDC Load permet d'utiliser deux charges 12 volts DC supplémentaires au terminal onduleur.

La Magie du Logiciel

Deux ensembles de code sont fournis, l'un est le code complet dans un seul onglet Arduino, l'autre est le code par onglets selon les fonctions séparées.

J'ai généralisé des groupes de tâches en une seule fonction.

Par exemple :

Get_ADCVal() mesure les tensions Panneau, Batterie Interne et Batterie Externe, prend 20 échantillons, fait la moyenne de ces valeurs et met à jour la variable contenant l'information de tension.

Context_Control() gère l'Interaction Utilisateur, le Contrôle d'Action, la Mise à Jour d'Info sur l'Affichage.

Charging_Control(), Discharging_Control(), Load_Control() sont des fonctions d'arrière-plan qui agissent comme des BOUCLES FERMÉES pour le système, surveillent le niveau de tension de la batterie, contrôlent la fonction Charge Auto, la protection Sur/Sous-charge, etc.

Les entrées utilisateur sont collectées via des interrupteurs momentanés pilotés par interruption. Quand ces interrupteurs sont pressés, les ISR liées à INT0/INT1 sont exécutées. Deux variables volatiles dp et ds changent. Une troisième variable level avec dp (pointeur d'affichage →) et ds (sélecteur de contenu d'affichage) permet à l'utilisateur de naviguer dans le menu/sous-menu et d'effectuer l'action requise.

Le Timer1 16 bits de l'AVR est configuré pour générer une Interruption de Dépassement de Timer toutes les 10 ms et bascule PIN_INVP et PIN_INVN quand la fonction Onduleur est Activée.

Toutes les fonctions Lcd_....() ont quelque chose à voir avec le contrôle de l'affichage.

Atmega8A vs Atmega328P (Uno)

Le système peut être facilement mis à niveau pour fonctionner avec Atmega328P/Uno en faisant les modifications suivantes au code. Trouver et remplacer :

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

Dans la partie matérielle, vous devez utiliser une résistance de 8,2 kΩ au lieu de 22 kΩ pour abaisser les tensions panneau, batterie dans la plage de mesure ADC.

Vidéos d'Action

Je ne lis généralement pas seulement des mots sur un projet, au lieu de cela je vais pour la vidéo d'abord. Si vous êtes comme moi, profitez des vidéos :

Marge d'Amélioration

J'ai manqué d'espace Flash dans l'Atmega8A. Je n'ai pas pu ajouter certaines fonctionnalités critiques comme :

  • Protection Court-Circuit/Surcharge Contrôlée par Logiciel
  • Quelques Icônes Graphiques et un Logo
  • Mesure d'Énergie et Journalisation
  • Estimation et Alarme pour Temps de Secours
  • Option Charge Ordinateur Portable
  • Support pour Système 6 Volts
  • Contrôle Charge Bluetooth
  • Contrôle Charge Basé sur Minuteur
  • Une Horloge RTC pour Plus de Fonctionnalités Sympas
  • Solution Connectée IoT

Si vous avez des plans pour faire quelque chose comme ça, n'oubliez pas d'ajouter certaines de ces fonctionnalités !

Atmega328P (Uno) ou Arduino Mega pourrait être un meilleur candidat pour inclure toutes ces options.

De toute façon, ça fait le job, je suis content.

Ressources Supplémentaires

  • Télécharger Arduino 1.0.6 avec support carte Atmega8
  • Ouvrir Arduino.exe, aller à Outils > Carte > Optiboot8
  • Flasher le bootloader avec cette méthode
  • Compiler et Téléverser le Code

Code

  • Code Onglet Unique
  • Code Complet
  • Bootloaders
Code Onglet Unique 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 // 12 v dc load
#define PIN_LAMP 10 // WHITE LED LIGHT
#define PIN_BATTPWM 11 // Drives PMOS for Ext BAtt Charging
#define PIN_BATTint_Sense A2
#define PIN_SOLAR_Sense A0
#define PIN_BATText_Sense A3
#define ADC_VREF 2.695 // internal ref voltage, around 1.11V for Arduino Uno aka Atmega328P, here my Atmega8A gives this !
#define ADCVDIV_R1 22 // 22 K voltage divider lower Resistor
#define ADCVDIV_R2 175 // 175 K voltage divider upper Resistor
//const uint8_t skulljoke[] PROGMEM ={2,} ; // PIN 2 & 3 USED AS INTERRUPT SWITCH
// PIN 0 & 1 AS PROGRAMMING
// PIN RESET AS
#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;

void setup(void) {
  LcdInitialise();
  LcdClear();
  LcdString("*ARDUBOY PV*");
  LcdString(" CONTROLLER,");
  LcdString("AC INVERTER,");
  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);// Interrupt for Switch 1
  pinMode(3, INPUT_PULLUP);
  attachInterrupt(1, SW2, FALLING);// Interrupt for Switch 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);
  }
  // average voltage
  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;
}

//////////// Display and Control //////////////
void Context_Control(void) {
  if(ds==0) {show_menu();}
  if(ds==1 && dp == 0) {show_info(); delay(100);} //LcdClear();Get_ADCVal();}
  ///////////////////////Enters 1st Sub Menu////////////////////////////
  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;}
    }
  }
  //////////////////////Enters 2nd Sub Menu//////////////////////////////
  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;}
    }
  }
  /////////////////////////////////////////////////////////
  ////////////////Enters 3rd Sub Menu/////////////////////////////
  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;}
    }
  }
  /////////////////////////////////////////////////////////
  if(blinker==1) {analogWrite(PIN_LAMP,0);}
  delay(250);
  if(blinker==1) {analogWrite(PIN_LAMP,127);}
}

/////////////////////////// Menu Text to be shown on Nokia 5110 display ///////////////////
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("Batt Conn OK");} else {LcdString("Connect Batt");}
  if (PV_Voltage > 10.5 && cdc_level!=3 && cdc_level!=0) {LcdString("Charging:ON ");} else {LcdString("Charging:OFF");}
  if (TCNT1 >=45535 ) {LcdString("Inverter:ON");} else {LcdString("Inverter:OFF");}
}

void show_load_ctrl(void) {
  LcdXY(0,dp); LcdString("->");
  LcdXY(15,0); LcdString("Load Off");
  LcdXY(15,1); LcdString("Load On");
  LcdXY(15,2); LcdString("Load Auto");
  LcdXY(15,3); LcdString("Return");
  LcdXY(0,4); LcdString("Must Connect");
  LcdString("12V DC Load");
}

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("Return");
  LcdXY(0,4); LcdString("2XDC Load,NO");
  LcdXY(0,5); LcdString("TRANSFORMER!");
}

void show_led_ctrl(void) {
  LcdXY(0,dp); LcdString("->");
  LcdXY(15,0); LcdString("LED ++");
  LcdXY(15,1); LcdString("LED --");
  LcdXY(15,2); LcdString("LED Blk");
  LcdXY(15,3); LcdString("Return");
  LcdXY(0,4); LcdString("LED DISABLEs");
  LcdXY(0,5); LcdString("When INVR On");
}

////////////// Interrupt 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); // dead band
    digitalWrite(PIN_INVN,LOW);
    delayMicroseconds(1);
  }
  if(cycle==1) {
    digitalWrite(PIN_INVP,LOW);
    delayMicroseconds(1); // dead band
    digitalWrite(PIN_INVN,HIGH);
    delayMicroseconds(1);
  }
  interrupts();
}

/////////////Nokia 5110 Functions ////////////
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 ); // LCD Extended Commands.
  LcdWrite(LCD_C, 0xA0 ); // Set LCD Vop (Contrast).
  //0xB1
  LcdWrite(LCD_C, 0x04 ); // Set Temp coefficent.
  //0x04
  LcdWrite(LCD_C, 0x14 ); // LCD bias mode 1:48.
  //0x13
  LcdWrite(LCD_C, 0x20 ); // LCD Basic Commands
  LcdWrite(LCD_C, 0x0C ); // LCD in normal mode.
}

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));
}

////////////// Background Loop Control Functions ////////////
// This codelet will automatically enable external load when Sun is Down using PV as Light Sensor
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) {
  // BattExt_Voltage Level 14.3 Charging off, 13.5 or below Charging on, 10.8 Load off, 12.5 Load on
  // this next condition prevenst the attemps of charging during night % night PV is 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; }
    // Over Voltage Lockout, while cdc_level is 3, NO Charging ! Charging Resumes when cdc is 2 which is below 13.5 v
    if (BattExt_Voltage > 14.3 ) { analogWrite(PIN_BATTPWM,0); cdc_level = 3; }
  } else {analogWrite(PIN_BATTPWM,0);cdc_level = 3;}
}

/// Under voltage Lockout
void Discharging_Control (void) {
  if (BattExt_Voltage <= 10.8) {
    cdc_level = 0;
    {digitalWrite(PIN_LOAD,LOW);}
    Timer1_DeInit();
  }
}

/////////////// Timer 2 Functions //////////////
// This portion of the code is written in AVR style
void Timer1_Init(void) {
  noInterrupts(); // disable all interrupts
  pinMode(PIN_INVP,OUTPUT);
  pinMode(PIN_INVN,OUTPUT);
  TCCR1A = 0;
  TCCR1B = 0;
  /* ========================================
  50 Hz AC means 20 ms Wave which is formed by 2, 10 ms Pulses from PIN_INVP and PIN_INVN pins
  so both this pin should toggle at 100 Hz !
  Now 100 Hz = .01 sec
  Arduino System Clock 16 MHz = 16000000 cycle in 0,01 sec we have 160000 cycles
  using prescaler of 8 (CS11) makes timer count 160000/8 = 20000 timer ticks
  Since the timer 2 is 16 bit Up Counter and it Overflows at 65635 value
  we need to start counting from 65535-20000 = from 45535 value upto 65535
  thus TCNT1 starts at 45535 ..then tick tick tick ... 46000 .... 50000 .............. 65536 !!!
  Boom Timer Over Flow Interrupt and toggle the Inverter driving pins in ISR
  and start counting from 45535 Again !!!
  (This happens in the Background)
  ======================================== */
  TCNT1 = 45535; //TCNT1 = 25535;
  TCCR1B |= (1 << CS11); // 8 prescaler
  TIMSK |= (1 << TOIE1); // enable timer compare interrupt
  interrupts();
}

void Timer1_DeInit(void) {
  noInterrupts(); // disable all interrupts
  TCCR1A = 0;
  TCCR1B = 0;
  TCNT1 = 0;
  // TIMSK &= (0 << TOIE1); // disable timer compare interrupt
  digitalWrite(PIN_INVP,LOW);
  digitalWrite(PIN_INVN,LOW);
  interrupts();
}
Code Complet C/C++

Code Organisé & Lisible

Pas d'aperçu (téléchargement uniquement).
Bootloaders C/C++
Pas d'aperçu (téléchargement uniquement).

Schémas

Hub Solaire Tout-en-Un : Régulateur de Charge, Onduleur, Power Bank et Lampe LED

Processus de fabrication

  1. Qu'est-ce qu'un Onduleur Solaire ? Comment il Convertit l'Énergie Solaire en Électricité Utilisable
  2. Lampes halogènes : technologie, histoire et avenir — analyse d'expert
  3. Lampe Lave : Histoire, Design et Secrets de Fabrication
  4. Systèmes de chauffage solaire : des solutions passives aux actives pour un chauffage domestique durable
  5. Circuits intégrés (CI) : puces compactes et puissantes alimentant l'électronique moderne
  6. Cellules solaires : des premières expériences au photovoltaïque moderne – Technologie, production et perspectives
  7. Feu de circulation intelligent : Éclairage public adaptatif alimenté par l'IoT
  8. Solar Tracker V2.0 – Système avancé de suivi solaire DIY pour panneau photovoltaïque
  9. Exploiter l'énergie solaire : guide complet pour une énergie propre et fiable