Objectifs du projet

  • Introduction à la commande d’une porte blindée
  • Savoir commander un actionneur linéaire
  • Savoir lire un clavier 4×4
  • Savoir mesurer le courant d’une charge avec Arduino
  • Savoir programmer la commande d’une porte blindée
  • Test du système complet
  • Etc.

Le tuto décrit le test du système complet. Le programme complet se trouve en bas de la page.  Voir le tuto pour les détails techniques.

Architecture matérielle

Architecture matérielle de la commande d'une porte blindée

Grafcet de la gestion de la surintensité (G2)

Grafcet 2

Grafcet principal (G1)

Grafcet 1

Programme Arduino

//------------------------------- 
// GRAFCET (G1)
//-------------------------------
#define NumEtapesG1 11
#define NumInG1 8 // +1
#define NumOutG1 6 // +1
#define NumInOutG1 3 // +1
#define NumTransG1 17

bool EtapesG1[NumEtapesG1];
int InputsG1[NumInG1];
int OutputsG1[NumOutG1];
int InOutG1[NumInOutG1];
bool TransG1[NumTransG1];


//-------------------------------
// GRAFCET (G2)
//-------------------------------
#define Sens 100.0E-3 // Sensibilité en (V/A) du capteur
#define NI 16 // Taille filtrage du courant
#define Ts_ms 10 // Période d'échantillonnage du courant
#define ImaxmA 8000 // Taille filtrage du courant (6000mA=6A)

#define NumEtapesG2 3
#define NumInG2 3 // +1
#define NumOutG2 2 // +1
#define NumTransG2 4

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

//-------------------------------
// Gestion du Clavier: PORTA
//-------------------------------
#include <Keypad.h>
#define MaxChar 5 // Longeur du code
#define MaxIter 3 // Max tentative
#define TimeOutmS 3000 // Timeout code

int Code[MaxChar];
int C; // Retour de getCode()
int Verif; // Retour de verifCode()
const int CodeSecret[MaxChar]={1,1,1,1,1};
const int CodeAdmin[MaxChar]={2,2,2,2,2};

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);

// 5. Affichage

//G1
for(int i=0;i<NumInG1;i++){Serial.print(InputsG1[i]);Serial.print(",");}
Serial.print("\t");for(int i=0;i<NumEtapesG1;i++){Serial.print(EtapesG1[i]);}
Serial.print("\t");Serial.print(C);
Serial.print(",");Serial.println(Verif);


/*
//G2
for(int i=0;i<NumInG2;i++){Serial.print(InputsG2[i]);Serial.print(",");}
Serial.print("\t");for(int i=0;i<NumEtapesG2-1;i++){Serial.print(EtapesG2[i]);}
Serial.println(EtapesG2[NumEtapesG2-1]);
*/
}

int getCode(int *codeout,int num_c, unsigned long timeOut_ms,int init_val, int valid_val)
{
for(int i=0;i<num_c;i++)codeout[i]=0; // Init saisie
long Tstart=(long)millis();
int id_code=0;
while(1)
{
// Code validé
int c=lireClavier();
if(c!=-1)
{
codeout[id_code]=c;
id_code++; id_code=id_code%num_c;
if (id_code==0) return 1;
}
if(valid_val!=0)return 1;

// Init saisié
if(init_val!=0)
{
for(int i=0;i<num_c;i++)codeout[i]=0;
return -1;
}

// TimeOut
long Tstop=(long)millis();
Tstop=Tstop-Tstart;
if(Tstop>=timeOut_ms){return -1;}
}
}

int lireClavier()
{
// Num lignes/colonnes
const byte numL= 4;
const byte numC= 4;

// Map du clavier
char keymap[numL][numC]={{'1', '2', '3', 'A'},
{'4', '5', '6', 'B'},
{'7', '8', '9', 'C'},
{'*', '0', '#', 'D'}};

// MSB-PORTA: lignes 0 à 3
byte rowPins[numL] = {29,28,27,26};

// LSB-PORTA: colonnes 0 à 3
byte colPins[numC] = {25,24,23,22};

//Init Clavier
static Keypad myKeypad= Keypad(makeKeymap(keymap), rowPins, colPins, numL, numC);

// Lecture du clavier
char code = myKeypad.getKey();
if (code == NO_KEY){return -1;}
else{
switch(code){
case '0': return 0;
case '1': return 1;
case '2': return 2;
case '3': return 3;
case '4': return 4;
case '5': return 5;
case '6': return 6;
case '7': return 7;
case '8': return 8;
case '9': return 9;
default: return -10;
}
}
}

int verifCode(int *code_in, int *code_secret, int nchar)
{
int j=0;
for (int i=0;i<nchar; i++)
{
if(code_in[i]==code_secret[i])j++;
}
if(j==nchar)return 1;
else return 0;
}

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

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

// Init des pins des E/S
// Courant: A0, A1 // I - InputsG1[0]
pinMode(2, INPUT); // Dcy - InputsG1[1]
pinMode(3, INPUT); // Close - InputsG1[2]
pinMode(4, INPUT); // Init - InputsG1[3]
pinMode(5, INPUT); // Enter - InputsG1[4]
pinMode(6, INPUT); // FCH - InputsG1[5]
pinMode(7, INPUT); // FCB - InputsG1[6]
// Clavier // PORTA

pinMode(8, OUTPUT); // A+ - OutputsG1[0]
pinMode(9, OUTPUT); // A- - OutputsG1[1]
pinMode(11, OUTPUT); // A - OutputsG1[2]
pinMode(12, OUTPUT); // E - OutputsG1[3]
pinMode(13, OUTPUT); // V - OutputsG1[4]
break;

case 2:
// Désactivation des étapes
for(int 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(int i=0;i<numInn;i++)Inputss[i]=false;

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

// Init des pins des E/S
pinMode(10, OUTPUT); // Défaut - OutputsG2[0]
// Courant: A0, A1 // Courant - InputsG2[0]
//Initialisée (G1) // Init - InputsG2[1]
//Initialisée (G1) // Enter - InputsG2[2]
break;

default:
break;
}
}

void SetOutputs(bool *Etapess, int *Outputss, int num_graf)
{
switch (num_graf)
{
case 1:
// Étape 0
if(Etapess[0])
{
Outputss[0]=1; // A+
Outputss[1]=1; // A-
Outputss[2]=0; // A
Outputss[3]=0; // E
Outputss[4]=0; // V
}

// Étape 1
if(Etapess[1])
{
Outputss[0]=1; // A+
Outputss[1]=1; // A-
Outputss[2]=0; // A
Outputss[3]=0; // E
Outputss[4]=0; // V
InOutG1[0]=0; // OpenClose
}

// Étape 2
if(Etapess[2])
{
Outputss[0]=1; // A+
Outputss[1]=1; // A-
Outputss[2]=0; // A
Outputss[3]=0; // E
Outputss[4]=0; // V
InOutG1[0]=1; // OpenClose
}

// Étape 3
if(Etapess[3])
{
Outputss[0]=1; // A+
Outputss[1]=1; // A-
Outputss[2]=0; // A
Outputss[3]=0; // E
Outputss[4]=0; // V
InOutG1[0]=2; // OpenClose
}

// Étape 4
if(Etapess[4])
{
Outputss[0]=1; // A+
Outputss[1]=1; // A-
Outputss[2]=0; // A
Outputss[3]=0; // E
Outputss[4]=0; // V
// Clavier
C=getCode(Code,MaxChar, TimeOutmS,InputsG1[3], InputsG1[4]);
Verif=verifCode(Code, CodeSecret,MaxChar);
}

// Étape 5
if(Etapess[5])
{
Outputss[0]=1; // A+
Outputss[1]=1; // A-
Outputss[2]=0; // A
Outputss[3]=1; // E
Outputss[4]=0; // V
InOutG1[1]=InOutG1[1]+1; // Count
}

// Étape 6
if(Etapess[6])
{
Outputss[0]=1; // A+
Outputss[1]=0; // A-
Outputss[2]=0; // A
Outputss[3]=0; // E
Outputss[4]=1; // V
}

// Étape 7
if(Etapess[7])
{
Outputss[0]=0; // A+
Outputss[1]=1; // A-
Outputss[2]=0; // A
Outputss[3]=0; // E
Outputss[4]=1; // V
}

// Étape 8
if(Etapess[8])
{
Outputss[0]=1; // A+
Outputss[1]=1; // A-
Outputss[2]=1; // A
Outputss[3]=0; // E
Outputss[4]=0; // V
// Clavier
C=getCode(Code,MaxChar, TimeOutmS,InputsG1[3], InputsG1[4]);
Verif=verifCode(Code, CodeAdmin,MaxChar);
}

// Étape 9
if(Etapess[9])
{
Outputss[0]=1; // A+
Outputss[1]=1; // A-
Outputss[2]=0; // A
Outputss[3]=0; // E
Outputss[4]=0; // V
}

// Étape 10
if(Etapess[10])
{
Outputss[0]=1; // A+
Outputss[1]=1; // A-
Outputss[2]=0; // A
Outputss[3]=0; // E
Outputss[4]=0; // V
InOutG1[1]=0; // Count
}

// Mise à jour des sorties Arduino
digitalWrite(8,Outputss[0]);
digitalWrite(9,Outputss[1]);
digitalWrite(11,Outputss[2]);
digitalWrite(12,Outputss[3]);
digitalWrite(13,Outputss[4]);
break;

case 2:
// Étape 0
if(Etapess[0]){Outputss[0]=0;} // Défaut

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

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

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

default:
break;
}
}

