/*

 

  /*

  Un Power Router est un appareil qui détecte toute énergie électrique domestique en dépassement. Si c'est le cas

  plusieurs actions peuvent être entreprises :

  - avec la fonction Triac : allumer progressivement une charge résistive qui prendra toute la

  dépasser l'énergie. Cette charge doit être résistive (lumière edison, chauffe-eau, etc...) du fait de

  le facteur de puissance qui doit rester proche de 1.

  - avec la fonction SSR : prévenir tout dépassement en effectuant un délestage : il suffit

  avant injection dans le réseau électrique public, soit une charge peut être ajoutée pour augmenter

  consommation

  L'opération est réalisée par :

  - une détection de décalage entre le courant du réseau et la tension qui détecte une consommation électrique

  ou une injection de puissance.

  - en cas d'injection, il initie l'absorption progressive par une charge résistive de tout dépassement de puissance

  - la mesure du courant permet le réglage de l'absorption

 

   Merci à Ryan McLaughlin pour sa description du triac dimming :

  https://web.archive.org/web/20091212193047/http://www.arduino.cc:80/cgi-bin/yabb2/YaBB.pl?num=1230333861/15

  _________________________________________________________________

  |

  | auteur : Philippe de Craene <dcphilippe@yahoo.fr |

  | Libre d'utilisation - Tout commentaire est le bienvenu |                                                             |

  _________________________________________________________________

//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

 PNT

  La version  3.8 de Philippe de Craene a été utilisée et adaptée pour ma version de carte électronique

 

  Version:

  PowerRouter_v3.8_PNT_V2_1 version pour la deuxieme version electronique simplifiée

  PowerRouter_v3.8_PNT_V2_2 rajout option mini switch pour puissance fixe dans la charge de 50,75,100% pour vérifier la temperature du triac

 

  Position dans le  PC voir ligne 59 "String Repertoire" . Modifier selon vos besoin

  S'affiche dans la console ainsi que la version au reset

 

  VERSION LIVREE ET INSTALLEE LE 18/09/2022 NE PLUS MODIFIER CREER UNE NOUVELLE VERSION !!!!

 

  +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

  PNT Modification de l’électronique d'origine :

  +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

  J’ai utilisé un arduino NANO. A priori de base le Watch dog ne fonctionne pas sur le nano, j'ai mis les instructions en commentaire

  J'ai remplacé les résistances des diviseurs de tension pour obtenir la tension de référence de 2.5V avec un circuit spécialisé AD584. Cela évite le calcul de ces résistances en fonction du transfo extérieur.

  Cette tension offset est mesurée sur l'entrée A3 de l'arduino pour être utilisée dans les calculs.

  J'ai remplacé le transfo extérieur qui fournit la référence tension par un transfo de courant 2mA/2mA qui débite sur une résistance de 1Kohm. Ce transfo est sur le circuit imprimé (1.20 euros les deux)

  J'ai rajouté trois switch minidip pour éviter de modifier les valeurs true et false de certaines variables sans être obligé de le faire à la main et recompiler. C’est pour mon frère , il ne sait pas faire!

 

  le triac est un module exterieur(SSR NON ZERO CROSSING), plus facile à changer, plus facile pour mettre un radiateur plus gros si necessaire;mais plus cher > 20 euros.

  Attention ils sont difficiles à trouver. Celui que j'ai acheté était un faux. En fin de compte j'en ai modifié un normal (SSR ZERO CROSSING à 3 €

  )

  Alimentation de la carte par un module 9V sur le circuit imprimé (6.52 euros les 2)

  Voilà de mémoire les principaux changements par rapport à la version d'origine. Bien sur le principal problème est la réalisation du circuit imprimé.

  Il ne me reste plus qu’a l'installer chez mon frère et faire les essais réels

 

  byte dimmax = 120;              //  valeur max de dim qui arrête le Triac

  // 128 d origine, mais avec irq sur falling, quand dim revient à 128 ca fou le bazar dans la prochaine irq. A 128 l'impulsion se trouve dans la fenetre de la detection du zéro secteur

  // Voir le doc "PROBLEME PV ROUTEUR" . J'ai conservé la solution 2(à la fin du document)

  // il me semble que Philippe de Craene à trouvé une solution plus "propre" pour un ESP32. faudrait adapter un jour!

*/

 

String nom_du_programme = "PowerRouter_v3.8_PNT_V2_2 ";

//String Repertoire = " G:/Arduino 1.8.13/ Travail/ Routeur panneaux solaire/ PVrouteur_V3.8_PNT_V2_2";// pour le retrouver plus tard dans mon bazard !

String Repertoire = " D:/Dropbox/PV-Routeur Doc/Programme Arduino/PowerRouter_V3.8_PNT_V2_2";// répertoire de livraison

 

#include <EEPROM.h>

#include <avr/wdt.h>    //  https://passionelectronique.fr/watchdog-arduino/

#include <TimerOne.h>   // library to install: https://github.com/PaulStoffregen/TimerOne

#include <LiquidCrystal_I2C.h>    // https://github.com/fdebrabander/Arduino-LiquidCrystal-I2C-library

// a priori j'ai celle là suite à un problème   LiquidCrystalI2C by Narco Schwatz Version 1.1.2

 

// calibration variables:

 

bool CALIBRATION = false;   // if true = adjustment of Vcalibration and Icalibration

bool VERBOSE     = false;   // if true = console display BUT VERY SLOW

bool PLOTTER     = false;

// sont positionnés par les micro switch

 

// Calibration des mesures qui dépendent du matériel. A faire une fois au début :

// d'abord : ajustez Vcalibration pour lire 230V sur la console

// après : Icalibration par comparaison avec un multimètre

// facultatif : l'étalonnage de la phase peut être ajusté à l'aide d'un wattmètre

 

 

//float Vcalibration     = 1.17;   // to obtain 230V premier jet 225 V

//float Vcalibration     = 1.19;   // to obtain 230V deuxieme jet 229.7 V

float Vcalibration     = 1.20;   // to obtain 230V premier jet 231.6 V >>>OK

 

float Icalibration     = 45.8;   // pour ajuster la lecture actuelle à la réalité >>0.31A ampoule de 75W OK

 

float phasecalibration = 1.9;    // pour corriger le déphasage dû au matériel

byte totalCount        = 20;     // nombre de demi-périodes utilisées du cycle de mesure

 

// PNT +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

float offset = 512;// PNT sera mesuré en temps réel en fonctionnement

 

// seuils de puissance en Watts

int limitP    = 5;  // hystérésis de tolérance pour l'action Triac : si 1 => la sensibilité est de +1W/-1W,

 

bool Test_triac = false ;

 

// Niveau de réactance pour calculer le dimstep :

// dimstep évolue par le facteur 'puissance à dissiper'/niveau de réactance

// c'est un compromis entre vitesse de réaction et instabilité :

// trop petit = risque d'instabilité, trop élevé = plus lent

// aide au calcul : niveau de réactance ~ (puissance de dissipation de la charge en watts)/40 >>>PNT j'ai pas utilisé

unsigned int coefdeReaction  = 3;//

 

// Arduino inputs and outputs

// entrées logiques

 

const byte miniDip1         =  6;    // miniDip pour choisir des options poids 1

const byte miniDip2         =  7;    // miniDip pour choisir des options poids 2

const byte miniDip3         =  8;    // miniDip pour choisir des options poids 4

 

const byte zeroCrossPin     =  2;    //variable for interruptions (zero-crossing) :

 

//sorties

const byte triacLedPin      =  3;    // LED display Triac activity

const byte test5            = 9;    // libre pour test et controle

const byte triacPin         = 10;    // pwm output to Triac gate /Cmd triac / test4

