Skip to main content

Projet d'Automatisation et régulation de la viscosité

UE MU5CI823-Optimisation, contrôle et digitalisation des procédés

 

Groupe 2

Noms et Prénoms:

DE LA TAILLE LOLAINVILLE Gregoire (gregoire.de_la_taille_lolainville@etu.sorbonne-université.fr) 21103148

PALAIN Ilies (ilies.palain@etu.sobonne-université.fr) 21400210

HOU Charles (charles.hou@etu.sorbonne-université.fr) 21400213

JIANG Alexandre (alexandre.jiang@etu.sorbonne-université.fr) 21113611

Cursus scolaire : Master 2 de Chimie - Parcours Ingénierie Chimique

Date de commencement du projet : Septembre 2025

 
Date de fin du projet : 30 janvier 2026

Introduction :

L'objectif de notre projet est de contrôler la concentration d'une solution aqueuse à partir de sa viscosité. Pour cela, nous utiliserons un agent visqueux afin de directement associer la viscosité du mélange à sa concentration en agent visqueux

Matériel utilisés:

Réactifs :

  • Eau
  • Grenadine

Composants:

  • 1 carte Arduino (Carte Arduino UNO Rev 3)
  • 4 pompes (LEX-WATER-PUMP2 Pompe miniature à eau 1,1 L/min)
  • 1 moteur agitateur pour mélanger (Motoréducteur 37025GM-12130)
  • 1 électrovannes (Electrovanne 12 V FDP360L)
  • 5 Relais (Module de relais 5 V SRD-05VDC-SL-C)
  • 1 capteur de niveau à ultrason (Capteur de détection ultrasons HC-SR04)
  • 1 capteur de débit (Capteur de débit YFS401) : FT (Flow Transmitter)
  • 1 BreadBoard
  • 4 récipients
  • 1 générateur

Avancement du projet:

16/10/2025: Lors de la semaine blanche, nous avons entamé une première séance de brainstorming qui nous servait de base préliminaire pour choisir le sujet de notre projet. Nous nous sommes ainsi porté sur un sujet portant sur la régulation du procédé d'une élaboration de biodiesel avec une analyse de sa pureté.

17/10/2025 : Après concertation avec notre tuteur de projet, M. Jérôme PULPYTEL, nous avons décider de modifier notre sujet, tout en gardant l'une des idée de base de l'ancien sujet qui est en rapport avec la viscosité. C'est pour cela que nous sommes donc partis sur l'automatisation de la régulation de la viscosité par une méthode in-situ. 

17/10/2025 jusqu'au 28/10/2025 : Réalisation du schéma de notre projet et la préparation de la liste de matériel nécessaire à notre projet.Cuve de mélange.png

Figure 1 : P&ID de départ

17/11/2025 : Nous allons chercher les matériaux de la liste pour pouvoir ainsi commencer le projet.

19/11/2025: Sciure pour créer les supports pour les deux réservoir des réactifs de départ.

dc3f600f-7195-47d5-a06b-d23c394d57b1.jpeg

Figure 2 : Support en bois après modification

24/11/2025 : Nous débutons le montage. Pour cela, on perce des trous dans la plaque en bois pour permettre le maintien des équipements. De plus, nous perçons les récipients pour permettre l'insertion des tuyaux. Nous installons ensuite les premiers éléments qui sont les récipients, une pompe, une électrovanne et un capteur.

IMG_6749.jpeg

Figure 3 : Assemblage des premiers éléments du projet

IMG_6746.jpeg

IMG_6751.jpeg

Figure 4 : Placement des éléments sous différents angles

26/11/2025 : 1er essai de modélisation du montage électrique sur TinkerCad. Modélisation 3D de l'hélice et de la tige à rattacher au moteur pour nous permettre de mélanger nos liquide. Création d'un support pour le moteur.

Screenshot 2025-11-26 15.55.22.png

Figure 5 : 1er essai de modélisation sur TinkerCad

