Skip to content

Commit b6e4734

Browse files
committed
feat(usb_uvc): add a example support open two usb cam with hub
1 parent dc88ac6 commit b6e4734

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

56 files changed

+5280
-2
lines changed

.gitlab/ci/build.yml

+10
Original file line numberDiff line numberDiff line change
@@ -933,6 +933,16 @@ build_example_usb_host_usb_cdc_basic:
933933
variables:
934934
EXAMPLE_DIR: examples/usb/host/usb_cdc_basic
935935

936+
build_example_usb_host_usb_hub_dual_camera:
937+
extends:
938+
- .build_examples_template
939+
- .rules:build:example_usb_host_usb_hub_dual_camera
940+
parallel:
941+
matrix:
942+
- IMAGE: espressif/idf:release-v5.4
943+
variables:
944+
EXAMPLE_DIR: examples/usb/host/usb_hub_dual_camera
945+
936946
build_example_usb_host_usb_msc_ota:
937947
extends:
938948
- .build_examples_template

.gitlab/ci/deploy.yml

+1
Original file line numberDiff line numberDiff line change
@@ -131,6 +131,7 @@ pack-upload_files:
131131
- job: "build_example_usb_host_usb_camera_mic_spk: [espressif/idf:release-v5.1]"
132132
- job: "build_example_usb_host_usb_cdc_4g_module: [espressif/idf:release-v5.1]"
133133
- job: "build_example_usb_host_usb_cdc_basic: [espressif/idf:release-v5.1]"
134+
- job: "build_example_usb_host_usb_hub_dual_camera: [espressif/idf:release-v5.4]"
134135
- job: "build_example_usb_host_usb_msc_ota: [espressif/idf:release-v5.1]"
135136
- job: "build_example_vision_opencv_color_tracker: [espressif/idf:release-v5.4]"
136137

.gitlab/ci/rules.yml

+13
Original file line numberDiff line numberDiff line change
@@ -612,6 +612,9 @@
612612
.patterns-example_usb_host_usb_cdc_basic: &patterns-example_usb_host_usb_cdc_basic
613613
- "examples/usb/host/usb_cdc_basic/**/*"
614614

615+
.patterns-example_usb_host_usb_hub_dual_camera: &patterns-example_usb_host_usb_hub_dual_camera
616+
- "examples/usb/host/usb_hub_dual_camera/**/*"
617+
615618
.patterns-example_usb_host_usb_msc_ota: &patterns-example_usb_host_usb_msc_ota
616619
- "examples/usb/host/usb_msc_ota/**/*"
617620

@@ -1551,6 +1554,16 @@
15511554
- <<: *if-dev-push
15521555
changes: *patterns-example_usb_host_usb_cdc_basic
15531556

1557+
.rules:build:example_usb_host_usb_hub_dual_camera:
1558+
rules:
1559+
- <<: *if-protected
1560+
- <<: *if-label-build
1561+
- <<: *if-trigger-job
1562+
- <<: *if-dev-push
1563+
changes: *patterns-build_system
1564+
- <<: *if-dev-push
1565+
changes: *patterns-example_usb_host_usb_hub_dual_camera
1566+
15541567
.rules:build:example_usb_host_usb_msc_ota:
15551568
rules:
15561569
- <<: *if-protected

.pre-commit-config.yaml

+1-1
Original file line numberDiff line numberDiff line change
@@ -93,4 +93,4 @@ repos:
9393
rev: v2.3.0
9494
hooks:
9595
- id: codespell
96-
args: [-w, "--ignore-words=codespell-ignore-list"]
96+
args: [-w, "--ignore-words=codespell-ignore-list", "--skip=*.js,*.vue,*/pnpm-lock.yaml,*/package-lock.json,*/yarn.lock"]

examples/.build-rules.yml

+4
Original file line numberDiff line numberDiff line change
@@ -408,6 +408,10 @@ examples/usb/host/usb_cdc_basic:
408408
enable:
409409
- if: IDF_TARGET in ["esp32s2","esp32s3"]
410410