const byte test3            = 12;    // libre pour test et controle

const byte limitLedPin      = 13;    // LED for power overflow

 

// entrées analogiques

const byte currentSensorPin =  0;    // input from current sensor

const byte voltageSensorPin =  1;    // input from voltage sensor

const byte offsetSensorPin  =  3;    // input mesure tension offset

 

byte dimmax = 120;              //  valeur max de dim qui arrête le Triac

// 128 d origine, mais ave irq sur falling, quand dim revient à 128 ca fou le bazar dans la prochaine irq.

 

byte dim = dimmax;              // Dimming level (0-128)  0 = on, 128 = 0ff

char periodStep = 75;           // value of the timer (65 for 60Hz, 78 for 50Hz, in µs)// valeur du timer (65 pour 60Hz, 78 pour 50Hz, en µs)

// according the formula (500000/AC_freq)/NumSteps = periodStep // selon la formule (500000/AC_freq)/NumSteps = periodStep

// 78*128=10ms=1/2 period 50Hz but in fact 75 works better// 78*128=10ms=1/2 période 50Hz mais en fait 75 marche mieux

 

volatile int i = 0;             // Variable to use as a counter

 

volatile bool zero_cross = false;       // zero-cross detected for driving the Triac

volatile bool zero_cross_flag = false;  // zero-cross detected for power calcultion

 

// variables for electrical mesasures

int readV, memo_readV, readI = 0;       // voltage and current in bits (0 à 1023 bits)

float rPower = 0;

float V, I, sqV, sumV = 0, sqI, sumI = 0, instP, sumP = 0;

 

//float tension_REF = 4.97 ;// version 1 valeur mesurée sur la pin ref arduino,ne sert à rien mais intellectuellement parlant j'aime bien!

//float tension_REF = 5.03 ;// version 2 arduino N°1

float tension_REF = 5.026 ;// version 2 arduino N°2

 

byte zero_crossCount = 0;               // halp-period counter

 

// other variables

 

int dimstep; // value of the increment of dim

unsigned long decompte; // décompte de la temporisation du délestage

unsigned int memo_temps = 0;

bool delestage = false; // load delestage state //état de délestage

 

//byte windows = 0;

//byte count_before_timeout = 0;

byte refresh_tempo = 2;

//byte timeout = 20;

 

// LCD declaration with I2C

// set the I2C LCD address to 0x27 for a 16 chars and 2 line display

LiquidCrystal_I2C lcd(0x27, 16, 2);

 

//PNT++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

//#include <Wire.h>

// j'ai un afficheur 4 lignes

//LiquidCrystal_I2C lcd(0x27, 20, 4); // 0X27 adresse trouvée avec PVrouteur_scanner_I2C

//PNT+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

 

//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

//                                    SETUP                               +

//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

 

void setup() // Begin setup

