ESP32 ٹیوٹوریل 45/55 - LED کنٹرول CAM-3 کے ساتھ کسٹم اسٹریمنگ سرور | سن فاؤنڈر کا ESP32 لرننگ کٹ
اس ٹیوٹوریل میں، ہم سیکھیں گے کہ SunFounder کے ESP32 ایکسٹینشن بورڈ کا استعمال کرتے ہوئے ایک کسٹم اسٹریمنگ سرور کیسے ترتیب دیا جائے۔ یہ پروجیکٹ آپ کو اپنے براؤزر میں لائیو ویڈیو اسٹریم کرنے کی اجازت دیتا ہے جبکہ انٹرفیس سے براہ راست ایک LED کو بھی کنٹرول کرتا ہے۔ خصوصیات کا یہ امتزاج IoT اور ویب ٹیکنالوجیز کے ساتھ عملی سیکھنے کا تجربہ فراہم کرتا ہے۔
ہم ESP32 کی بلٹ ان وائی فائی صلاحیتوں کو استعمال کریں گے تاکہ ایک ویب سرور بنایا جا سکے جو ویڈیو اسٹریم کرے اور LED کنٹرول کمانڈز کو سنبھالے۔ اس پروجیکٹ میں کوڈنگ، وائرنگ، اور یہ سمجھنا شامل ہے کہ اجزاء کیسے آپس میں تعامل کرتے ہیں۔ اگر آپ سیٹ اپ کی واضح سمجھ چاہتے ہیں تو ویڈیو (ویڈیو میں 00:00 پر) ضرور دیکھیں۔
ہارڈویئر کی وضاحت
اس پروجیکٹ کے اہم اجزاء میں ESP32 مائیکروکنٹرولر، ایک کیمرہ ماجیول، ایک LED، اور ایک ریزسٹر شامل ہیں۔ ESP32 ایک ورسٹائل مائیکروکنٹرولر ہے جس میں بلٹ ان وائی فائی اور بلوٹوتھ ہے، جو اسے IoT ایپلیکیشنز کے لیے بہترین بناتا ہے۔ کیمرہ ماجیول ہمیں ویڈیو کیپچر کرنے کی اجازت دیتا ہے، جبکہ LED کنٹرول کے لیے ایک سادہ آؤٹ پٹ ڈیوائس فراہم کرتا ہے۔
LED کو کرنٹ محدود کرنے کے لیے ایک ریزسٹر کے ذریعے جوڑا جاتا ہے، جو LED اور مائیکروکنٹرولر دونوں کو نقصان سے بچاتا ہے۔ یہ سیٹ اپ ہمیں اپنے ویب انٹرفیس کے ذریعے LED کو آن اور آف کرنے کی اجازت دے گا، جو نیٹ ورک پر ان پٹ اور آؤٹ پٹ کو سنبھالنے میں ESP32 کی صلاحیتوں کو ظاہر کرتا ہے۔
ڈیٹاشیٹ کی تفصیلات
| مینوفیکچرر | Espressif |
|---|---|
| پارٹ نمبر | ESP32-WROOM-32 |
| لاجک/آئی او وولٹیج | 3.3 V |
| سپلائی وولٹیج | 3.0–3.6 V |
| آؤٹ پٹ کرنٹ (فی چینل) | 12 mA |
| پیک کرنٹ (فی چینل) | 40 mA |
| PWM فریکوئنسی رہنمائی | 1 kHz |
| ان پٹ لاجک تھریشولڈز | 0.2 V (کم) / 0.8 V (زیادہ) |
| وولٹیج ڈراپ / RDS(on) / سیچوریشن | 0.2 V (عام) |
| تھرمل حدود | زیادہ سے زیادہ جنکشن درجہ حرارت: 125 °C |
| پیکیج | QFN48 |
| نوٹس / ویریئنٹس | مختلف کنفیگریشنز میں دستیاب |
- یقینی بنائیں کہ ESP32 کو ریگولیٹڈ 3.3 V سپلائی سے پاور مل رہی ہے۔
- LED کے ساتھ کرنٹ محدود کرنے والا ریزسٹر (220 Ohm) استعمال کریں تاکہ نقصان سے بچا جا سکے۔
- فلوٹنگ ان پٹ سے بچنے کے لیے مناسب کنکشن برقرار رکھیں۔
- چیک کریں کہ وائی فائی اسناد درست اور کیس حساس ہیں۔
- مستقل کارکردگی کے لیے ایک مستحکم پاور سورس استعمال کریں۔
- بند جگہوں میں گرمی کی منتقلی پر غور کریں۔
وائرنگ ہدایات