411+
examples/usb/host/usb_hub_dual_camera:
412+
enable:
413+
- if: IDF_TARGET in ["esp32s2", "esp32s3","esp32p4"]
414+
411415
examples/usb/host/usb_msc_ota:
412416
enable:
413417
- if: SOC_USB_OTG_SUPPORTED == 1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
# The following five lines of boilerplate have to be in your project's
2+
# CMakeLists in this exact order for cmake to work correctly
3+
cmake_minimum_required(VERSION 3.16)
4+
5+
include($ENV{IDF_PATH}/tools/cmake/project.cmake)
6+
project(usb_hub_dual_camera)
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
# USB Hub Dual Camera Example
2+
3+
This example demonstrates how to use the [usb_host_uvc](https://components.espressif.com/components/espressif/usb_host_uvc) component to connect USB cameras and preview camera images via an HTTP server.
4+
5+
* Supports previewing MJPEG format images only.
6+
* Supports USB Hub, allowing up to two cameras to be connected.
7+
* Web interface allows saving the current frame.
8+
9+
## How to Use
10+
11+
### Hardware Requirements
12+
13+
* Development Board
14+
15+
Any `ESP32-S2`, `ESP32-S3`, or `ESP32-P4` development board.
16+
17+
By default, the ESP32-P4 uses the [ESP32-P4-Function-EV-Board](https://docs.espressif.com/projects/esp-dev-kits/en/latest/esp32p4/esp32-p4-function-ev-board/user_guide.html#getting-started) development board.
18+
19+
* Connection
20+
21+
| | USB_DP | USB_DM |
22+
| ----------- | ------ | ------ |
23+
| ESP32-S2/S3 | GPIO20 | GPIO19 |
24+
| ESP32-P4 | GPIO50 | GPIO49 |
25+
26+
### Build and Flash
27+
28+
Build the project and flash it to the board, then run the monitor tool to view the serial output:
29+
30+
* Run `. ./export.sh` to set IDF environment
31+
* Run `idf.py set-target esp32s3` to set target chip
32+
* Run `pip install "idf-component-manager~=2.1.0"` to upgrade your component manager if any error happens during last step
33+
* Run `idf.py -p PORT flash monitor` to build, flash and monitor the project
34+
35+
(To exit the serial monitor, type `Ctrl-]`.)
36+
37+
See the Getting Started Guide for all the steps to configure and use the ESP-IDF to build projects.
38+
39+
### Preview camera image
40+
41+
* Connect with ESP32S2 through Wi-Fi, SSID: `ESP-USB-UVC-Demo` with no password by default.
42+
43+
* Input `192.168.4.1` in your browser, you can find a file list of the disk.
44+
45+
Note: Safari browser is not recommended.
46+
47+
![demo](https://dl.espressif.com/AE/esp-iot-solution/uvc_dual_hub_camera_1.gif)
48+
49+
<p align="center">
50+
<img src="https://dl.espressif.com/AE/esp-iot-solution/uvc_dual_hub_camera_2.gif" alt="demo2">
51+
</p>
52+
53+
### Frontend Source Files
54+
55+
Please refer to the [frontend source files](./frontend_source).
56+
57+
## Example Output
58+
59+
```
60+
I (4108) main_task: Returned from app_main()
61+
W (31940) uvc: USB device with addr(1) is not UVC device
62+
I (32025) uvc: Device connected
63+
I (32026) uvc: Cam[0] uvc_stream_index = 0
64+
I (32026) uvc: Pick Cam[0] FORMAT_MJPEG 1280*[email protected]
65+
I (32026) uvc: Pick Cam[0] FORMAT_MJPEG 800*[email protected]
66+
I (32031) uvc: Pick Cam[0] FORMAT_MJPEG 640*[email protected]
67+
I (32036) uvc: Pick Cam[0] FORMAT_MJPEG 480*[email protected]
68+
I (32041) uvc: Pick Cam[0] FORMAT_MJPEG 320*[email protected]
69+
I (32109) uvc: Device connected
70+
I (32110) uvc: Cam[1] uvc_stream_index = 0
71+
I (32110) uvc: Pick Cam[1] FORMAT_MJPEG 1280*[email protected]
72+
I (32110) uvc: Pick Cam[1] FORMAT_MJPEG 800*[email protected]
73+
I (32115) uvc: Pick Cam[1] FORMAT_MJPEG 640*[email protected]
74+
I (32120) uvc: Pick Cam[1] FORMAT_MJPEG 480*[email protected]
75+
I (32125) uvc: Pick Cam[1] FORMAT_MJPEG 320*[email protected]
76+
I (32246) uvc: Opening the UVC[0]...
77+
I (32246) uvc: frame_size.advanced.frame_size: 40000
78+
I (32330) uvc: Opening the UVC[1]...
79+
I (32330) uvc: frame_size.advanced.frame_size: 40000
80+
```
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
> 1%
2+
last 2 versions
3+
not dead
4+
not ie 11
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
{
2+
"globals": {
3+
"Component": true,
4+
"ComponentPublicInstance": true,
5+
"ComputedRef": true,
6+
"EffectScope": true,
7+
"ExtractDefaultPropTypes": true,
8+
"ExtractPropTypes": true,
9+
"ExtractPublicPropTypes": true,
10+
"InjectionKey": true,
11+
"PropType": true,
12+
"Ref": true,
13+
"VNode": true,
14+
"WritableComputedRef": true,
15+
"computed": true,
16+
"createApp": true,
17+
"customRef": true,
18+
"defineAsyncComponent": true,
19+
"defineComponent": true,
20+
"effectScope": true,
21+
"getCurrentInstance": true,
22+
"getCurrentScope": true,
23+
"h": true,
24+
"inject": true,
25+
"isProxy": true,
26+
"isReactive": true,
27+
"isReadonly": true,
28+
"isRef": true,
29+
"markRaw": true,
30+
"nextTick": true,
31+
"onActivated": true,
32+
"onBeforeMount": true,
33+
"onBeforeUnmount": true,
34+
"onBeforeUpdate": true,
35+
"onDeactivated": true,
36+
"onErrorCaptured": true,
37+
"onMounted": true,
38+
"onRenderTracked": true,
39+
"onRenderTriggered": true,
40+
"onScopeDispose": true,
41+
"onServerPrefetch": true,
42+
"onUnmounted": true,
43+
"onUpdated": true,
44+
"provide": true,
45+
"reactive": true,
46+
"readonly": true,
47+
"ref": true,
48+
"resolveComponent": true,
49+
"shallowReactive": true,
50+
"shallowReadonly": true,
51+
"shallowRef": true,
52+
"toRaw": true,
53+
"toRef": true,
54+
"toRefs": true,
55+
"toValue": true,
56+
"triggerRef": true,
57+
"unref": true,
58+
"useAttrs": true,
59+
"useCssModule": true,
60+
"useCssVars": true,
61+
"useRoute": true,
62+
"useRouter": true,
63+
"useSlots": true,
64+
"watch": true,
65+
"watchEffect": true,
66+
"watchPostEffect": true,
67+
"watchSyncEffect": true,
68+
"DirectiveBinding": true,
69+
"MaybeRef": true,
70+
"MaybeRefOrGetter": true,
71+
"onWatcherCleanup": true,
72+
"useId": true,
73+
"useModel": true,
74+
"useTemplateRef": true
75+
}
76+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
.DS_Store
2+
node_modules
3+
/dist
4+
5+
# local env files
6+
.env.local
7+
.env.*.local
8+
9+
# Log files
10+
npm-debug.log*
11+
yarn-debug.log*
12+
yarn-error.log*
13+
pnpm-debug.log*
14+
15+
# Editor directories and files
16+
.idea
17+
.vscode
18+
*.suo
19+
*.ntvs*
20+
*.njsproj
21+
*.sln
22+
*.sw?
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
registry=https://registry.npmmirror.com/
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
# USB-Hub Dual Camera Web Display Component
2+
3+
## Build Guide
4+
5+
Please install `node >= 20`. It is recommended to use `pnpm` as the package manager.
6+
7+
In the `frontend_source` directory:
8+
9+
```bash
10+
pnpm install # install dependencies
11+
# You may need to run `pnpm approve-builds` to execute the postinstall script for some dependencies.
12+
pnpm build # build
13+
14+
# Gzip compress the build artifacts and move them to the spiffs directory.
15+
./../scripts/gzip_webserver_files.sh
16+
```
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
# USB-Hub Dual Camera 网页显示组件
2+
3+
## 编译指南
4+
5+
请安装 `node >= 20`,推荐使用 `pnpm` 作为包管理器。
6+
7+
`frontend_source` 目录下:
8+
9+
```bash
10+
pnpm install # install dependencies
11+
# You may need to run `pnpm approve-builds` to execute the postinstall script for some dependencies.
12+
pnpm build # build
13+
14+
# Gzip compress the build artifacts and move them to the spiffs directory.
15+
./../scripts/gzip_webserver_files.sh
16+
```
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
/// <reference types="vite/client" />
2+
/// <reference types="unplugin-vue-router/client" />
3+
/// <reference types="vite-plugin-vue-layouts/client" />
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
/**
2+
* .eslint.js
3+
*
4+
* ESLint configuration file.
5+
*/
6+
7+
import pluginVue from 'eslint-plugin-vue'
8+
import vueTsEslintConfig from '@vue/eslint-config-typescript'
9+
10+
export default [
11+
{
12+
name: 'app/files-to-lint',
13+
files: ['**/*.{ts,mts,tsx,vue}'],
14+
},
15+
16+
{
17+
name: 'app/files-to-ignore',
18+
ignores: ['**/dist/**', '**/dist-ssr/**', '**/coverage/**'],
19+
},
20+
21+
...pluginVue.configs['flat/recommended'],
22+
...vueTsEslintConfig(),
23+
24+
{
25+
rules: {
26+
'@typescript-eslint/no-unused-expressions': [
27+
'error',
28+
{
29+
allowShortCircuit: true,
30+
allowTernary: true,
31+
},
32+
],
33+
'vue/multi-word-component-names': 'off',
34+
}
35+
}
36+
]
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
<!DOCTYPE html>
2+
<html lang="en">
3+
<head>
4+
<meta charset="UTF-8">
5+
<link rel="icon" href="/favicon.ico">
6+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
7+
<title>ESP UVC Camera Display</title>
8+
</head>
9+
<body>
10+
<div id="app"></div>
11+
<script type="module" src="/src/main.ts"></script>
12+
</body>
13+
</html>

0 commit comments

Comments
 (0)