{

  pinMode( miniDip1 , INPUT_PULLUP);

  pinMode( miniDip2 , INPUT_PULLUP);

  pinMode( miniDip3 , INPUT_PULLUP);

 

  pinMode(triacPin, OUTPUT);            // Set the Triac pin as output

  pinMode(triacLedPin, OUTPUT);         // Set the LED pin as output

  pinMode(limitLedPin, OUTPUT);

 

  pinMode(test3, OUTPUT);

  pinMode(test5, OUTPUT);

 

  attachInterrupt(0, zero_cross_detect, FALLING); // Attach an Interupt to Pin 2 (interupt 0) for Zero Cross Detection

  // à chaque changement d'état de zeroCrossPin la fonction 'zero_cross_detect' est exécutée

  // quelque soit l'endroit où se trouvait l'exécution du programme : définition d'une interruption

  // documentation :http://www.mon-club-elec.fr/pmwiki_reference_arduino/pmwiki.php?n=Main.AttachInterrupt

 

  Timer1.initialize(periodStep); // Initialize TimerOne library for the freq we need

  //  Timer1.attachInterrupt(dim_check);//ORG

  Timer1.attachInterrupt(dim_check, periodStep); // Use the TimerOne Library to attach an interrupt

 

  // autre mode d'interruption avec la librairie TimerOne.h : à chaque periodStep écoulé dont la

  // valeur est définie en microsecondes la fonction 'dim_check' est lancée : cette interruption

  // nous assure d'actionner le triac au bon moment

 

  // EEPROM functions are used to calculate how many time the device has rebooted

  // EEPROM stored values are of type char.

  // default values in case of first use are set to 255

  unsigned char reboot_high = EEPROM.read(0);  // to get the high value of the number

  unsigned char reboot_low  = EEPROM.read(1);  // to get the low value of the number

  unsigned int reboot = (reboot_high << 8) + reboot_low;

  reboot++;

  EEPROM.update(0, highByte(reboot));

  EEPROM.update(1, lowByte(reboot));

 

  //RAZ reboot EEPROM avant livraison

//    EEPROM.update(0, highByte(0));

//    EEPROM.update(1, lowByte(0));

 

 

  //PNT

  lcd.init();  // initialize the lcd

  lcd.backlight();

 

  lcd.home();

  lcd.clear();

  //PNT

 

  // initialisation de la console

  Serial.begin(250000);

 

  // PNT++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

  if ( miniDip() == 0) // fonctionnement normal en exploitation

  {

    Serial.print ("Nom de programme = ");

    Serial.println (nom_du_programme);// permet de savoir ce qu'il y a comme programme au lancement sur la console

    Serial.print ("Repertoire = ");

    Serial.println (Repertoire);

    Serial.println ();

  }

  // PNT++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

 

  lcd.setCursor(0, 0);

  lcd.print("POWER ROUTER");

  lcd.setCursor(0, 1);

  lcd.print("is starting !");

 

  if ( miniDip() == 0) {

    Serial.println ();

    Serial.print("PLEASE NOTE : ");

    Serial.print(reboot);

    Serial.println(" total number of reboots");

    Serial.println();

    Serial.println("Ready to start ...");

    Serial.println ();

  }

  delay(500);

 

  if ( miniDip() == 0) {

    if ( VERBOSE == true ) Serial.print("  Pu (W) || dimstep |  dim ||  DELESTAGE");

    else Serial.println("It is working now !");

    Serial.println();

  }

 

  //  wdt_enable(WDTO_500MS);    // watchdog = reset if no activity longer than 500ms

  wdt_disable();// pour desactiver le watchdog //a priori ne fonctionne pas de base avec arduino nano et fou le bazar dans le boot

 

  // https://forum.arduino.cc/t/watchdog-arduino-nano/368629/5

}                // End setup

 

 

//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

//                      ZERO CROSS DETECT : gestion du passage à zéro par interruption                 +

//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

 

void zero_cross_detect() // this function is called at each zero-cross interrupt/durée 75µs

{

 

  //   digitalWrite(test5, HIGH);

  digitalWrite(test3, HIGH);   // pour vérification

  delayMicroseconds(50);

  digitalWrite(test3, LOW);

 

  zero_cross_flag = true;    // flag for the real power calculation

  zero_cross = true;         // flag to drive the Triac

 

  //   digitalWrite(test5, LOW);

}

 

 

//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

//                    DIM CHECK : drive the Triac // IRQ 10ms                                          +

//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

 

void dim_check()

 

