|
#include <ansi_c.h>
|
|
#include <utility.h>
|
|
#include <userint.h>
|
|
#include "smu.h"
|
|
#include "T_Batt.h"
|
|
//***************************************************************************************************
|
|
|
|
//DEFINE
|
|
#define RS232 0
|
|
#define GPIB 1
|
|
#define USB 2
|
|
#define ETH 3
|
|
|
|
#define SCPI 0
|
|
#define ARPS 1
|
|
|
|
#define CHARGE 0
|
|
#define DECHARGE 1
|
|
|
|
#define NORMAL 0
|
|
#define BOOST 1
|
|
#define CURR 0
|
|
#define POWER 1
|
|
#define VERSION "2012_11_28"
|
|
//***************************************************************************************************
|
|
|
|
//VARIABLE
|
|
int chargeonly=0;
|
|
char racine[MAX_PATHNAME_LEN];
|
|
char chn_nom[MAX_PATHNAME_LEN];
|
|
char nom_fich[MAX_PATHNAME_LEN];
|
|
FILE *fichier;
|
|
time_t t_date_heure;
|
|
time_t t_date_heure_depart;
|
|
struct tm tm;
|
|
int p_general,p_port,p_cell,p_about,barre_de_menu;
|
|
unsigned int duree;
|
|
unsigned int temps_relatif;
|
|
double x;
|
|
int mode_SMU;
|
|
struct S_rep_smu
|
|
{
|
|
char tension[13];
|
|
char sep1;
|
|
char courant[13];
|
|
char sep2;
|
|
char resistance[13];
|
|
char sep3;
|
|
char temps[13];
|
|
char sep4;
|
|
char status[13];
|
|
char sep5;
|
|
};
|
|
|
|
union U_rep_smu
|
|
{
|
|
char brut[70];
|
|
struct S_rep_smu rep_smu;
|
|
};
|
|
union U_rep_smu reponse;
|
|
struct S_COM
|
|
{
|
|
char instrDescr[255];
|
|
int typeCOM;
|
|
int numGPIB;
|
|
int numcarteGPIB;
|
|
int numCOM;
|
|
char numUSB[255];
|
|
char numETH[30];
|
|
int numcarteETH;
|
|
|
|
//RS232
|
|
int baudRate;
|
|
char dataBits;
|
|
char parity;
|
|
char stopBits;
|
|
char flow;
|
|
char termchar;
|
|
};
|
|
|
|
struct S_mode
|
|
{
|
|
int present;
|
|
struct S_COM port;
|
|
unsigned long handle;
|
|
int handleplot;
|
|
int handleprint;
|
|
char IDQuery[255];
|
|
char reponseIDQuery[255];
|
|
int language;
|
|
|
|
|
|
}control_alim,control_load,*ptr_control;
|
|
|
|
struct S_cell
|
|
{
|
|
char IDcell[255];
|
|
double vmax;
|
|
double vmaxboost;
|
|
double vmin;
|
|
|
|
double imin;
|
|
double imin_boost;
|
|
double icharge;
|
|
double icharge_boost;
|
|
double idecharge;
|
|
double decharge_power;
|
|
double charge_charge;
|
|
double charge_decharge;
|
|
|
|
double puissance_charge;
|
|
double puissance_decharge;
|
|
int cycle;
|
|
int type_cycle;
|
|
int mode;
|
|
int mode_load;
|
|
}limite;
|
|
//***************************************************************************************************
|
|
//PROTO
|
|
int check_type (int type);
|
|
int set_panel_port(void);
|
|
int init(void);
|
|
int initcom(void) ;
|
|
int init_load(void) ;
|
|
int init_alim(void);
|
|
int fnct_stop(void);
|
|
//***************************************************************************************************
|
|
|
|
//CODE
|
|
//***************************************************************************************************
|
|
/**
|
|
* @brief main
|
|
* @param main
|
|
* @return 0
|
|
* @date 01/07/2010
|
|
*
|
|
*/
|
|
int main (int argc, char *argv[])
|
|
{
|
|
if (InitCVIRTE (0, argv, 0) == 0)
|
|
return -1; /* out of memory */
|
|
if ((p_general = LoadPanel (0, "T_BATT.uir", PANEL)) < 0)
|
|
return -1;
|
|
if ((p_port = LoadPanel (p_general, "T_BATT.uir", P_PORT)) < 0)
|
|
return -1;
|
|
if ((p_cell = LoadPanel (p_general, "T_BATT.uir", P_CELL)) < 0)
|
|
return -1;
|
|
if ((p_about = LoadPanel (p_general, "T_BATT.uir", P_ABOUT)) < 0)
|
|
return -1;
|
|
if ((barre_de_menu = LoadMenuBar (p_general, "T_BATT.uir", MENUBAR)) < 0)
|
|
return -1;
|
|
|
|
DisplayPanel (p_general);
|
|
GetDir (racine);
|
|
init();
|
|
RunUserInterface ();
|
|
DiscardPanel (p_general);
|
|
|
|
//fin
|
|
if (control_alim.present==1)
|
|
smu_close(control_alim.handle);
|
|
if (control_load.present==1)
|
|
smu_close(control_load.handle);
|
|
//FERMETURE FICHIER
|
|
if(fichier)
|
|
{
|
|
fclose(fichier);
|
|
fichier=NULL;
|
|
}
|
|
return 0;
|
|
}
|
|
//***************************************************************************************************
|
|
|
|
/**
|
|
* @brief gestion du timer
|
|
* @param CVI
|
|
* @return CVI
|
|
* @date 25/02/2010
|
|
*
|
|
*/
|
|
int CVICALLBACK CVI_timer (int panel, int control, int event,
|
|
void *callbackData, int eventData1, int eventData2)
|
|
{
|
|
char buffer [1024];
|
|
char message [1024];
|
|
int nbbitlu;
|
|
double test;
|
|
double volt_alim,volt_load;
|
|
double curr_alim,curr_load;
|
|
double curr;
|
|
|
|
switch (event)
|
|
{
|
|
case EVENT_TIMER_TICK:
|
|
ProcessSystemEvents ();
|
|
//VOLT
|
|
//load
|
|
sprintf(message,"MEAS:VOLT?");
|
|
if(mode_SMU)
|
|
{
|
|
smu_WriteInstrData (control_alim.handle,message );
|
|
smu_ReadInstrData (control_alim.handle, 70,reponse.brut, &nbbitlu);
|
|
volt_load=atof(reponse.rep_smu.tension);
|
|
volt_alim= volt_load;
|
|
}else
|
|
{
|
|
|
|
smu_WriteInstrData (control_load.handle,message );
|
|
smu_ReadInstrData (control_load.handle, 70,buffer, &nbbitlu);
|
|
volt_load=atof(buffer)+0.014095;
|
|
|
|
//alim
|
|
sprintf(message,"MEAS:VOLT?");
|
|
if (control_alim.language==ARPS)
|
|
{
|
|
sprintf(message,"VOUT?");
|
|
}
|
|
smu_WriteInstrData (control_alim.handle,message );
|
|
smu_ReadInstrData (control_alim.handle, 70,buffer, &nbbitlu);
|
|
volt_alim=atof(buffer);
|
|
}
|
|
//CURR
|
|
//load
|
|
sprintf(message,"MEAS:CURR?");
|
|
if(mode_SMU)
|
|
{
|
|
smu_WriteInstrData (control_alim.handle,message );
|
|
smu_ReadInstrData (control_alim.handle, 70,reponse.brut, &nbbitlu);
|
|
curr=atof(reponse.rep_smu.courant);
|
|
}else
|
|
{
|
|
smu_WriteInstrData (control_load.handle,message );
|
|
smu_ReadInstrData (control_load.handle, 70,buffer, &nbbitlu);
|
|
curr_load=atof(buffer);
|
|
//alim
|
|
sprintf(message,"MEAS:CURR?");
|
|
if (control_alim.language==ARPS)
|
|
{
|
|
sprintf(message,"IOUT?");
|
|
}
|
|
smu_WriteInstrData (control_alim.handle,message );
|
|
smu_ReadInstrData (control_alim.handle, 70,buffer, &nbbitlu);
|
|
curr_alim=atof(buffer);
|
|
curr=curr_alim-curr_load;
|
|
}
|
|
/***********************/
|
|
//limite de tension en decharge
|
|
if(volt_load<=limite.vmin)
|
|
{
|
|
//arret LOAD
|
|
if(mode_SMU)
|
|
{
|
|
sprintf(message,"OUTP OFF");
|
|
smu_WriteInstrData (control_alim.handle,message );
|
|
sprintf(message,":SOUR:CURR:LEV %2.4E",limite.icharge); //regulmation CC charge
|
|
smu_WriteInstrData (control_alim.handle,message );
|
|
|
|
sprintf(message,"OUTP ON");
|
|
smu_WriteInstrData (control_alim.handle,message );
|
|
|
|
}else
|
|
{
|
|
sprintf(message,"INP OFF");
|
|
smu_WriteInstrData (control_load.handle,message );
|
|
|
|
//demarrage alim
|
|
//mode BOOST
|
|
if(limite.mode==BOOST)
|
|
{
|
|
//modif Vmaxboost
|
|
sprintf(message,"VOLT:LEV:IMM %2.4E",limite.vmaxboost); //regulation CV
|
|
if (control_alim.language==ARPS)
|
|
{
|
|
sprintf(message,"VSET %2.3fV",limite.vmax);
|
|
}
|
|
smu_WriteInstrData (control_alim.handle,message );
|
|
sprintf(message,"CURR:LEV:IMM %2.4E",limite.icharge_boost); //regulmation CC
|
|
if (control_alim.language==ARPS)
|
|
{
|
|
sprintf(message,"ISET %2.3fA",limite.icharge_boost);
|
|
}
|
|
smu_WriteInstrData (control_alim.handle,message );
|
|
}
|
|
|
|
sprintf(message,"OUTP ON");
|
|
if (control_alim.language==ARPS)
|
|
{
|
|
sprintf(message,"OUT ON");
|
|
}
|
|
smu_WriteInstrData (control_alim.handle,message );
|
|
}
|
|
ptr_control=&control_alim;
|
|
//nouveau cycle
|
|
limite.cycle++;
|
|
limite.type_cycle=CHARGE;
|
|
limite.charge_charge=0;
|
|
limite.puissance_charge=0;
|
|
limite.charge_decharge=0;
|
|
limite.puissance_decharge=0;
|
|
curr=limite.icharge;//courant de charge
|
|
SetCtrlVal(p_general,PANEL_DECHARGE,0.0);
|
|
SetCtrlVal(p_general,PANEL_CYCLE,limite.cycle);
|
|
|
|
//FERMETURE FICHIER
|
|
if(fichier)
|
|
{
|
|
fclose(fichier);
|
|
fichier=NULL;
|
|
|
|
//OUVERTURE FICHIER
|
|
sprintf (chn_nom, "%s\\Cell-%s-cycle%d.dat", racine,limite.IDcell,limite.cycle);
|
|
fichier = fopen (chn_nom, "w");
|
|
fprintf (fichier,"temps\tValim(V)\tVload(V)\tICell(A)");
|
|
fprintf (fichier,"\tcharge(Ah)\tdecharge(Ah)");
|
|
fprintf (fichier,"\tpuissanceIN(Wh)\tpuissanceOUT(Wh)");
|
|
fprintf (fichier,"\n");
|
|
}
|
|
/********************************/
|
|
}else
|
|
{
|
|
if( limite.type_cycle==CHARGE)
|
|
{
|
|
//limite de decharge
|
|
if(curr<=limite.imin)
|
|
{
|
|
//arret alim
|
|
sprintf(message,"OUTP OFF");
|
|
if (control_alim.language==ARPS)
|
|
{
|
|
sprintf(message,"OUT OFF");
|
|
}
|
|
smu_WriteInstrData (control_alim.handle,message );
|
|
//demarrage LOAD
|
|
if(chargeonly==0)
|
|
{
|
|
if(mode_SMU)
|
|
{
|
|
sprintf(message,":SOUR:CURR:LEV %2.4E",-1*limite.idecharge); //regulmation CC charge
|
|
smu_WriteInstrData (control_alim.handle,message );
|
|
|
|
sprintf(message,"OUTP ON");
|
|
smu_WriteInstrData (control_alim.handle,message );
|
|
}else
|
|
{
|
|
sprintf(message,"INP ON");
|
|
smu_WriteInstrData (control_load.handle,message );
|
|
ptr_control=&control_load;
|
|
}
|
|
limite.type_cycle=DECHARGE;
|
|
limite.charge_decharge=0;
|
|
limite.puissance_decharge=0;
|
|
curr=-1*limite.idecharge; //courant de decharge
|
|
} else
|
|
{
|
|
fnct_stop();
|
|
|
|
|
|
}
|
|
} else
|
|
{
|
|
//limite de charge BOOST
|
|
if(limite.mode==BOOST)
|
|
if(curr<=limite.imin_boost)
|
|
{
|
|
//modif Vmaxboost
|
|
sprintf(message,"VOLT:LEV:IMM %2.4E",limite.vmax); //regulation CV
|
|
if (control_alim.language==ARPS)
|
|
{
|
|
sprintf(message,"VSET %2.3fV",limite.vmax);
|
|
}
|
|
smu_WriteInstrData (control_alim.handle,message );
|
|
|
|
sprintf(message,"CURR:LEV:IMM %2.4E",limite.icharge); //regulmation CC
|
|
if (control_alim.language==ARPS)
|
|
{
|
|
sprintf(message,"ISET %2.3fA",limite.icharge);
|
|
}
|
|
smu_WriteInstrData (control_alim.handle,message );
|
|
}
|
|
}
|
|
}
|
|
}
|
|
if(limite.type_cycle==CHARGE)
|
|
{
|
|
|
|
limite.charge_charge=limite.charge_charge+curr;
|
|
limite.puissance_charge=limite.puissance_charge+volt_load*curr;
|
|
SetCtrlVal(p_general,PANEL_CHARGE,(limite.charge_charge/3600));
|
|
|
|
}
|
|
if(limite.type_cycle==DECHARGE)
|
|
{
|
|
limite.charge_decharge=limite.charge_decharge+curr;
|
|
limite.puissance_decharge=limite.puissance_decharge+volt_load*curr;
|
|
SetCtrlVal(p_general,PANEL_DECHARGE,(limite.charge_decharge/3600));
|
|
}
|
|
if(mode_SMU)
|
|
{
|
|
sprintf(message,"%.4fV @ %.4fA",volt_alim,curr);
|
|
SetCtrlVal(p_general,control_alim.handleprint,message);
|
|
}else
|
|
{
|
|
sprintf(message,"%.4fV @ %.4fA",volt_alim,curr_alim);
|
|
SetCtrlVal(p_general,control_alim.handleprint,message);
|
|
sprintf(message,"%.4fV @ %.4fA",volt_load,curr_load);
|
|
SetCtrlVal(p_general,control_load.handleprint,message);
|
|
}
|
|
|
|
|
|
//graph
|
|
|
|
temps_relatif++;
|
|
if(temps_relatif<=600 || (temps_relatif%15==0 && temps_relatif<=1200) || (temps_relatif%60==0 && temps_relatif>1200))
|
|
{
|
|
time (&t_date_heure);
|
|
x=t_date_heure-t_date_heure_depart;
|
|
|
|
PlotPoint (p_general, PANEL_GRAPH_V, x, volt_load, VAL_ASTERISK, VAL_GREEN);
|
|
PlotPoint (p_general, PANEL_GRAPH_I, x, curr, VAL_ASTERISK, VAL_YELLOW);
|
|
//limite
|
|
PlotPoint (p_general, PANEL_GRAPH_V, x, limite.vmax, VAL_SIMPLE_DOT, VAL_RED);
|
|
PlotPoint (p_general, PANEL_GRAPH_V, x, limite.vmin, VAL_SIMPLE_DOT, VAL_BLUE);
|
|
PlotPoint (p_general, PANEL_GRAPH_I, x, limite.icharge, VAL_SIMPLE_DOT, VAL_BLUE);
|
|
PlotPoint (p_general, PANEL_GRAPH_I, x, limite.idecharge, VAL_SIMPLE_DOT, VAL_BLUE);
|
|
PlotPoint (p_general, PANEL_GRAPH_I, x, limite.imin, VAL_ASTERISK, VAL_RED);
|
|
}
|
|
|
|
//FICHIER
|
|
if (fichier != NULL)
|
|
{
|
|
// GetSystemDate (&tm.tm_mon,&tm.tm_mday ,&tm.tm_year );
|
|
// GetSystemTime (&tm.tm_hour, &tm.tm_min,&tm.tm_sec );
|
|
// fprintf (fichier,"%d/%d/%d %d:%d:%d" ,tm.tm_mday,tm.tm_mon,tm.tm_year,tm.tm_hour,tm.tm_min,tm.tm_sec);
|
|
fprintf (fichier,"%d",temps_relatif);
|
|
fprintf (fichier,"\t%2.4E\t%2.4E\t%2.4E",volt_alim,volt_load,curr);
|
|
//conversion As -> Ah 1/3600 sample 1s
|
|
fprintf (fichier,"\t%2.4E\t%2.4E",limite.charge_charge/3600,limite.charge_decharge/3600);
|
|
fprintf (fichier,"\t%2.4E\t%2.4E",limite.puissance_charge/3600,limite.puissance_decharge/3600);
|
|
fprintf (fichier,"\n");
|
|
}
|
|
|
|
ProcessDrawEvents ();
|
|
break;
|
|
|
|
}
|
|
return 0;
|
|
}
|
|
//***************************************************************************************************
|
|
/**
|
|
* @brief fermeture panel
|
|
* @param CVI
|
|
* @return CVI
|
|
* @date 25/02/2010
|
|
*
|
|
*/
|
|
int CVICALLBACK CVI_CLOSE (int panel, int control, int event,
|
|
void *callbackData, int eventData1, int eventData2)
|
|
{
|
|
|
|
switch (event)
|
|
{
|
|
case EVENT_COMMIT:
|
|
|
|
|
|
if (panel==p_general)
|
|
{
|
|
|
|
QuitUserInterface (0);
|
|
}
|
|
else
|
|
{
|
|
HidePanel (panel);
|
|
}
|
|
break;
|
|
}
|
|
return 0;
|
|
}
|
|
//***************************************************************************************************
|
|
/**
|
|
* @brief gestion des bouton
|
|
* @param CVI
|
|
* @return CVI
|
|
* @date 25/02/2010
|
|
*
|
|
*/
|
|
|
|
int CVICALLBACK CVI_on_off (int panel, int control, int event,
|
|
void *callbackData, int eventData1, int eventData2)
|
|
{
|
|
char buffer [1024];
|
|
char message [1024];
|
|
if(event==EVENT_COMMIT)
|
|
{
|
|
if (panel==p_general)
|
|
{
|
|
switch (control)
|
|
{
|
|
case PANEL_START :
|
|
SetCtrlAttribute(p_general,PANEL_START,ATTR_DIMMED,1);
|
|
SetCtrlAttribute(p_general,PANEL_STOP,ATTR_DIMMED,0);
|
|
SetMenuBarAttribute (barre_de_menu, MENUBAR_FILE, ATTR_DIMMED, 1);
|
|
SetMenuBarAttribute (barre_de_menu, MENUBAR_CONFIG, ATTR_DIMMED, 1);
|
|
SetMenuBarAttribute (barre_de_menu, MENUBAR_HELP, ATTR_DIMMED, 1);
|
|
limite.cycle=0;
|
|
SetCtrlVal(p_general,PANEL_CYCLE,limite.cycle);
|
|
SetCtrlVal(p_general,PANEL_CHARGE,0.0);
|
|
SetCtrlVal(p_general,PANEL_DECHARGE,0.0);
|
|
fichier = NULL;
|
|
|
|
if (DirSelectPopup (racine, "Sauvegarde des donn?es", 1, 1, racine))
|
|
{
|
|
|
|
GetSystemDate (&tm.tm_mon,&tm.tm_mday ,&tm.tm_year );
|
|
GetSystemTime (&tm.tm_hour, &tm.tm_min,&tm.tm_sec );
|
|
sprintf (racine, "%s\\Cell-%s-%d_%2.2d_%2.2d-%2.2dh%2.2dm%2.2ds",racine,limite.IDcell ,tm.tm_year,tm.tm_mon,tm.tm_mday,tm.tm_hour,tm.tm_min,tm.tm_sec);
|
|
MakeDir (racine);
|
|
sprintf (chn_nom, "%s\\Cell-%s.ini", racine,limite.IDcell);
|
|
fichier = fopen (chn_nom, "w");
|
|
fprintf (fichier,"Vmax:%2.4E\n",limite.vmax);
|
|
fprintf (fichier,"Vmaxboost:%2.4E\n",limite.vmaxboost);
|
|
fprintf (fichier,"Vmin:%2.4E\n",limite.vmin);
|
|
fprintf (fichier,"Icharge:%2.4E\n",limite.icharge);
|
|
fprintf (fichier,"Icharge_boost:%2.4E\n",limite.icharge_boost);
|
|
fprintf (fichier,"Idecharge:%2.4E\n",limite.idecharge);
|
|
fprintf (fichier,"Imin:%2.4E\n",limite.imin);
|
|
fprintf (fichier,"Imin_boost:%2.4E\n",limite.imin_boost);
|
|
fprintf (fichier,"Pdecharge:%2.4E\n",limite.decharge_power);
|
|
fprintf (fichier,"%s\n",control_alim.reponseIDQuery);
|
|
fprintf (fichier,"%s\n",control_load.reponseIDQuery);
|
|
fclose(fichier);
|
|
|
|
sprintf (chn_nom, "%s\\Cell-%s-cycle%d.dat", racine,limite.IDcell,limite.cycle);
|
|
fichier = fopen (chn_nom, "w");
|
|
fprintf (fichier,"temps\tValim(V)\tVload(V)\tICell(A)");
|
|
fprintf (fichier,"\tcharge(Ah)\tdecharge(Ah)");
|
|
fprintf (fichier,"\tpuissanceIN(Wh)\tpuissanceOUT(Wh)");
|
|
fprintf (fichier,"\n");
|
|
}
|
|
|
|
|
|
//demarrage LOAD
|
|
if(mode_SMU)
|
|
{
|
|
sprintf(message,":SOUR:FUNC CURR"); // voltage source
|
|
smu_WriteInstrData (control_alim.handle,message );
|
|
//PROTECTION
|
|
sprintf(message,"VOLT:PROT %2.4E",limite.vmax);
|
|
smu_WriteInstrData (control_alim.handle,message );
|
|
sprintf(message,":SENS:VOLT:RANG %2.4E",limite.vmax);
|
|
smu_WriteInstrData (control_alim.handle,message );
|
|
sprintf(message,":SENS:VOLT:PROT %2.4E",limite.vmax);
|
|
smu_WriteInstrData (control_alim.handle,message );
|
|
sprintf(message,":SOUR:CURR:LEV %2.4E",-1*limite.idecharge);
|
|
smu_WriteInstrData (control_alim.handle,message );
|
|
}else
|
|
{
|
|
if(limite.mode_load==CURR)
|
|
sprintf(message,"CURR:RANG %2.4E;:CURR %2.4E;MODE:CURR",limite.idecharge+1.0,limite.idecharge);
|
|
if(limite.mode_load==POWER)
|
|
sprintf(message,"POW:RANG %2.4E;:POW %2.4E;MODE:POW",limite.decharge_power+1.0,limite.decharge_power);
|
|
|
|
smu_WriteInstrData (control_load.handle,message );
|
|
|
|
sprintf(message,"VOLT:RANG %2.4E;VOLT:PROT %2.4E",limite.vmax+1.0,limite.vmax);
|
|
smu_WriteInstrData (control_load.handle,message );
|
|
sprintf(message,"INP ON");
|
|
smu_WriteInstrData (control_load.handle,message );
|
|
|
|
|
|
//alim
|
|
sprintf(message,"OUTP OFF;VOLT:LEV:IMM %2.4E",limite.vmax); //regulation CV
|
|
if (control_alim.language==ARPS)
|
|
{
|
|
sprintf(message,"VSET %2.3fV",limite.vmax);
|
|
}
|
|
smu_WriteInstrData (control_alim.handle,message );
|
|
sprintf(message,"CURR:LEV:IMM %2.4E",limite.icharge); //regulmation CC
|
|
if (control_alim.language==ARPS)
|
|
{
|
|
sprintf(message,"ISET %2.3fA",limite.icharge);
|
|
}
|
|
smu_WriteInstrData (control_alim.handle,message );
|
|
}
|
|
//INITIALISATION GRAPH
|
|
//GRAPH
|
|
DeleteGraphPlot ( p_general,PANEL_GRAPH_I,-1,VAL_IMMEDIATE_DRAW);
|
|
DeleteGraphPlot ( p_general,PANEL_GRAPH_V,-1,VAL_IMMEDIATE_DRAW);
|
|
//TIMER
|
|
time (&t_date_heure_depart);
|
|
temps_relatif=0;
|
|
x=0;
|
|
limite.type_cycle=DECHARGE;
|
|
limite.charge_decharge=0;
|
|
limite.puissance_decharge=0;
|
|
//LANCEMENT TIMER
|
|
SetCtrlAttribute(p_general,PANEL_TIMER ,ATTR_ENABLED,1);
|
|
break;
|
|
case PANEL_STOP :
|
|
fnct_stop();
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (panel==p_cell)
|
|
{
|
|
switch (control)
|
|
{
|
|
case P_CELL_OK :
|
|
HidePanel (panel);
|
|
GetCtrlVal (p_cell,P_CELL_VMAX,&limite.vmax);
|
|
GetCtrlVal (p_cell,P_CELL_VMAX_BOOST,&limite.vmaxboost);
|
|
GetCtrlVal (p_cell,P_CELL_VMIN,&limite.vmin);
|
|
GetCtrlVal (p_cell,P_CELL_ICHARGE,&limite.icharge);
|
|
GetCtrlVal (p_cell,P_CELL_ICHARGE_BOOST,&limite.icharge_boost);
|
|
GetCtrlVal (p_cell,P_CELL_IDECHARGE,&limite.idecharge);
|
|
GetCtrlVal (p_cell,P_CELL_PDECHARGE,&limite.decharge_power);
|
|
GetCtrlVal (p_cell,P_CELL_IMIN,&limite.imin);
|
|
GetCtrlVal (p_cell,P_CELL_IMIN_BOOST,&limite.imin_boost);
|
|
GetCtrlVal (p_cell,P_CELL_ID,limite.IDcell);
|
|
break;
|
|
case P_CELL_BP_BOOST :
|
|
limite.mode=!limite.mode;
|
|
SetCtrlAttribute(p_cell,P_CELL_ICHARGE_BOOST,ATTR_DIMMED,!limite.mode);
|
|
SetCtrlAttribute(p_cell,P_CELL_VMAX_BOOST,ATTR_DIMMED,!limite.mode);
|
|
SetCtrlAttribute(p_cell,P_CELL_IMIN_BOOST,ATTR_DIMMED,!limite.mode);
|
|
SetCtrlAttribute(p_general,PANEL_TEXT_BOOST,ATTR_VISIBLE,limite.mode);
|
|
|
|
break;
|
|
case P_CELL_BP_LOAD :
|
|
limite.mode_load=!limite.mode_load;
|
|
SetCtrlAttribute(p_cell,P_CELL_IDECHARGE,ATTR_DIMMED,limite.mode_load);
|
|
SetCtrlAttribute(p_cell,P_CELL_PDECHARGE,ATTR_DIMMED,!limite.mode_load);
|
|
SetCtrlAttribute(p_general,PANEL_TEXT_POWER,ATTR_VISIBLE,limite.mode_load);
|
|
break;
|
|
|
|
case P_CELL_CHARGE :
|
|
chargeonly=!chargeonly;
|
|
SetCtrlVal(p_cell,P_CELL_CHARGE,chargeonly);
|
|
|
|
break;
|
|
}
|
|
}
|
|
if(panel==p_port)
|
|
{
|
|
switch (control)
|
|
{
|
|
|
|
case P_PORT_COM:
|
|
ptr_control->port.typeCOM=RS232;
|
|
check_type (RS232);
|
|
break;
|
|
case P_PORT_USB:
|
|
ptr_control->port.typeCOM=USB;
|
|
check_type (USB);
|
|
break;
|
|
case P_PORT_GPIB:
|
|
ptr_control->port.typeCOM=GPIB;
|
|
check_type (GPIB);
|
|
break;
|
|
case P_PORT_ETH:
|
|
ptr_control->port.typeCOM=ETH;
|
|
check_type (ETH);
|
|
break;
|
|
case P_PORT_OK:
|
|
HidePanel (panel);
|
|
//RS232
|
|
GetCtrlVal (p_port,P_PORT_PORCOM,&ptr_control->port.numCOM);
|
|
GetCtrlVal (p_port,P_PORT_RS232BAUD,&ptr_control->port.baudRate);
|
|
GetCtrlVal (p_port,P_PORT_RS232PARITY,&ptr_control->port.parity);
|
|
GetCtrlVal (p_port,P_PORT_RS232BITS,&ptr_control->port.dataBits);
|
|
GetCtrlVal (p_port,P_PORT_RS232STOP,&ptr_control->port.stopBits);
|
|
GetCtrlVal (p_port,P_PORT_RS232HAND,&ptr_control->port.flow);
|
|
GetCtrlVal (p_port,P_PORT_RS232TERMCHAR,&ptr_control->port.termchar);
|
|
//USB
|
|
GetCtrlVal (p_port,P_PORT_PORUSB,ptr_control->port.numUSB);
|
|
//GPIB
|
|
GetCtrlVal (p_port,P_PORT_PORGPIB,&ptr_control->port.numGPIB);
|
|
GetCtrlVal (p_port,P_PORT_PORGPIB_2,&ptr_control->port.numcarteGPIB);
|
|
//ETHER
|
|
GetCtrlVal (p_port,P_PORT_PORETH,ptr_control->port.numETH);
|
|
GetCtrlVal (p_port,P_PORT_PORETH_2,&ptr_control->port.numcarteETH);
|
|
//LANG
|
|
GetCtrlVal (p_port,P_PORT_LANG,&ptr_control->language);
|
|
initcom();
|
|
|
|
break;
|
|
|
|
}
|
|
}
|
|
}
|
|
return 0;
|
|
}
|
|
//***************************************************************************************************
|
|
/**
|
|
* @brief gestion des menus
|
|
* @param CVI
|
|
* @return CVI
|
|
* @date 25/02/2010
|
|
*
|
|
*/
|
|
void CVICALLBACK CVI_menu (int menuBar, int menuItem, void *callbackData,
|
|
int panel)
|
|
{
|
|
switch (menuItem)
|
|
{
|
|
//Menu FILE
|
|
case MENUBAR_FILE_SAVE_CFG :
|
|
if(FileSelectPopup (racine,"*.ini","*.ini", "Sauvegarde fichier ini", VAL_SAVE_BUTTON, 0, 1, 1, 1, chn_nom ))
|
|
{
|
|
fichier = fopen (chn_nom, "w");
|
|
fprintf(fichier,"Vmax:%f\n",limite.vmax);
|
|
fprintf (fichier,"Vmaxboost:%2.4E\n",limite.vmaxboost);
|
|
fprintf (fichier,"Vmin:%f\n",limite.vmin);
|
|
fprintf (fichier,"Icharge:%f\n",limite.icharge);
|
|
fprintf (fichier,"Icharge_boost:%f\n",limite.icharge_boost);
|
|
fprintf (fichier,"Idecharge:%f\n",limite.idecharge);
|
|
fprintf (fichier,"Imin:%f\n",limite.imin);
|
|
fprintf (fichier,"Imin_boost:%f\n",limite.imin_boost);
|
|
fprintf (fichier,"Pdecharge:%2.4E\n",limite.decharge_power);
|
|
fclose(fichier);
|
|
fichier=NULL;
|
|
}
|
|
break;
|
|
case MENUBAR_FILE_LOAD_CFG :
|
|
if(FileSelectPopup (racine,"*.ini","*.ini", "Lecture fichier ini", VAL_LOAD_BUTTON, 0, 1, 1, 1, chn_nom ))
|
|
{
|
|
fichier = fopen (chn_nom, "r");
|
|
fscanf(fichier,"Vmax:%lf\nVmaxboost:%lf\nVmin:%lf\nIcharge:%lf\nIcharge_boost:%lf\nIdecharge:%lf\nImin:%lf\nImin_boost:%lf\nPdecharge:%lf",&limite.vmax,&limite.vmaxboost,&limite.vmin,&limite.icharge,&limite.icharge_boost,&limite.idecharge,&limite.imin,&limite.imin_boost,&limite.decharge_power);
|
|
fclose(fichier);
|
|
fichier=NULL;
|
|
}
|
|
break;
|
|
case MENUBAR_FILE_QUIT :
|
|
QuitUserInterface (0);
|
|
break;
|
|
//Menu configuration
|
|
|
|
case MENUBAR_CONFIG_ALIM_CONFIG :
|
|
ptr_control=&control_alim;
|
|
set_panel_port();
|
|
DisplayPanel (p_port);
|
|
break;
|
|
case MENUBAR_CONFIG_LOAD_CONFIG :
|
|
ptr_control=&control_load;
|
|
set_panel_port();
|
|
DisplayPanel (p_port);
|
|
break;
|
|
case MENUBAR_CONFIG_SMU :
|
|
mode_SMU=!mode_SMU;
|
|
SetMenuBarAttribute (barre_de_menu, MENUBAR_CONFIG_SMU, ATTR_CHECKED, mode_SMU);
|
|
ptr_control=&control_alim;
|
|
set_panel_port();
|
|
DisplayPanel (p_port);
|
|
|
|
SetCtrlAttribute(p_general,PANEL_START,ATTR_DIMMED,0);
|
|
SetCtrlAttribute(p_general,PANEL_STOP,ATTR_DIMMED,0);
|
|
|
|
break;
|
|
case MENUBAR_CONFIG_CELL :
|
|
SetCtrlVal (p_cell,P_CELL_VMAX,limite.vmax);
|
|
SetCtrlVal (p_cell,P_CELL_VMAX_BOOST,limite.vmaxboost);
|
|
SetCtrlVal (p_cell,P_CELL_VMIN,limite.vmin);
|
|
SetCtrlVal (p_cell,P_CELL_ICHARGE,limite.icharge);
|
|
SetCtrlVal (p_cell,P_CELL_ICHARGE_BOOST,limite.icharge_boost);
|
|
SetCtrlVal (p_cell,P_CELL_IDECHARGE,limite.idecharge);
|
|
SetCtrlVal (p_cell,P_CELL_PDECHARGE,limite.decharge_power);
|
|
SetCtrlVal (p_cell,P_CELL_IMIN,limite.imin);
|
|
SetCtrlVal (p_cell,P_CELL_IMIN_BOOST,limite.imin_boost);
|
|
SetCtrlVal (p_cell,P_CELL_ID,limite.IDcell);
|
|
DisplayPanel (p_cell);
|
|
break;
|
|
//Menu HELP
|
|
case MENUBAR_HELP_ABOUT :
|
|
DisplayPanel (p_about);
|
|
break;
|
|
}
|
|
}
|
|
|
|
//***************************************************************************************************
|
|
/**
|
|
* @brief affichage des parametres de communication
|
|
* @param
|
|
* @return 0
|
|
* @date 25/02/2010
|
|
*
|
|
*/
|
|
int set_panel_port(void)
|
|
{
|
|
SetCtrlVal(p_port,P_PORT_IDQUERY,ptr_control->reponseIDQuery);
|
|
check_type (ptr_control->port.typeCOM);
|
|
//RS232
|
|
SetCtrlVal (p_port,P_PORT_PORCOM,ptr_control->port.numCOM);
|
|
SetCtrlVal (p_port,P_PORT_RS232BAUD,ptr_control->port.baudRate);
|
|
SetCtrlVal (p_port,P_PORT_RS232PARITY,ptr_control->port.parity);
|
|
SetCtrlVal (p_port,P_PORT_RS232BITS,ptr_control->port.dataBits);
|
|
SetCtrlVal (p_port,P_PORT_RS232STOP,ptr_control->port.stopBits);
|
|
SetCtrlVal (p_port,P_PORT_RS232HAND,ptr_control->port.flow);
|
|
SetCtrlVal (p_port,P_PORT_RS232TERMCHAR,ptr_control->port.termchar);
|
|
//USB
|
|
SetCtrlVal (p_port,P_PORT_PORUSB,ptr_control->port.numUSB);
|
|
//GPIB
|
|
SetCtrlVal (p_port,P_PORT_PORGPIB,ptr_control->port.numGPIB);
|
|
SetCtrlVal (p_port,P_PORT_PORGPIB_2,ptr_control->port.numcarteGPIB);
|
|
//ETHER
|
|
SetCtrlVal (p_port,P_PORT_PORETH,ptr_control->port.numETH);
|
|
SetCtrlVal (p_port,P_PORT_PORETH_2,ptr_control->port.numcarteETH);
|
|
//LANG
|
|
SetCtrlVal (p_port,P_PORT_LANG,ptr_control->language);
|
|
return 0;
|
|
}
|
|
//***************************************************************************************************
|
|
/**
|
|
* @brief initialisation du logiciel
|
|
* @param
|
|
* @return 0
|
|
* @date 01/07/2010
|
|
*
|
|
*/
|
|
int init(void)
|
|
{
|
|
char buffer [1024];
|
|
char message [1024];
|
|
limite.vmax=14.1; //4.2
|
|
limite.vmaxboost=14.1; //4.2
|
|
limite.vmin=10.8; //2.0
|
|
limite.icharge=0.7; //1.0
|
|
limite.icharge_boost=0;
|
|
limite.idecharge=0.7; //1.0
|
|
limite.decharge_power=0.0;
|
|
limite.imin=0.1; //0.1
|
|
limite.imin_boost=0.0; //
|
|
limite.IDcell[0]='\0';
|
|
limite.mode=NORMAL;
|
|
limite.mode_load=CURR;
|
|
mode_SMU=0;
|
|
SetCtrlVal (p_about,P_ABOUT_VERSION,VERSION);
|
|
//ALIM
|
|
if(init_alim())
|
|
SetCtrlAttribute(p_general,PANEL_PICTURE_ALIM,ATTR_DIMMED,1);
|
|
//LOAD
|
|
if(init_load())
|
|
SetCtrlAttribute(p_general,PANEL_PICTURE_LOAD,ATTR_DIMMED,1);
|
|
|
|
if((control_alim.present==0)||(control_load.present==0))
|
|
{
|
|
SetCtrlAttribute(p_general,PANEL_START,ATTR_DIMMED,1);
|
|
SetCtrlAttribute(p_general,PANEL_STOP,ATTR_DIMMED,1);
|
|
}
|
|
return 0;
|
|
}
|
|
//***************************************************************************************************
|
|
/**
|
|
* @brief initialisation de la charge LOAD
|
|
* @param
|
|
* @return 0
|
|
* @date 01/07/2010
|
|
*
|
|
*/
|
|
int init_load(void)
|
|
{
|
|
char buffer [1024];
|
|
char message [1024];
|
|
//LOAD
|
|
sprintf(control_load.IDQuery,""); //LOAD
|
|
sprintf(control_load.reponseIDQuery,"");
|
|
control_load.port.typeCOM=RS232;
|
|
control_load.port.numCOM=16;
|
|
control_load.port.baudRate=9600;
|
|
control_load.port.dataBits='8';
|
|
control_load.port.parity='E';
|
|
control_load.port.stopBits='2';
|
|
control_load.port.flow='R';
|
|
control_load.port.termchar=0x0A;
|
|
control_load.handleprint=PANEL_TXT_LOAD;
|
|
control_load.language==SCPI;
|
|
ptr_control=&control_load;
|
|
if(initcom())
|
|
return -1;
|
|
|
|
//vitesse ADC LOAD
|
|
// sprintf(message,"SET:ADC SLOW");
|
|
// smu_WriteInstrData (control_load.handle,message );
|
|
sprintf(message,"SYST:SPE SLOW");
|
|
smu_WriteInstrData (control_load.handle,message );
|
|
|
|
return 0;
|
|
}
|
|
//***************************************************************************************************
|
|
/**
|
|
* @brief initialisation de la alim
|
|
* @param
|
|
* @return 0
|
|
* @date 01/07/2010
|
|
*
|
|
*/
|
|
int init_alim(void)
|
|
{
|
|
char buffer [1024];
|
|
char message [1024];
|
|
//ALIM
|
|
sprintf(control_alim.IDQuery,""); //ALIM
|
|
sprintf(control_alim.reponseIDQuery,"");
|
|
// control_alim.port.typeCOM=GPIB;
|
|
// control_alim.port.numGPIB=8; //Agilent 8 //XFR 2
|
|
// control_alim.port.numcarteGPIB=0;
|
|
// control_alim.port.termchar=0x0D; //Agilent 0x0D //XFR 0x0D
|
|
control_alim.port.typeCOM=RS232;
|
|
control_alim.port.numCOM=1;
|
|
control_alim.port.baudRate=9600;
|
|
control_alim.port.dataBits='8';
|
|
control_alim.port.parity='E';
|
|
control_alim.port.stopBits='1';
|
|
control_alim.port.flow='N';
|
|
control_alim.port.termchar=0x0A;
|
|
|
|
control_alim.handleprint=PANEL_TXT_ALIM;
|
|
control_alim.language=SCPI; //Agilent SCPI //XFR ARPS
|
|
ptr_control=&control_alim;
|
|
|
|
if(initcom())
|
|
return -1;
|
|
|
|
//init trigger
|
|
// sprintf(message,"INIT:CONT ON");
|
|
// smu_WriteInstrData (control_alim.handle,message );
|
|
|
|
|
|
return 0;
|
|
}
|
|
//***************************************************************************************************
|
|
/**
|
|
* @brief initialisation des parametres de communication
|
|
* @param
|
|
* @return 0
|
|
* @date 25/02/2010
|
|
*
|
|
*/
|
|
int initcom(void)
|
|
{
|
|
|
|
char buffer [1024];
|
|
char message [1024];
|
|
int nbbitlu;
|
|
switch (ptr_control->port.typeCOM)
|
|
{
|
|
|
|
case RS232:
|
|
sprintf(ptr_control->port.instrDescr,"ASRL%d::INSTR::%d-%c-%c-%c-%c-%c",ptr_control->port.numCOM,ptr_control->port.baudRate,ptr_control->port.dataBits,ptr_control->port.parity,ptr_control->port.stopBits,ptr_control->port.flow,ptr_control->port.termchar);
|
|
break;
|
|
case USB:
|
|
sprintf(ptr_control->port.instrDescr,"%s",ptr_control->port.numUSB); //descripteur connection instrument);
|
|
break;
|
|
case GPIB:
|
|
sprintf(ptr_control->port.instrDescr,"GPIB%d::%d::INSTR",ptr_control->port.numcarteGPIB,ptr_control->port.numGPIB); //descripteur connection instrument);
|
|
break;
|
|
case ETH:
|
|
sprintf(ptr_control->port.instrDescr,"TCPIP%d::%s::INSTR",ptr_control->port.numcarteETH,ptr_control->port.numETH); //descripteur connection instrument);
|
|
break;
|
|
}
|
|
|
|
if(smu_init ((ViChar*)ptr_control->port.instrDescr, VI_FALSE, VI_FALSE,&ptr_control->handle ))
|
|
{
|
|
ptr_control->present=0;
|
|
return -1;
|
|
}
|
|
ptr_control->present=1;
|
|
//RESET
|
|
sprintf(message,"*RST");
|
|
if (ptr_control->language==ARPS)
|
|
{
|
|
sprintf(message,"CLR");
|
|
}
|
|
smu_WriteInstrData (ptr_control->handle,message );
|
|
//IDQUERY
|
|
sprintf(message,"*IDN?");
|
|
if (ptr_control->language==ARPS)
|
|
{
|
|
sprintf(message,"ID?");
|
|
}
|
|
smu_WriteInstrData (ptr_control->handle,message );
|
|
smu_ReadInstrData (ptr_control->handle, 100,ptr_control->reponseIDQuery, &nbbitlu);
|
|
|
|
SetCtrlVal(p_general,ptr_control->handleprint,ptr_control->reponseIDQuery);
|
|
SetCtrlVal(p_port,P_PORT_IDQUERY,ptr_control->reponseIDQuery);
|
|
|
|
return 0;
|
|
}
|
|
//***************************************************************************************************
|
|
/**
|
|
* @brief gestion des type de portCOM
|
|
* @param type
|
|
* @return 0
|
|
* @date 25/02/2010
|
|
*
|
|
*/
|
|
int check_type (int type)
|
|
{
|
|
|
|
if(type==RS232)
|
|
{
|
|
SetCtrlVal (p_port,P_PORT_COM,1);
|
|
SetCtrlAttribute(p_port,P_PORT_PORCOM,ATTR_DIMMED,0);
|
|
SetCtrlAttribute(p_port,P_PORT_RS232BAUD,ATTR_DIMMED,0);
|
|
SetCtrlAttribute(p_port,P_PORT_RS232PARITY,ATTR_DIMMED,0);
|
|
SetCtrlAttribute(p_port,P_PORT_RS232BITS,ATTR_DIMMED,0);
|
|
SetCtrlAttribute(p_port,P_PORT_RS232STOP,ATTR_DIMMED,0);
|
|
SetCtrlAttribute(p_port,P_PORT_RS232HAND,ATTR_DIMMED,0);
|
|
}else
|
|
{
|
|
SetCtrlVal (p_port,P_PORT_COM,0);
|
|
SetCtrlAttribute(p_port,P_PORT_PORCOM,ATTR_DIMMED,1);
|
|
SetCtrlAttribute(p_port,P_PORT_RS232BAUD,ATTR_DIMMED,1);
|
|
SetCtrlAttribute(p_port,P_PORT_RS232PARITY,ATTR_DIMMED,1);
|
|
SetCtrlAttribute(p_port,P_PORT_RS232BITS,ATTR_DIMMED,1);
|
|
SetCtrlAttribute(p_port,P_PORT_RS232STOP,ATTR_DIMMED,1);
|
|
SetCtrlAttribute(p_port,P_PORT_RS232HAND,ATTR_DIMMED,1);
|
|
}
|
|
if(type==USB)
|
|
{
|
|
SetCtrlVal (p_port,P_PORT_USB,1);
|
|
SetCtrlAttribute(p_port,P_PORT_PORUSB,ATTR_DIMMED,0);
|
|
}else
|
|
{
|
|
SetCtrlVal (p_port,P_PORT_USB,0);
|
|
SetCtrlAttribute(p_port,P_PORT_PORUSB,ATTR_DIMMED,1);
|
|
}
|
|
if(type==GPIB)
|
|
{
|
|
SetCtrlVal (p_port,P_PORT_GPIB,1);
|
|
SetCtrlAttribute(p_port,P_PORT_PORGPIB,ATTR_DIMMED,0);
|
|
SetCtrlAttribute(p_port,P_PORT_PORGPIB_2,ATTR_DIMMED,0);
|
|
}else
|
|
{
|
|
SetCtrlVal (p_port,P_PORT_GPIB,0);
|
|
SetCtrlAttribute(p_port,P_PORT_PORGPIB,ATTR_DIMMED,1);
|
|
SetCtrlAttribute(p_port,P_PORT_PORGPIB_2,ATTR_DIMMED,1);
|
|
}
|
|
if(type==ETH)
|
|
{
|
|
SetCtrlVal (p_port,P_PORT_ETH,1);
|
|
SetCtrlAttribute(p_port,P_PORT_PORETH,ATTR_DIMMED,0);
|
|
SetCtrlAttribute(p_port,P_PORT_PORETH_2,ATTR_DIMMED,0);
|
|
}else
|
|
{
|
|
SetCtrlVal (p_port,P_PORT_ETH,0);
|
|
SetCtrlAttribute(p_port,P_PORT_PORETH,ATTR_DIMMED,1);
|
|
SetCtrlAttribute(p_port,P_PORT_PORETH_2,ATTR_DIMMED,1);
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
int fnct_stop(void)
|
|
{
|
|
char message [1024];
|
|
//ARRET TIMER
|
|
SetCtrlAttribute(p_general,PANEL_TIMER ,ATTR_ENABLED,0);
|
|
//ARRET APPARIELS
|
|
if(mode_SMU)
|
|
{
|
|
|
|
}else
|
|
{
|
|
sprintf(message,"INP OFF");
|
|
smu_WriteInstrData (control_load.handle,message );
|
|
}
|
|
sprintf(message,"OUTP OFF");
|
|
if (control_alim.language==ARPS)
|
|
{
|
|
sprintf(message,"OUT OFF");
|
|
}
|
|
smu_WriteInstrData (control_alim.handle,message );
|
|
//FERMETURE FICHIER
|
|
if(fichier)
|
|
{
|
|
fclose(fichier);
|
|
fichier=NULL;
|
|
}
|
|
//REMISE EN PLACE UIR
|
|
SetCtrlAttribute(p_general,PANEL_TIMER ,ATTR_ENABLED,0);
|
|
SetCtrlAttribute(p_general,PANEL_START,ATTR_DIMMED,0);
|
|
SetCtrlAttribute(p_general,PANEL_STOP,ATTR_DIMMED,1);
|
|
SetMenuBarAttribute (barre_de_menu, MENUBAR_FILE, ATTR_DIMMED, 0);
|
|
SetMenuBarAttribute (barre_de_menu, MENUBAR_CONFIG, ATTR_DIMMED, 0);
|
|
SetMenuBarAttribute (barre_de_menu, MENUBAR_HELP, ATTR_DIMMED, 0);
|
|
return 0;
|
|
}
|