ESP32-CAM 拍照上傳 XAMPP

更新於 發佈於 閱讀時間約 13 分鐘
raw-image
raw-image
raw-image
raw-image


XAMPP 伺服器架設

S1. 下載與安裝

S2. 啟動XAMPP、Apache、Mysql

S3. Mysql安全性設定

shell : --user=root password "1234"

phpmyadmin(config.inc.php)

S4. Apache設定 網站根目錄

http.conf : documentroot

S5. PHP環境設定

php.ini :

短標籤 : short_open_tag = On

參數為全域變數 : register_globals = off

錯誤訊息 : display_errors = On

錯誤等級 : error_reporting = E_ALL & ~E_NOTICE

時區 : date.timezone = Asia / Taipei

ESP32-CAM CODE

#include <WiFi.h>
#include "esp_camera.h"
#define SERVER "192.168.137.1" // 請改成你的網站伺服器位址或域名
#define UPLOAD_URL "/esp32cam/index.php" //此處為後端 接收圖檔的php程式
#define PORT 80

const char* ssid = "Wi-Fi網路名稱";
const char* password = "網路密碼";

WiFiClient client;

const int timerInterval = 10000; // 上傳影像的間隔毫秒數
unsigned long previousMillis = 0;

bool initCamera() {
// 設定攝像頭的接腳和影像格式與尺寸
static camera_config_t camera_config = {
.pin_pwdn = 32, // 斷電腳
.pin_reset = -1, // 重置腳
.pin_xclk = 0, // 外部時脈腳
.pin_sscb_sda = 26, // I2C資料腳
.pin_sscb_scl = 27, // I2C時脈腳
.pin_d7 = 35, // 資料腳
.pin_d6 = 34,
.pin_d5 = 39,
.pin_d4 = 36,
.pin_d3 = 21,
.pin_d2 = 19,
.pin_d1 = 18,
.pin_d0 = 5,
.pin_vsync = 25, // 垂直同步腳
.pin_href = 23, // 水平同步腳
.pin_pclk = 22, // 像素時脈腳
.xclk_freq_hz = 20000000, // 設定外部時脈:20MHz
.ledc_timer = LEDC_TIMER_0, // 指定產生XCLK時脈的計時器
.ledc_channel = LEDC_CHANNEL_0, // 指定產生XCLM時脈的通道
.pixel_format = PIXFORMAT_JPEG, // 設定影像格式:JPEG
.frame_size = FRAMESIZE_SVGA, // 設定影像大小:SVGA
.jpeg_quality = 10, // 設定JPEG影像畫質,有效值介於0-63,數字越低畫質越高。
.fb_count = 1 // 影像緩衝記憶區數量
};

// 初始化攝像頭
esp_err_t err = esp_camera_init(&camera_config);
if (err != ESP_OK) {
Serial.printf("攝像頭出錯了,錯誤碼:0x%x", err);
return false;
}

return true;
}

void postImage() {
camera_fb_t *fb = NULL; // 宣告儲存影像結構資料的變數
fb = esp_camera_fb_get(); // 拍照

if(!fb) {
Serial.println("無法取得影像資料…");
delay(1000);
ESP.restart(); // 重新啟動
}

Serial.printf("連接伺服器:%s\n", SERVER);

if (client.connect(SERVER, PORT)) {
Serial.println("開始上傳影像…");

String boundBegin = "--ESP32CAM\r\n";
boundBegin += "Content-Disposition: form-data; name=\"filename\"; filename=\"pict.jpg\"\r\n";
boundBegin += "Content-Type: image/jpeg\r\n";
boundBegin += "\r\n";

String boundEnd = "\r\n--ESP32CAM--\r\n";

uint32_t imgSize = fb->len; // 取得影像檔的大小
uint32_t payloadSize = boundBegin.length() + imgSize + boundEnd.length();

String httpMsg = String("POST ") + UPLOAD_URL + " HTTP/1.1\r\n";
httpMsg += String("Host: ") + SERVER + "\r\n";
httpMsg += "User-Agent: Arduino/ESP32CAM\r\n";
httpMsg += "Content-Length: " + String(payloadSize) + "\r\n";
httpMsg += "Content-Type: multipart/form-data; boundary=ESP32CAM\r\n";
httpMsg += "\r\n";
httpMsg += boundBegin;

// 送出HTTP標頭訊息
client.print(httpMsg.c_str());

// 上傳檔案
uint8_t *buf = fb->buf;

for (uint32_t i=0; i<imgSize; i+=1024) {
if (i+1024 < imgSize) {
client.write(buf, 1024);
buf += 1024;
} else if (imgSize%1024>0) {
uint32_t remainder = imgSize%1024;
client.write(buf, remainder);
}
}

client.print(boundEnd.c_str());

esp_camera_fb_return(fb);

// 等待伺服器的回應(10秒)
long timout = 10000L + millis();

while (timout > millis()) {
Serial.print(".");
delay(100);

if (client.available()){
// 讀取伺服器的回應
Serial.println("\n伺服器回應:");
String line = client.readStringUntil('\r');
Serial.println(line);
break;
}
}

Serial.println("關閉連線");
} else {
Serial.printf("無法連接伺服器:%s\n", SERVER);
}

client.stop(); // 關閉用戶端
}