{ // Function will fire the triac at the proper time

 

  if (zero_cross == true && dim < dimmax)  // Vérifiez d'abord pour vous assurer que le passage par zéro s'est produit, sinon ne faites rien

  {

    if (i >= dim)//i est un compteur qui définit le délai d'allumage. plus il est faible plus je vais compter

 

    {

      // Voir le doc PROBLEME PV ROUTEUR . J'ai conservé la solution 2(à la fin du document)

      //solution 1

      //      if ( dim < 10)// si dim est < 10 on rajoute un delais de 550µs pour ne pas déclencher le triac quand sa tension a ses borne est nulle > il ne déclencherait pas

      //      {

      //        delayMicroseconds(550);

      //      }

 

      digitalWrite(triacPin, HIGH); // and later the triac will fire

      delayMicroseconds(50);        // Pause briefly to ensure the triac turned on

      digitalWrite(triacPin, LOW);  // Turn off the Triac gate, but the triac stays switch on until OV

 

      i = 0;                        // Reset the counter for the next cycle

      zero_cross = false;

    }

    else i++;    // If the dimming value has not been reached, increase it

    //      Serial.println (i);

  }  // End zero_cross check

 

 

} // End dim_check function

 

//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

//    LOOP    LOOP    LOOP    LOOP    LOOP    LOOP    LOOP    LOOP    LOOP    LOOP    LOOP    LOOP    LOOP    LOOP   +

//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

void loop()

