Les limites des fiches techniques sont des points de départ, pas des limites de production. Les cartes réelles présentent des tolérances, des variations d'assemblage et des dérives environnementales que les fiches techniques ne peuvent pas capturer. Ce guide vous montre comment collecter des données de mesure depuis votre ligne de production, appliquer la méthode 3-sigma pour dériver des limites statistiquement fiables, et configurer ces limites dans OpenHTF avec le suivi TofuPilot.
Prérequis
- Compte TofuPilot avec des données d'exécution de production
- Python 3.8+
numpyetscipyinstallés- Au moins 30 échantillons de test (100+ recommandés)
Pourquoi les limites des fiches techniques ne suffisent pas
| Source de variation | Exemple |
|---|---|
| Tolérance des composants | Une résistance à +/-5 % décale la tension de sortie |
| Impédance des pistes du PCB | Différences de routage selon les positions dans le panneau |
| Variation d'assemblage | La résistance des joints de soudure varie |
| Dérive environnementale | Température à la station de test vs. sur le terrain |
| Bruit de mesure | Contact de la sonde, longueur du câble |
Un rail 3,3 V avec une plage de +/-5 % selon la fiche technique (3,135 V-3,465 V) peut montrer une distribution de production réelle centrée à 3,31 V avec un écart-type de 0,012 V. Définir les limites uniquement à partir de la fiche technique ne permet pas de voir que votre processus dérive vers le haut.
Étape 1 : Collecter les échantillons de référence
Vous avez besoin d'un minimum de 30 échantillons provenant de cartes déjà validées comme conformes. Utilisez 100+ pour des estimations de sigma stables.
import numpy as np
# Collecte simulée à partir de cartes validées conformes
# En pratique, exportez depuis TofuPilot ou accumulez à partir des exécutions en direct
vdd_samples = [
3.312, 3.308, 3.315, 3.310, 3.307,
3.319, 3.311, 3.314, 3.309, 3.316,
3.313, 3.308, 3.312, 3.317, 3.310,
3.306, 3.315, 3.311, 3.313, 3.309,
3.318, 3.310, 3.312, 3.315, 3.308,
3.311, 3.314, 3.307, 3.316, 3.313,
3.310, 3.308, 3.315, 3.312, 3.311,
3.309, 3.317, 3.314, 3.310, 3.313,
]
n = len(vdd_samples)
mean = np.mean(vdd_samples)
std = np.std(vdd_samples, ddof=1) # écart-type d'échantillon, pas de population
print(f"N={n} moyenne={mean:.4f}V écart-type={std:.4f}V")
# N=40 moyenne=3.3119V écart-type=0.0031VUtilisez ddof=1 pour l'écart-type d'échantillon lorsque la taille de votre échantillon est inférieure à la population complète.
Étape 2 : Vérifier les valeurs aberrantes et les distributions bimodales
Avant de calculer les limites, inspectez la distribution. Une distribution bimodale signale deux populations distinctes.
import numpy as np
from scipy import stats
vdd_samples = [
3.312, 3.308, 3.315, 3.310, 3.307,
3.319, 3.311, 3.314, 3.309, 3.316,
3.313, 3.308, 3.312, 3.317, 3.310,
3.306, 3.315, 3.311, 3.313, 3.309,
3.318, 3.310, 3.312, 3.315, 3.308,
3.311, 3.314, 3.307, 3.316, 3.313,
3.310, 3.308, 3.315, 3.312, 3.311,
3.309, 3.317, 3.314, 3.310, 3.313,
]
# Détection des valeurs aberrantes par z-score
z_scores = np.abs(stats.zscore(vdd_samples))
outliers = [v for v, z in zip(vdd_samples, z_scores) if z > 3]
print(f"Valeurs aberrantes (|z| > 3) : {outliers}")
# Test de normalité de Shapiro-Wilk
stat, p = stats.shapiro(vdd_samples)
print(f"Shapiro-Wilk p={p:.4f} ({'normal' if p > 0.05 else 'NON normal'})")Si Shapiro-Wilk renvoie p < 0.05, recherchez si vos échantillons proviennent de deux lots d'assemblage ou de deux bobines de composants.
Étape 3 : Calculer les limites 3-sigma
La règle des 3-sigma couvre 99,73 % d'une distribution normale (environ 2700 DPMO au bord de la limite).
import numpy as np
vdd_samples = [
3.312, 3.308, 3.315, 3.310, 3.307,
3.319, 3.311, 3.314, 3.309, 3.316,
3.313, 3.308, 3.312, 3.317, 3.310,
3.306, 3.315, 3.311, 3.313, 3.309,
3.318, 3.310, 3.312, 3.315, 3.308,
3.311, 3.314, 3.307, 3.316, 3.313,
3.310, 3.308, 3.315, 3.312, 3.311,
3.309, 3.317, 3.314, 3.310, 3.313,
]
mean = np.mean(vdd_samples)
std = np.std(vdd_samples, ddof=1)
sigma_levels = {
"3s (99,73%)" : 3,
"4s (99,9937%)" : 4,
"6s (99,99966%)": 6,
}
print(f"Moyenne : {mean:.4f} V")
print(f"Écart-type : {std:.4f} V
")
for label, k in sigma_levels.items():
lo = mean - k * std
hi = mean + k * std
print(f"{label:25s} bas={lo:.4f}V haut={hi:.4f}V")| Niveau sigma | Couverture | Limites dures (exemple VDD) |
|---|---|---|
| 3-sigma | 99,73 % | 3,3026 V à 3,3212 V |
| 4-sigma | 99,9937 % | 3,2995 V à 3,3243 V |
| 6-sigma | 99,99966 % | 3,2933 V à 3,3305 V |
Étape 4 : Ajouter des limites marginales (zone d'alerte)
Les limites marginales créent une zone d'alerte entre la limite souple et l'échec dur. Une carte dans la zone marginale passe mais est signalée pour surveillance.
| Zone | Plage | Résultat |
|---|---|---|
| Pass | moyenne +/- 2-sigma | Passage normal |
| Marginal | moyenne +/- 2-sigma à moyenne +/- 3-sigma | Passage avec avertissement |
| Fail | au-delà de moyenne +/- 3-sigma | Échec dur |
Étape 5 : Configurer les limites dans OpenHTF avec TofuPilot
import openhtf as htf
from openhtf.util import units
from tofupilot.openhtf import TofuPilot
# Dérivé de 40 échantillons de production : moyenne=3.3119V, écart-type=0.0031V
VDD_HARD_LOW = 3.3026 # moyenne - 3-sigma
VDD_HARD_HIGH = 3.3212 # moyenne + 3-sigma
VDD_MARGINAL_LOW = 3.3057 # moyenne - 2-sigma
VDD_MARGINAL_HIGH = 3.3181 # moyenne + 2-sigma
@htf.measures(
htf.Measurement("vdd_rail_voltage")
.in_range(
minimum=VDD_HARD_LOW,
maximum=VDD_HARD_HIGH,
marginal_minimum=VDD_MARGINAL_LOW,
marginal_maximum=VDD_MARGINAL_HIGH,
)
.with_units(units.VOLT)
.doc("Rail 3,3 V avec zone marginale [2-sigma, 3-sigma] pour la surveillance de dérive.")
)
def measure_vdd(test):
voltage = read_voltage_at_tp12()
test.measurements.vdd_rail_voltage = voltage
def main():
test = htf.Test(
measure_vdd,
test_name="VDD Rail Validation",
)
with TofuPilot(test):
test.execute(test_start=lambda: "SN-001")
if __name__ == "__main__":
main()Le résultat marginal d'OpenHTF correspond à MARGINAL_PASS dans TofuPilot. Vous pouvez filtrer par ce résultat dans le tableau de bord pour suivre les tendances de dérive sans arrêter la ligne.
Étape 6 : Suivre la dérive des limites dans TofuPilot
Relancez l'analyse sigma mensuellement et comparez :
import numpy as np
from datetime import datetime
def compute_sigma_limits(samples: list[float], k: float = 3.0) -> dict:
arr = np.array(samples)
mean = np.mean(arr)
std = np.std(arr, ddof=1)
return {
"n": len(arr),
"mean": round(mean, 6),
"std": round(std, 6),
"low": round(mean - k * std, 6),
"high": round(mean + k * std, 6),
"sigma": k,
"computed_at": datetime.utcnow().isoformat(),
}Comparez les nouvelles limites aux limites de production actuelles avant le déploiement. Un décalage de la moyenne supérieur à 1-sigma justifie une investigation du processus.
| Déclencheur de revue | Action |
|---|---|
| Décalage de la moyenne > 1-sigma | Investiguer la cause racine avant de mettre à jour |
| Augmentation de l'écart-type > 20 % | Vérifier le changement de bobine de composants ou la calibration de la station |
| Taux marginal > 5 % | Resserrer les limites ou améliorer le processus |
| Nouvel échantillon N > 500 | Réévaluer le niveau sigma (envisager le 4-sigma) |