258 lines
12 KiB
C
258 lines
12 KiB
C
//**********************************************************************************************************************************************************************************
|
|
// Fichier RESERVOIRS.C
|
|
//
|
|
// Contient toutes les fonctions liées aux réservoirs de ShipHeart
|
|
//**********************************************************************************************************************************************************************************/
|
|
|
|
// #define __DEBUG_RESERVOIRS
|
|
|
|
|
|
// Includes :
|
|
#include "main.h"
|
|
|
|
// Prototypes :
|
|
int8_t init_reservoirs(void);
|
|
void gestion_reservoirs(void);
|
|
int16_t reservoir_cle_primaire(uint16_t cle_primaire);
|
|
int16_t variable_reservoir_cle_primaire(uint16_t cle_primaire);
|
|
|
|
|
|
// Variables globales :
|
|
struct Struct_reservoirs reservoirs;
|
|
|
|
|
|
/**********************************************************************************************************************************************************************************
|
|
Fonction : Initialise les différents paramètres des reservoirs au démarrage de l'application
|
|
Reçoit : Rien
|
|
Retour : -1 si erreur, 0 sinon.
|
|
**********************************************************************************************************************************************************************************/
|
|
int8_t init_reservoirs(void)
|
|
{
|
|
//------------------------------------------------------------------------------------------------------
|
|
// Init des variables générales :
|
|
|
|
reservoirs.sequenceur.etat = ETAT_SEQUENCEUR_RESERVOIRS_INIT;
|
|
reservoirs.sequenceur.compteur = RESERVOIRS_TEMPO_INIT;
|
|
|
|
|
|
// Affichage du message de débug :
|
|
affichage_debug(__FILE__, __LINE__, "Initialisation des reservoirs\t: OK", TYPE_MESSAGE_DEBUG_OK);
|
|
return(0);
|
|
|
|
}
|
|
|
|
|
|
/**********************************************************************************************************************************************************************************
|
|
Fonction : Fonction de plus haut niveau de gestion reservoirs
|
|
Reçoit : Rien
|
|
Retour : Rien
|
|
**********************************************************************************************************************************************************************************/
|
|
void gestion_reservoirs(void)
|
|
{
|
|
uint16_t i, j;
|
|
uint16_t val_u16;
|
|
float val;
|
|
float niv;
|
|
bool flag_erreur;
|
|
char tmp[MAX_LONGUEUR_BUFFER_TEMPORAIRE_DEBUG];
|
|
|
|
if (!systeme.flag_cm3p_ready) return; // Evite que le traitement soit fait au milieu d'une reconfiguration...
|
|
|
|
switch(reservoirs.sequenceur.etat)
|
|
{
|
|
//--------------------------------------------------------
|
|
case ETAT_SEQUENCEUR_RESERVOIRS_INIT :
|
|
{
|
|
if ((systeme.flag_cm3p_ready) && // Permet de s'assurer que le cycle d'init système est terminé. En particulier, on est sûr que 'init_bdd()' puis 'annuaire_k_bus()' ont été traités.
|
|
(reservoirs.sequenceur.compteur == 0))
|
|
{
|
|
|
|
affichage_debug(__FILE__, __LINE__, "------------------RESERVOIRS INIT", TYPE_MESSAGE_DEBUG_WARNING);
|
|
|
|
reservoirs.sequenceur.etat = ETAT_SEQUENCEUR_RESERVOIRS_REPOS;
|
|
}
|
|
|
|
break;
|
|
}
|
|
|
|
//--------------------------------------------------------
|
|
case ETAT_SEQUENCEUR_RESERVOIRS_REPOS :
|
|
{
|
|
if (reservoirs.sequenceur.compteur == 0)
|
|
{
|
|
reservoirs.sequenceur.compteur = RESERVOIRS_PERIODE_MESURES;
|
|
|
|
for (i=0; i<reservoirs.nb; i++)
|
|
{
|
|
if (reservoirs.reservoirs[i].flag_validite == FALSE) continue;
|
|
|
|
flag_erreur = FALSE;
|
|
val = 0;
|
|
|
|
switch(reservoirs.reservoirs[i].type_entrees)
|
|
{
|
|
//--------------------------------------------------------------------------
|
|
case TYPE_ENTREES_AUXILIAIRES :
|
|
{
|
|
// Calcul de la valeur brute en fonction de l'état des entrées AUX :
|
|
val_u16 = 0;
|
|
for (j = 0; j < reservoirs.reservoirs[i].nb_entrees; j ++) // Boucle sur toutes les entrées du réservoir :
|
|
{
|
|
if (entrees.aux.entrees[reservoirs.reservoirs[i].no_entrees[j]].valeur == 1) val_u16 |= (1 << j);
|
|
}
|
|
reservoirs.reservoirs[i].valeur_brute = (float) val_u16; // SDIR #288 Note : on ne traite pas ici le 'flag_dde_maj_bdd' car si la valeur brute a changée, le niveau -ou l'erreur d'entrées) a changé et déclenchera la demande de MAJ...
|
|
|
|
// Détection d'électrodes mal configurées :
|
|
uint16_t masque = 1;
|
|
for (j = 0; j < (reservoirs.reservoirs[i].nb_entrees + 1); j ++)
|
|
{
|
|
if (val_u16 == (masque - 1)) break; // Permet de tester la valeur juste en-dessous des puissances de 2 : 0, 1, 3, 7, 15, 31, ...
|
|
masque <<= 1; // Permet de balayer toutes les puissances de 2 : 1, 2, 4, 8, 16, 32...
|
|
}
|
|
|
|
if (j < (reservoirs.reservoirs[i].nb_entrees + 1)) reservoirs.reservoirs[i].etat_entrees = RESERVOIRS_ETAT_ENTREES_OK; // Pas d'erreur
|
|
else // Erreur :
|
|
{
|
|
flag_erreur = TRUE;
|
|
reservoirs.reservoirs[i].etat_entrees = RESERVOIRS_ETAT_ENTREES_ELECTRODES_PLONGEES_INVERSEES;
|
|
reservoirs.reservoirs[i].flag_dde_maj_bdd = TRUE;
|
|
// break;
|
|
}
|
|
|
|
val = val_u16;
|
|
|
|
#ifdef __DEBUG_RESERVOIRS
|
|
sprintf(tmp, "Réservoir #%i : valeur brute des entrées = %.2f et état entrées = %i", (i+1), val, reservoirs.reservoirs[i].etat_entrees);
|
|
affichage_debug(__FILE__, __LINE__, tmp, TYPE_MESSAGE_DEBUG_PAR_DEFAUT);
|
|
#endif
|
|
|
|
break;
|
|
}
|
|
|
|
//--------------------------------------------------------------------------
|
|
case TYPE_ENTREES_LEVEL_SENSOR :
|
|
{
|
|
// Récupération de l'état de l'entrées Level Sensor configurée sur ce réservoir :
|
|
// NB : en V si 0-10V, en Ohms si 500R ou en mA pour tous les autres cas
|
|
val = entrees.level_sensor.entrees[reservoirs.reservoirs[i].no_entrees[0]].valeur;
|
|
|
|
// SDIR #288 : Début
|
|
if (fabs(reservoirs.reservoirs[i].valeur_brute - val) > 0)
|
|
{
|
|
reservoirs.reservoirs[i].flag_dde_maj_bdd = TRUE; // Flag pour mise à jour dans la BDD
|
|
}
|
|
|
|
reservoirs.reservoirs[i].valeur_brute = val;
|
|
// SDIR #288 : Fin
|
|
|
|
#ifdef __DEBUG_RESERVOIRS
|
|
sprintf(tmp, "Réservoir #%i : valeur brute de l'entrée = %.2f", (i+1), val);
|
|
affichage_debug(__FILE__, __LINE__, tmp, TYPE_MESSAGE_DEBUG_PAR_DEFAUT);
|
|
#endif
|
|
|
|
break;
|
|
}
|
|
|
|
//--------------------------------------------------------------------------
|
|
default :
|
|
{
|
|
sprintf(tmp, "Le 'Type_entrées' du réservoir #%i est invalide [%i]. Le réservoir est dévalidé", (i+1), reservoirs.reservoirs[i].type_entrees);
|
|
affichage_debug(__FILE__, __LINE__, tmp, TYPE_MESSAGE_DEBUG_ERREUR);
|
|
reservoirs.reservoirs[i].flag_validite = FALSE;
|
|
break;
|
|
}
|
|
}
|
|
|
|
// Traitement :
|
|
if (flag_erreur == FALSE)
|
|
{
|
|
// Calcul de la nouvelle moyenne à partir de l'ancienne et de la valeur lue :
|
|
niv = calcul_niveau(reservoirs.reservoirs[i].liste_valeurs_niveaux, MAX_NOMBRE_VALEURS_NIVEAUX_RESERVOIRS, val);
|
|
if (niv >= 0) // S'il y a une erreur lors du calcul du niveau, on ne traite pas le résultat...
|
|
{
|
|
// Calcul de la nouvelle moyenne de valeur courante à partir de l'ancienne et de la valeur lue :
|
|
reservoirs.reservoirs[i].variables[0].valeur_courante = (((reservoirs.reservoirs[i].variables[0].valeur_courante * (reservoirs.reservoirs[i].niveau_coeff_filtrage - 1))) + niv) / reservoirs.reservoirs[i].niveau_coeff_filtrage;
|
|
if (reservoirs.reservoirs[i].variables[0].valeur_courante > 100) reservoirs.reservoirs[i].variables[0].valeur_courante = 100;
|
|
|
|
// Mise à jour du cumul :
|
|
reservoirs.reservoirs[i].variables[0].cumul += reservoirs.reservoirs[i].variables[0].valeur_courante;
|
|
reservoirs.reservoirs[i].cumuls_nb_val ++; // MàJ du nombre d'échantillons dans le cumul
|
|
|
|
// Traitement si la valeur a suffisemment évolué :
|
|
// if (fabs(reservoirs.reservoirs[i].variables[0].valeur_bdd - reservoirs.reservoirs[i].variables[0].valeur_courante) >= reservoirs.variables[0].marge)
|
|
if (fabs(reservoirs.reservoirs[i].variables[0].valeur_bdd - reservoirs.reservoirs[i].variables[0].valeur_courante) > 0)
|
|
{
|
|
reservoirs.reservoirs[i].flag_dde_maj_bdd = TRUE; // Flag pour mise à jour dans la BDD
|
|
#ifdef __DEBUG_RESERVOIRS
|
|
sprintf(tmp, "Réservoir #%i : Niveau = %.2f% (coeff filtrage niveau = %i)", i, reservoirs.reservoirs[i].variables[0].valeur_courante, reservoirs.reservoirs[i].niveau_coeff_filtrage);
|
|
affichage_debug(__FILE__, __LINE__, tmp, TYPE_MESSAGE_DEBUG_PAR_DEFAUT);
|
|
#endif
|
|
}
|
|
}
|
|
else
|
|
{
|
|
sprintf(tmp, "Erreur de calcul de niveau sur réservoir #%i avec Valeur = %.3f. La valeur lue n'est pas exploitée.\n", i, val);
|
|
affichage_debug(__FILE__, __LINE__, tmp, TYPE_MESSAGE_DEBUG_WARNING);
|
|
}
|
|
|
|
|
|
// Mise à jour des valeurs BDD des variables :
|
|
if (reservoirs.reservoirs[i].flag_dde_maj_bdd)
|
|
{
|
|
for (j = 0; j < MAX_NOMBRE_VARIABLES_RESERVOIRS; j ++) reservoirs.reservoirs[i].variables[j].valeur_bdd = reservoirs.reservoirs[i].variables[j].valeur_courante;
|
|
}
|
|
}
|
|
}
|
|
|
|
}
|
|
break;
|
|
}
|
|
|
|
//--------------------------------------------------------
|
|
default :
|
|
{
|
|
sprintf(tmp, "L'état du séquenceur Réservoirs est inconnu [%i]. Il est repositionné au REPOS", reservoirs.sequenceur.etat);
|
|
affichage_debug(__FILE__, __LINE__, tmp, TYPE_MESSAGE_DEBUG_ERREUR);
|
|
reservoirs.sequenceur.etat = ETAT_SEQUENCEUR_RESERVOIRS_REPOS;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
|
|
//**********************************************************************************************************************************************************************************
|
|
// Fonction : Recherche le réservoir dont la Clé_primaire est reçue en paramètre
|
|
// Reçoit : La Cle_primaire du réservoir à rechercher
|
|
// Retourne : le numéro de réservoir correspondant (ou -1 si aucun circuit valide ne correspond). La numérotation allant de 0 à MAX_NOMBRE_RESERVOIRS - 1.
|
|
//**********************************************************************************************************************************************************************************
|
|
int16_t reservoir_cle_primaire(uint16_t cle_primaire)
|
|
{
|
|
uint16_t i;
|
|
|
|
for (i = 0; i < reservoirs.nb; i ++)
|
|
{
|
|
if ((reservoirs.reservoirs[i].cle_primaire == cle_primaire) && (reservoirs.reservoirs[i].flag_validite)) return(i);
|
|
}
|
|
return (-1); // Si on est arrivé au bout de la boucle, on renvoi le code de 'non trouvé'.
|
|
}
|
|
|
|
|
|
//**********************************************************************************************************************************************************************************
|
|
// Fonction VARIABLE_RESERVOIR_CLE_PRIMAIRE
|
|
// Reçoit en paramètre :
|
|
// - La Cle_primaire de la variable à rechercher
|
|
// Retourne :
|
|
// - le numéro de variable correspondant (ou -1 si aucune variable valide ne correspond). La numérotation allant de 0 à MAX_NOMBRE_VARIABLES_RESERVOIRS-1.
|
|
//**********************************************************************************************************************************************************************************
|
|
int16_t variable_reservoir_cle_primaire(uint16_t cle_primaire)
|
|
{
|
|
uint16_t i;
|
|
|
|
for (i=0; i<MAX_NOMBRE_VARIABLES_RESERVOIRS; i++)
|
|
{
|
|
if (reservoirs.variables[i].cle_primaire == cle_primaire) return(i);
|
|
|
|
}
|
|
return (-1); // Si on est arrivé au bout de la boucle, on renvoi le code de 'non trouvé'.
|
|
} |