27/11/2025 : Après un premier envoi de notre essai de modélisation, notre tuteur nous explique qu'il manque des composants sur notre modèle TinkerCad et le code est incomplet. Suite à cela, nous nous décidons de modifier notre envoi de modélisation. En parallèle à cela, nous imprimons en 3D les pales de notre agitateur. Puis nous avons fait des trous dans nos planches pour pouvoir installer les derniers pièces manquantes sur le support.

IMG_6837.jpeg

Figure 6 : Pales imprimées en 3D pour l'agitation

IMG_6838.jpeg

Figure 7 : Support comportant tout les emplacements finaux

28/11/2025 : Nous commençons les branchement des modules relais à l'Arduino. Tous les équipements ont d'abord été testé avec le code correspond afin de vérifier leur bon fonctionnement. Ils ont ensuite été placés sur le support avec les différents récipients et les branchements associés.

projet 823 avant.jpeg

Figure 8a : Support comportant les équipements, récipients et branchements (face avant)

projet 823 arriere.jpeg

Figure 8b : Support comportant les équipements, récipients et branchements (face avant)

Du fait d'un débit de sortie de l'eau beaucoup trop faible à cause de la vanne associée, il a été décidé de la remplacer par une pompe. Voici le nouveau P&ID du projet : 

Cuve de mélange (1).png

Figure 9 : Nouveau P&ID de l'installation

26/01/2025 : Il n'a pas été possible d'obtenir de la glycérine pour le projet. Ainsi, la glycérine est remplacée par un autre liquide visqueux, la grenadine, car disponible à bas coût et en grande quantité, la viscosité a été estimé à environ 1500 CP.

On obtient la courbe d'étalonnage suivante, grâce à des différentes mesures d'eau pure, de grenadine pure, et de mélange 50/50, :

 

Figure 10 : Graphique montrant l'évolution du débit en fonction de la viscosité

Nous avons également fait le code Arduino en s'aidant de l'IA claude.ai :

// MACHINE DE REGULATION DE VISCOSITE 
#include "Ultrasonic.h" // Bibliothèque pour le capteur de niveau

// Valeur de viscosité cible en centipoise
const float VISCOSITE_CIBLE = 500.0;  // Entre 1 et 1500 cP

// pin occupés
const int pumpWaterPin = 2;      // Pompe eau
const int pumpGrenadinePin = 3;  // Pompe grenadine
const int pumpCircuitPin = 4;    // Pompe circuit de mesure
const int transferPumpPin = 5;   // Pompe de transfert
const int transferValvePin = 6;  // Vanne de transfert
const int flowSensorPin = 7;     // Capteur de débit
const int ultrasonicPin = 8;     // Capteur niveau ultrason

// Paramètres
const float TOLERANCE_DEBIT = 0.10;    // 10% de tolérance sur le débit
const unsigned long minPulseInterval = 50; // Filtre anti-bruit
const int NIVEAU_MIN = 6;  // Niveau minimum en cm (débordement si < 6cm)

// Variable mesurées
volatile int pulseCount = 0;
int lastState = HIGH;
unsigned long lastPulseTime = 0;
float flowReadings[10];
Ultrasonic ultrasonic(ultrasonicPin);
unsigned long lastLevelCheck = 0;

void setup() {
  Serial.begin(115200);
  
  // Configuration des pins
  pinMode(pumpWaterPin, OUTPUT);
  pinMode(pumpGrenadinePin, OUTPUT);
  pinMode(pumpCircuitPin, OUTPUT);
  pinMode(transferPumpPin, OUTPUT);
  pinMode(transferValvePin, OUTPUT);
  pinMode(flowSensorPin, INPUT_PULLUP);
  
  // Tout éteint au départ
  digitalWrite(pumpWaterPin, LOW);
  digitalWrite(pumpGrenadinePin, LOW);
  digitalWrite(pumpCircuitPin, LOW);
  digitalWrite(transferPumpPin, LOW);
  digitalWrite(transferValvePin, LOW);
  
  
  // Attente de 3 secondes avant de démarrer
  Serial.println("Démarrage dans 3 secondes...");
  delay(3000);
  
  // ETAPE 1: Injection initiale d'eau
  Serial.println("INJECTION INITIALE D'EAU");
  digitalWrite(pumpWaterPin, HIGH);
  delay(5000);
  digitalWrite(pumpWaterPin, LOW);
  
  delay(2000); // Pause pour stabilisation
  
  // Boucle de régulation
  regulateViscosity();
}

