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 II
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.