Exercice : Commande d'une pompe

Simulateur

Cet exercice est à réaliser avec le simulateur en ligne Wokwi

Description et fonctionnement

On souhaite réaliser l'automatisation d'une pompe munie de deux capteurs de niveau utilisée pour maintenir un niveau bas de liquide dans une cuve. Le fonctionnement est résumé ainsi lorsque le niveau de liquide monte dans la cuve :

  • tant que le niveau est bas dans la cuve (c'est-à-dire inférieur au capteur bas), la pompe est à l'arrêt,

  • lorsque le niveau haut est atteint, la pompe se met en marche,

  • tant que le niveau est au-dessus du niveau bas, la pompe fonctionne

  • dès que le niveau passe en dessous du capteur bas, la pompe s'arrête

Cuve équipée d'une pompe et de deux capteurs de niveauInformations[1]

Implantation dans le simulateur

Outre l'Arduino, vous utiliserez, pour simuler le système, les composants suivants :

  • 2 interrupteurs à deux positions stables pour simuler les capteurs,

  • une LED et sa résistance pour simuler la pompe.

Schéma de simulation de la commande de pompe

Question

Créez et testez une classe Sensor composée de :

  • deux variables membres privées :

    • pinNumber qui stockera le numéro du port sur lequel le capteur sera branché

    • state qui stockera l'état du capteur

  • un constructeur avec paramètre pour initialiser l'objet avec le numéro de port

  • un accesseur de lecture pour renvoyer l'état du capteur

Question

Créez et testez une classe Pump composée de :

  • deux variables membres privées :

    • pinNumber qui stockera le numéro du port sur lequel la LED, qui simule la pompe, sera branchée

    • state qui stockera l'état de la pompe

  • un constructeur avec paramètre pour initialiser l'objet avec le numéro de port et mettre la pompe à l'arrêt,

  • un accesseur d'écriture pour fixer l'état de la pompe

  • un accesseur de lecture pour renvoyer l'état de la pompe

Question

Proposez une solution répondant au cahier des charges

Solution

1
#define POMPE 13
2
#define CAPTEUR_HAUT 12
3
#define CAPTEUR_BAS 11
4
5
//Déclaration des classes
6
7
class Sensor{ //capteur
8
  private:
9
      byte pinNumber;
10
      bool state;
11
  public:
12
  Sensor(int);
13
  bool getState();
14
};
15
class Pump{
16
  private:
17
    byte pinNumber;
18
      bool state;
19
  public:
20
  Pump(int);
21
  void setState(bool);
22
  bool getState();
23
};
24
25
// Programme principal
26
Sensor sensorHaut(CAPTEUR_HAUT);
27
Sensor sensorBas(CAPTEUR_BAS);
28
Pump pump(POMPE);
29
void setup(){
30
}
31
void loop()
32
{
33
34
  /*On teste l'état des capteurs et de la pompe :
35
    - si les deux capteurs sont activés et que la pompe était à l'arrêt, on la met en marche
36
    - si la pompe est activée et que le capteur bas n'est plus activé, on arrête la pompe
37
  */
38
39
40
  if(sensorHaut.getState() && sensorBas.getState() && !pump.getState()){
41
    pump.setState(HIGH);
42
  }
43
  if(pump.getState() && !sensorBas.getState()){
44
    pump.setState(LOW);
45
  }
46
}
47
48
// Objets : définition des fonctions membres
49
Sensor::Sensor(int pin){ //Constructeur
50
  	pinNumber = pin;
51
	pinMode(pinNumber, OUTPUT);  
52
};
53
bool Sensor::getState(){ //permet d'obtenir l'état d'un capteur
54
  state=digitalRead(pinNumber);
55
  return(state);
56
};
57
Pump::Pump(int pin){ //Constructeur
58
  pinNumber = pin;
59
  pinMode(pinNumber, OUTPUT);
60
  digitalWrite(pinNumber,LOW);
61
};
62
void Pump::setState(bool state){//Fixe l'état de la pompe
63
  this->state = state;
64
  digitalWrite(pinNumber,this->state);
65
};
66
bool Pump::getState(){//permet d'obtenir l'état de la pomp
67
  return(this->state);
68
}

Héritage de classe : ajout d'une temporisation

On souhaite maintenant améliorer le fonctionnement de la pompe tout en gardant la classe initiale. L'amélioration consiste à ajouter une temporisation réglable lorsque la pompe passe de l'état « en marche » à l'état « à l'arrêt ».

Question

Créez une nouvelle classe qui héritera de la classe Pump et qui intégrera la nouvelle fonctionnalité.

Solution

1
Cet exemple permet de mettre en place un héritage de classe : la nouvelle classe PumpTemp hérite de la classe Pump. Elle ne fait que modifier la fonction membre setState() à laquelle on ajoute une temporisation dans le cas  on demande l'arrêt de la pompe. Cela permet de garder le même programme principal à l'exception près de la création de l'objet pump qui fait maintenant référence à la classe PumpTemp (ligne PumpTemp pump(POMPE);)
2
3
4
#define POMPE 13
5
6
#define CAPTEUR_HAUT 12
7
8
#define CAPTEUR_BAS 11
9
10
11
class Sensor{
12
13
  private:
14
15
      byte pinNumber;
16
17
      bool state;
18
19
  public:
20
21
  Sensor(int);
22
23
  bool getState();
24
25
};
26
27
28
class Pump{
29
30
  protected:
31
32
    byte pinNumber;
33
34
      bool state;
35
36
  public:
37
38
  Pump(int);
39
40
  void setState(bool);
41
42
  bool getState();
43
44
};
45
46
47
//Héritage de la classe Pump avec ajout d'une tempo à l'arrêt de la pompe
48
49
class PumpTemp : public Pump{
50
51
  public:
52
53
  PumpTemp(int);
54
55
  void setState(bool);
56
57
};
58
59
/* Programme principal */
60
61
Sensor sensorHaut(CAPTEUR_HAUT);
62
63
Sensor sensorBas(CAPTEUR_BAS);
64
65
PumpTemp pump(POMPE);
66
67
void setup()
68
69
{
70
71
}
72
73
74
void loop()
75
76
{
77
78
  if(sensorHaut.getState() && sensorBas.getState() && !pump.getState()){
79
80
    pump.setState(HIGH);
81
82
  }
83
84
  if(pump.getState() && !sensorBas.getState()){
85
86
    pump.setState(LOW);
87
88
  }
89
90
    
91
92
}
93
94
95
/* Objets */
96
97
Sensor::Sensor(int pin){
98
99
      pinNumber = pin;
100
101
    pinMode(pinNumber, OUTPUT);  
102
103
};
104
105
bool Sensor::getState(){
106
107
  state=digitalRead(pinNumber);
108
109
  return(state);
110
111
};
112
113
114
Pump::Pump(int pin){
115
116
  pinNumber = pin;
117
118
  pinMode(pinNumber, OUTPUT);
119
120
  digitalWrite(pinNumber,LOW);
121
122
};
123
124
void Pump::setState(bool state){
125
126
  this->state = state;
127
128
  digitalWrite(pinNumber,this->state);
129
130
};
131
132
bool Pump::getState(){
133
134
  return(this->state);
135
136
};
137
138
139
PumpTemp::PumpTemp(int pin) : Pump(pin){
140
141
};
142
143
void PumpTemp::setState(bool state){
144
145
  //si on demande extinction, on temporise
146
147
  //Extinction : état demandé = 0, ancien état = 1
148
149
  if(state == LOW && this->state == HIGH){
150
151
    //Temporisation
152
153
    delay(3000);
154
155
  }
156
157
  Pump::setState(state);
158
159
};

Héritage de classe : commandes on/off

Il s'agit maintenant de revoir la manière de fonctionner de la pompe : plutôt que de fixer le fonctionnement par un état logique dans le programme principal, il est demandé de mettre en place des fonctions plus explicites de mise en marche, setPumpOn() et mise à l'arrêt setPumpOff() : une nouvelle classe PumpOnOff sera créée.

Question

Créez et testez la nouvelle classe PumpOnOff

Solution

1
/*
2
Commande pompe à 2 capteurs
3
Intégre les fonctions setPumpOn et setPumpOff
4
*/
5
6
7
#define POMPE 13
8
#define CAPTEUR_HAUT 12
9
#define CAPTEUR_BAS 11
10
11
class Sensor{
12
  private:
13
      byte pinNumber;
14
      bool state;
15
  public:
16
  Sensor(int);
17
  bool getState();
18
};
19
20
class Pump{
21
  protected:
22
    byte pinNumber;
23
      bool state;
24
  public:
25
  Pump(int);
26
  void setState(bool);
27
  bool getState();
28
};
29
30
//Héritage de la classe Pump avec ajout d'une tempo à l'arrêt de la pompe
31
class PumpTemp : public Pump{
32
  public:
33
  PumpTemp(int);
34
  void setState(bool);
35
};
36
37
38
/* Programme principal */
39
Sensor sensorHaut(CAPTEUR_HAUT);
40
Sensor sensorBas(CAPTEUR_BAS);
41
PumpTemp pump(POMPE);
42
void setup()
43
{
44
}
45
46
void loop()
47
{
48
  if(sensorHaut.getState() && sensorBas.getState() && !pump.getState()){
49
    pump.setState(HIGH);
50
  }
51
  if(pump.getState() && !sensorBas.getState()){
52
    pump.setState(LOW);
53
  }
54
    
55
}
56
57
/* Objets */
58
Sensor::Sensor(int pin){
59
      pinNumber = pin;
60
    pinMode(pinNumber, OUTPUT);  
61
};
62
bool Sensor::getState(){
63
  state=digitalRead(pinNumber);
64
  return(state);
65
};
66
67
68
Pump::Pump(int pin){
69
  pinNumber = pin;
70
  pinMode(pinNumber, OUTPUT);
71
  digitalWrite(pinNumber,LOW);
72
};
73
void Pump::setState(bool state){
74
  this->state = state;
75
  digitalWrite(pinNumber,this->state);
76
};
77
bool Pump::getState(){
78
  return(this->state);
79
};
80
81
PumpTemp::PumpTemp(int pin) : Pump(pin){
82
};
83
void PumpTemp::setState(bool state){
84
  //si on demande extinction, on temporise
85
  //Extinction : état demandé = 0, ancien état = 1
86
  if(state == LOW && this->state == HIGH){
87
    //Temporisation
88
    delay(3000);
89
  }
90
  Pump::setState(state);
91
};
92