ESP32 اور LED کو وائر کرنے کے لیے، LED کے لمبے پن کو ایک مناسب GPIO پن سے جوڑ کر شروع کریں، اس صورت میں ہم پن 14 استعمال کریں گے۔ چھوٹا پن آپ کے بریڈ بورڈ پر گراؤنڈ لائن سے جڑنا چاہیے۔ اگلا، LED کے ساتھ سیریز میں ایک 220 Ohm ریزسٹر رکھیں، ایک سرا GPIO پن (پن 14) سے اور دوسرا سرا گراؤنڈ سے جوڑیں۔ یقینی بنائیں کہ ESP32 صحیح طریقے سے پاور ہو رہا ہے، یا تو مائیکرو USB پورٹ کے ذریعے یا 18650 لیتھیم بیٹری کے ساتھ۔
کیمرہ ماجیول کے لیے، آپ جس کیمرہ ماڈل کو استعمال کر رہے ہیں اس کے مطابق ضروری پنوں کو جوڑنا یقینی بنائیں، کیونکہ وائرنگ قدرے مختلف ہو سکتی ہے۔ ESP32 اپنی بلٹ ان صلاحیتوں کے ذریعے ویڈیو اسٹریم کو سنبھالے گا، اور LED کنٹرول کوڈ میں ترتیب دیے گئے ویب انٹرفیس کے ذریعے منظم کیا جائے گا۔
کوڈ مثالیں اور واک تھرو
پروگرام ضروری لائبریریوں کو شامل کرنے اور وائی فائی اسناد کی وضاحت کے ساتھ شروع ہوتا ہے۔ آپ کو ESP32 کو اپنے نیٹ ورک سے جوڑنے کے لیے ssid اور password کو اپنی اصل وائی فائی اسناد سے تبدیل کرنا ہوگا۔
const char* ssid = "SSID";
const char* password = "PASSWORD";
اگلا، ہم LED پن کی وضاحت کرتے ہیں اور کیمرہ کنفیگریشنز سیٹ کرتے ہیں۔ LED کے لیے استعمال ہونے والا پن LED_PIN کے طور پر بیان کیا گیا ہے، جو بعد میں کوڈ میں LED کی حالت کو کنٹرول کرنے کے لیے استعمال ہوگا۔
#define LED_PIN 14
pinMode(LED_PIN, OUTPUT);
LED کنٹرول کے لیے درخواست ہینڈلر میں، ہم ویب انٹرفیس سے موصول ہونے والی کمانڈ چیک کرتے ہیں۔ اس بات پر منحصر ہے کہ کمانڈ "on" ہے یا "off"، ہم LED کو آن کرنے کے لیے digitalWrite(LED_PIN, 1); اور اسے آف کرنے کے لیے digitalWrite(LED_PIN, 0); استعمال کرتے ہیں۔
if(!strcmp(variable, "on")) {
Serial.println("ON");
digitalWrite(LED_PIN, 1);
}
else if(!strcmp(variable, "off")) {
Serial.println("OFF");
digitalWrite(LED_PIN, 0);
}
یہ منطق ویب انٹرفیس کو ESP32 کے ساتھ مؤثر طریقے سے بات چیت کرنے کی اجازت دیتی ہے، جس سے صارف کے تعاملات کی بنیاد پر LED کا ریئل ٹائم کنٹرول ممکن ہوتا ہے۔ مکمل کوڈ مضمون کے نیچے مزید تحقیق کے لیے لوڈ ہوتا ہے۔
ڈیمونسٹریشن / کیا توقع کریں
ایک بار جب سب کچھ سیٹ ہو جائے اور کوڈ اپ لوڈ ہو جائے، تو آپ کو اپنے ویب براؤزر میں ESP32 کا IP ایڈریس رسائی کرنے کے قابل ہونا چاہیے۔ اسٹریمنگ ویڈیو ظاہر ہوگی، اور آپ انٹرفیس پر بٹنوں کا استعمال کرتے ہوئے LED کو کنٹرول کر سکتے ہیں۔ "ON" پر کلک کرنے سے LED روشن ہوگی، جبکہ "OFF" اسے بند کر دے گا۔ یقینی بنائیں کہ ESP32 اور آپ کا کمپیوٹر ایک ہی نیٹ ورک سے جڑے ہوئے ہیں تاکہ مناسب فعالیت کو یقینی بنایا جا سکے (ویڈیو میں 12:30 پر)۔
ویڈیو ٹائم اسٹیمپس
- 00:00 شروع
- 1:51 پروجیکٹ کا تعارف
- 2:31 دستاویزات کا صفحہ
- 3:33 وائرنگ کی وضاحت
- 5:08 Arduino کوڈ کی وضاحت
- 13:28 Arduino IDE میں ESP32 بورڈ اور COM پورٹ کا انتخاب
- 15:10 ڈیمونسٹریشن
/*********
Permission is hereby granted, free of charge,
to any person obtaining a copy of this software and associated documentation files.
The above copyright notice and this permission
notice shall be included in all copies or substantial portions of the Software.
*********/
#include "esp_camera.h"
#include <WiFi.h>
#include "esp_timer.h"
#include "img_converters.h"
#include "Arduino.h"
#include "fb_gfx.h"
#include "soc/soc.h" // disable brownout problems
#include "soc/rtc_cntl_reg.h" // disable brownout problems
#include "esp_http_server.h"
// Replace the next variables with your SSID/Password combination
const char* ssid = "SSID";
const char* password = "PASSWORD";
#define PART_BOUNDARY "123456789000000000000987654321"
#define CAMERA_MODEL_AI_THINKER
//#define CAMERA_MODEL_M5STACK_PSRAM
//#define CAMERA_MODEL_M5STACK_WITHOUT_PSRAM
//#define CAMERA_MODEL_M5STACK_PSRAM_B
//#define CAMERA_MODEL_WROVER_KIT
#if defined(CAMERA_MODEL_WROVER_KIT)
#define PWDN_GPIO_NUM -1
#define RESET_GPIO_NUM -1
#define XCLK_GPIO_NUM 21
#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 19
#define Y4_GPIO_NUM 18
#define Y3_GPIO_NUM 5
#define Y2_GPIO_NUM 4
#define VSYNC_GPIO_NUM 25
#define HREF_GPIO_NUM 23
#define PCLK_GPIO_NUM 22
#elif defined(CAMERA_MODEL_M5STACK_PSRAM)
#define PWDN_GPIO_NUM -1
#define RESET_GPIO_NUM 15
#define XCLK_GPIO_NUM 27
#define SIOD_GPIO_NUM 25
#define SIOC_GPIO_NUM 23
#define Y9_GPIO_NUM 19
#define Y8_GPIO_NUM 36
#define Y7_GPIO_NUM 18
#define Y6_GPIO_NUM 39
#define Y5_GPIO_NUM 5
#define Y4_GPIO_NUM 34
#define Y3_GPIO_NUM 35
#define Y2_GPIO_NUM 32
#define VSYNC_GPIO_NUM 22
#define HREF_GPIO_NUM 26
#define PCLK_GPIO_NUM 21
#elif defined(CAMERA_MODEL_M5STACK_WITHOUT_PSRAM)
#define PWDN_GPIO_NUM -1
#define RESET_GPIO_NUM 15
#define XCLK_GPIO_NUM 27
#define SIOD_GPIO_NUM 25
#define SIOC_GPIO_NUM 23
#define Y9_GPIO_NUM 19
#define Y8_GPIO_NUM 36
#define Y7_GPIO_NUM 18
#define Y6_GPIO_NUM 39
#define Y5_GPIO_NUM 5
#define Y4_GPIO_NUM 34
#define Y3_GPIO_NUM 35
#define Y2_GPIO_NUM 17
#define VSYNC_GPIO_NUM 22
#define HREF_GPIO_NUM 26
#define PCLK_GPIO_NUM 21
#elif defined(CAMERA_MODEL_AI_THINKER)
#define PWDN_GPIO_NUM 32
#define RESET_GPIO_NUM 33
#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
#elif defined(CAMERA_MODEL_M5STACK_PSRAM_B)
#define PWDN_GPIO_NUM -1
#define RESET_GPIO_NUM 15
#define XCLK_GPIO_NUM 27
#define SIOD_GPIO_NUM 22
#define SIOC_GPIO_NUM 23
#define Y9_GPIO_NUM 19
#define Y8_GPIO_NUM 36
#define Y7_GPIO_NUM 18
#define Y6_GPIO_NUM 39
#define Y5_GPIO_NUM 5
#define Y4_GPIO_NUM 34
#define Y3_GPIO_NUM 35
#define Y2_GPIO_NUM 32
#define VSYNC_GPIO_NUM 25
#define HREF_GPIO_NUM 26
#define PCLK_GPIO_NUM 21
#else
#error "Camera model not selected"
#endif
#define LED_PIN 14
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 camera_httpd = NULL;
httpd_handle_t stream_httpd = NULL;
static const char PROGMEM INDEX_HTML[] = R"rawliteral(
<html>
<head>
<title>ESP32-CAM Robot</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<style>
body { font-family: Arial; text-align: center; margin:0px auto; padding-top: 30px;}
table { margin-left: auto; margin-right: auto; }
td { padding: 8 px; }
.button {
background-color: #2f4468;
border: none;
color: white;
padding: 10px 20px;
text-align: center;
text-decoration: none;
display: inline-block;
font-size: 18px;
margin: 6px 3px;
cursor: pointer;
-webkit-touch-callout: none;
-webkit-user-select: none;
-khtml-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
user-select: none;
-webkit-tap-highlight-color: rgba(0,0,0,0);
}
img { width: auto ;
max-width: 100% ;
height: auto ;
transform: rotate(180deg);
}
</style>
</head>
<body>
<h1>ESP32 CAMERA</h1>
<img src="" id="photo" >
<table>
<tr><td align="center"><button class="button" onmousedown="toggleCheckbox('on');" ontouchstart="toggleCheckbox('on');onmouseup="toggleCheckbox('on');" ontouchend="toggleCheckbox('on');">ON</button></td>
<td align="center"><button class="button" onmousedown="toggleCheckbox('off');" ontouchstart="toggleCheckbox('off');onmouseup="toggleCheckbox('off');" ontouchend="toggleCheckbox('off');">OFF</button></td></tr>
</table>
<script>
function toggleCheckbox(x) {
var xhr = new XMLHttpRequest();
xhr.open("GET", "/action?go=" + x, true);
xhr.send();
}
window.onload = document.getElementById("photo").src = window.location.href.slice(0, -1) + ":81/stream";
</script>
</body>
</html>
)rawliteral";
static esp_err_t index_handler(httpd_req_t *req){
httpd_resp_set_type(req, "text/html");
return httpd_resp_send(req, (const char *)INDEX_HTML, strlen(INDEX_HTML));
}
static esp_err_t stream_handler(httpd_req_t *req){
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);
if(res != ESP_OK){
return res;
}
while(true){
fb = esp_camera_fb_get();
if (!fb) {
Serial.println("Camera capture failed");
res = ESP_FAIL;
} else {
if(fb->width > 400){
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;
}
}
}
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;
}
//Serial.printf("MJPG: %uB\n",(uint32_t)(_jpg_buf_len));
}
return res;
}
static esp_err_t cmd_handler(httpd_req_t *req){
char* buf;
size_t buf_len;
char variable[32] = {0,};
buf_len = httpd_req_get_url_query_len(req) + 1;
if (buf_len > 1) {
buf = (char*)malloc(buf_len);
if(!buf){
httpd_resp_send_500(req);
return ESP_FAIL;
}
if (httpd_req_get_url_query_str(req, buf, buf_len) == ESP_OK) {
if (httpd_query_key_value(buf, "go", variable, sizeof(variable)) == ESP_OK) {
} else {
free(buf);
httpd_resp_send_404(req);
return ESP_FAIL;
}
} else {
free(buf);
httpd_resp_send_404(req);
return ESP_FAIL;
}
free(buf);
} else {
httpd_resp_send_404(req);
return ESP_FAIL;
}
sensor_t * s = esp_camera_sensor_get();
int res = 0;
if(!strcmp(variable, "on")) {
Serial.println("ON");
digitalWrite(LED_PIN, 1);
}
else if(!strcmp(variable, "off")) {
Serial.println("OFF");
digitalWrite(LED_PIN, 0);
}
else {
res = -1;
}
if(res){
return httpd_resp_send_500(req);
}
httpd_resp_set_hdr(req, "Access-Control-Allow-Origin", "*");
return httpd_resp_send(req, NULL, 0);
}
void startCameraServer(){
httpd_config_t config = HTTPD_DEFAULT_CONFIG();
config.server_port = 80;
httpd_uri_t index_uri = {
.uri = "/",
.method = HTTP_GET,
.handler = index_handler,
.user_ctx = NULL
};
httpd_uri_t cmd_uri = {
.uri = "/action",
.method = HTTP_GET,
.handler = cmd_handler,
.user_ctx = NULL
};
httpd_uri_t stream_uri = {
.uri = "/stream",
.method = HTTP_GET,
.handler = stream_handler,
.user_ctx = NULL
};
if (httpd_start(&camera_httpd, &config) == ESP_OK) {
httpd_register_uri_handler(camera_httpd, &index_uri);
httpd_register_uri_handler(camera_httpd, &cmd_uri);
}
config.server_port += 1;
config.ctrl_port += 1;
if (httpd_start(&stream_httpd, &config) == ESP_OK) {
httpd_register_uri_handler(stream_httpd, &stream_uri);
}
}
void setup() {
WRITE_PERI_REG(RTC_CNTL_BROWN_OUT_REG, 0); //disable brownout detector
pinMode(LED_PIN, OUTPUT);
Serial.begin(115200);
Serial.setDebugOutput(false);
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;
if(psramFound()){
config.frame_size = FRAMESIZE_VGA;
config.jpeg_quality = 10;
config.fb_count = 2;
} else {
config.frame_size = FRAMESIZE_SVGA;
config.jpeg_quality = 12;
config.fb_count = 1;
}
// 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;
}
// Wi-Fi connection
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
Serial.println("");
Serial.println("WiFi connected");
Serial.print("Camera Stream Ready! Go to: http://");
Serial.println(WiFi.localIP());
// Start streaming web server
startCameraServer();
}
void loop() {
}
Common Course Links
Common Course Files
وسائل اور حوالہ جات
-
دستاویزاتESP32 Tutorial 45/55 - SunFounder doc page for Custom Streaming Serverdocs.sunfounder.com
فائلیں📁
کوئی فائلیں دستیاب نہیں ہیں۔