Catégories
Arduino électronique Grafcet Projets Arduino Projets électroniques

GRAFCET | Arduino #29: La commande multisources d’un chauffage électrique – Partie III

Objectifs

  • Savoir faire la commande multisources d’une charge
  • Savoir implémenter plusieurs grafcets avec Arduino
  • Initier au découpage d’un automatise en micro Grafcet
  • Savoir commander un chauffage électrique
  • Etc.

Voir le tuto pour les détails techniques.

Grafcet I

Grafcet 1

Grafcet II

Grafcet 2

Le Programme Arduino Complet

#define VSeuil      500
#define N 128

//-------------------------------
// GRAFCET (G1)
//-------------------------------
#define NumEtapesG1 3
#define NumInG1 3
#define NumOutG1 3
#define NumTransG1 4

bool EtapesG1[NumEtapesG1];
word InputsG1[NumInG1];
word OutputsG1[NumOutG1];
bool TransG1[NumTransG1];

//-------------------------------
// GRAFCET (G2)
//-------------------------------
#define NumEtapesG2 3
#define NumInG2 4
#define NumOutG2 2
#define NumTransG2 4

#define TmaxVal 400.0 // Température Max (0.0-1023.0)
#define TminVal 100.0

bool EtapesG2[NumEtapesG2];
word InputsG2[NumInG2];
word OutputsG2[NumOutG2];
bool TransG2[NumTransG2];

void setup()
{
// Affichage
Serial.begin(115200);

// Initialisation des étapes & les E/S
InitStateIO(EtapesG1, NumEtapesG1, InputsG1, NumInG1, OutputsG1, NumOutG1, 1);
InitStateIO(EtapesG2, NumEtapesG2, InputsG2, NumInG2, OutputsG2, NumOutG2, 2);
}

void loop()
{
// 1. Activation des sorties
SetOutputs(EtapesG1, OutputsG1, 1);
SetOutputs(EtapesG2, OutputsG2, 2);

// 2. Lecture des entrées
GetInputs(InputsG1, 1);
GetInputs(InputsG2, 2);

// 3. Calcul des transitions
ComputeTrans(EtapesG1, TransG1, InputsG1, 1);
ComputeTrans(EtapesG2, TransG2, InputsG2, 2);

// 4. Mise à jour des étapes
SetupStates(EtapesG1, TransG1, 1);
SetupStates(EtapesG2, TransG2, 2);

delay(100);
}

word Analog2LogiV1(word in, word seuil)
{
if (in>=seuil) return 1;
else return 0;
}

word Analog2LogiV2(word nn, int pinAx, word seuil)
{
float somme=0.0, vmoy=0.0;

switch (pinAx)
{
case 0:
for(word i=0;i<nn; i++)somme+=(float)analogRead(A0);
vmoy=somme/(float)nn;
//Serial.print(vmoy); Serial.print(",");
if((word)vmoy>=seuil) return 1;
else return 0; break;

case 1:
for(word i=0;i<nn; i++)somme+=(float)analogRead(A1);
vmoy=somme/(float)nn;
//Serial.print(vmoy);Serial.print(","); Serial.println((float)analogRead(A1));
if((word)vmoy>=seuil) return 1;
else return 0; break;

case 2:
for(word i=0;i<nn; i++)somme+=(float)analogRead(A2);
vmoy=somme/(float)nn;
if((word)vmoy>=seuil) return 1;
else return 0; break;

case 3:
for(word i=0;i<nn; i++)somme+=(float)analogRead(A3);
vmoy=somme/(float)nn;
if((word)vmoy>=seuil) return 1;
else return 0; break;

case 4:
for(word i=0;i<nn; i++)somme+=(float)analogRead(A4);
vmoy=somme/(float)nn;
if((word)vmoy>=seuil) return 1;
else return 0; break;

case 5:
for(word i=0;i<nn; i++)somme+=(float)analogRead(A5);
vmoy=somme/(float)nn;
if((word)vmoy>=seuil) return 1;
else return 0; break;

default:
return 0;
}
}

float getMean(word nn, int pinAx)
{
float somme=0.0, vmoy=0.0;
switch (pinAx)
{
case 0:
for(word i=0;i<nn; i++)somme+=(float)analogRead(A0);
vmoy=somme/(float)nn;
return vmoy; break;

case 1:
for(word i=0;i<nn; i++)somme+=(float)analogRead(A1);
vmoy=somme/(float)nn;
return vmoy; break;

case 2:
for(word i=0;i<nn; i++)somme+=(float)analogRead(A2);
vmoy=somme/(float)nn;
return vmoy; break;

case 3:
for(word i=0;i<nn; i++)somme+=(float)analogRead(A3);
vmoy=somme/(float)nn;
return vmoy; break;

case 4:
for(word i=0;i<nn; i++)somme+=(float)analogRead(A4);
vmoy=somme/(float)nn;
return vmoy; break;

case 5:
for(word i=0;i<nn; i++)somme+=(float)analogRead(A5);
vmoy=somme/(float)nn;
return vmoy; break;

default:
return 0.0;
}
}