void loop() {
  // Programme terminé, ne fait rien
}

void regulateViscosity() {
  int iteration = 1;
  
  while (true) {
    // Vérification du niveau toutes les 5 secondes
    if (millis() - lastLevelCheck >= 5000) {
      checkLevel();
      lastLevelCheck = millis();
    }
    
    // Mesure du débit
    float avgFlow = measureFlow();
    
    // Calcul de la viscosité mesurée par interpolation
    // Points d'étalonnage : (1, 0.815), (750, 0.772), (1500, 0.688)
    float viscositeMesuree;
    
    if (avgFlow >= 0.772) {
      // Entre eau et mélange : interpolation linéaire
      // De 0.815 L/min (1 cP) à 0.772 L/min (750 cP)
      viscositeMesuree = 1 + (0.815 - avgFlow) / (0.815 - 0.772) * (750 - 1);
    } else {
      // Entre mélange et grenadine : interpolation linéaire
      // De 0.772 L/min (750 cP) à 0.688 L/min (1500 cP)
      viscositeMesuree = 750 + (0.772 - avgFlow) / (0.772 - 0.688) * (1500 - 750);
    }
    
    // Calcul du débit cible par interpolation inverse
    float debitCible;
    
    if (VISCOSITE_CIBLE <= 750) {
      // Entre eau et mélange
      debitCible = 0.815 - (VISCOSITE_CIBLE - 1) / (750 - 1) * (0.815 - 0.772);
    } else {
      // Entre mélange et grenadine
      debitCible = 0.772 - (VISCOSITE_CIBLE - 750) / (1500 - 750) * (0.772 - 0.688);
    }
    
    Serial.print(">>> Débit cible: ");
    Serial.print(debitCible, 2);
    Serial.print(" L/min  |  Débit mesuré: ");
    Serial.print(avgFlow, 2);
    Serial.println(" L/min");
    
    // Calcul de l'écart sur le débit
    float ecartDebit = abs(avgFlow - debitCible) / debitCible;
    Serial.print(">>> Écart débit: ");
    Serial.print(ecartDebit * 100, 1);
    Serial.println("%");
    
    // PREMIERE ITERATION : on ignore et on passe à la suivante puisque l'on a remarqué que l'on a souvent des valeurs incohérentes lors de la première itération
    if (iteration == 1) {
      Serial.println("\n--> Première itération: aucun ajustement");
      Serial.println("Pause de stabilisation (2 sec)...\n");
      delay(2000);
      iteration++;
      continue;
    }
    
    // Vérification si dans la tolérance (à partir de l'itération 2)
    if (ecartDebit <= TOLERANCE_DEBIT) {
      Serial.println("\n*** DEBIT CIBLE ATTEINT! ***\n");
      transferMixture();
      Serial.println("\n========================================");
      Serial.println("  PROCESSUS TERMINE AVEC SUCCES");
      Serial.println("========================================\n");
      break;
    }
    
    // Ajustement nécessaire
    if (avgFlow > debitCible) {
      // Débit trop élevé (trop fluide) => Ajouter grenadine
      Serial.println("\n--> Débit trop élevé: Ajout de GRENADINE (3 sec)");
      digitalWrite(pumpGrenadinePin, HIGH);
      delay(3000);
      digitalWrite(pumpGrenadinePin, LOW);
    } else {
      // Débit trop faible (trop visqueux) => Ajouter eau
      Serial.println("\n--> Débit trop faible: Ajout d'EAU (3 sec)");
      digitalWrite(pumpWaterPin, HIGH);
      delay(3000);
      digitalWrite(pumpWaterPin, LOW);
    }
    
    Serial.println("Pause de stabilisation (2 sec)...\n");
    delay(2000);
    
    iteration++;
  }
}

float measureFlow() {
  Serial.println("=== MESURE DU DEBIT ===");
  Serial.println("Pompe circuit: ON");
  digitalWrite(pumpCircuitPin, HIGH);
  
  // 10 mesures de 1 seconde chacune
  for (int i = 0; i < 10; i++) {
    pulseCount = 0;
    unsigned long startTime = millis();
    
    // Mesure pendant 1 seconde
    while (millis() - startTime < 1000) {
      int currentState = digitalRead(flowSensorPin);
      
      if (lastState == HIGH && currentState == LOW) {
        unsigned long currentTime = millis();
        if (currentTime - lastPulseTime > minPulseInterval) {
          pulseCount++;
          lastPulseTime = currentTime;
        }
      }
      lastState = currentState;
    }
    
    // Calcul du débit
    float flowRate = (pulseCount / 450.0) * 60.0;
    flowReadings[i] = flowRate;
    
    Serial.print("Mesure ");
    Serial.print(i + 1);
    Serial.print("/10: ");
    Serial.print(flowRate, 2);
    Serial.println(" L/min");
  }
  
  // Arrêt de la pompe
  digitalWrite(pumpCircuitPin, LOW);
  Serial.println("Pompe circuit: OFF");
  
  // Calcul de la moyenne
  float sum = 0;
  for (int i = 0; i < 10; i++) {
    sum += flowReadings[i];
  }
  float avgFlow = sum / 10.0;
  
  Serial.print("\nDébit moyen: ");
  Serial.print(avgFlow, 2);
  Serial.println(" L/min");
  
  return avgFlow;
}

void transferMixture() {
  Serial.println("\n=== TRANSFERT DU MELANGE ===");
  Serial.println("Pompe transfert + Vanne: ON (30 sec)");
  
  digitalWrite(transferPumpPin, HIGH);
  digitalWrite(transferValvePin, HIGH);
  
  delay(30000);
  
  digitalWrite(transferPumpPin, LOW);
  digitalWrite(transferValvePin, LOW);
  
  Serial.println("Pompe transfert + Vanne: OFF");
  Serial.println("Transfert terminé!");
}

// Mesure de la hauteur du mélange, arrêt si < 6 cm

void checkLevel() {
  long distance = ultrasonic.MeasureInCentimeters();
  
  Serial.print("[NIVEAU] Distance: ");
  Serial.print(distance);
  Serial.println(" cm");
  
  if (distance < NIVEAU_MIN) {
    Serial.println("\n!!! ALERTE: RISQUE DE DEBORDEMENT !!!");
    Serial.print("Distance mesurée: ");
    Serial.print(distance);
    Serial.print(" cm < ");
    Serial.print(NIVEAU_MIN);
    Serial.println(" cm");
    
    // Arrêt de toutes les pompes
    digitalWrite(pumpWaterPin, LOW);
    digitalWrite(pumpGrenadinePin, LOW);
    digitalWrite(pumpCircuitPin, LOW);
    
    Serial.println("\n=== VIDANGE D'URGENCE ===");
    
    // Vidange
    digitalWrite(transferPumpPin, HIGH);
    digitalWrite(transferValvePin, HIGH);
    
    delay(30000);
    
    digitalWrite(transferPumpPin, LOW);
    digitalWrite(transferValvePin, LOW);
    
    Serial.println("\n========================================");
    Serial.println("  ERREUR: NIVEAU CRITIQUE ATTEINT");
    Serial.println("  Vidange effectuée - Programme arrêté");
    Serial.println("========================================\n");
    
    // Arrêt du programme
    while(1) {
      delay(1000);
    }
  }
}

 

 

Ce programme Arduino contrôle une machine automatique capable de réguler la viscosité d'un mélange liquide entre 1 et 1500 centipoise (cP). Le système mélange de l'eau et de la grenadine pour atteindre une viscosité cible définie par l'utilisateur.

Fonctionnement du code

1. Étalonnage

Le système s'appuie sur un étalonnage réalisé avec trois points de mesure :

  • Eau pure : 1 cP → débit de 0.815 L/min

  • Mélange 50/50 : 750 cP → débit de 0.772 L/min

  • Grenadine pure : 1500 cP → débit de 0.688 L/min

Ces mesures établissent une relation entre le débit mesuré et la viscosité du liquide : plus le liquide est visqueux, plus le débit est faible.

2. Processus de régulation

Étape 1: Initialisation

  • Injection initiale de 5 secondes d'eau pour créer une base de travail

  • Pause de 2 secondes pour stabilisation

Étape 2: Cycle de mesure et ajustement

  1. Mesure du débit : La pompe de circuit (pin 4) fait circuler le liquide pendant 10 secondes à travers le débitmètre (pin 7). Le système prend 10 mesures d'une seconde chacune et calcule la moyenne.

  2. Calcul de la viscosité : En utilisant l'interpolation linéaire sur les points d'étalonnage, le programme convertit le débit mesuré en valeur de viscosité.

  3. Comparaison avec la cible : Le système calcule l'écart entre le débit mesuré et le débit cible (correspondant à la viscosité désirée).

  4. Ajustement :

    • Si le débit est trop élevé (liquide trop fluide) → ajout de grenadine pendant 3 secondes (pin 3)

    • Si le débit est trop faible (liquide trop visqueux) → ajout d'eau pendant 3 secondes (pin 2)

  5. Répétition : Le cycle se répète jusqu'à ce que l'écart soit inférieur à 10% du débit cible.

  6. La première itération sert uniquement à mesurer l'état initial, aucun ajustement n'est effectué.

Étape 3: Transfert Une fois la viscosité cible atteinte, le mélange est transféré en activant simultanément la pompe de transfert (pin 5) et la vanne (pin 6) pendant 30 secondes.

Sécurité: Détection de débordement

Un capteur ultrason (pin 8) surveille le niveau du liquide toutes les 5 secondes. Si la distance mesurée est inférieure à 6 cm (risque de débordement), le système :

  1. Arrête immédiatement toutes les pompes

  2. Effectue une vidange d'urgence (30 secondes)

  3. Affiche un message d'erreur

  4. Stoppe définitivement le programme

Configuration matérielle

Pins utilisées

  • Pin 2 : Pompe d'injection d'eau

  • Pin 3 : Pompe d'injection de grenadine

  • Pin 4 : Pompe du boucle de mesure

  • Pin 5 : Pompe de vidange

  • Pin 6 : Vanne de vidange

  • Pin 7 : Capteur de débit (débitmètre SEN0217)

  • Pin 8 : Capteur de niveau ultrason

Limites et recommandations

Zone de précision réduite (> 750 cP) Au-delà de 750 cP, la variation de débit devient très faible (seulement 0.084 L/min entre 750 et 1500 cP). Le système devient donc plus sensible aux fluctuations et moins précis. Pour ces viscosités élevées, il est recommandé d'augmenter la tolérance à 15-20%.

Bibliothèque requise: Le programme nécessite la bibliothèque Ultrasonic.h pour le capteur de niveau.

Conclusion : 

Ce projet portant sur la conception et la mise en place d’un système d''automatisation et de régulation de la viscosité. Le projet nous a permis de mettre en pratique la théorie acquise académiquement à une réalisation concrète, en intégrant des éléments mécaniques, hydrauliques et électroniques contrôlées par Arduino.

Avec plus de temps, nous aurions pu améliorer la robustesse du montage, de meilleurs attaches, réaliser un câble management  ainsi que l’optimisation du code pour rendre l'automatisation plus stable et plus précise surtout à haute viscosité. Une meilleure droite d'étalonnage et un meilleur débitmètre aurait également permis d’augmenter la fiabilité des mesures.
 
Ce projet nous a surtout appris à travailler en équipe, à résoudre des problèmes techniques imprévus (fuites, erreurs de câblage, difficultés de programmation) et à adapter notre conception en cours de route. Nous avons retenu l’importance des tests progressifs, de la communication entre les membres du groupe et du lien entre théorie et pratique dans la réalisation d’un procédé expérimental.

Cela nous a permis de développer des compétences clés, comme le travail d’équipe, la résolution de problèmes techniques (fuites, câblage, programmation) et l’adaptabilité face aux imprévus. Il a aussi souligné l’importance des tests réguliers, d’une communication efficace et de l’équilibre entre théorie et pratique pour mener à bien une expérience.