Le suivi du temps de cycle remplace l'étude au chronomètre par la mesure de chaque cycle, sur chaque poste, toute la journée. Dans ce tutoriel, vous allez capter les signaux de cycle depuis une sortie d'automate ou un capteur avec un ESP32, publier chaque cycle via MQTT et faire tourner un petit service d'analyse qui calcule des statistiques glissantes par poste et identifie le goulot d'étranglement de la ligne par rapport au takt time.
Temps de cycle, takt time et pourquoi la différence compte
Trois termes sont souvent confondus :
| Terme | Définition | Source |
|---|---|---|
| Takt time | Temps de production disponible divisé par la demande client ; le rythme que la ligne doit tenir | Planification |
| Temps de cycle idéal (nominal) | Temps le plus court possible pour un cycle dans des conditions idéales | Spécification machine, ingénierie process |
| Temps de cycle réel | Temps mesuré entre deux fins de cycle consécutives sur un poste | Mesure |
Lorsque le temps de cycle réel d'un poste dépasse le takt time, la ligne ne peut pas satisfaire la demande sans heures supplémentaires. Lorsqu'il dépasse le temps de cycle idéal, l'écart constitue une perte de performance au sens du TRS. Une étude au chronomètre donne un instantané de quelques dizaines de cycles ; le suivi continu montre toute la distribution, y compris les cycles lents qui surviennent en début de poste, après un changement d'outil ou avec certains opérateurs et matériaux.
Quel signal utiliser
Choisissez un signal qui marque le même point de chaque cycle :
- Sortie « fin de cycle » de l'automate, ou un bit que vous pouvez affecter à une sortie libre. L'option la plus précise.
- Capteur de présence pièce en sortie de poste, par exemple un capteur photoélectrique ou inductif.
- Signal de bridage ou de porte pour les machines chargées manuellement, si une séquence ouverture/fermeture correspond à un cycle.
- Signature de courant d'une broche ou d'une presse, en dernier recours lorsqu'aucun signal TOR n'existe.
Tous les signaux 24 V doivent atteindre le microcontrôleur via un optocoupleur ou un module d'entrée avec adaptation de niveau adéquat, jamais directement.
Conception des topics
Un message par cycle préserve les données brutes et permet à chaque consommateur de calculer ses propres statistiques :
connectmq/plant1/assembly/line1/st-10/cycle {"seq":1532,"ct_ms":41250,"ts":1760600000}
connectmq/plant1/assembly/line1/st-20/cycle ...
connectmq/plant1/assembly/line1/cycle-stats retained summary for all stations
Le numéro de séquence permet aux consommateurs de détecter les messages perdus, et ct_ms est calculé sur l'appareil à partir de sa propre horloge, si bien que la latence réseau ne fausse pas la mesure.
Capter les cycles sur un ESP32
Le sketch ci-dessous utilise une interruption matérielle pour horodater chaque front avec millis(), calcule le temps écoulé depuis le front précédent et publie un message JSON par cycle avec PubSubClient. Installez PubSubClient depuis le gestionnaire de bibliothèques Arduino. Si vous découvrez la carte, le tutoriel MQTT sur ESP32 présente la chaîne d'outils.
#include <WiFi.h>
#include <PubSubClient.h>
const char* WIFI_SSID = "YOUR_WIFI";
const char* WIFI_PASS = "YOUR_WIFI_PASSWORD";
const char* BROKER = "broker.connectmq.com";
const char* STATION = "st-10";
const char* TOPIC = "connectmq/demo/ctm-3k8p/line1/st-10/cycle";
const int CYCLE_PIN = 4; // sortie de l'optocoupleur, active à l'état bas
const unsigned long MIN_CYCLE_MS = 2000; // ignore les rebonds et les doubles impulsions
WiFiClient net;
PubSubClient mqtt(net);
volatile unsigned long lastEdge = 0;
volatile unsigned long pendingCt = 0;
volatile bool havePending = false;
unsigned long seq = 0;
void IRAM_ATTR onCycle() {
unsigned long now = millis();
unsigned long ct = now - lastEdge;
if (ct < MIN_CYCLE_MS) return;
if (lastEdge != 0) {
pendingCt = ct;
havePending = true;
}
lastEdge = now;
}
void connectMqtt() {
while (!mqtt.connected()) {
String id = String("ctm-3k8p-") + STATION;
if (mqtt.connect(id.c_str())) {
Serial.println("MQTT connected");
} else {
Serial.printf("MQTT failed, rc=%d\n", mqtt.state());
delay(2000);
}
}
}
void setup() {
Serial.begin(115200);
pinMode(CYCLE_PIN, INPUT_PULLUP);
attachInterrupt(digitalPinToInterrupt(CYCLE_PIN), onCycle, FALLING);
WiFi.begin(WIFI_SSID, WIFI_PASS);
while (WiFi.status() != WL_CONNECTED) delay(250);
mqtt.setServer(BROKER, 1883);
}
void loop() {
if (!mqtt.connected()) connectMqtt();
mqtt.loop();
if (havePending) {
noInterrupts();
unsigned long ct = pendingCt;
havePending = false;
interrupts();
char payload[96];
snprintf(payload, sizeof(payload), "{\"seq\":%lu,\"ct_ms\":%lu,\"up_ms\":%lu}",
++seq, ct, millis());
mqtt.publish(TOPIC, payload);
Serial.println(payload);
}
}
La garde MIN_CYCLE_MS filtre les rebonds de contact et les doubles impulsions ; réglez-la à environ la moitié du cycle réaliste le plus rapide. Le premier front après le démarrage ne fait que lancer le chronomètre : aucun faux cycle long n'est donc signalé. PubSubClient publie en QoS 0 ; si vous avez besoin d'une livraison QoS 1 pour chaque cycle, AsyncMqttClient la prend en charge, ou vous pouvez mettre les cycles en tampon et les publier par lots. Pour la production, passez à WiFiClientSecure, au port 8883 et aux identifiants fournis par votre broker.
Analyser les données de suivi du temps de cycle
Le service d'analyse s'abonne à tous les postes, garde en mémoire les 200 derniers cycles de chaque poste et publie un résumé retained toutes les 30 secondes. Utiliser la médiane et le 90e centile plutôt que la moyenne évite que quelques cycles très longs (qui sont en réalité des micro-arrêts) ne faussent l'image.
#!/usr/bin/env python3
"""Rolling cycle time statistics and bottleneck detection."""
import json
import statistics
import threading
import time
from collections import defaultdict, deque
import paho.mqtt.client as mqtt
PREFIX = "connectmq/demo/ctm-3k8p/line1"
TAKT_MS = 45_000
STOP_THRESHOLD_MS = 3 * TAKT_MS # les écarts plus longs sont des micro-arrêts, pas des cycles
cycles = defaultdict(lambda: deque(maxlen=200))
lock = threading.Lock()
def on_connect(client, userdata, flags, reason_code, properties):
client.subscribe(f"{PREFIX}/+/cycle", qos=1)
def on_message(client, userdata, msg):
station = msg.topic.split("/")[-2]
ct = json.loads(msg.payload)["ct_ms"]
if ct <= STOP_THRESHOLD_MS:
with lock:
cycles[station].append(ct)
def p90(values):
return statistics.quantiles(values, n=10)[-1] if len(values) >= 10 else max(values)
client = mqtt.Client(mqtt.CallbackAPIVersion.VERSION2, client_id="ctm-stats-3k8p")
client.on_connect = on_connect
client.on_message = on_message
client.connect("broker.connectmq.com", 1883, keepalive=60)
client.loop_start()
while True:
time.sleep(30)
with lock:
stats = {
st: {"n": len(v), "median_ms": int(statistics.median(v)), "p90_ms": int(p90(v))}
for st, v in cycles.items() if v
}
if not stats:
continue
bottleneck = max(stats, key=lambda s: stats[s]["median_ms"])
summary = {
"ts": int(time.time()),
"takt_ms": TAKT_MS,
"bottleneck": bottleneck,
"over_takt": [s for s, v in stats.items() if v["median_ms"] > TAKT_MS],
"stations": stats,
}
client.publish(f"{PREFIX}/cycle-stats", json.dumps(summary), qos=1, retain=True)
print(json.dumps(summary, indent=2))
Vous pouvez le tester sans matériel en publiant des cycles synthétiques :
for i in $(seq 1 20); do
mosquitto_pub -h broker.connectmq.com -p 1883 -i ctm-sim-$RANDOM \
-t connectmq/demo/ctm-3k8p/line1/st-20/cycle \
-m "{\"seq\":$i,\"ct_ms\":$((44000 + RANDOM % 6000))}"
sleep 1
done
Notez que le serveur MQTT public gratuit autorise 10 messages par seconde et par client, bien plus que ce dont un poste réel a besoin. Tout ce qui y est publié est lisible publiquement : utilisez-le uniquement pour des tests et des données synthétiques.
Interpréter les résultats
| Observation | Signification probable | Étape suivante |
|---|---|---|
| Médiane au-dessus du takt sur un poste | Véritable goulot d'étranglement | Rééquilibrer le contenu de travail, ajouter de la capacité, réduire les réglages |
| Médiane sous le takt mais p90 très au-dessus | Instabilité, pas un problème de capacité | Rechercher les causes matière, opérateur ou qualité des cycles lents |
| Tous les postes proches du takt, la ligne rate pourtant sa production | Micro-arrêts ou blocages/famines | Croiser avec l'état des machines et les niveaux de stock tampon |
| Temps de cycle qui dérive à la hausse sur plusieurs semaines | Usure d'outil, équipement qui se dégrade | Corréler avec les données de maintenance |
| Grande différence entre les équipes | Différences de méthode ou d'effectifs | Standardiser le travail, former |
Le poste goulot est celui où l'amélioration profite à toute la ligne ; améliorer n'importe quel autre poste ne fait qu'accumuler des en-cours. Surveillez le déplacement du goulot après des modifications : c'est le signe d'une ligne équilibrée.
Déployer le suivi du temps de cycle sur une ligne
Commencez par le poste que tout le monde soupçonne d'être le goulot, ainsi qu'un poste de chaque côté. Trois postes suffisent pour voir si les cycles lents proviennent du poste lui-même ou de famines et blocages dus à ses voisins. Une fois le choix du signal et les réglages anti-rebond validés, copiez le même sketch sur les autres postes en ne changeant que le nom du poste et le topic.
Quelques règles pratiques facilitent le déploiement :
- Nommez les postes exactement comme sur l'implantation de la ligne. Opérateurs et ingénieurs doivent reconnaître
st-20sur le tableau de bord sans table de correspondance. - Mettez-vous d'accord sur le point de cycle de chaque poste. Si un poste compte à l'entrée de la pièce et le suivant à sa sortie, les chiffres ne sont pas comparables.
- Enregistrez le takt time avec les données. Le takt change quand la demande change ; le stocker dans le résumé garde les anciens rapports interprétables.
- Vérifiez les horloges des appareils.
ct_msprovient du timer interne de l'appareil et reste fiable, mais tout horodatage ajouté pour la corrélation nécessite des passerelles synchronisées par NTP. - Affichez les données sur la ligne. Un écran montrant en direct la médiane par poste face au takt suscite plus de discussions d'amélioration qu'un rapport hebdomadaire.
Dans le portail ConnectMQ, l'explorateur de topics en direct permet de vérifier rapidement pendant la mise en service que chaque poste publie bien, et une règle d'alerte sur seuil sur le median_ms d'un poste enregistre chaque dérive au-dessus du takt.
Relier le temps de cycle aux autres indicateurs
Les données de cycle constituent le volet performance du TRS. Combinées au temps de fonctionnement issu de la surveillance de l'état des machines et aux comptages de pièces bonnes issus du comptage de production avec l'IoT, vous disposez de tout le nécessaire pour calculer le TRS. Gardez le tout sur un seul broker et une seule hiérarchie de topics, et chaque nouveau KPI devient un abonné plutôt qu'un nouveau projet d'intégration. Pour comprendre ce que fait un broker MQTT au cœur de cette architecture, commencez par là ; le guide de l'industrie intelligente l'intègre dans une feuille de route plus large.
Démarrer avec ConnectMQ
Une ligne de plusieurs dizaines de postes publiant chaque cycle a besoin d'un broker toujours joignable. ConnectMQ est un broker MQTT cloud, plus précisément un broker MQTT managé, avec TLS, MQTT 5, retained messages, un explorateur de topics en direct et des alertes sur seuil pour des champs comme median_ms. Créez gratuitement un broker Serverless, sans carte bancaire, et connectez votre premier poste.
Questions fréquentes
Quelle est la différence entre temps de cycle et takt time ?
Le takt time est le rythme imposé par la demande client, calculé à partir du temps disponible et de la demande. Le temps de cycle est la durée réelle d'un poste par unité. Un poste dont le temps de cycle dépasse le takt limite la production de la ligne.
Faut-il utiliser la moyenne ou la médiane du temps de cycle ?
Utilisez la médiane pour le cycle typique et un centile élevé comme le p90 pour la variabilité. La moyenne est facilement faussée par quelques cycles longs qui sont en réalité des micro-arrêts.
Peut-on mesurer le temps de cycle sans accès à l'automate ?
Oui. Un capteur photoélectrique en sortie de poste, un signal de porte ou de bridage, ou la signature de courant de l'entraînement principal peuvent marquer chaque cycle. Les signaux automate restent les plus précis lorsqu'ils sont disponibles.
Comment traiter les très longs écarts entre deux cycles ?
Considérez les écarts nettement supérieurs au takt comme des arrêts et non comme des cycles. Excluez-les des statistiques de cycle et enregistrez-les comme temps d'arrêt à l'aide des données d'état des machines.