{

  //  digitalWrite(test5, HIGH);

 

  // 1ère partie : calcul de la puissance réelle relevée par les capteurs avec rPower

 

  // lecture des mini dip pour verifier si la calibration est bonne ou gerer l'affichage des commentaires

  // pour les personnes qui ne savent pas modifier un peu le code mais au minimum lancer la console arduino

 

  switch ( miniDip())

  {

    case 0: // fonctionnement normal; minidip : 000

      // digitalWrite(test5, HIGH);// durée 0.3ms fr repetition 200ms

      Test_triac = false;

      CALIBRATION  = false;   // if true = adjustment of Vcalibration and Icalibration

      VERBOSE      = false;   // if true = console display BUT VERY SLOW

      PLOTTER      = false;

      lcd.noBacklight();

      //      digitalWrite(test5, LOW);

      break;

 

    case 1: // vérification / ajustement de la calibration sur  console sérieminidip : 100

      Test_triac = false;

      CALIBRATION = true;   // if true = adjustment of Vcalibration and Icalibration

      VERBOSE     = false;   // if true = console display BUT VERY SLOW

      PLOTTER     = false;

      lcd.backlight();

      break;

 

    case 2: // utilisation de la console série minidip : 010

      Test_triac = false;

      CALIBRATION = false;   // if true = adjustment of Vcalibration and Icalibration

      VERBOSE     = true;   // if true = console display BUT VERY SLOW

      PLOTTER     = false;

      lcd.backlight();

      break;

 

    case 3:// utilistion du plotter  arduino minidip : 110

      Test_triac = false;

      CALIBRATION = false;   // if true = adjustment of Vcalibration and Icalibration

      VERBOSE     = false;   // if true = console display BUT VERY SLOW

      PLOTTER     = true; // utilisation du plotter arduino

      lcd.backlight();

      break;

 

    case 4:// fonctionnement normal avec l'allumage écran ;nminidip : 001

      Test_triac = false;

      lcd.backlight();//

      break;

 

    case 5:// Test temperature à 50% ; minidip : 101

      Test_triac = true;

      dim = 60;//3.7A 805W 35 degrés

      lcd.backlight();

      break;

 

    case 6://Test temperature à 75% ; minidip : 011

      Test_triac = true;

      dim = 30;//6.1A 1474W 39 degrés

      lcd.backlight();

      break;

 

    case 7://

      Test_triac = true;//Test temperature à 100% ; minidip : 111

      dim = 0;//7.5A 1697W 50 degrés

      lcd.backlight();

      break;

 

    default:

      break;

  }

 

  unsigned int numberOfSamples = 0;

  sumV = 0;

  sumI = 0;

  sumP = 0;

  unsigned int temps_actuel = millis() / 1000; // mesure du temps en secondes

 

  // à chaque passage à zéro de la tension du secteur réinitialisation périodique du compteur de

  // passage à zéro "zero_crossCount" lorque le nombre de cycles de mesures totalCount est atteint

 

  if ( zero_crossCount >= totalCount ) zero_crossCount = 0;

 

  // le plus grand nombre possible de mesures entre le nombre totalCount de demi-périodes

  // eux-mêmes définis par le drapeau zero-cross

 

  // processus de relevé de mesures durant le nombre défini de demi-périodes

 

  while ( zero_crossCount < totalCount )

  {

    if ( zero_cross_flag == true )

    { // incrémentation du compteur de demi-périodes secteur

      zero_cross_flag = false;

      zero_crossCount++;

    }

    numberOfSamples++;                      // comptage du nombre d'itérations

    memo_readV = readV;                     // mémorisation du relevé précédent

    readV = analogRead(voltageSensorPin);   //  mesure de V en bits - 0V = bit 512

    delayMicroseconds(50);

 

    //    if ( readV == memo_readV && readV > 509 && readV < 515 ) {  // test if no grid / test si pas de réseau >> pas bon ne tient pas compte de la valeur reelle de l'offset qui peut varier celon le hard

 

    //PNT+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

    offset = analogRead(offsetSensorPin); // on lit l offset de 2.5 V sur la pin A3

    if ( readV == memo_readV && readV > offset - 3 && readV < offset + 3  )

      //PNT+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

 

    { // test si pas de réseau

      analogWrite(triacLedPin, LOW);

      lcd.setCursor(0, 0);

      lcd.print("ABSENCE DE      ");

      lcd.setCursor(0, 1);

      lcd.print("TENSION SECTEUR ");

      delay(200);

      goto nogrid; // exit to the end of program PNT++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

    }

 

    readI = analogRead(currentSensorPin);   //  mesure de I en bits - 0A = bit 512

    // calcul des valeurs efficaces de tension et courant

    delayMicroseconds(50);

 

    if ( CALIBRATION == true ) // positionné par le soft ou les micro switch

    {

      //ne sert que pour définir la calibration de V et I

 

      offset = analogRead(offsetSensorPin); // on lit les données du pin A3

 

      sqV = (readV - offset) * (readV - offset);

      sumV += sqV; //= sumV = sumV + sqV;

      sqI = (readI - offset) * (readI - offset);

      sumI += sqI;

    }    //   end test upon CALIBRATION// fin de test sur VERBOSE

 

    //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

 

    // calcul de la puissance instantanée

 

    offset = analogRead(offsetSensorPin); // on lit les données du pin A3

    instP = ((memo_readV - offset) + phasecalibration * ((readV - offset) - (memo_readV - offset))) * (readI - offset);

    sumP += instP; // sumP = sumP + instP; //PNT pour la comprehention de la ligne

  }

  // End of while upon zero_crossCount

 

  //---------------------------------------------------------------------------------------------------------------

 

  // memorization of the values

  if ( numberOfSamples > 0 )

  {

    if ( CALIBRATION == true )// positionné par le soft ou les micro switch

    {

      V = Vcalibration * sqrt(sumV / numberOfSamples);

      I = Icalibration * sqrt(sumI / numberOfSamples);

    }

    rPower = ((Vcalibration * Icalibration * sumP ) / numberOfSamples) / 1000.0; // ici il est negatif si consomation

  }

 

  //____________________________________________________________________________________________

  // 2ème partie : calcul du taux de puissance à délester pour ne pas injecter avec dim et dimstep

  // calcul du dimstep : plus la puissance à prendre en charge est élevée, plus le dimstep sera élevé

  //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

  if ( Test_triac == false) // fonctionnement normal, sinon on ne modifie pas dim des microdip pour les tests

  {

    if ( rPower > 0 )

    {

      dimstep = rPower / 10 / coefdeReaction + 1;// donne un nombre positif ex 41

    }

    else

    {

      dimstep = 1 - rPower / 10 / coefdeReaction;// donne un nombre negatif ex -39

    }

 

    if ( rPower > limitP )// limitP  = hystérésis de tolérance pour l'action Triac

    { // injection increases, the delay to fire the Triac decreases

      if ( dim > dimstep )

      {

        dim -= dimstep;

      }

      else

      {

        dim = 0;

      }

    }

    //+++++++++++++++++++++++

    else if ( rPower < -limitP )

    { // injection decreases, the delay to fire the Triac decreases

      if ( dim + dimstep < dimmax )

      {

        dim += dimstep;

      }

      else

      {

        dim = dimmax;

      }

    }

    if ( dim < 1 )// donc dim ==0

    {

      lcd.backlight();// fait flacher l'afficheur pour attirer l'attention d'overflow

      digitalWrite(limitLedPin, HIGH);    // overload LED dim // dim 0 = on, 128 = 0ff

    }

    else

    {

      digitalWrite(limitLedPin, LOW);

    }

  }

  analogWrite(triacLedPin, dimmax - dim);            // Write the value to the LED for testing

 

 

  //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

  //                  LCD management   durée 45.8ms                         +

  //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

 

  // affichage de ce qui se passe toutes les 2 secondes car ça bouffe du temps....

 

  if ( temps_actuel >= memo_temps + refresh_tempo )

  {

    memo_temps = temps_actuel;

 

    //+++++++++++++++++++++++++++++++++++++++++++

    //durée 27.1 ms

    lcd.clear();

    lcd.setCursor(0, 0);//C L

    lcd.print("P= ");

    // lcd.print(String(-rPower, 0));//org

    lcd.print(String(rPower, 0));//PNT rPower est negatif pour de la consomation il est deja negatif dans les calculs

    lcd.print("w ");

    lcd.setCursor(10, 0);

    lcd.print("T= ");

    lcd.print( map(dim, 0, dimmax, 99, 0) );

    lcd.print("%");

    //+++++++++++++++++++++++++++++++++++++++++++

 

    //PNT

    //lcd.setCursor(0, 3);// afficheur 4 lignes

    //lcd.print("Offset = ");

    //lcd.setCursor(16, 3);

 

    //------------------------------------------------------

    //durée 20.4 ms

    lcd.setCursor(0, 1);// afficheur 2 lignes

    lcd.print("Offset= ");// durée de la ligne12 ms

    float tension = offset * (tension_REF / 1023.0);

    lcd.print (tension);

    //------------------------------------------------------

 

  }     // end of display management

 

  // console display sur arduino

  if ( CALIBRATION == true )

  {

    Serial.print(V);

    Serial.print(" V");

    Serial.print("  |  ");

 

    Serial.print(I / 1000);

    Serial.print(" A");

    Serial.print("  |  ");

 

    Serial.print(rPower);

    Serial.print(" W");

    Serial.println();

    Serial.println();

  }

 

  if ( VERBOSE == true )

  {

    Serial.print(" rPower : ");

    //    Serial.print(rPower);

    Serial.print(String(rPower, 0));//PNT rPower est negatif pour de la consomation il est deja negatif dans les calculs

    Serial.print("  ||     ");

    Serial.print("dimstep : ");

    Serial.print(dimstep);

    Serial.print("  |  ");

    Serial.print("dim : ");

    Serial.print(dim);

    Serial.print(" ||  ");

    Serial.print(" seconds : ");

    Serial.println(temps_actuel - decompte);

 

    lcd.clear();

    lcd.setCursor(0, 0);//colonne ligne

    lcd.print("P=");

    //    lcd.print(rPower);

    lcd.print(String(rPower, 0));//PNT rPower est negatif pour de la consomation il est deja negatif dans les calculs

    lcd.print("w");

 

    lcd.setCursor(8, 0);

    lcd.print("DIM= ");

    lcd.print(dim);

 

    lcd.setCursor(0, 1);//colonne ligne

    lcd.print("DIMSTEP= ");

    lcd.print(dimstep);

  }

 

  if (PLOTTER == true )

    // les instructions doivent se terminer par false, sauf la derniere qui doit se terminer par true

  {

 

    plot("dim ", dim , false);

 

    plot("rPower", rPower, true);

  }

 

  else

    // delay(1);               // required for stability

    delayMicroseconds(10);

  //  espion (); // activer et renseigner la procedure avec ce que vous voulez suivre

 

nogrid:

  // wdt_reset();                 // watchdog reset pas de watchdog avec le Nano

  delay(1);// 1 ms

}                              // end of main Loop

 

 

 

 

