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

L'Avenir de l'Électronique : Des Projets Innovants Vous Attendent !