void GetInputs(int *Inputss, int num_graf)
{
switch (num_graf)
{
case 1:
Inputss[0]=(int)getCourantmA(Sens, NI, Ts_ms); // I, A0,A1
Inputss[1]=digitalRead(2); // Dcy
Inputss[2]=digitalRead(3); // Close
Inputss[3]=digitalRead(4); // Init
Inputss[4]=digitalRead(5); // Enter
Inputss[5]=digitalRead(6); // FCH
Inputss[6]=digitalRead(7); // FCB
break;

case 2:
Inputss[0]=(int)getCourantmA(Sens, NI, Ts_ms); // A0,A1
Inputss[1]=digitalRead(4); // Init
Inputss[2]=digitalRead(5); // Enter
break;

default:
break;
}
}

void ComputeTrans(bool *Etapess, bool *Transs, int *Inputss, int num_graf)
{
switch (num_graf)
{
case 1:
Transs[0] =Etapess[0] && Inputss[1] && !OutputsG2[0]; //Defaut=OutputsG2[0];
Transs[1] =Etapess[1] && Inputss[5] && Inputss[6];
Transs[2] =Etapess[1] && !Inputss[5] && !Inputss[6];
Transs[3] =Etapess[3] || Etapess[2];
Transs[4] =Etapess[1] && ((Inputss[5] && !Inputss[6])|| (!Inputss[5] && Inputss[6]));
Transs[5] =Etapess[4] && (C==-1);
Transs[6] =Etapess[4] && (C==1) && (Verif!=1);
Transs[7] =Etapess[4] && (C==1) && (Verif==1) && (InOutG1[0]==1);
Transs[8] =Etapess[4] && (C==1) && (Verif==1) && (InOutG1[0]==2);
Transs[9] =Etapess[5] && (InOutG1[1]<=MaxIter);

Transs[10]=Etapess[5] && (InOutG1[1]>MaxIter);
Transs[11]=Etapess[6] && ((!Inputss[5] && !Inputss[6]) || OutputsG2[0]);
Transs[12]=Etapess[7] && ((Inputss[5] && Inputss[6]) || OutputsG2[0]);
Transs[13]=Etapess[8] && (C==-1);
Transs[14]=Etapess[8] && (C==1) && (Verif==1);
Transs[15]=Etapess[9];
Transs[16]=Etapess[10];
break;

case 2:
Transs[0]=Etapess[0] && (Inputss[0]>ImaxmA);
Transs[1]=Etapess[1] && (Inputss[0]>ImaxmA);
Transs[2]=Etapess[1] && (Inputss[0]<=ImaxmA);
Transs[3]=Etapess[2] && Inputss[1] && Inputss[2];
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[3]=true;

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

// Désactivation des étapes précédentes
Etapess[10]=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[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;

default:
break;
}
}

float getCourantmA(float sens, int nummoy, int ts_ms)
{
float moy=0.0;
for (int i=0; i<nummoy; i++)
{
int V_5=analogRead(A0);
float V5_f=(float)V_5*5.0/1023.0;
int V_I=analogRead(A1);
float VI_f=(float)V_I*5.0/1023.0;
moy+= abs(1000.0*(VI_f-(V5_f/2.0))/sens);
delay(ts_ms);
}
return moy/(float)nummoy;
}

// To be used later...
void setPorte(int etat, int pin_ap, int pin_am)
{
switch(etat)
{
case 0: // Sens 1
digitalWrite(pin_ap, HIGH);
digitalWrite(pin_am, LOW);
break;

case 1: // Sens 2
digitalWrite(pin_ap, LOW);
digitalWrite(pin_am, HIGH);
break;

default: // Arret
digitalWrite(pin_ap, LOW);
digitalWrite(pin_am, LOW);
}
}

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

Click to rate this post!
[Total: 1 Average: 5]

Laisser un commentaire

Votre adresse e-mail ne sera pas publiée. Les champs obligatoires sont indiqués avec *

Retour en haut

You have successfully subscribed to the newsletter

There was an error while trying to send your request. Please try again.

FPGA | Arduino | Matlab | Cours will use the information you provide on this form to be in touch with you and to provide updates and marketing.