Chaque mesure dans un test de fabrication nécessite trois éléments : un nom, une valeur et des limites qui définissent le succès ou l'échec. OpenHTF fournit des validateurs intégrés pour les plages numériques, les correspondances exactes, les pourcentages et les expressions régulières. Lorsque vous enregistrez ces mesures via TofuPilot, vous obtenez automatiquement le FPY, le Cpk et les cartes de contrôle. Ce guide couvre chaque type de mesure avec du code fonctionnel.
Validateurs de mesure
OpenHTF dispose de six validateurs intégrés :
| Validateur | Cas d'utilisation | Exemple |
|---|---|---|
.in_range(min, max) | Valeur dans une plage | Tension, courant, résistance |
.in_range(minimum=x) | Valeur au-dessus d'un minimum | Force du signal, gain |
.in_range(maximum=x) | Valeur en dessous d'un maximum | Latence, bruit de fond |
.equals(value) | Correspondance exacte | Version du firmware, drapeaux booléens |
.within_percent(target, pct) | Valeur dans un pourcentage de la cible | Fréquence du cristal, capteurs calibrés |
.matches_regex(pattern) | Chaîne correspondant à une regex | Adresse MAC, format de numéro de série |
Plage numérique : .in_range()
Le validateur le plus courant. Réussite si la valeur se situe entre les limites inférieure et supérieure.
import openhtf as htf
from openhtf.util import units
@htf.measures(
htf.Measurement("rail_3v3")
.in_range(3.2, 3.4)
.with_units(units.VOLT)
.doc("Tension du rail d'alimentation 3.3V"),
htf.Measurement("rail_5v0")
.in_range(4.8, 5.2)
.with_units(units.VOLT)
.doc("Tension du rail d'alimentation 5.0V"),
htf.Measurement("rail_1v8")
.in_range(1.7, 1.9)
.with_units(units.VOLT)
.doc("Tension du rail cœur 1.8V"),
htf.Measurement("idle_current")
.in_range(0.05, 0.25)
.with_units(units.AMPERE)
.doc("Consommation de courant au repos de la carte"),
)
def test_power_rails(test):
test.measurements.rail_3v3 = 3.31
test.measurements.rail_5v0 = 5.01
test.measurements.rail_1v8 = 1.82
test.measurements.idle_current = 0.12Limites unilatérales
Utilisez des arguments nommés pour les limites avec minimum uniquement ou maximum uniquement.
import openhtf as htf
# Minimum uniquement : réussite si la valeur >= -80
@htf.measures(
htf.Measurement("signal_strength")
.in_range(minimum=-80)
.doc("Force du signal Wi-Fi en dBm"),
)
def test_signal(test):
test.measurements.signal_strength = -65
# Maximum uniquement : réussite si la valeur <= 100
@htf.measures(
htf.Measurement("response_time")
.in_range(maximum=100)
.doc("Latence de réponse en millisecondes"),
)
def test_latency(test):
test.measurements.response_time = 42Correspondance exacte : .equals()
Réussite si la valeur correspond exactement. Fonctionne avec les chaînes de caractères, les booléens et les nombres.
import openhtf as htf
# Correspondance de chaîne
@htf.measures(
htf.Measurement("firmware_version")
.equals("2.1.0")
.doc("Chaîne de version du firmware attendue"),
)
def test_firmware(test):
test.measurements.firmware_version = "2.1.0"
# Correspondance booléenne
@htf.measures(
htf.Measurement("led_on")
.equals(True)
.doc("La LED d'alimentation est allumée"),
htf.Measurement("error_flag")
.equals(False)
.doc("Aucun drapeau d'erreur activé"),
)
def test_indicators(test):
test.measurements.led_on = True
test.measurements.error_flag = FalseTolérance en pourcentage : .within_percent()
Réussite si la valeur est dans un pourcentage de la cible. Utile pour les composants calibrés.
import openhtf as htf
from openhtf.util import units
@htf.measures(
# Cristal 8MHz, tolérance 1% -> 7.92MHz à 8.08MHz
htf.Measurement("clock_freq")
.within_percent(8_000_000, 1.0)
.with_units(units.HERTZ)
.doc("Fréquence de l'oscillateur à cristal 8MHz"),
# Résistance 10kOhm, tolérance 5% -> 9.5kOhm à 10.5kOhm
htf.Measurement("pullup_resistance")
.within_percent(10_000, 5.0)
.with_units(units.OHM)
.doc("Valeur de la résistance de rappel I2C"),
)
def test_components(test):
test.measurements.clock_freq = 8_000_100
test.measurements.pullup_resistance = 9_850.within_percent(target, percent) est équivalent à .in_range(target * (1 - pct/100), target * (1 + pct/100)) mais plus clair dans son intention.
Correspondance regex : .matches_regex()
Réussite si la chaîne correspond à une expression régulière. Utile pour la validation de format.
import openhtf as htf
@htf.measures(
# Format d'adresse MAC : AA:BB:CC:DD:EE:FF
htf.Measurement("mac_address")
.matches_regex(r"^([0-9A-F]{2}:){5}[0-9A-F]{2}$")
.doc("Format de l'adresse MAC de la carte"),
# Version sémantique : X.Y.Z
htf.Measurement("fw_version")
.matches_regex(r"^\d+\.\d+\.\d+$")
.doc("Format de la version du firmware"),
)
def test_strings(test):
test.measurements.mac_address = "AA:BB:CC:DD:EE:FF"
test.measurements.fw_version = "2.1.0"Limites marginales
OpenHTF prend en charge les limites marginales (limites internes au sein de la plage de réussite). Une mesure entre la limite marginale et la limite de spécification réussit mais est signalée comme marginale. Cela permet de détecter les mesures qui dérivent vers l'échec.
import openhtf as htf
from openhtf.util import units
@htf.measures(
htf.Measurement("rail_3v3")
.in_range(
minimum=3.2,
maximum=3.4,
marginal_minimum=3.22,
marginal_maximum=3.38,
)
.with_units(units.VOLT)
.doc("Rail 3.3V avec bande marginale"),
)
def test_marginal_voltage(test):
# 3.21V réussit mais est signalé comme marginal (entre 3.20 et 3.22)
# 3.25V réussit normalement (dans les limites marginales)
# 3.19V échoue (en dessous de 3.20)
test.measurements.rail_3v3 = 3.21| Valeur | Statut | Explication |
|---|---|---|
| 3.25 | Réussite | Dans les limites marginales |
| 3.21 | Marginal | Entre la limite de spécification (3.20) et la limite marginale (3.22) |
| 3.39 | Marginal | Entre la limite marginale (3.38) et la limite de spécification (3.40) |
| 3.19 | Échec | En dessous de la limite de spécification (3.20) |
| 3.41 | Échec | Au-dessus de la limite de spécification (3.40) |
Référence des unités
OpenHTF fournit les unités SI standard via from openhtf.util import units. Utilisez toujours .with_units() pour les mesures numériques. Cela alimente les analyses TofuPilot et rend les rapports lisibles.
| Unité | Constante OpenHTF | Cas d'utilisation |
|---|---|---|
| Volt | units.VOLT | Rails de tension, signaux analogiques |
| Ampère | units.AMPERE | Consommation de courant |
| Ohm | units.OHM | Résistance, impédance |
| Hertz | units.HERTZ | Fréquence, signaux d'horloge |
| Celsius | units.DEGREE_CELSIUS | Température |
| Seconde | units.SECOND | Temps, latence |
| Watt | units.WATT | Consommation électrique |
Plusieurs mesures par phase
Regroupez les mesures liées dans une seule phase. Cela permet de garder le rapport de test organisé et le temps de test efficace.
import openhtf as htf
from openhtf.util import units
@htf.measures(
htf.Measurement("rail_3v3").in_range(3.2, 3.4).with_units(units.VOLT),
htf.Measurement("rail_5v0").in_range(4.8, 5.2).with_units(units.VOLT),
htf.Measurement("idle_current").in_range(0.05, 0.25).with_units(units.AMPERE),
htf.Measurement("led_on").equals(True),
htf.Measurement("firmware").equals("2.1.0"),
)
def test_board_basics(test):
test.measurements.rail_3v3 = 3.31
test.measurements.rail_5v0 = 5.01
test.measurements.idle_current = 0.12
test.measurements.led_on = True
test.measurements.firmware = "2.1.0"Recommandation : Regroupez les mesures logiquement liées (tous les rails d'alimentation dans une phase, toutes les vérifications de communication dans une autre). Séparez en phases distinctes si elles nécessitent des instruments différents ou ont des délais d'attente différents.
Définir les limites à partir des fiches techniques
Commencez avec les valeurs maximales et minimales absolues de la fiche technique. Puis affinez en fonction des données de production.
| Source | Utilisation | Exemple |
|---|---|---|
| Fiche technique | Limites initiales | Régulateur 3.3V : 3.135V à 3.465V (tolérance 5%) |
| Données de production (100+ unités) | Limites affinées | 3-sigma à partir de la distribution mesurée |
| Exigences client | Limites obligatoires | Spécifiées dans la spécification de test |
import openhtf as htf
from openhtf.util import units
# La fiche technique indique : 3.3V +/- 5% = 3.135V à 3.465V
# Les données de production montrent : moyenne=3.30, écart-type=0.015
# 3-sigma : 3.255 à 3.345 (plus serré, utilisez ces valeurs)
@htf.measures(
htf.Measurement("rail_3v3")
.in_range(3.255, 3.345)
.with_units(units.VOLT)
.doc("Rail 3.3V (3-sigma des données de production)"),
)
def test_refined_limits(test):
test.measurements.rail_3v3 = 3.31