- Slot Occupancy Detection
- PCB Defect Inspection
- PCBA Big Component Inspection
- PCBA Small Component Inspection

- Bare PCBs are inspected for scratches and visible surface damage.
- Assembled PCBAs go through component-Slevel inspection, verifying both large components (USB-C, JST connectors, switches, power ICs, inductors) and smaller 0805 components (LEDs, resistors, capacitors).
Training the Machine Learning Models
As mentioned earlier, for this project I am using a custom battery charging and discharging circuit PCB, but the same approach can be applied to almost any PCB or PCBA depending on your inspection requirements. The first step is to build the dataset for each of the four vision models. Since the final system will use the same webcam and camera position, it is important to capture the training images using the same camera and setup that will be used during the actual inspection. I connected the webcam to my PC, opened the Camera app, and captured multiple images of the different inspection conditions. I captured images of an empty slot, bare PCB, and assembled PCBA, along with different examples of the defects and components that I wanted the models to learn. In general, having more representative images for each condition gives the model more examples to learn from and can help improve its ability to generalize.



Model Classes & Annotations
-
Slot Occupancy Model (Image Classification):
EmptyPCBPCBA
-
PCB Inspection Model (Object Detection):
Issue / Scratch— Used to identify visible scratches or damage on the PCB surface.

- PCBA Big Component Inspection Model (Object Detection):
Classes based on the component type and whether the component is present (
A= Available) or missing (N= Not Available):SA/SN— SMD Switch Available / Not AvailableUA/UN— USB Type-C Available / Not AvailableC1A/C1N,C2A/C2N— JST Connector 1/2 Available / Not AvailableIA/IN— Inductor Available / Not AvailablePA/PN— Power IC Available / Not Available

- PCBA Small Component Inspection Model (Object Detection for 0805 components):
L1A/L1N,L2A/L2N— LEDsC1A/C1NthroughC7A/C7N— CapacitorsR1A/R1N,R3A/R3N,R4A/R4N,R5A/R5N— Resistors
Dataset Organization

Label.csv file. Keeping the four datasets isolated is important because each model has a different purpose and different set of classes.
Preparing the Dataset for YOLO Training
Once the images have been captured and annotated in MakeSense, the next step is to convert the dataset into the format required by YOLO. The original dataset contains the captured images and thelabels_makesense.csv annotation file. For the example Big Component Inspection model, the dataset contains 44 images and 264 bounding-box annotations, split into 36 training images and 8 testing images.
The MakeSense annotations are then converted into the standard YOLO dataset structure:
[!IMPORTANT] One critical detail in this project is that the components are mounted in fixed physical positions on the PCB. Because of this, horizontal and vertical image flipping were disabled during augmentation. Flipping the image could effectively swap components from one side of the PCB to another and teach the model an incorrect spatial relationship.
Training & Evaluating the YOLO Model
Training the YOLO Model
For this project, I used YOLO11 Nano (yolo11n.pt), a lightweight object-detection model that is well suited for edge deployment. The model was trained for 80 epochs with an image size of 640 × 640, a batch size of 8, and an NVIDIA RTX 5070 Ti GPU.
The training was executed using:





Evaluating and Testing the YOLO Model
After training the YOLO model, the next step is to evaluate its performance using the validation dataset. For the example Big Component Inspection model:- Precision: 97.94%
- Recall: 100%
- mAP@0.5: 99.50%
- mAP@0.5:0.95: 89.60%



Exporting the YOLO Model to ONNX
Once the YOLO model has been trained and tested successfully, the next step is to export the best model into ONNX (Open Neural Network Exchange) format:- Saved Path:
runs/train/weights/best.onnx - Model Size: ~10.1 MB
- Opset Version: 17/18
- Graph Optimization: Optimized using
onnxslimto reduce unnecessary overhead while keeping the trained model intact. - Input Shape:
[1, 3, 640, 640]infloat32format. - Output Shape:
[1, 16, 8400], containing bounding-box coordinates and confidence scores for the 12 large-component classes. - Inference Speed: ~3.2 ms per image in ONNX Runtime.
Importing the YOLO Model into Edge Impulse (BYOM)
The same training process is followed for the other inspection models. Once the models are exported to ONNX, we bring them into Edge Impulse using Bring Your Own Model (BYOM).Creating the Edge Impulse Project