//PNT---------------------------------------------------------------

byte miniDip()// retourne un code de 0 à 7 suivant les positions selon les poids 1/2/4

{

  //                               1                                2                                 4

  if ( digitalRead(miniDip1   ) == 0 && digitalRead(miniDip2   ) == 0  && digitalRead(miniDip3   ) == 0) {

    return 0;

  }

 

  if ( digitalRead(miniDip1   ) == 1 && digitalRead(miniDip2   ) == 0 && digitalRead(miniDip3   ) == 0 ) {

    return 1;

  }

 

  if ( digitalRead(miniDip1   ) == 0 && digitalRead(miniDip2   ) == 1  && digitalRead(miniDip3   ) == 0) {

    return 2;

  }

 

  if ( digitalRead(miniDip1   ) == 1 && digitalRead(miniDip2   ) == 1 && digitalRead(miniDip3   ) == 0 ) {

    return 3;

  }

 

 

  if ( digitalRead(miniDip1   ) == 0 && digitalRead(miniDip2   ) == 0  && digitalRead(miniDip3   ) == 1) {

    return 4;

  }

 

  if ( digitalRead(miniDip1   ) == 1 && digitalRead(miniDip2   ) == 0 && digitalRead(miniDip3   ) == 1 ) {

    return 5;

  }

 

  if ( digitalRead(miniDip1   ) == 0 && digitalRead(miniDip2   ) == 1  && digitalRead(miniDip3   ) == 1) {

    return 6;

  }

 

  if ( digitalRead(miniDip1   ) == 1 && digitalRead(miniDip2   ) == 1 && digitalRead(miniDip3   ) == 1 ) {

    return 7;

  }

}

 

 

