ESP32-CAM 拍照上傳 XAMPP

閱讀時間約 14 分鐘
ESP32 CAM 運行畫面
Server 端上檔案 有 index.php
ESP32 CAM 拍照 上傳 pict.jpg 檔

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
40會員
130內容數
獨立遊戲開發紀錄
留言0
查看全部
avatar-img
發表第一個留言支持創作者!
吳佳鑫的沙龍 的其他內容
本範例為 PHP 載入 CSV檔,進行數據統計,並計算出各號碼開出次數。 資料來源: 政府資料開放平台 公益彩券各年度各期電腦型彩券獎號、銷售金額與獎金總額 載入CSV檔的作法 將資料進行統計整理 將資料放於陣列的方式 自定義函式 完整原碼
構想上,前端簡單的使用Google Map 做定位,並寫入SQL做第一段比對經緯度。接著前端有一個php上傳圖片的功能(沒有 https 所以就不做網頁開相機的方式)。經過上傳至伺服器後,python 圖形辨識,比對上傳的圖片,若比對成功或相似度差異不大,則判定正確,寫入SQL,端頁面顯示奪寶成功。
本專題為兩塊ESP8266-ESP01 ,分別為 Arduino+ESP-01+YL-69 土壤濕度檢測器與LED燈 ,以及 ESP-01 + DHT11 + LED 傳輸給伺服器端,並於伺服器上 WebSite 透過ESP-01上傳儲 存於 MYSQL 資料呈現曲線圖給前端使用者。此外,前端使用者
本專題為兩塊ESP8266-ESP01 ,分別為 Arduino+ESP-01+YL-69 土壤濕度檢測器與LED燈 ,以及 ESP-01 + DHT11 + LED 傳輸給伺服器端,並於伺服器上 WebSite 透過ESP-01上傳儲 存於 MYSQL 資料呈現曲線圖給前端使用者。此外,前端使用者
使用網路上找來的原碼 測試圖片 因版本問題會出現 error pytesseract.pytesseract.TesseractNotFoundError: C:\Program Files (x86)\Tesseract-OCR esseract.exe is not installed or i
Haar Cascade classifier OpenCV 官方 Github:https://github.com/opencv/opencv/tree/4.x/data 人臉特徵模型:haarcascade_frontalface_default.xml 資料來源: https://steam
本範例為 PHP 載入 CSV檔,進行數據統計,並計算出各號碼開出次數。 資料來源: 政府資料開放平台 公益彩券各年度各期電腦型彩券獎號、銷售金額與獎金總額 載入CSV檔的作法 將資料進行統計整理 將資料放於陣列的方式 自定義函式 完整原碼
構想上,前端簡單的使用Google Map 做定位,並寫入SQL做第一段比對經緯度。接著前端有一個php上傳圖片的功能(沒有 https 所以就不做網頁開相機的方式)。經過上傳至伺服器後,python 圖形辨識,比對上傳的圖片,若比對成功或相似度差異不大,則判定正確,寫入SQL,端頁面顯示奪寶成功。
本專題為兩塊ESP8266-ESP01 ,分別為 Arduino+ESP-01+YL-69 土壤濕度檢測器與LED燈 ,以及 ESP-01 + DHT11 + LED 傳輸給伺服器端,並於伺服器上 WebSite 透過ESP-01上傳儲 存於 MYSQL 資料呈現曲線圖給前端使用者。此外,前端使用者
本專題為兩塊ESP8266-ESP01 ,分別為 Arduino+ESP-01+YL-69 土壤濕度檢測器與LED燈 ,以及 ESP-01 + DHT11 + LED 傳輸給伺服器端,並於伺服器上 WebSite 透過ESP-01上傳儲 存於 MYSQL 資料呈現曲線圖給前端使用者。此外,前端使用者
使用網路上找來的原碼 測試圖片 因版本問題會出現 error pytesseract.pytesseract.TesseractNotFoundError: C:\Program Files (x86)\Tesseract-OCR esseract.exe is not installed or i
Haar Cascade classifier OpenCV 官方 Github:https://github.com/opencv/opencv/tree/4.x/data 人臉特徵模型:haarcascade_frontalface_default.xml 資料來源: https://steam
你可能也想看
Google News 追蹤
Thumbnail
這個秋,Chill 嗨嗨!穿搭美美去賞楓,裝備款款去露營⋯⋯你的秋天怎麼過?秋日 To Do List 等你分享! 秋季全站徵文,我們準備了五個創作主題,參賽還有機會獲得「火烤兩用鍋」,一起來看看如何參加吧~
Thumbnail
11/20日NVDA即將公布最新一期的財報, 今天Sell Side的分析師, 開始調高目標價, 市場的股價也開始反應, 未來一週NVDA將重新回到美股市場的焦點, 今天我們要分析NVDA Sell Side怎麼看待這次NVDA的財報預測, 以及實際上Buy Side的倉位及操作, 從
Thumbnail
Hi 大家好,我是Ethan😊 相近大家都知道保濕是皮膚保養中最基本,也是最重要的一步。無論是在畫室裡長時間對著畫布,還是在旅途中面對各種氣候變化,保持皮膚的水分平衡對我來說至關重要。保濕化妝水不僅能迅速為皮膚補水,還能提升後續保養品的吸收效率。 曾經,我的保養程序簡單到只包括清潔和隨意上乳液
Thumbnail
EP32精華重點: 1.定價是創業過程中非常頭痛但又不得不面對的重要課題。定價定得好不僅能確保獲利,更能建立品牌價值。 2.常見的定價策略包括成本加成定價法、競爭導向定價法、價值導向定價法等。每種策略適用的情況不同,需要根據產品特性、市場環境、目標客群等因素綜合考量。
Thumbnail
這篇文章介紹瞭如何利用單晶片來控制不同功能模組的應用,並分享了親手體驗的影片和遇到的卡關。文章強調了需要具備基礎程式語言撰寫的邏輯,以及解決卡關時需要個人調整程式碼的順序。
Thumbnail
本文是參考 https://github.com/Tinyu-Zhao/TinyGPSPlus-ESP32 官方資料庫範例
Thumbnail
責任感 我們都曾幻想過,和奧客翻臉打架的畫面 接續上一篇的爭吵事件,過了幾天後 專頁的消息欄跑出了一則令人震驚的訊息 客人:「我是昨天那位鞋底有燒焦的先生,首先換我向你們說聲抱歉。」 客人:「我試著回頭去找鞋子原本的照片,確實是有這個痕跡,至於怎麼造成的我也不清楚,所以我鄭重的向你們抱
Thumbnail
「我不是一個幸運的人,但我很努力,所以我的努力創造了幸運」從小的夢想成為空姐,歷經多次落選,最後卻在收到空姐入取通知的同時錄取研究所,夢想與創業怎麼選擇?這集邀請到 IMPCT Coffee創辦人 Jessi Fu 來和我們分享他如何看待失敗,以及他如何面對創創業過程中所遇到的挫折。
Thumbnail
上一集我們討論到行動前,如何成功找到目標、方向的方法,並善用好運加速逹到成功的方法,而這一集我們要討論的是如何在行動之中,創造運氣關鍵鑰匙!? STEP1: 找到持續行動的力量!(持續) Q:面對高度競爭,如何調適心態? A:利用三個取勝心態,找到持續行動的力量! 上一集小倉鼠分享了在找尋努力目
Thumbnail
https://www.facebook.com/103269891605396/posts/146468143952237/ 好的一面,你可以高興,因為孩子的認知能力已經到了可以想到新的方法回應你,而不只是呆呆地回答的程度。可以想像後果,以此迴避懲罰,這是種很大的進步。 . . . . . .
Thumbnail
柚子貍 從0到1媒體人x斜槓 (柚子貍&安妮動物園) https://open.firstory.me/embed/story/cksx6wjntf3bj0822c5vtkotm?description=1 本集重點:整集都很精彩,歡迎全集收聽,或您也可以依照自己興趣依序跳著聽 1.走失的老狗會用眼
Thumbnail
「阿飛的人生相談所」,故名思義就是聊人生的各種問題,我會在這裡用聲音跟讀者聊聊日常生活的大小事,也會開放讀者留言與來信提問,無論是感情上、工作上或是家庭、人際關係的問題都可以留言或來信問我,然後我會從中挑選適合的問題在音頻聊聊我的看法,當然不想問問題,單純留言給我鼓勵,我也非常開心。
Thumbnail
這個秋,Chill 嗨嗨!穿搭美美去賞楓,裝備款款去露營⋯⋯你的秋天怎麼過?秋日 To Do List 等你分享! 秋季全站徵文,我們準備了五個創作主題,參賽還有機會獲得「火烤兩用鍋」,一起來看看如何參加吧~
Thumbnail
11/20日NVDA即將公布最新一期的財報, 今天Sell Side的分析師, 開始調高目標價, 市場的股價也開始反應, 未來一週NVDA將重新回到美股市場的焦點, 今天我們要分析NVDA Sell Side怎麼看待這次NVDA的財報預測, 以及實際上Buy Side的倉位及操作, 從
Thumbnail
Hi 大家好,我是Ethan😊 相近大家都知道保濕是皮膚保養中最基本,也是最重要的一步。無論是在畫室裡長時間對著畫布,還是在旅途中面對各種氣候變化,保持皮膚的水分平衡對我來說至關重要。保濕化妝水不僅能迅速為皮膚補水,還能提升後續保養品的吸收效率。 曾經,我的保養程序簡單到只包括清潔和隨意上乳液
Thumbnail
EP32精華重點: 1.定價是創業過程中非常頭痛但又不得不面對的重要課題。定價定得好不僅能確保獲利,更能建立品牌價值。 2.常見的定價策略包括成本加成定價法、競爭導向定價法、價值導向定價法等。每種策略適用的情況不同,需要根據產品特性、市場環境、目標客群等因素綜合考量。
Thumbnail
這篇文章介紹瞭如何利用單晶片來控制不同功能模組的應用,並分享了親手體驗的影片和遇到的卡關。文章強調了需要具備基礎程式語言撰寫的邏輯,以及解決卡關時需要個人調整程式碼的順序。
Thumbnail
本文是參考 https://github.com/Tinyu-Zhao/TinyGPSPlus-ESP32 官方資料庫範例
Thumbnail
責任感 我們都曾幻想過,和奧客翻臉打架的畫面 接續上一篇的爭吵事件,過了幾天後 專頁的消息欄跑出了一則令人震驚的訊息 客人:「我是昨天那位鞋底有燒焦的先生,首先換我向你們說聲抱歉。」 客人:「我試著回頭去找鞋子原本的照片,確實是有這個痕跡,至於怎麼造成的我也不清楚,所以我鄭重的向你們抱
Thumbnail
「我不是一個幸運的人,但我很努力,所以我的努力創造了幸運」從小的夢想成為空姐,歷經多次落選,最後卻在收到空姐入取通知的同時錄取研究所,夢想與創業怎麼選擇?這集邀請到 IMPCT Coffee創辦人 Jessi Fu 來和我們分享他如何看待失敗,以及他如何面對創創業過程中所遇到的挫折。
Thumbnail
上一集我們討論到行動前,如何成功找到目標、方向的方法,並善用好運加速逹到成功的方法,而這一集我們要討論的是如何在行動之中,創造運氣關鍵鑰匙!? STEP1: 找到持續行動的力量!(持續) Q:面對高度競爭,如何調適心態? A:利用三個取勝心態,找到持續行動的力量! 上一集小倉鼠分享了在找尋努力目
Thumbnail
https://www.facebook.com/103269891605396/posts/146468143952237/ 好的一面,你可以高興,因為孩子的認知能力已經到了可以想到新的方法回應你,而不只是呆呆地回答的程度。可以想像後果,以此迴避懲罰,這是種很大的進步。 . . . . . .
Thumbnail
柚子貍 從0到1媒體人x斜槓 (柚子貍&安妮動物園) https://open.firstory.me/embed/story/cksx6wjntf3bj0822c5vtkotm?description=1 本集重點:整集都很精彩,歡迎全集收聽,或您也可以依照自己興趣依序跳著聽 1.走失的老狗會用眼
Thumbnail
「阿飛的人生相談所」,故名思義就是聊人生的各種問題,我會在這裡用聲音跟讀者聊聊日常生活的大小事,也會開放讀者留言與來信提問,無論是感情上、工作上或是家庭、人際關係的問題都可以留言或來信問我,然後我會從中挑選適合的問題在音頻聊聊我的看法,當然不想問問題,單純留言給我鼓勵,我也非常開心。