void setup() {
Serial.begin(115200);

WiFi.mode(WIFI_STA);
WiFi.begin(ssid, password);
Serial.println("\n\n連接Wi-Fi");
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
Serial.print("\nIP位址:");
Serial.println(WiFi.localIP());

bool cameraReady = initCamera();
if (!cameraReady) {
Serial.println("攝像頭出錯了…");
delay(1000);
ESP.restart(); // 重新啟動ESP32
}

postImage(); // 上傳影像
}

void loop() {
unsigned long currentMillis = millis();
if (currentMillis - previousMillis >= timerInterval) {
postImage(); // 上傳影像
previousMillis = currentMillis;
}
}

Server 端 php code

<?php
# 檢查檔案是否上傳成功
if ($_FILES['filename']['error'] === UPLOAD_ERR_OK){
echo '檔案名稱: ' . $_FILES['filename']['name'] . '<br/>';
echo '檔案類型: ' . $_FILES['filename']['type'] . '<br/>';
echo '檔案大小: ' . ($_FILES['filename']['size'] / 1024) . ' KB<br/>';
echo '暫存名稱: ' . $_FILES['filename']['tmp_name'] . '<br/>';

# 檢查檔案是否已經存在
if (file_exists('./' . $_FILES['filename']['name'])){
echo '檔案已存在。<br/>';
} else {
$file = $_FILES['filename']['tmp_name'];
$dest = './' . $_FILES['filename']['name'];

# 將檔案移至指定位置
move_uploaded_file($file, $dest);
}
} else {
echo '錯誤代碼:' . $_FILES['filename']['error'] . '<br/>';
}
?>
留言
avatar-img
留言分享你的想法!
avatar-img
MJ的沙龍
42會員
136內容數
獨立遊戲開發紀錄
MJ的沙龍的其他內容
2025/04/12
🗓 Steam 上市日期:2025/4/28 | 🖤 加入願望清單:https://store.steampowered.com/app/3634400/Elara/ 「他們說我太敏感,說我不合群。 但我只是——不想學會沉默。」 —Elara Quinn 你是否曾經在工作時,感
Thumbnail
2025/04/12
🗓 Steam 上市日期:2025/4/28 | 🖤 加入願望清單:https://store.steampowered.com/app/3634400/Elara/ 「他們說我太敏感,說我不合群。 但我只是——不想學會沉默。」 —Elara Quinn 你是否曾經在工作時,感
Thumbnail
2025/03/05
在靈異頻發的醫院夜班,小護士林筱筱意外發現她的冷酷上司——蘇醫生,竟然早已死亡五年,從此她與這位神秘的「鬼醫生」攜手處理靈異事件,並在驚魂不斷的夜班中逐漸建立起一段超越生死的羈絆。
Thumbnail
2025/03/05
在靈異頻發的醫院夜班,小護士林筱筱意外發現她的冷酷上司——蘇醫生,竟然早已死亡五年,從此她與這位神秘的「鬼醫生」攜手處理靈異事件,並在驚魂不斷的夜班中逐漸建立起一段超越生死的羈絆。
Thumbnail
2025/02/24
這是一篇懸疑驚悚小說,描述女主角江語珊調查一起離奇命案的故事。死者林曦是一位心理學教授,死於自家公寓,現場佈滿鏡子,死者嘴角帶著詭異的微笑。語珊在調查過程中發現,此案與一種名為「鏡像侵蝕」的心理現象有關,並逐漸被捲入其中。
Thumbnail
2025/02/24
這是一篇懸疑驚悚小說,描述女主角江語珊調查一起離奇命案的故事。死者林曦是一位心理學教授,死於自家公寓,現場佈滿鏡子,死者嘴角帶著詭異的微笑。語珊在調查過程中發現,此案與一種名為「鏡像侵蝕」的心理現象有關,並逐漸被捲入其中。
Thumbnail
看更多
你可能也想看
Thumbnail
2025 vocus 推出最受矚目的活動之一——《開箱你的美好生活》,我們跟著創作者一起「開箱」各種故事、景點、餐廳、超值好物⋯⋯甚至那些讓人會心一笑的生活小廢物;這次活動不僅送出了許多獎勵,也反映了「內容有價」——創作不只是分享、紀錄,也能用各種不同形式變現、帶來實際收入。
Thumbnail
2025 vocus 推出最受矚目的活動之一——《開箱你的美好生活》,我們跟著創作者一起「開箱」各種故事、景點、餐廳、超值好物⋯⋯甚至那些讓人會心一笑的生活小廢物;這次活動不僅送出了許多獎勵,也反映了「內容有價」——創作不只是分享、紀錄,也能用各種不同形式變現、帶來實際收入。
Thumbnail
戴夫寇爾研究團隊發現PHP在Windows系統上存在遠端程式碼執行漏洞,影響多個PHP版本,包括XAMPP預設安裝環境。漏洞源於字元編碼轉換的問題,允許攻擊者在遠端伺服器上執行任意程式碼。建議使用者立即升級至最新PHP版本,或採取臨時緩解措施。
Thumbnail
戴夫寇爾研究團隊發現PHP在Windows系統上存在遠端程式碼執行漏洞,影響多個PHP版本,包括XAMPP預設安裝環境。漏洞源於字元編碼轉換的問題,允許攻擊者在遠端伺服器上執行任意程式碼。建議使用者立即升級至最新PHP版本,或採取臨時緩解措施。
Thumbnail
ESP32 連接 GPS模組 讀取gps 模組資料
Thumbnail
ESP32 連接 GPS模組 讀取gps 模組資料
Thumbnail
本文介紹如何設定ESXI HOST中的虛擬機自動隨著HOST開關機。
Thumbnail
本文介紹如何設定ESXI HOST中的虛擬機自動隨著HOST開關機。
Thumbnail
php.ini 1.short_open_tag = On 2.register_globals = Off 3.display_errors = On 4.error_reporting = E_ALL & ~E_NOTICE 5.date.timezone = Asia/Tai
Thumbnail
php.ini 1.short_open_tag = On 2.register_globals = Off 3.display_errors = On 4.error_reporting = E_ALL & ~E_NOTICE 5.date.timezone = Asia/Tai
Thumbnail
仍舊是紀錄一下自己的過程,避免真的又找半天 1.準備 Console線 ( RS-232 公母接頭 ) 2.準備 USB-RS232 轉接線 ( 驅動程式 ) 3.putty ( 下載位置 ) 4.Zyxel ES3500 的帳號密碼 ( 我的預設是admin/1234 )
Thumbnail
仍舊是紀錄一下自己的過程,避免真的又找半天 1.準備 Console線 ( RS-232 公母接頭 ) 2.準備 USB-RS232 轉接線 ( 驅動程式 ) 3.putty ( 下載位置 ) 4.Zyxel ES3500 的帳號密碼 ( 我的預設是admin/1234 )
Thumbnail
燒錄方式可用兩種: 拆開直接用USB to TTL燒 以OTA方式燒錄 以OTA方式燒錄,請先去程式碼加上web server,並OTA一次,之後輸入設備IP進入網頁,再選擇此處的檔案燒錄 此燒錄檔會開啟以下功能: device name後綴mac address web server
Thumbnail
燒錄方式可用兩種: 拆開直接用USB to TTL燒 以OTA方式燒錄 以OTA方式燒錄,請先去程式碼加上web server,並OTA一次,之後輸入設備IP進入網頁,再選擇此處的檔案燒錄 此燒錄檔會開啟以下功能: device name後綴mac address web server
Thumbnail
ESP8266 / ESP32單晶片的學習者或玩家常用板卡,依大小體積區分為 大型板卡: Arduino UNO/MEGA/M0 Pro , WEMOS D1 R2 ,WEMOS UNO 中型板卡: NodeMCU ESP8266-12E , ESP32/WROOM-32 , WEMOS D1
Thumbnail
ESP8266 / ESP32單晶片的學習者或玩家常用板卡,依大小體積區分為 大型板卡: Arduino UNO/MEGA/M0 Pro , WEMOS D1 R2 ,WEMOS UNO 中型板卡: NodeMCU ESP8266-12E , ESP32/WROOM-32 , WEMOS D1
追蹤感興趣的內容從 Google News 追蹤更多 vocus 的最新精選內容追蹤 Google News