电子产业一站式赋能平台

PCB联盟网

搜索
查看: 114|回复: 0
收起左侧

ESP32-S3搭建外网可访问的网络摄像头(内网穿透)

[复制链接]

840

主题

840

帖子

6491

积分

高级会员

Rank: 5Rank: 5

积分
6491
发表于 2023-9-6 12:00:00 | 显示全部楼层 |阅读模式

xn004lltngs64024997850.gif

xn004lltngs64024997850.gif

* |5 I# g: A8 a点击上方蓝色字体,关注我们
9 R$ r( }. S0 O8 v8 U1 L5 E2 r本篇博文使用ESP32-S3搭建网络摄像头,相比较局域网摄像头,本篇博文将分享如何搭建外网可以访问的网络摄像头。, x3 f! c4 D# B  W( s
这主要是使用内网穿透技术,内网穿透是为了使具有某一个特定源 IP 地址和源端口号的数据包(这里指局域网摄像头)不被网络地址转换设备屏蔽而正确路由到内网主机。6 g, Y/ G! A' t, W$ v
主要流程分为两步:
0 Q% S1 Z5 E" y2 [3 I; k1、先实现局域网访问网络摄像头;9 Y' m, O+ K# f& D
2、在此基础,使用内网穿透的方式,搭建外网可访问的网络摄像头。6 ~) U( \. f/ R0 g! W
1- U$ r3 i# I! m+ K. I3 r3 r
局域网摄像头
: c0 Y5 _6 h( b) JESP32实现局域网摄像头的方式比较简单,驱动代码如下:, m% f# b5 p4 B# K

4 v5 J+ L6 s5 O9 s- ?2 d# W
  • #include "esp_camera.h"#include
    * r- h7 I) b3 d  H% ?//// WARNING!!! PSRAM IC required for UXGA resolution and high JPEG quality//            Ensure ESP32 Wrover Module or other board with PSRAM is selected//            Partial images will be transmitted if image exceeds buffer size////            You must select partition scheme from the board menu that has at least 3MB APP space.//            Face Recognition is DISABLED for ESP32 and ESP32-S2, because it takes up from 15 //            seconds to process single frame. Face Detection is ENABLED if PSRAM is enabled as well/ I5 }/ j! H6 ~7 O4 Q5 ]/ l( E( C
    // ===================// Select camera model// ===================//#define CAMERA_MODEL_WROVER_KIT // Has PSRAM// #define CAMERA_MODEL_ESP_EYE // Has PSRAM//#define CAMERA_MODEL_ESP32S3_EYE // Has PSRAM//#define CAMERA_MODEL_M5STACK_PSRAM // Has PSRAM//#define CAMERA_MODEL_M5STACK_V2_PSRAM // M5Camera version B Has PSRAM//#define CAMERA_MODEL_M5STACK_WIDE // Has PSRAM//#define CAMERA_MODEL_M5STACK_ESP32CAM // No PSRAM//#define CAMERA_MODEL_M5STACK_UNITCAM // No PSRAM//#define CAMERA_MODEL_AI_THINKER // Has PSRAM//#define CAMERA_MODEL_TTGO_T_JOURNAL // No PSRAM//#define CAMERA_MODEL_XIAO_ESP32S3 // Has PSRAM// ** Espressif Internal Boards **//#define CAMERA_MODEL_ESP32_CAM_BOARD//#define CAMERA_MODEL_ESP32S2_CAM_BOARD//#define CAMERA_MODEL_ESP32S3_CAM_LCD#define CAMERA_MODEL_DFRobot_FireBeetle2_ESP32S3 // Has PSRAM//#define CAMERA_MODEL_DFRobot_Romeo_ESP32S3 // Has PSRAM) b! i+ S" R8 M" G
    #include "camera_pins.h"#include "DFRobot_AXP313A.h"
    ! e/ ]+ U2 @! @, Y% t3 f2 Q% M* ~DFRobot_AXP313A axp;6 g9 b, o  y- p4 A" Y
    // ===========================// Enter your WiFi credentials// ===========================const char* ssid = "";const char* password = "";: j) a) V- O9 O4 x0 y1 @
    void startCameraServer();void setupLedFlash(int pin);7 k+ ]) U7 a% k6 W3 X+ D3 u
    void setup() {  Serial.begin(115200);  Serial.setDebugOutput(true);  Serial.println();# |3 M" z; w8 a+ e# }" p# G- a: K
      while(axp.begin() != 0){    Serial.println("init error");    delay(1000);  }
    $ z. K% P6 I" {# o  axp.enableCameraPower(axp.eOV2640);  // 给摄像头供电' i! U1 H& y) n- v+ D# J/ ?
      camera_config_t config;  config.ledc_channel = LEDC_CHANNEL_0;  config.ledc_timer = LEDC_TIMER_0;  config.pin_d0 = Y2_GPIO_NUM;  config.pin_d1 = Y3_GPIO_NUM;  config.pin_d2 = Y4_GPIO_NUM;  config.pin_d3 = Y5_GPIO_NUM;  config.pin_d4 = Y6_GPIO_NUM;  config.pin_d5 = Y7_GPIO_NUM;  config.pin_d6 = Y8_GPIO_NUM;  config.pin_d7 = Y9_GPIO_NUM;  config.pin_xclk = XCLK_GPIO_NUM;  config.pin_pclk = PCLK_GPIO_NUM;  config.pin_vsync = VSYNC_GPIO_NUM;  config.pin_href = HREF_GPIO_NUM;  config.pin_sccb_sda = SIOD_GPIO_NUM;  config.pin_sccb_scl = SIOC_GPIO_NUM;  config.pin_pwdn = PWDN_GPIO_NUM;  config.pin_reset = RESET_GPIO_NUM;  config.xclk_freq_hz = 20000000;  config.frame_size = FRAMESIZE_UXGA;  config.pixel_format = PIXFORMAT_JPEG; // for streaming  //config.pixel_format = PIXFORMAT_RGB565; // for face detection/recognition  config.grab_mode = CAMERA_GRAB_WHEN_EMPTY;  config.fb_location = CAMERA_FB_IN_PSRAM;  config.jpeg_quality = 12;  config.fb_count = 1;/ C" `+ ~/ V# a1 B
      // if PSRAM IC present, init with UXGA resolution and higher JPEG quality  //                      for larger pre-allocated frame buffer.  if(config.pixel_format == PIXFORMAT_JPEG){    if(psramFound()){      config.jpeg_quality = 10;      config.fb_count = 2;      config.grab_mode = CAMERA_GRAB_LATEST;    } else {      // Limit the frame size when PSRAM is not available      config.frame_size = FRAMESIZE_SVGA;      config.fb_location = CAMERA_FB_IN_DRAM;    }  } else {    // Best option for face detection/recognition    config.frame_size = FRAMESIZE_240X240;#if CONFIG_IDF_TARGET_ESP32S3    config.fb_count = 2;#endif  }) C; j" c. h9 R: `  H+ g1 w
    #if defined(CAMERA_MODEL_ESP_EYE)  pinMode(13, INPUT_PULLUP);  pinMode(14, INPUT_PULLUP);#endif
    ' M: `+ l5 \: Y4 I6 _  // camera init  esp_err_t err = esp_camera_init(&config);  if (err != ESP_OK) {    Serial.printf("Camera init failed with error 0x%x", err);    return;  }# ^* H& S! S+ Y4 ^. v
      sensor_t * s = esp_camera_sensor_get();  // initial sensors are flipped vertically and colors are a bit saturated  if (s->id.PID == OV3660_PID) {    s->set_vflip(s, 1); // flip it back    s->set_brightness(s, 1); // up the brightness just a bit    s->set_saturation(s, -2); // lower the saturation  }  // drop down frame size for higher initial frame rate  if(config.pixel_format == PIXFORMAT_JPEG){    s->set_framesize(s, FRAMESIZE_QVGA);  }& L7 h6 j% P0 z! i" q
    #if defined(CAMERA_MODEL_M5STACK_WIDE) || defined(CAMERA_MODEL_M5STACK_ESP32CAM)  s->set_vflip(s, 1);  s->set_hmirror(s, 1);#endif
    " d+ ~7 {: J) V* V#if defined(CAMERA_MODEL_ESP32S3_EYE)  s->set_vflip(s, 1);#endif' {( J" a' ~$ r8 Q  z7 h$ G9 [' U7 f
    // Setup LED FLash if LED pin is defined in camera_pins.h#if defined(LED_GPIO_NUM)  setupLedFlash(LED_GPIO_NUM);#endif
    ) v9 `+ I% }, E5 x4 W- @  WiFi.begin(ssid, password);  WiFi.setSleep(false);
    5 G  I4 {$ W; Y' \  while (WiFi.status() != WL_CONNECTED) {    delay(500);    Serial.print(".");  }  Serial.println("");  Serial.println("WiFi connected");
    7 ^# ]4 V2 }0 I! x- q7 I+ x8 a6 m" G  startCameraServer();$ B5 _5 ^. D6 p! J3 I
      Serial.print("Camera Ready! Use 'http://");  Serial.print(WiFi.localIP());  Serial.println("' to connect");}
    - U! I) d1 I# V- Pvoid loop() {  // Do nothing. Everything is done in another task by the web server  delay(10000);}
    ! f7 @* R( O, p8 M* A代码中有几点需要注意:/ E( L4 _' J9 _. @, ]0 r& p- F' |

    3 z3 ?5 W! g1 A  b2 f1、宏定义选择适配的摄像头模式。% W- O7 {- a' V( l% o" N. [
    ) n9 G) r$ |4 L
  • // ===================// Select camera model// ===================//#define CAMERA_MODEL_WROVER_KIT // Has PSRAM// #define CAMERA_MODEL_ESP_EYE // Has PSRAM//#define CAMERA_MODEL_ESP32S3_EYE // Has PSRAM//#define CAMERA_MODEL_M5STACK_PSRAM // Has PSRAM//#define CAMERA_MODEL_M5STACK_V2_PSRAM // M5Camera version B Has PSRAM//#define CAMERA_MODEL_M5STACK_WIDE // Has PSRAM//#define CAMERA_MODEL_M5STACK_ESP32CAM // No PSRAM//#define CAMERA_MODEL_M5STACK_UNITCAM // No PSRAM//#define CAMERA_MODEL_AI_THINKER // Has PSRAM//#define CAMERA_MODEL_TTGO_T_JOURNAL // No PSRAM//#define CAMERA_MODEL_XIAO_ESP32S3 // Has PSRAM// ** Espressif Internal Boards **//#define CAMERA_MODEL_ESP32_CAM_BOARD//#define CAMERA_MODEL_ESP32S2_CAM_BOARD//#define CAMERA_MODEL_ESP32S3_CAM_LCD#define CAMERA_MODEL_DFRobot_FireBeetle2_ESP32S3 // Has PSRAM//#define CAMERA_MODEL_DFRobot_Romeo_ESP32S3 // Has PSRAM8 U5 }2 Q  U5 M
    2、无线路由器SSID和密码要填写正确。1 Z6 o2 M% Z7 o) v- D
    ; h- k1 `8 n* {3 `6 J$ V
  • // ===========================// Enter your WiFi credentials// ===========================const char* ssid = "";const char* password = "";7 w4 D8 L- w. R5 R/ v7 v0 l8 G/ |
    3、给摄像头供电
    # q9 G( l; u8 C( C" I
    , D/ B& ?; i" b+ U! M% U7 a8 C9 y
  • axp.enableCameraPower(axp.eOV2640);  // 给摄像头供电  x# P+ M+ V( m9 w3 v$ x
    4、板卡需要外接天线,否则可能无法连接路由器。
    ! Q+ K0 `3 E; |# s, L1 ~9 }
    5 v( R( w' x1 t! J2 F! ^0 [编译下载程序到板卡中,确保局域网访问网络摄像头可正常使用。
    + p- ^0 _% M  n3 N$ `28 _+ i7 x5 n- q% V8 `
    内网穿透网络摄像头" z) B3 A( l8 G
    内网穿透我们使用花生壳这款软件提供的内网穿透服务。! M. L3 @4 N% T' l: Y$ L% B

    1 a7 B* W& _4 q  d. d

    0jnk2h53pao64024997950.png

    0jnk2h53pao64024997950.png

    . J& ?/ C' D. ^4 f  A1 f. F- b
    & B* W+ b3 O  t; b0 g- V% n在官网下载APP:https://hsk.oray.com/" @3 o5 S  \1 q% \+ i
    ( m2 H4 C' C- z. S0 ?- }
    下载安装完成后,在内网穿透服务点击新建映射,如下图所示:
    . m3 p2 Z4 ~8 M+ X% r8 ~
    8 l% V: ~# ~  y/ T! w$ I; [* `' y+ l

    2ihowi4eyk164024998050.png

    2ihowi4eyk164024998050.png
    + f+ ~3 ^+ A: T0 l' }/ o
    , U. u% |; o4 m, A5 @& u& P6 r5 H/ r
    填写新建映射的基本信息,请注意内网主机和内网端口是局域网摄像头的主机和端口(端口默认为80) ,如下图所示:7 c" p* u: F( U6 \" n: Y
    . H4 |" [% ]* ~5 D% P

    uwg2bilylxy64024998150.png

    uwg2bilylxy64024998150.png
    1 A! }7 G. I5 Q3 {9 F2 S

    ( p% U- A1 m0 r, k4 y& Y2 x: h" F. m新建映射完成后,可以在APP看到新增的设备列表,如下图所示:
    + m' C5 S) ]& o: B
    ; u4 ~+ u$ d4 o5 n, o3 d" E

    1ep4jr0jimd64024998250.png

    1ep4jr0jimd64024998250.png
    + G/ k4 @  T, O8 Q; p

    + p. ]7 o% C" f" f复制访问网址,在浏览器中打开:http://2j90962r69.goho.co:47918/2 j8 L. }* @! p

    3 D6 r  K" i( N+ s0 z即使不在同一个局域网内也可以正常访问摄像头啦。- H6 u' v+ `  [: d: ^% N

    , A8 b3 S6 @/ i9 e4 S6 t3 w

    ihll0o153jn64024998350.png

    ihll0o153jn64024998350.png
    " j) t( Q7 ?8 x- L( e! @4 o' @

    / _: w# R; [1 J: g0 W/ G
    & d5 d" c# Y0 |* w. \0 c4 @

    cacav3gtzet64024998450.png

    cacav3gtzet64024998450.png
    / a  P& Y8 E8 a0 k
    往期推荐HarmonyOS学习路之开发篇—Java UI框架(Position和AdaptiveBox layout)
    & q/ b6 b/ b, ]! ]Python数据可视化:如何选择合适的图表可视化?6 e/ W; p& d' D. K; C: ]
    磁耦合共振无线供电装置
    ' c4 ~5 _3 N. r1 H! QPython Qt GUI设计:表格和树类(提升篇—1)
    + I# K0 r8 v. @
    1 h6 |9 R4 }5 l% m/ U( E" q

    aeltjeee3ob64024998551.jpg

    aeltjeee3ob64024998551.jpg

    ) V1 G; U$ p7 h/ y6 f

    tze3hq3ggik64024998651.gif

    tze3hq3ggik64024998651.gif

    1 |! a3 b/ h0 s  K+ y, V" v点击阅读原文,更精彩~
  • 回复

    使用道具 举报

    发表回复

    您需要登录后才可以回帖 登录 | 立即注册

    本版积分规则


    联系客服 关注微信 下载APP 返回顶部 返回列表