- Open Edge Impulse Studio and log into your account.
- Click Create New Project and enter a name.
- In the project dashboard, click Upload your Model.
- Select the
weights/best.onnxfile generated during the YOLO training process. - When Edge Impulse asks whether you want performance characteristics (latency, RAM, ROM) for a specific device, select Yes.
- Select Arduino Uno Q as the target device.
- Click Upload.


Configuring the Imported Model

- Model Input: Image
- Model Output: Object Detection
- Resize Mode: Fit Long Axis
- Output Layer: YOLOv11 (Coordinates in absolute values)
- Output Labels: Match the class names used when training the YOLO model.
- Click Save.
Why Use Edge Impulse If We Already Have a YOLO Model?
- Customization: With BYOM, we are not restricted to only models trained inside Edge Impulse. We can train separate YOLO models specifically for slot occupancy, PCB inspection, and PCBA component inspection using standard PyTorch/Ultralytics pipelines.
- Performance Optimization: Edge Impulse profiles and optimizes the model specifically for the target hardware (Qualcomm QRB2210 Linux MPU on the Arduino UNO Q).
- Faster Deployment: Packaging models into standalone
.eimexecutable binaries removes external Python runtime overhead and makes deployment seamless. - Flexibility: Keeps a modular workflow:
Testing and Building the Model
In Edge Impulse, upload validation images to Data Acquisition, go to Model Testing, and click Classify All.

Deploying the Vision Inspection System on Arduino UNO Q
You can also use Live Classification directly in the browser to point your webcam at the PCB/PCBA and inspect real-time predictions. On the Deployment page, select Arduino UNO Q and click Build to download the standalone.eim executable binary.

.eim files ready, we deploy the complete system to the Arduino UNO Q:

Inspection Pipeline Flow
- Camera Acquisition: The webcam continuously captures the inspection area.
- Slot Occupancy: Stage 1 runs
slot-occupancy.eim.- If Empty: Inspection for this slot is skipped.
- If PCB: Runs
pcb-inspection.eimto check for scratches and defects. - If PCBA: Runs
big-components-inspection.eimandsmall-components-inspection.eimto verify all components.
- PASS / FAIL Logic: Determines pass/fail status based on missing parts or detected defects.
- Hardware Action: Sends RPC commands to the Arduino firmware to set the WS2812B RGB LED color and rotate the servo turntable to the next slot.
- Web Dashboard: Hosts a live interface on port 5000 to display camera frames, bounding boxes, and pass/fail counts.
Arduino UNO Q Dual-Domain Architecture (MPU + MCU)
The UNO Q features two separate processors:- Qualcomm MPU (Linux): Runs the Python application, webcam capture, Edge Impulse
.eimmodels, inspection logic, and Flask web dashboard. - STM32U585 MCU (Zephyr / Arduino): Handles real-time hardware execution: servo motor PWM on Pin 9 and WS2812B addressable LED data on Pin 8.
Step-by-Step Setup & Execution
Flash Arduino Firmware

- Open the Arduino IDE on your computer.
- Open
bms_servo_led.inolocated in:BMS EIM Vision Inspection/arduino_firmware/bms_servo_led/bms_servo_led.ino - Select board Arduino UNO Q and the corresponding port.
- Click Upload.
- Once complete, the RGB LED illuminates green and the turntable positions itself to home (0°).
Aligning the Rotating Plate
Check whether the first slot is aligned with the camera. If it is slightly off, loosen the center servo horn screw, manually rotate the plate to exact center, and re-tighten. This sets the mechanical home position.Deploying to the Arduino UNO Q
- Connect the Arduino UNO Q to a powered USB hub and connect the webcam to the same hub.
-
Identify your UNO Q’s IP address (e.g.,
192.168.1.18). -
Copy the project folder to the UNO Q using
scp: -
SSH into the UNO Q:
-
Set up the Python environment:
-
Start the inspection application:
(If your webcam is assigned to a different index, try
--source 1or--source 2).

Running the Application on Subsequent Boots
Accessing the Web Dashboard
Open any browser on the local network and navigate to:



- Live inspection camera stream with detection overlays
- Current slot number and inspection status (Empty, PCB, PCBA, Pass/Fail)
- Manual turntable indexing and home calibration controls
- Captured defect snapshots and inspection history
Conclusion

