Welcome to ESP32 WiFi Camera Lite repository
ESP32
ESP32-S3 Image Transmission and Steel Ball Detection Tutorial
1. Feature Overview
- ESP32-S3 drives the GC2145 camera to capture
320x240 YUV422images. - Identifies the bright core and surrounding dark ring of steel balls on the raw YUV422 frame.
- Web page displays real-time MJPEG preview, blue ROI bounding box, red target box, and FPS.
- Web page allows adjusting manual exposure, ROI Y, and ROI Height.
- Browser can capture still frames or record the preview as MP4.
- Detection results are sent to MSPM0 via UART1 in a fixed 8-byte data packet.
- Serial log provides detection status and timing statistics for camera, encoding, and network transmission.
Do not confuse the two image sizes currently in use:
| Purpose | Size | Format | Description |
|---|---|---|---|
| Camera capture and local detection | 320x240 | YUV422 | Detection always reads the Y luminance channel from this raw frame |
| Web MJPEG preview | 320x240 | JPEG | Scaled proportionally in the HTTP streaming module; only affects web clarity and bandwidth |
Changing the web preview size does not alter the detection coordinate system. The X coordinate received by MSPM0 remains 0~319 in the original 320x240 image.

2. Hardware and Software Environment
2.1 Software Environment
- Windows PowerShell
- ESP-IDF
v5.1.2 - Target chip: ESP32-S3
- Project directory:
C:\Espressif\frameworks\esp-idf-v5.1.2\video-wifi\esp32Board_wifi - Shared components directory:
C:\Espressif\frameworks\esp-idf-v5.1.2\video-wifi\components - JPEG component:
esp_new_jpeg 1.0.2
2.2 Hardware Configuration
- Camera: GC2145
- Flash: 4 MB
- PSRAM: 2 MB, 80 MHz
- ESP32-S3 CPU: 240 MHz
- Camera XCLK: 15 MHz
- UART0: 115200, used for logging and IP information
- UART1: 115200, 8N1, no flow control, used for sending detection results to MSPM0
- UART1 TX: GPIO36
- UART1 RX: GPIO35
3. Quick Start
3.1 Set Up the ESP-IDF Environment
Place the source code in the C:\Espressif\frameworks\esp-idf-v5.1.2 directory, open ESP-IDF 5.1 CMD, and run:
cd video-wifi\esp32Board_wifi3.2 Build
xxxxxxxxxxidf.py buildAfter a successful build, the main firmware files are located at:
xxxxxxxxxxbuild/Camera_Display.binDo not run idf.py set-target esp32s3 before every build. This command may regenerate the configuration and should only be used when creating a new build directory or when the target configuration is corrupted.
3.3 Flash and Open Serial Monitor
First confirm the current COM port number in Device Manager, then run:
xxxxxxxxxxidf.py -p COMxx flash monitorReplace COMxx with your actual port number, e.g., com48. You can check which port is currently in use via Device Manager.

