电子产业一站式赋能平台

PCB联盟网

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

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

[复制链接]

1001

主题

1001

帖子

8805

积分

高级会员

Rank: 5Rank: 5

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

zbqnzzlfbyx64015934649.gif

zbqnzzlfbyx64015934649.gif

% B( P4 j6 a$ ?$ D6 X点击上方蓝色字体,关注我们, b1 G( D, v( `6 E: z: N
本篇博文使用ESP32-S3搭建网络摄像头,相比较局域网摄像头,本篇博文将分享如何搭建外网可以访问的网络摄像头。/ [% U5 d' f) R8 z' D
这主要是使用内网穿透技术,内网穿透是为了使具有某一个特定源 IP 地址和源端口号的数据包(这里指局域网摄像头)不被网络地址转换设备屏蔽而正确路由到内网主机。5 Z: f8 Z+ P& `; N* D* C
主要流程分为两步:
" D; w9 W- m% @1、先实现局域网访问网络摄像头;5 o, c/ ?& c& I7 u+ Q
2、在此基础,使用内网穿透的方式,搭建外网可访问的网络摄像头。
9 _$ r3 g7 d  N; H& z) Y1 |1
" ]) W9 u. X" F6 T  M2 u局域网摄像头& Y* o# ]% [( \) H! w
ESP32实现局域网摄像头的方式比较简单,驱动代码如下:! H( E; S; _6 a& T  ^# B2 _2 n$ Q

( m4 y4 c: i. E) J" l* k& E
  • #include "esp_camera.h"#include/ N( {, P5 M8 n# c
    //// 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 well0 m5 x9 i- `* w5 Z
    // ===================// 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& g( L1 `) O/ w3 A, n
    #include "camera_pins.h"#include "DFRobot_AXP313A.h"
    ' O0 \, p3 K  ZDFRobot_AXP313A axp;
    1 W$ f/ [3 @; d// ===========================// Enter your WiFi credentials// ===========================const char* ssid = "";const char* password = "";
    / y1 k7 A0 A- o- S8 hvoid startCameraServer();void setupLedFlash(int pin);
    1 L' q. `2 B: h# B  C/ yvoid setup() {  Serial.begin(115200);  Serial.setDebugOutput(true);  Serial.println();
    - q; U* S1 N3 j5 F: L: o, D5 N2 j/ l  while(axp.begin() != 0){    Serial.println("init error");    delay(1000);  }
    1 O0 s* g. ~  ^$ v! Z+ d  axp.enableCameraPower(axp.eOV2640);  // 给摄像头供电
      i- O1 m- O) F  _2 w' H! R: z4 \6 y  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;, {2 O  N* f2 I; J: e- ^
      // 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  }$ F$ c. R! |4 t- `# O
    #if defined(CAMERA_MODEL_ESP_EYE)  pinMode(13, INPUT_PULLUP);  pinMode(14, INPUT_PULLUP);#endif2 h  w8 w; ]% v1 F
      // 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;  }
    6 L* @4 o/ S) D0 y' S; q$ l  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);  }
    / }3 |! r" M0 m1 w5 m: r4 a; `/ @#if defined(CAMERA_MODEL_M5STACK_WIDE) || defined(CAMERA_MODEL_M5STACK_ESP32CAM)  s->set_vflip(s, 1);  s->set_hmirror(s, 1);#endif5 Q" d; [* V# P) b0 ^3 w/ o
    #if defined(CAMERA_MODEL_ESP32S3_EYE)  s->set_vflip(s, 1);#endif! n! [9 D0 l9 R; U- e6 }
    // Setup LED FLash if LED pin is defined in camera_pins.h#if defined(LED_GPIO_NUM)  setupLedFlash(LED_GPIO_NUM);#endif4 s' [. U* F: C- e
      WiFi.begin(ssid, password);  WiFi.setSleep(false);" O) z; C4 e$ J( j- U8 d" w" N( x
      while (WiFi.status() != WL_CONNECTED) {    delay(500);    Serial.print(".");  }  Serial.println("");  Serial.println("WiFi connected");
    ( [8 F" w1 f, B% i* p$ m9 W  p  startCameraServer();6 I6 e6 U+ m2 u4 \( `( c4 r
      Serial.print("Camera Ready! Use 'http://");  Serial.print(WiFi.localIP());  Serial.println("' to connect");}' z( S' _0 ?/ m+ E3 h; C' L
    void loop() {  // Do nothing. Everything is done in another task by the web server  delay(10000);}
    ) ~7 y6 D/ D* z, g3 N) I, G" U代码中有几点需要注意:
    2 }% s, l$ L# w# C2 h& k
    0 B' k" z6 n" j: A8 v( v1、宏定义选择适配的摄像头模式。
      f5 V7 b. Z9 s+ b7 }! N  J5 ^7 X1 z$ Z
  • // ===================// 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
    5 T! ^* [! D% k2、无线路由器SSID和密码要填写正确。
    4 D( ?: s+ j; \8 Q7 Q& K) N: E
    3 ?! L+ {+ I  q1 X
  • // ===========================// Enter your WiFi credentials// ===========================const char* ssid = "";const char* password = "";
    4 r3 I4 _2 p/ c3、给摄像头供电
    % ]5 j3 n/ l% m% [% v
    3 p2 P0 B! T' N* r( }7 Y+ b
  • axp.enableCameraPower(axp.eOV2640);  // 给摄像头供电. x8 Z$ o' `0 V! Z/ m& D" D2 d# k
    4、板卡需要外接天线,否则可能无法连接路由器。( E' L( x& C" J0 B" E2 a5 l

    7 r4 V0 ^- s' }. d3 y0 _; z( w编译下载程序到板卡中,确保局域网访问网络摄像头可正常使用。# F6 Y) Q3 h1 E1 q7 k  @' a
    2# G) w4 w# W* f, V  c3 I  \/ ]
    内网穿透网络摄像头
    ; `- Q2 Q$ d" }- s& i内网穿透我们使用花生壳这款软件提供的内网穿透服务。/ a; X$ d  K0 e2 B
    + I. K4 q  O2 h5 I3 f

    dttrqmvbu4x64015934750.png

    dttrqmvbu4x64015934750.png
    ; ~2 s5 E- S: S2 l0 R$ j9 `
    : z5 K7 M* l6 |; z1 g& E
    在官网下载APP:https://hsk.oray.com/
    * o+ s* r7 k& F0 [, e& `
    3 P: Z2 r/ }% Y' |: d/ v下载安装完成后,在内网穿透服务点击新建映射,如下图所示: 6 S- u% p0 Q; G8 Q. p* c1 s) X

    ; i" K6 \6 t  P7 ~+ w6 s9 ^

    1bbr34sidfm64015934850.png

    1bbr34sidfm64015934850.png

    ' G- E, m" X; G! r& r, ^( F+ x
    $ ]- Y. H8 \# ]4 M9 a/ S填写新建映射的基本信息,请注意内网主机和内网端口是局域网摄像头的主机和端口(端口默认为80) ,如下图所示:% Z: z* |) {8 U  f. y9 k
    & f' T: U4 s& [. i& K  k; ]. e

    duxl423cvwd64015934950.png

    duxl423cvwd64015934950.png

    ! k" S1 ]3 S) ]+ r( l, |2 N& D
    # y6 |4 {( p1 k: u5 P2 C新建映射完成后,可以在APP看到新增的设备列表,如下图所示:' a7 ^3 _$ o5 S; y. h( \6 T- S

    / z/ i6 U# j& L4 S/ A* [0 Q. R

    2c1v3pckhpb64015935050.png

    2c1v3pckhpb64015935050.png

    ) W0 P5 |: |6 P
    2 i( H6 D2 q5 R+ r( H- @& T/ s# g复制访问网址,在浏览器中打开:http://2j90962r69.goho.co:47918/0 k" b/ D7 e+ h4 x
    ( C: q1 d; O3 [% O0 ]
    即使不在同一个局域网内也可以正常访问摄像头啦。) w* m7 d; G  Z, x
    " s. [, b5 D% n2 L

    tndj42z4axt64015935151.png

    tndj42z4axt64015935151.png
    ! p- n  {  l% G# r/ s, T( i  G
    : X1 N, R" D3 N  U
    , O& l: z" ]7 n; o

    xlnz0k2y1nn64015935251.png

    xlnz0k2y1nn64015935251.png

    5 Z% L  Z7 A  C" p) x5 |往期推荐HarmonyOS学习路之开发篇—Java UI框架(Position和AdaptiveBox layout)7 G* l' V; D( v' m
    Python数据可视化:如何选择合适的图表可视化?$ y6 C& v0 \. M8 A
    磁耦合共振无线供电装置
    ; ]6 \% k2 C- tPython Qt GUI设计:表格和树类(提升篇—1)
    & K4 n$ [( j2 f3 S% `
    ) j, b/ J: C$ n- e* l3 e

    qim5pouk0fb64015935351.jpg

    qim5pouk0fb64015935351.jpg
    3 D$ K- [- V8 I* L) g

    0jpvlcj4kpz64015935451.gif

    0jpvlcj4kpz64015935451.gif
    ( g6 S! T- g. @& c9 _( A
    点击阅读原文,更精彩~
  • 回复

    使用道具 举报

    发表回复

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

    本版积分规则


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