Suivi des inspections IPC-A-610 avec TofuPilot
IPC-A-610 est la norme d'acceptabilité pour les assemblages électroniques. Elle définit ce à quoi ressemble un « bon » résultat pour les joints de soudure, le placement des composants, la propreté et l'assemblage mécanique. TofuPilot suit les résultats d'inspection de manière systématique au lieu de s'appuyer sur des listes de contrôle papier.
Ce que couvre IPC-A-610
IPC-A-610 classe les défauts en trois classes de produits :
| Classe | Application | Critères d'acceptation |
|---|---|---|
| Classe 1 | Électronique générale (grand public) | Les moins stricts |
| Classe 2 | Électronique de service dédié (industriel) | Modérés |
| Classe 3 | Électronique haute performance (médical, aérospatial, militaire) | Les plus stricts |
Les critères d'inspection incluent :
| Catégorie | Exemples |
|---|---|
| Joints de soudure | Mouillage, ménisques, ponts, joints froids |
| Placement des composants | Alignement, orientation, polarité |
| Propreté | Résidus de flux, contamination, corrosion |
| Mécanique | Routage des fils, décharge de traction, enrobage conforme |
| Marquage | Étiquettes, références, codes de date |
Enregistrer les résultats d'inspection dans TofuPilot
Inspection par carte
from tofupilot import TofuPilotClient
client = TofuPilotClient()
def log_inspection(serial, inspector, defects):
"""Enregistrer les résultats d'inspection IPC-A-610."""
measurements = [
{"name": "inspector_id", "value": inspector, "unit": ""},
{"name": "ipc_class", "value": 2, "unit": "class"},
{"name": "total_defects", "value": len(defects), "unit": "count", "limit_high": 0},
]
# Enregistrer chaque catégorie de défaut
defect_categories = {
"solder": 0, "placement": 0, "cleanliness": 0,
"mechanical": 0, "marking": 0,
}
for d in defects:
if d["category"] in defect_categories:
defect_categories[d["category"]] += 1
for cat, count in defect_categories.items():
measurements.append({
"name": f"defects_{cat}",
"value": count,
"unit": "count",
"limit_high": 0,
})
passed = len(defects) == 0
client.create_run(
procedure_id="IPC610-VISUAL-INSPECTION",
unit_under_test={
"serial_number": serial,
"part_number": "MAIN-BOARD-V4",
},
run_passed=passed,
steps=[{
"name": "IPC-A-610 Class 2 Inspection",
"step_type": "measurement",
"status": passed,
"measurements": measurements,
}],
)
# Exemple : carte avec deux défauts
log_inspection(
serial="PCB-2025-04521",
inspector="OP-012",
defects=[
{"category": "solder", "location": "U12-pin3", "type": "insufficient_wetting"},
{"category": "cleanliness", "location": "J5-area", "type": "flux_residue"},
],
)Classification des défauts
Enregistrez les types de défauts spécifiques pour construire un pareto de défauts.
# Enregistrement détaillé des défauts
defect_types = {
"solder_bridge": "Pont de soudure entre broches adjacentes",
"cold_joint": "Joint de soudure froid ou perturbé",
"insufficient_wetting": "Mouillage insuffisant sur le pad ou la broche",
"solder_ball": "Bille de soudure libre sur la surface de la carte",
"tombstone": "Composant debout sur un côté (effet pierre tombale)",
"misalignment": "Composant décalé par rapport au centre du pad",
"wrong_polarity": "Composant polarisé installé à l'envers",
"missing_component": "Composant non placé",
"flux_residue": "Résidus de flux excessifs après nettoyage",
"damaged_component": "Corps du composant fissuré ou ébréché",
}
# Enregistrer chaque défaut avec son type
for defect in board_defects:
measurements.append({
"name": f"defect_{defect['type']}",
"value": 1,
"unit": "count",
"limit_high": 0,
})Analyse Pareto des défauts
Les analyses de TofuPilot vous montrent les types de défauts les plus courants sur l'ensemble de la production.
| Rang | Type de défaut | Nombre | Pourcentage |
|---|---|---|---|
| 1 | Mouillage insuffisant | 45 | 32% |
| 2 | Pont de soudure | 28 | 20% |
| 3 | Résidus de flux | 22 | 16% |
| 4 | Désalignement | 15 | 11% |
| 5 | Joint froid | 12 | 9% |
| - | Tous les autres | 18 | 13% |
Corrigez d'abord le type de défaut le plus fréquent. Le mouillage insuffisant (32%) est probablement un problème de pâte à braser (usure du pochoir, viscosité de la pâte ou profil de refusion).
Cohérence des inspecteurs
Suivez les taux de détection de défauts par inspecteur pour identifier les besoins en formation.
from tofupilot import TofuPilotClient
client = TofuPilotClient()
runs = client.get_runs(
procedure_id="IPC610-VISUAL-INSPECTION",
limit=1000,
)
# Grouper par inspecteur
inspector_stats = {}
for run in runs:
for step in run.get("steps", []):
for m in step.get("measurements", []):
if m["name"] == "inspector_id":
inspector = m["value"]
if inspector not in inspector_stats:
inspector_stats[inspector] = {"total": 0, "rejected": 0}
inspector_stats[inspector]["total"] += 1
if not run["run_passed"]:
inspector_stats[inspector]["rejected"] += 1
for inspector, stats in inspector_stats.items():
reject_rate = stats["rejected"] / stats["total"] * 100
print(f"Inspecteur {inspector} : {stats['total']} cartes, {reject_rate:.1f}% taux de rejet")Si l'inspecteur A rejette 8% et l'inspecteur B rejette 2% sur le même produit, soit A est trop strict, soit B manque des défauts. Calibrez les inspecteurs à l'aide de cartes de référence avec des défauts connus.
Relier l'inspection au test électrique
La vraie puissance réside dans la corrélation des résultats d'inspection visuelle avec les résultats de test électrique.
Si des cartes passent l'inspection visuelle mais échouent au test fonctionnel sur une mesure spécifique, il peut y avoir un type de défaut que l'inspection visuelle ne détecte pas. Inversement, si des cartes rejetées visuellement sont reprises et passent systématiquement le test fonctionnel, les critères visuels sont peut-être trop stricts pour votre classe de produit.
TofuPilot lie les résultats d'inspection et de test électrique au même numéro de série, rendant cette corrélation directe.
Intégration AOI
Les systèmes d'Inspection Optique Automatisée (AOI) peuvent envoyer les résultats à TofuPilot de la même manière que les inspections manuelles.
# Analyser la sortie de la machine AOI et l'envoyer à TofuPilot
import json
with open("aoi_results.json") as f:
aoi_data = json.load(f)
for board in aoi_data["boards"]:
defects = board.get("defects", [])
client.create_run(
procedure_id="AOI-INSPECTION",
unit_under_test={"serial_number": board["serial"]},
run_passed=len(defects) == 0,
steps=[{
"name": "AOI Scan",
"step_type": "measurement",
"status": len(defects) == 0,
"measurements": [
{"name": "defect_count", "value": len(defects), "unit": "count", "limit_high": 0},
{"name": "scan_coverage_pct", "value": board.get("coverage", 100), "unit": "%"},
],
}],
)Combinez les données AOI avec les données d'inspection manuelle et de test électrique dans TofuPilot pour obtenir une image qualité complète de chaque carte.