L'interface est rustique mais suffisante pour un programme dont le but est de générer un fichier trace.
C'est du spécifique pour ma config et mon modele de compteur donc même si ça marche très bien chez moi, ça devra sans doute être modifié pour fonctionner dans d'autres contextes :
Par exemple, la variable fNbWattParImp est égale à 37,5 car sur mon compteur
1600 impulsions = 1KWh donc 1 impulsion = 0,625 Wh ou 37,5 Watts minute (0,625 X 60)
mais il y aussi le port COM utilisé (COM1 dans le code) ainsi que l'histoire des +12v/-12V évoqué plus haut...
Code : Tout sélectionner
#include <stdio.h>
#include <time.h>
#include <stdlib.h>
#include <conio.h>
#include <string.h>
#include <memory.h>
#include <io.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <windows.h>
HANDLE hCOM; // handle de la sortie serie
int hTrace; // handle du fichier trace
// --------------------------------------------------------------------------------
// Ouverture du port COM et positionnement DTR à ON
// --------------------------------------------------------------------------------
int initCOM()
{
int iRet=0; // variable code retour (0=OK)
DCB dcb; // Zone stockage etat de la sortie serie
// Ouverture de COM1
// -----------------
hCOM=CreateFile("COM1",GENERIC_READ|GENERIC_WRITE,0,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,NULL);
if (hCOM==INVALID_HANDLE_VALUE)
{
// Si erreur, code retour = 1
// --------------------------
iRet=1;
}
else
{
// Si ouverture OK, DTR est mis à ON, RTS inutilisé est mis a OFF
// --------------------------------------------------------------
GetCommState(hCOM,&dcb);
dcb.fDtrControl = DTR_CONTROL_ENABLE;
dcb.fRtsControl = RTS_CONTROL_DISABLE;
SetCommState(hCOM,&dcb);
}
return iRet;
}
// --------------------------------------------------------------------------------
// Initialisation du fichier trace et écriture entete dans fichier trace
// --------------------------------------------------------------------------------
void initTrace()
{
char szBufTrace[80];
// Ouverture fichier trace.csv
// ---------------------------
hTrace=_open( "trace.csv", _O_RDWR|_O_TEXT|_O_CREAT|_O_APPEND, _S_IREAD|_S_IWRITE );
if (hTrace==-1)
{
// Si erreur, affichage erreur a l'ecran
// -------------------------------------
printf("Erreur d'ouverture du fichier trace\n");
}
else
{
// Si OK, ecriture entete dans fichier trace.csv
// ---------------------------------------------
sprintf(szBufTrace,"%s;%s;%s\n","Minute","Watts minute","Cumul KWH");
_write(hTrace,szBufTrace,strlen(szBufTrace));
printf("\n+--------+---------+---------+");
printf("\n| Minute | Watts | Cumul |");
printf("\n| | minute | KWH |");
printf("\n+--------+---------+---------+\n");
}
}
// --------------------------------------------------------------------------------
// Fonction principale
// --------------------------------------------------------------------------------
void main (int argc,char *argv[])
{
int iRet; // variable code retour
DWORD dwStatus; // Zone pour recuperer le statut de la sortie serie
DWORD dwDSRSav; // Zone contenant le precedent DSR memorise
DWORD dwDSRNew; // Zone contenant la derniere valeur de DSR
int iCompteurGlobal; // Variable contenant le nb total d'impulsions depuis le debut de la capture
int iCompteurMinute; // Variable contenant le nb d'impulsions de la minute en cours
char szBufTime[9]; // Zone contenant heure minute en cours
char szBufTimeSav[6]; // Zone contenant precedente heure minute memorisee
char szBufTrace[80]; // Zone de formatage du texte a ecrire a l'ecran ou dans le fichier
float fNbWattParImp=37.5; // Nb de Watts minute par impulsion
float fKWHGlobal; // variable contenant nb total de KWH consommes depuis le debut de la capture
float fWattMinute; // variable contenant nb de watts minute de la minute en cours
float fWattMaxiMinute; // variable contenant nb maxi de watts minute consomme
// Initialisation des variables
// ----------------------------
iCompteurMinute=0;
iCompteurGlobal=0;
dwDSRSav=0xFFFF;
fWattMaxiMinute=0.0;
// Appel fonction qui ouvre le port COM et met le DTR à 1
// ------------------------------------------------------
iRet=initCOM();
if (iRet !=0)
{
// Si erreur, affichage erreur a l'ecran
// -------------------------------------
printf("Erreur d'ouverture du port serie\n");
}
else
{
// Si initCom est OK, boucle d'attente du debut de la prochaine minute pour commencer la capture
// ---------------------------------------------------------------------------------------------
printf("Attente du debut de la prochaine minute");
_strtime(szBufTimeSav);
do
{
Sleep(500);
_strtime(szBufTime);
printf(".");
}
while (strncmp(szBufTime,szBufTimeSav,5)==0);
// Affichage ecran debut de capture
// --------------------------------
printf("\n\nDebut de capture a %s ! Frappez une touche pour arreter la capture\n",szBufTime);
// Reinit de la zone de memorisation heure:minute
// ----------------------------------------------
strcpy(szBufTimeSav,"99:99");
// Appel fonction qui cree le fichier trace (CSV)
// ----------------------------------------------
initTrace();
// Boucle tant qu'il n'y a pas de frappe clavier et pas d'erreur
// -------------------------------------------------------------
while (!kbhit() && iRet==0)
{
// Recup dans variable dwDSRNew de la valeur actuelle du DSR
// ---------------------------------------------------------------
iRet=!GetCommModemStatus(hCOM,&dwStatus);
dwDSRNew=dwStatus&MS_DSR_ON;
// Si nouvelle valeur de DSR differente de celle memorisée
// ----------------------------------------------------------
if (dwDSRNew!=dwDSRSav)
{
// on memorise la nouvelle valeur dans dwDSRSav
// --------------------------------------------
dwDSRSav=dwDSRNew;
// Si le DSR vient de passer à ON
// ------------------------------
if (dwDSRSav==MS_DSR_ON)
{
// Recuperation de heure et minute courante
// ----------------------------------------
_strtime(szBufTime);
szBufTime[5]=0;
// Si heure:minute courante differente de heure:minute memorisée...
// ---------------------------------------------------------------
if (strcmp(szBufTime,szBufTimeSav)!=0)
{
// ...et que ce n'est pas le premier passage
// -----------------------------------------
if (strcmp(szBufTimeSav,"99:99")!=0)
{
// calcul du nb de watts minute consommé dans la derniere minute
// -------------------------------------------------------------
fWattMinute=iCompteurMinute*fNbWattParImp;
// Mise à jour du nb total de KWH consommes depuis le debut de la capture
// ----------------------------------------------------------------------
fKWHGlobal=iCompteurGlobal*fNbWattParImp/60000;
// Ecriture de ces valeurs dans le fichier CSV
// -------------------------------------------
sprintf(szBufTrace,"%s;%.2f;%.2f\n",szBufTimeSav,fWattMinute,fKWHGlobal);
*strchr(szBufTrace,'.')=',';
*strchr(szBufTrace,'.')=',';
if (hTrace!=-1)
{
_write(hTrace,szBufTrace,strlen(szBufTrace));
}
// Ecriture de ces valeurs a l'ecran
// ---------------------------------
sprintf(szBufTrace,"| %s | %07.1f | %07.3f |\n",szBufTimeSav,fWattMinute,fKWHGlobal);
*strchr(szBufTrace,'.')=',';
*strchr(szBufTrace,'.')=',';
printf("%s",szBufTrace);
// Memorisation de la conso maxi
// ---------------------------------
if (fWattMinute>fWattMaxiMinute)
{
fWattMaxiMinute=fWattMinute;
}
}
// Remise a 0 du compteur d'impulsions de la minute courante
// ---------------------------------------------------------
iCompteurMinute=0;
// Mise a jour de heure:minute memorisee avec nouvelle heure:minute
// ----------------------------------------------------------------
strcpy(szBufTimeSav,szBufTime);
}
// Incrément des deux compteurs d'impulsion (minute en cours et global)
// --------------------------------------------------------------------
iCompteurMinute++;
iCompteurGlobal++;
}
}
// Rendre la main au PC pour le laisser se reposer
// -----------------------------------------------
Sleep(1);
}
// Vidage buffer clavier
// ---------------------
_getch();
// Fermeture de la sortie serie
// ----------------------------
CloseHandle(hCOM);
// Fermeture du fichier trace
// --------------------------
_close(hTrace);
// Ecriture du resume de la capture à l'ecran
// ------------------------------------------
printf("+--------+---------+---------+\n");
_strtime(szBufTime);
printf("\nFin de la capture a %s\n",szBufTime);
fKWHGlobal=iCompteurGlobal*fNbWattParImp/60000;
printf("Nb total de KWH consommes depuis le debut de la capture : %.2f\n",fKWHGlobal);
printf("Nb maxi de Watts consommes dans une minute : %.2f\n",fWattMaxiMinute);
}
// Attente frappe clavier pour sortie du programme avec remontee du code retour
// ----------------------------------------------------------------------------
printf("\nFrappez une touche pour fermer la fenetre\n");
_getch();
exit(iRet);
}
La vue d'ensemble :
L'écran en début de capture :
L'écran en fin de capture :
Le contenu du fichier CSV ouvert avec Excel. Il n'y a ensuite plus qu'à faire un graphique :