3.4 Obtain the Device IP
After startup, UART0 outputs the version and IP address, for example:
xxxxxxxxxxYAHBOOM Board Ver:AI_V1.5.1sta_ip:192.168.x.xap_ip:192.168.4.1You can also manually send the IP query command:
xxxxxxxxxxsta_ip:ap_ip:
The current source code sets wifi_Mode = 1, which means only STA mode is enabled. Therefore, you should access the sta_ip address rather than the fixed AP address.
Open in browser:
xxxxxxxxxxDevice STA IPFor example:
xxxxxxxxxx192.168.1.1004. Wi-Fi Configuration
The Wi-Fi implementation is located in:
xxxxxxxxxxmain/src/app_mywifi.cThis file contains the SSID and password configuration for both STA and AP modes:
wifi_SSID: Router name the ESP32 connects towifi_PASSWD: Router passwordAP_wifi_SSID: SSID of the hotspot created by ESP32AP_wifi_PASSWD: Password of the hotspot created by ESP32
The Wi-Fi mode is selected in main/app_main.cpp:
xxxxxxxxxxuint16_t wifi_Mode = 1; // 0: AP, 1: STA, 2: AP+STA| Value | Mode | Usage |
|---|---|---|
0 | AP | Connect your computer to the ESP32 hotspot, then visit http://192.168.4.1/ |
1 | STA | ESP32 connects to a router; visit the sta_ip shown in the serial output |
2 | AP+STA | Both network interfaces are active simultaneously |
The current configuration is STA-only. If switched to AP mode, the default AP name is Yahboom_ESP32_WIFI with a fixed address of 192.168.4.1.
5. Web Page Operations
5.1 Video Streaming
After opening the device home page:
- Click
Start Streamto begin real-time video streaming. - Click
Stop Streamto stop streaming. - Click
Get Stillto capture a single frame. - Click
Record MP4to start browser-side recording. - During recording, the button displays
Recording. - Click the record button again to stop and download the MP4 file.
Recording is performed by the browser: the page draws the MJPEG stream onto a Canvas and uses the browser's MediaRecorder to produce MP4/H.264. If the browser does not support MP4 MediaRecorder, the page will display a notification and will not generate a fake MP4 with just a renamed extension. A recent version of Microsoft Edge or Chrome is recommended for best compatibility.
5.2 Manual Exposure
The Exposure control on the web page supports:
- Slider adjustment
-and+single-step adjustment- Current value display
- Valid range:
1~4095

Value behavior:
| Direction | Visual Change | Motion Effect |
|---|---|---|
| Decrease value | Darker image | Shorter exposure time, usually less motion blur |
| Increase value | Brighter image | Longer exposure time, usually more pronounced motion blur |
The current firmware disables the GC2145 auto-exposure (AEC) at startup and sets the manual exposure to:
xxxxxxxxxxHexadecimal 0x0400 equals decimal 1024. If you re-enable AEC SENSOR on the web page, the sensor will automatically adjust exposure and the manual Exposure value may no longer correspond to a fixed exposure level. To maintain a fixed brightness and reduce motion blur, keep AEC SENSOR disabled.
5.3 ROI Adjustment
The web page provides the following two runtime parameters:
ROI Y: Top Y coordinate of the detection regionROI Height: Height of the detection region
Both support slider and - / + single-step adjustment, changing by 1 pixel each time. The blue rectangle represents the current ROI.
Default values:
xxxxxxxxxxROI X = 0ROI Y = 70ROI Width = 320ROI Height = 25The following constraints must be satisfied:
xxxxxxxxxxROI Y >= 0ROI Height >= 9ROI Y + ROI Height <= 240The web page enforces linked limits on Y and Height, and the firmware interface also performs boundary checks. Web page modifications are only stored in RAM and will revert to the defaults in the header file after a device restart.
It is recommended to position the steel ball's trajectory near the center line of the blue box. The algorithm only scans a narrow band of 5 pixels above and below the ROI center line, so even if the steel ball is within the blue box, it may not be detected if it is too far from the ROI center line.
6. Code Directory and Module Responsibilities
xxxxxxxxxxvideo-wifi/├─ components/ Shared components│ ├─ modules/web/www/│ │ ├─ index_gc2145.html GC2145 web page source│ │ └─ index_gc2145.html.gz Compressed page embedded into firmware at build time│ └─ yahboom_esp32-camera/│ └─ sensors/gc2145.c GC2145 sensor registers and control interface└─ esp32Board_wifi/ ├─ main/ │ ├─ app_main.cpp Application entry and module initialization │ ├─ include/ │ │ ├─ yahboom_detection.h Detection parameters, state structures, and interfaces │ │ ├─ yahboom_camera.h Camera interface │ │ ├─ yahboom_msp_uart.h MSPM0 data packet definition │ │ ├─ my_usart.h UART0 configuration │ │ └─ my_usart1_user.h UART1 configuration │ └─ src/ │ ├─ yahboom_camera.c Camera initialization and camera task │ ├─ yahboom_detection.c Bright-core dark-ring detection, tracking, and image overlay │ ├─ yahboom_msp_uart.c MSPM0 data packet and asynchronous send task │ ├─ app_myhttpd.cpp HTTP control, status, and MJPEG streaming │ ├─ app_mywifi.c Wi-Fi initialization and credential configuration │ ├─ app_mymdns.c mDNS service │ ├─ my_usart.c UART0 driver and command handling │ └─ my_usart1_user.c UART1 low-level send driver ├─ partitions.csv Flash partition table ├─ sdkconfig Current complete build configuration └─ sdkconfig.defaults* Default configuration7. Startup Sequence and Data Flow
The main startup sequence in main/app_main.cpp is:
- Create a camera streaming queue with length 1.
- Initialize UART1.
- Initialize the MSPM0 data packet send task.
- Initialize Wi-Fi.
- Register and start the GC2145 camera.
- Start mDNS.
- Start the HTTP control service and MJPEG streaming service.
- Initialize UART0 and output version and IP information.
The complete data flow is as follows:
The camera queue length is 1. When a new frame arrives and the queue still contains an old frame, the program returns the old frame and replaces it with the new one, preventing preview latency from growing due to temporary network stalls.
The camera uses:
xxxxxxxxxxmy_register_camera(PIXFORMAT_YUV422, FRAMESIZE_QVGA, 2, xQueueAIFrame);Which corresponds to:
- QVGA
320x240 - YUV422
- 2 frame buffers
- Frame buffers allocated in PSRAM
CAMERA_GRAB_LATEST- Camera task pinned to CPU1, priority 5
8. Steel Ball Detection Algorithm
8.1 Why Use YUV422 Directly
GC2145 outputs YUV422. The algorithm only needs luminance, not color, so it reads the Y component of each pixel directly:
- Does not generate an RGB image
- Does not separately generate a grayscale image
- Does not perform background modeling
- Does not invoke neural networks
This reduces memory usage and eliminates color conversion overhead.
8.2 Bright Core and Dark Ring Sampling
Since the steel ball is fixed inside the swing arm, the detection scenario can be visualized as follows:

The image clearly shows that the steel ball has a bright center and a dark outer ring. This characteristic can be leveraged for detection to reduce the processing load on the ESP32.
For each candidate center (x, y):
- Read 5 luminance samples at the center and at the up/down/left/right neighbors to compute
center_brightness. - Read 4 samples at a radius of 4 pixels from the center (up, down, left, right).
- Read 4 diagonal samples with horizontal and vertical offsets of 3 pixels.
- Compute
ring_brightnessfrom the 8 ring samples. - Calculate:
xxxxxxxxxxscore = center_brightness - ring_brightness- Count how many of the 8 dark ring points satisfy:
xxxxxxxxxxcenter_brightness - ring_sample >= 18A candidate must simultaneously satisfy:
xxxxxxxxxxcenter_brightness >= 120score >= 32dark_sample_count >= 6Among all valid candidates, the one with the highest score is selected.
8.3 Scan Range
The restriction to the swing arm region for ball searching means the algorithm does not scan the entire image. An ROI detection range is defined:
- X direction covers the ROI width.
- Y direction only scans 5 pixels above and below the ROI center line.
- X and Y candidate step sizes are both 2 pixels.
- When a valid trajectory exists, the X search is limited to ±48 pixels around the previous coordinate.
This approach suits scenarios where the steel ball moves laterally along a fixed pipe or rail. The computational cost is low, but the mechanical setup must first align the ROI center line with the steel ball trajectory.
8.4 Tracking, Miss Hold, and Recapture
The detection state is not "hit once and use forever" — it also enforces consecutive-frame constraints:
- During normal tracking, the maximum allowed jump between adjacent valid coordinates is 30 pixels.
- After a single missed detection, the last measured coordinate is held for at most 1 detection cycle.
- After 3 consecutive detection cycles without a hit, the old trajectory is cleared.
- After clearing, a newly found candidate must be confirmed 2 consecutive times before a trajectory is re-established.
- During recapture, the maximum allowed X drift between adjacent candidates is 40 pixels.
This suppresses instantaneous false jumps caused by isolated bright spots, but overly strict thresholds will make it difficult to track fast-moving steel balls.
8.5 On-Screen Markers
- Blue rectangle: Current ROI, line width 2 pixels.
- Red rectangle: Fixed marker near the current target center.
- Red box half-length is 6 pixels, so the actual bounding box is approximately
13x13original pixels. - Red box line width is 2 pixels.
The red box size does not represent the actual diameter of the detected steel ball. The WIDTH field in the UART data packet is currently the dark ring diameter, fixed at 8, and should not be treated as an actual physical width measurement.
9. MSPM0 UART Communication
9.1 Hardware and Serial Parameters
xxxxxxxxxxESP32-S3 GPIO36 (UART1 TX) -> MSPM0 RXESP32-S3 GPIO35 (UART1 RX) <- MSPM0 TXESP32-S3 GND - MSPM0 GNDSerial configuration:
xxxxxxxxxx115200 baud, 8 data bits, no parity, 1 stop bit, no flow controlA common ground connection is required even though the current communication is unidirectional.
9.2 8-Byte Data Packet
| Offset | Field | Description |
|---|---|---|
| 0 | 0xAA | Fixed frame header byte 1 |
| 1 | 0x55 | Fixed frame header byte 2 |
| 2 | FLAGS | bit0 = 1 indicates coordinates are valid |
| 3 | SEQ | Increments by 1 with each packet; wraps from 0xFF to 0x00 |
| 4 | X_L | Center X coordinate, low byte |
| 5 | X_H | Center X coordinate, high byte |
| 6 | WIDTH | Current feature width; currently the dark ring diameter of 8 |
| 7 | CHECKSUM | Lower 8 bits of the sum of the first 7 bytes |
Coordinate assembly:
xxxxxxxxxxuint16_t x = packet[4] | ((uint16_t)packet[5] << 8);Checksum:
xxxxxxxxxxuint8_t checksum = 0;for (int i = 0; i < 7; ++i) checksum += packet[i];When FLAGS & 0x01 is 0, both X and WIDTH are set to 0, and MSPM0 should not continue using stale coordinates.
The send module uses a queue of length 1 with xQueueOverwrite(): if the UART task has not finished sending the previous packet, the new detection state overwrites the old one, ensuring the latest coordinates are sent rather than accumulating a backlog.
MSPM0-side recommendations:
- Use a state machine to search for the consecutive frame header
AA 55. - Verify the checksum only after the fixed length is confirmed.
- Only use X when
valid = 1and the checksum is correct. - Monitor whether
SEQis continuously updating. - If no new sequence number is received for approximately
100~150 ms, enter a coordinate-loss protection state.
10. Key Detection Parameters
The main detection parameters are located in:
xxxxxxxxxxmain/include/yahboom_detection.h10.1 ROI Parameters
| Parameter | Current Value | Function | Adjustment Advice |
|---|---|---|---|
DETECTION_ROI_X | 0 | ROI top-left X | Currently covers the full width; generally no change needed |
DETECTION_ROI_Y_DEFAULT | 70 | ROI top at startup | Position above the steel ball trajectory |
DETECTION_ROI_WIDTH | 320 | ROI width | Currently covers the full X coordinate range |
DETECTION_ROI_HEIGHT_DEFAULT | 25 | ROI height at startup | Smaller reduces interference but decreases installation tolerance |
DETECTION_ROI_BORDER_THICKNESS_PIXELS | 2 | Blue box line width | Display only |
10.2 Feature Geometry Parameters
| Parameter | Current Value | Function | Effect of Increasing |
|---|---|---|---|
DETECTION_RING_CENTER_RADIUS | 1 | Bright core cross-sampling offset | More dispersed bright core sampling; too large and it samples the dark ring |
DETECTION_RING_RADIUS | 4 | Up/down/left/right dark ring radius | Matches larger targets; WIDTH also increases |
DETECTION_RING_DIAGONAL_OFFSET | 3 | Diagonal dark ring sampling offset | Changes the diagonal sampling ring size |
DETECTION_RING_CENTERLINE_HALF_HEIGHT | 5 | ROI center line search half-height | Tolerates larger vertical deviations but increases computation and false positives |
DETECTION_RING_SCAN_STEP | 2 | Candidate scan step | Faster but coarser coordinates; may skip small bright cores |
DETECTION_RING_TRACK_SEARCH_HALF_WIDTH | 48 | X search half-width during tracking | Tolerates faster motion but increases interference candidates |
RING_RADIUS and DIAGONAL_OFFSET should be adjusted as a pair based on the actual pixel size of the steel ball in the original 320x240 image. Do not judge by the scaled web preview display size.
10.3 Brightness Thresholds
| Parameter | Current Value | Meaning | Effect of Increasing |
|---|---|---|---|
DETECTION_RING_MIN_CENTER_BRIGHTNESS | 120 | Minimum average Y of bright core | Reduces false positives in dark areas but may miss balls with insufficient highlights |
DETECTION_RING_MIN_SCORE | 32 | Minimum difference between bright core and dark ring averages | Requires stronger bright-dark contrast; fewer false positives, more misses |
DETECTION_RING_MIN_DARK_SAMPLE_CONTRAST | 18 | Minimum difference between a single dark ring sample and the bright core | Stricter dark ring consistency requirement |
DETECTION_RING_MIN_DARK_SAMPLES | 6 | Minimum number of qualifying dark ring samples out of 8 | Increasing to 7 or 8 is stricter; easier to miss under occlusion or reflections |
10.4 State and Tracking Parameters
| Parameter | Current Value | Function | Adjustment Direction |
|---|---|---|---|
DETECTION_EVERY_N_FRAMES | 1 | Detect every N frames | Increase to reduce load, but coordinate updates become slower |
DETECTION_HOLD_MISSED_FRAMES | 1 | Briefly hold coordinates after a miss | Increase for smoother output, but may output stale coordinates |
DETECTION_LOST_COUNT | 3 | Number of consecutive misses before clearing trajectory | Increase to avoid premature loss reports, but recovery to global search is slower |
DETECTION_TRACK_MAX_JUMP_PIXELS | 30 | Maximum single-frame jump for tracked coordinates | Increase for high-speed motion, but more susceptible to jumping to interference |
DETECTION_REACQUIRE_CONFIRM_COUNT | 2 | Consecutive confirmations needed for recapture | Increase for stability, but recovery is slower |
DETECTION_REACQUIRE_MAX_DRIFT_PIXELS | 40 | Maximum X drift for recapture candidates | Increase for high-speed targets, but risk of false capture rises |
DETECTION_LOG_INTERVAL_MS | 500 | Minimum interval between continuous detection logs | Only affects log frequency |
10.5 Display Parameters
| Parameter | Current Value | Function |
|---|---|---|
DETECTION_MARKER_HALF_SIZE_PIXELS | 6 | Red box half-length |
DETECTION_MARKER_THICKNESS_PIXELS | 2 | Red box line width |
Display parameters do not participate in candidate evaluation. Modifying them will not improve detection rate.
11. Recommended Tuning Procedure
Do not change many thresholds at once. Follow this recommended sequence:
Step 1: Fix Mechanical Position and Lighting
- Secure the camera, track, and steel ball height.
- Avoid flickering lights, moving shadows, and direct overexposure.
- Ensure the steel ball has a stable bright core with a relatively darker surrounding profile.
Step 2: Adjust Exposure
- Keep
AEC SENSORdisabled. - Start from the current value around
1024. - Gradually decrease Exposure when motion blur is pronounced.
- If the bright core Y value cannot reach 120, moderately increase Exposure or improve lighting.
- Do not raise exposure solely to make the image "look bright" — overexposure eliminates the dark ring contrast.
Step 3: Adjust ROI
- Start video streaming first.
- Use
ROI Yto align the blue box center line with the steel ball center trajectory. - Use
ROI Heightto cover the vertical fluctuation of the trajectory. - Prefer a narrower ROI when the installation is stable to reduce background interference.
Step 4: Review Detection Logs
Focus on:
xxxxxxxxxxRING_NO_MATCH center=<value> contrast=<value> dark=<value>center < 120: Bright core is not bright enough. Check exposure and lighting first, then consider lowering the center brightness threshold.contrast < 32: Insufficient contrast between bright core and dark ring. Check for overexposure, focus, and sampling radius.dark < 6: Only a few directions on the ring are dark enough. Possible reflections, occlusion, or ring radius mismatch.
Log values provide more reliable guidance than blindly adjusting thresholds.
Step 5: Adjust Geometry
If the bright core and dark ring are clearly visible but dark or contrast consistently fails, adjust:
- Steel ball image is larger: moderately increase
RING_RADIUSandDIAGONAL_OFFSET. - Steel ball image is smaller: moderately decrease both.
- Change only 1 pixel at a time, rebuild, and compare logs.
Step 6: Adjust Tracking Speed
Only consider increasing when static detection is reliable but tracking is lost during motion:
DETECTION_TRACK_MAX_JUMP_PIXELSDETECTION_RING_TRACK_SEARCH_HALF_WIDTHDETECTION_REACQUIRE_MAX_DRIFT_PIXELS
Increasing these parameters does not improve single-frame feature quality; it only relaxes the motion range.
12. Streaming Resolution, Quality, and Smoothness
The web preview parameters are located in:
xxxxxxxxxxmain/src/app_myhttpd.cppCurrent values:
xxxxxxxxxx12.1 Changing the Web Preview Resolution
For example, to change to 240x180:
xxxxxxxxxxThen rebuild and flash. Increasing the preview resolution will:
- Reduce clarity.
- Reduce the load from scaling, JPEG encoding, and Wi-Fi transmission.
- Reduce per-frame JPEG size.
- Be less prone to FPS drops or stuttering under poor network conditions.
Detection still uses the original 320x240, so raising the web preview resolution is not necessary solely for detection accuracy.
The width should remain even because YUV422 shares chroma data between every two pixels. If increasing to a larger size, also verify that STREAM_PREVIEW_BUFFER_SIZE and the JPEG buffer are sufficient.
12.2 JPEG Quality Adaptation
Under normal conditions, Q60 is used. When a frame's network send time exceeds 100 ms, the quality drops to Q40; after 12 consecutive stable frames, quality increases by 5 each time until it recovers to Q60.
The serial output shows:
xxxxxxxxxxPreview JPEG quality adjusted to <value>Adjustment advice:
- For smoother playback: reduce preview size,
STREAM_JPEG_QUALITY, or congestion quality. - For better clarity: increase preview size or quality, but first observe
PERF_STREAM. - High
send_avg/send_max: The bottleneck is primarily Wi-Fi/TCP, not the detection algorithm. - High
encode_avg/max: The bottleneck is primarily scaling or JPEG encoding.
The streaming service uses TCP_NODELAY with a per-send timeout of 800 ms. After JPEG encoding completes, the original camera frame is returned before network transmission begins, preventing slow connections from holding both frame buffers for an extended period.
When fast esp_new_jpeg encoding fails, it falls back to the generic frame2jpg(); frequent fallbacks should be investigated together with the fallback counter for format, size, or memory issues.
13. HTTP API
The control page is served on port 80, and the streaming service runs on port 81.
| Endpoint | Port | Purpose |
|---|---|---|
/ | 80 | Device control page |
/status | 80 | Get sensor, exposure, and ROI status |
/control?var=<name>&val=<value> | 80 | Modify sensor or runtime parameters |
/capture | 80 | Capture a single frame |
/monitor | 80 | Monitoring endpoint |
/mdns | 80 | mDNS information |
/stream | 81 | MJPEG continuous stream |
Examples:
xxxxxxxxxxhttp://<device-IP>/control?var=aec_value&val=900http://<device-IP>/control?var=DETECTION_ROI_Y&val=72http://<device-IP>/control?var=DETECTION_ROI_HEIGHT&val=24http://<device-IP>:81/streamDirect API calls must also satisfy ROI boundary constraints; otherwise the firmware will reject the parameters.
14. Log Descriptions
14.1 Detection Logs
| Log | Meaning |
|---|---|
RING_FOUND | Target confirmed for the first time |
RING_REACQUIRED x=... y=... | Target reconfirmed after loss |
RING x=... y=... width=... center=... contrast=... dark=... | Current valid target with feature data |
RING_NO_MATCH center=... contrast=... dark=... | No candidate passed all thresholds; reports the closest candidate |
RING_LOST | Consecutive misses reached the loss threshold |
RING: invalid YUV422 frame or detection ROI | Invalid input frame or ROI parameters |
14.2 Performance Logs
The camera side outputs PERF_CAMERA approximately every 2 seconds:
capture_avg/max: Camera frame capture timedetect_avg/max: Detection timeoverlay_avg/max: Overlay marking timequeue_replace: Number of old frames replaced by new frames in the streaming queue
The streaming side outputs PERF_STREAM approximately every 2 seconds:
wait_avg/max: Camera frame wait timeencode_avg/max: Scaling and JPEG encoding timesend_avg/max: HTTP/TCP send timejpeg_avg: Average JPEG sizefallback: Number of fallbacks toframe2jpg()
Troubleshooting guidelines:
detect_avgis low butsend_avgis high: Network is the primary bottleneck.capture_avgis high: Check exposure time, camera clock, and frame buffer usage.queue_replacekeeps increasing: Consumer cannot keep up with the camera, but the latest-frame strategy prevents latency from accumulating indefinitely.fallbackkeeps increasing: Check fast encoder initialization, input format, size, and memory.
15. Updating the Web Page
The GC2145 web page source file is:
xxxxxxxxxx../components/modules/web/www/index_gc2145.htmlWhat the firmware actually embeds is:
xxxxxxxxxx../components/modules/web/www/index_gc2145.html.gzTherefore, after modifying the HTML, you must regenerate the gzip file and rebuild the firmware. Changing only the HTML without updating the .gz file means the device will still display the old page after flashing.
Run the following PowerShell commands in the web directory:
xxxxxxxxxxSet-Location C:\Espressif\frameworks\esp-idf-v5.1.2\video-wifi\components\modules\web\www$source = (Resolve-Path .\index_gc2145.html).Path$target = Join-Path (Get-Location) 'index_gc2145.html.gz'$inputStream = [System.IO.File]::OpenRead($source)$outputStream = [System.IO.File]::Create($target)$gzipStream = [System.IO.Compression.GZipStream]::new($outputStream, [System.IO.Compression.CompressionLevel]::Optimal)try { $inputStream.CopyTo($gzipStream)} finally { $gzipStream.Dispose() $outputStream.Dispose() $inputStream.Dispose()}After re-flashing, if the browser still shows the old page:
- Close the old tab and reopen it.
- Or use
Ctrl+F5to force-refresh. - Confirm you are accessing the correct IP of the newly flashed device.
16. Troubleshooting
16.1 Web Page Cannot Be Opened
- Check whether UART0 outputs a valid
sta_ip. - Confirm the computer and ESP32 are on the same local network.
- Confirm the current
wifi_Mode. - In STA-only mode, do not access
192.168.4.1directly. - First
ping <device IP>, then check the port 80 page.
16.2 Steel Ball Visible but No Red Box
- Confirm the steel ball center passes through the blue box center line, not just the edge.
- Check the
center/contrast/darkvalues inRING_NO_MATCHlogs. - Check whether exposure is too low or too high.
- Check whether the actual pixel size of the bright core and dark ring matches the radius of 4.
- Check whether reflections cause the dark ring to appear bright in certain directions.
16.3 Red Box Jumps to Background Bright Spots
- Reduce ROI Height or adjust ROI Y to exclude irrelevant regions.
- Moderately increase
MIN_SCORE. - Moderately increase
MIN_DARK_SAMPLES. - Check whether the background contains similar bright-core dark-ring textures.
- Do not start by significantly loosening the tracking jump threshold.
16.4 Detection Works When Stationary but Fails During Motion
- First reduce exposure to minimize motion blur.
- Improve lighting to ensure the bright core remains sufficiently bright under short exposure.
- Then moderately increase
TRACK_MAX_JUMP_PIXELS. - If necessary, increase
TRACK_SEARCH_HALF_WIDTH. - Check camera FPS and
capture_avgto confirm that frame capture is not too slow.
16.5 Web Stuttering but Detection Logs Look Normal
Detection and streaming share camera frames, but web page transmission also involves scaling, JPEG encoding, and Wi-Fi/TCP overhead. First check PERF_STREAM:
- High
send_avg/max: Reduce preview resolution or JPEG quality; improve Wi-Fi signal. - High
encode_avg/max: Reduce preview resolution. - More stuttering during browser recording: Stop MP4 recording and compare, since browser-side encoding also consumes computer resources.
16.6 Exposure Slider Appears Non-Responsive
- Confirm
AEC SENSORis disabled. - Check whether the exposure value in
/statuschanges. - If the change is too small, adjust by tens or hundreds to compare.
- Confirm you are using the GC2145 page and the latest gzipped page.
16.7 MSPM0 Cannot Receive Data or Data Is Misaligned
- Confirm TX/RX are cross-connected and share a common ground.
- Both ends must use 115200, 8N1.
- Use a logic analyzer to check for the
AA 55frame header. - Verify using the lower 8 bits of the sum of the first 7 bytes, not CRC8.
- Use a state machine on the receiving end to resynchronize; do not assume the first read always starts at a packet header.
- When
valid = 0, immediately stop using stale coordinates.
17. Current Limitations and Notes
- The current algorithm is designed for bright-core dark-ring targets on a fixed track; it is not a general-purpose steel ball detector.
- Thresholds and sampling radii may need recalibration if ambient lighting, ball material, focal length, motion speed, or mounting distance changes.
- ROI Y and Height changes made via the web page are not written to Flash and revert to defaults after reboot.
- Currently only the X coordinate is output; the Y coordinate is not sent to MSPM0.
- UART
WIDTHcurrently reflects the fixed dark ring diameter of 8, not the actual measured width of the target. - The web preview is scaled to
240x160and cannot be used to precisely measure original pixel dimensions. - Several generic sensor control interfaces on the GC2145 are still stubs and must be verified against actual device behavior and the driver implementation.
- After modifying detection thresholds, default exposure, preview size, or web page resources, you must rebuild and re-flash the firmware.
18. Minimal On-Site Verification Checklist
After each parameter change and re-flash, it is recommended to verify the following in order:
- UART0 outputs version, STA IP, and startup logs normally.
- Web page opens and
Start Streamshows a continuous video feed. - Blue ROI covers the steel ball trajectory, with the center line passing through the ball center.
AEC SENSORis disabled; adjusting Exposure changes brightness and motion blur.RING_FOUNDorRINGlogs and a red box appear when the steel ball is present.RING_LOSTappears after the ball disappears; MSP packet showsvalid=0.- UART1 packet header, X, SEQ, and checksum are correct.
- Detection time in
PERF_CAMERAis normal. PERF_STREAMshows no persistent abnormal send spikes or excessive fallbacks.- Browser recording produces a genuine MP4 file with the
ftypidentifier.