void InitStateIO(bool *Etapess, word numEtapess, word *Inputss,word numInn, word *Outputss, word numOutt, int num_graf)
{
switch (num_graf)
{
case 1:
// Désactivation des étapes
for(word i=0;i<numEtapess;i++)Etapess[i]=false;

// Activation d'une ou plusieurs étapes par défaut
Etapess[0]=true;

// Initialisation des entrées
for(word i=0;i<numInn;i++)Inputss[i]=false;

// Initialisation des sorties
for(word i=0;i<numOutt;i++)Outputss[i]=false;

// Init des pins des E/S
pinMode(2, INPUT); // Dcy - InputsG1[0]

// Init des pins des sorties
pinMode(3, OUTPUT); // SecSolEN - OutputsG1[0]
pinMode(5, OUTPUT); // Sec - OutputsG1[1]
pinMode(6, OUTPUT); // Sol - OutputsG1[2]
break;

case 2:
// Désactivation des étapes
for(word i=0;i<numEtapess;i++)Etapess[i]=false;

// Activation d'une ou plusieurs étapes par défaut
Etapess[0]=true;

// Initialisation des entrées
for(word i=0;i<numInn;i++)Inputss[i]=false;

// Initialisation des sorties
for(word i=0;i<numOutt;i++)Outputss[i]=false;

// Init des pins des E/S
pinMode(2, INPUT); // Dcy - InputsG2[0]

// Init des pins des sorties
pinMode(4, OUTPUT); // ChaufEN - OutputsG2[0]
pinMode(7, OUTPUT); // Chauf - OutputsG2[1]
break;

default:
break;
}
}


void SetOutputs(bool *Etapess, word *Outputss, int num_graf)
{
switch (num_graf)
{
case 1:
// Étape 0
if(Etapess[0])
{
Outputss[0]=0; // SecSolEN
Outputss[1]=0; // Sec
Outputss[2]=0; // Sol
}

// Étape 1
if(Etapess[1])
{
Outputss[0]=0; // SecSolEN
Outputss[1]=1; // Sec
Outputss[2]=0; // Sol
}

// Étape 2
if(Etapess[2])
{
Outputss[0]=1; // SecSolEN
Outputss[1]=0; // Sec
Outputss[2]=1; // Sol
}

// Mise à jour des sorties Arduino
digitalWrite(3,Outputss[0]);
digitalWrite(5,Outputss[1]);
digitalWrite(6,Outputss[2]);
break;

case 2:
// Étape 0
if(Etapess[0])
{
Outputss[0]=0; // ChaufEN
Outputss[1]=0; // Chauf
}

// Étape 1
if(Etapess[1])
{
Outputss[0]=1; // ChaufEN
Outputss[1]=1; // Chauf
}

// Étape 2
if(Etapess[2])
{
Outputss[0]=0; // ChaufEN
Outputss[1]=0; // Chauf
}

// Mise à jour des sorties Arduino
digitalWrite(4,Outputss[0]);
digitalWrite(7,Outputss[1]);
break;

default:
break;
}
}


void GetInputs(word *Inputss, int num_graf)
{
switch (num_graf)
{
case 1:
Inputss[0]=digitalRead(2); // D2
Inputss[1]=Analog2LogiV2(N,0,VSeuil); // A0
Inputss[2]=Analog2LogiV2(N,1,VSeuil); // A1
break;

case 2:
Inputss[0]=digitalRead(2); // D2
Inputss[1]=(word)getMean(N,2); // A2 (T)
Inputss[2]=(word)(Inputss[1]>=TmaxVal); // A2 (T> Tmax)
Inputss[3]=(word)(Inputss[1]<TminVal); // A2 (T< Tmin)
break;

default:
break;
}
}


void ComputeTrans(bool *Etapess, bool *Transs, word *Inputss, int num_graf)
{
switch (num_graf)
{
case 1:
Transs[0]=Etapess[0] && Inputss[0] && Inputss[1];
Transs[1]=Etapess[1] && Inputss[2];
Transs[2]=Etapess[1] && !Inputss[2] && !Inputss[1];
Transs[3]=Etapess[2] && !Inputss[2];
break;

case 2:
Transs[0]=Etapess[0] && Inputss[0];
Transs[1]=Etapess[1] && Inputss[2];
Transs[2]=Etapess[2] && !Inputss[0] && Inputss[3];
Transs[2]=Etapess[2] && Inputss[0] && Inputss[3];
break;

default:
break;
}
}



void SetupStates(bool *Etapess, bool *Transs, int num_graf)
{
switch (num_graf)
{
case 1:
// Transition 0
if(Transs[0])
{
// Activation des étapes suivantes
Etapess[1]=true;

// Désactivation des étapes précédentes
Etapess[0]=false;
}

// Transition 1
if(Transs[1])
{
// Activation des étapes suivantes
Etapess[2]=true;

// Désactivation des étapes précédentes
Etapess[1]=false;
}

// Transition 2
if(Transs[2])
{
// Activation des étapes suivantes
Etapess[0]=true;

// Désactivation des étapes précédentes
Etapess[1]=false;
}

// Transition 3
if(Transs[3])
{
// Activation des étapes suivantes
Etapess[0]=true;

// Désactivation des étapes précédentes
Etapess[2]=false;
}
break;

case 2:
// Transition 0
if(Transs[0])
{
// Activation des étapes suivantes
Etapess[1]=true;

// Désactivation des étapes précédentes
Etapess[0]=false;
}

// Transition 1
if(Transs[1])
{
// Activation des étapes suivantes
Etapess[2]=true;

// Désactivation des étapes précédentes
Etapess[1]=false;
}

// Transition 2
if(Transs[2])
{
// Activation des étapes suivantes
Etapess[0]=true;

// Désactivation des étapes précédentes
Etapess[2]=false;
}

// Transition 3
if(Transs[3])
{
// Activation des étapes suivantes
Etapess[1]=true;

// Désactivation des étapes précédentes
Etapess[2]=false;
}
break;

default:
break;
}
}

Le programme complet sera prochainement en ligne. Merci pour votre patience.

Obtenir le livre « Codage en C du GRAFCET avec ARDUINO »

Laisser un commentaire