//------------------------------------------------------------------------------

void plot(String label, float value, bool last)

{

  Serial.print(label);// peut etre une chaine vide

  if (label != "" ) Serial.print(": ");

  Serial.print(value);

  if (last == false) Serial.print (", ");

  else Serial.println();

}

 

//+++++++++++++++++++++++++++++++++

void espion ()// mettez ce qu vous voulez voir et appeler espion à l'endroit désirer, de base il est à decommenter a la fin de LOOP

{

  //    digitalWrite(test3, HIGH);   // pour vérification

  //    digitalWrite(test3, LOW);

  //  delayMicroseconds(50);

 

  //  Serial.print ("rPower ");

  //  Serial.println (rPower);

  //  Serial.print ("limitP ");

  //  Serial.println (limitP);

 

 

  //  Serial.print ("delestON ");

  //  Serial.println (-delestON);

  //  Serial.print ("délestage ");

  //  Serial.println (delestage);

 

  //  Serial.print ("dim ");

  //  Serial.println (dim);

  //  Serial.print ("dimstep ");

  //  Serial.println (dimstep);

  //  Serial.print ("i ");

  //  Serial.println (i);

  //  //  Serial.print ("limitLedPin ");

  //  Serial.println (limitLedPin);

 

 

  Serial.print (" miniDip  ");

  Serial.println ( miniDip());

  Serial.print ("dim ");

  Serial.println (dim);

  Serial.print ("Test_triac ");

  Serial.println (Test_triac);

  Serial.println ("");

 

}