-
-
Save cjaca/7a23ea9e8f857c8b816bd5737959b9e7 to your computer and use it in GitHub Desktop.
esp32-cam
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
//Dodawanie bibliotek do tworzenia serwera | |
#include "esp_camera.h" | |
#include <WiFi.h> | |
#include "esp_timer.h" | |
#include "img_converters.h" | |
#include "Arduino.h" | |
#include "fb_gfx.h" | |
#include "esp_http_server.h" | |
//Zamiana danych do sieci WiFi | |
const char * ssid = "IDENTYFIKATOR_SIECI"; | |
const char * password = "HASŁO_DO_SIECI"; | |
#define PART_BOUNDARY "123456789000000000000987654321" | |
// Definiowanie modelu uzywanej plytki, w projekcie został wykorzystany AI_THINKER | |
#define CAMERA_MODEL_AI_THINKER | |
#define PWDN_GPIO_NUM 32 | |
#define RESET_GPIO_NUM - 1 | |
#define XCLK_GPIO_NUM 0 | |
#define SIOD_GPIO_NUM 26 | |
#define SIOC_GPIO_NUM 27 | |
#define Y9_GPIO_NUM 35 | |
#define Y8_GPIO_NUM 34 | |
#define Y7_GPIO_NUM 39 | |
#define Y6_GPIO_NUM 36 | |
#define Y5_GPIO_NUM 21 | |
#define Y4_GPIO_NUM 19 | |
#define Y3_GPIO_NUM 18 | |
#define Y2_GPIO_NUM 5 | |
#define VSYNC_GPIO_NUM 25 | |
#define HREF_GPIO_NUM 23 | |
#define PCLK_GPIO_NUM 22 | |
static | |
const char * _STREAM_CONTENT_TYPE = "multipart/x-mixed-replace;boundary=" | |
PART_BOUNDARY; | |
static | |
const char * _STREAM_BOUNDARY = "\r\n--" | |
PART_BOUNDARY "\r\n"; | |
static | |
const char * _STREAM_PART = "Content-Type: image/jpeg\r\nContent-Length: %u\r\n\r\n"; | |
httpd_handle_t stream_httpd = NULL; | |
static esp_err_t stream_handler(httpd_req_t * req) { | |
//Definicja zmiennych | |
camera_fb_t * fb = NULL; | |
esp_err_t res = ESP_OK; | |
size_t _jpg_buf_len = 0; | |
uint8_t * _jpg_buf = NULL; | |
char * part_buf[64]; | |
res = httpd_resp_set_type(req, _STREAM_CONTENT_TYPE); | |
//sprawdzanie czy komunikacja z płytką się powiodła | |
if (res != ESP_OK) { | |
return res; | |
} | |
while (true) { | |
fb = esp_camera_fb_get(); | |
//jeśli komunikacja z płytką się nie powiodła zwracany jest błąd | |
if (!fb) { | |
Serial.println("Uchwycenie obrazu się nie powiodło"); | |
res = ESP_FAIL; | |
} else { | |
if (fb -> width > 400) { | |
//kompresja obrazu | |
if (fb -> format != PIXFORMAT_JPEG) { | |
bool jpeg_converted = frame2jpg(fb, 80, & _jpg_buf, & _jpg_buf_len); | |
esp_camera_fb_return(fb); | |
fb = NULL; | |
if (!jpeg_converted) { | |
Serial.println("JPEG compression failed"); | |
res = ESP_FAIL; | |
} | |
} else { | |
_jpg_buf_len = fb -> len; | |
_jpg_buf = fb -> buf; | |
} | |
} | |
} | |
//sprawdzenie czy nie występują błędy | |
if (res == ESP_OK) { | |
size_t hlen = snprintf((char * ) part_buf, 64, _STREAM_PART, _jpg_buf_len); | |
res = httpd_resp_send_chunk(req, (const char * ) part_buf, hlen); | |
} | |
if (res == ESP_OK) { | |
res = httpd_resp_send_chunk(req, (const char * ) _jpg_buf, _jpg_buf_len); | |
} | |
if (res == ESP_OK) { | |
res = httpd_resp_send_chunk(req, _STREAM_BOUNDARY, strlen(_STREAM_BOUNDARY)); | |
} | |
if (fb) { | |
esp_camera_fb_return(fb); | |
fb = NULL; | |
_jpg_buf = NULL; | |
} else if (_jpg_buf) { | |
free(_jpg_buf); | |
_jpg_buf = NULL; | |
} | |
if (res != ESP_OK) { | |
break; | |
} | |
} | |
return res; | |
} | |
//rozpoczęcie serwera kamery | |
void startCameraServer() { | |
httpd_config_t config = HTTPD_DEFAULT_CONFIG(); | |
config.server_port = 80; | |
httpd_uri_t index_uri = { | |
.uri = "/", | |
.method = HTTP_GET, | |
.handler = stream_handler, | |
.user_ctx = NULL | |
}; | |
if (httpd_start( & stream_httpd, & config) == ESP_OK) { | |
httpd_register_uri_handler(stream_httpd, & index_uri); | |
} | |
} | |
void setup() { | |
Serial.begin(115200); | |
Serial.setDebugOutput(false); | |
//konfigurowanie kamery/pinów | |
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_sscb_sda = SIOD_GPIO_NUM; | |
config.pin_sscb_scl = SIOC_GPIO_NUM; | |
config.pin_pwdn = PWDN_GPIO_NUM; | |
config.pin_reset = RESET_GPIO_NUM; | |
config.xclk_freq_hz = 20000000; | |
config.pixel_format = PIXFORMAT_JPEG; | |
//ustawienie jakości zdjęc JPEG | |
if (psramFound()) { | |
config.frame_size = FRAMESIZE_UXGA; | |
config.jpeg_quality = 10; | |
config.fb_count = 2; | |
} else { | |
config.frame_size = FRAMESIZE_SVGA; | |
config.jpeg_quality = 12; | |
config.fb_count = 1; | |
} | |
// Rozpoczęcie pracy kamery | |
esp_err_t err = esp_camera_init( & config); | |
if (err != ESP_OK) { | |
Serial.printf("Wystąpił błąd 0x%x", err); | |
return; | |
} | |
// połączenie WiFi | |
WiFi.begin(ssid, password); | |
while (WiFi.status() != WL_CONNECTED) { | |
delay(500); | |
Serial.print("."); | |
} | |
Serial.println(""); | |
Serial.println("WiFi połączone"); | |
Serial.print("Stream Kamery jest gotowy! idz do: http://"); | |
Serial.print(WiFi.localIP()); | |
// rozpocznięcie streama kamery w celu sprawdzenia obrazu w przeglądarce | |
startCameraServer(); | |
} | |
void loop() { | |
delay(1); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment