Ich habe zuvor OV2640 verwendet, um das Bild abzurufen, daher habe ich diesmal versucht, das Bild mit OV7725 abzurufen. Der OV7725 gibt Bilder im BMP-Format anstelle von JPEG aus, daher unterscheidet sich die Steuermethode geringfügig.
Dieses Mal habe ich es möglich gemacht, das OV7725-Register im Browser zu ändern! Aus dem Fazit konnte ich kein sehr schönes Bild mit 300.000 Pixeln machen. Es scheint die gleiche Leistung zu haben wie die in den frühen Handys installierte Kamera ... Wenn Sie schöne Bilder machen möchten, sollten Sie einen Himbeerkuchen verwenden und mit OV5640 fotografieren.
Ich habe ESP32-WROOM-32 für OV2640 verwendet, aber ich habe ESP32-WROVER-B mit PSRAM verwendet, da OV7725 bmp ist und die Speichernutzung zunimmt.
offiziell https://github.com/espressif/esp32-camera
Vielleicht bevor es offiziell verabschiedet wurde https://github.com/igrr/esp32-cam-demo
Pin-Platzierung https://www.instructables.com/id/The-Incredible-ESP32-Wrover-From-Espressif/
OV7725 Datenblatt https://cdn.sparkfun.com/datasheets/Sensors/LightImaging/OV7725.pdf
Klonen Sie das Submodul in den Ordner esp-idf.
git submodule add https://github.com/espressif/esp32-camera.git components/esp32-camera
mv esp-idf/components/esp32-camera/driver/private_include/sccb.h esp-idf/components/esp32-camera/driver/include/sccb.h
mv esp-idf/components/esp32-camera/driver/private_include/sensor.h esp-idf/components/esp32-camera/driver/include/sensor.h
Der einfache Server im Beispiel von esp-idf wurde verbessert. Wenn Sie mit einem Browser auf "http: //
Alle Codes sind unten aufgeführt. https://github.com/koki-iwaizumi/esp32-ov7725
Die Größe ist VGA und das Ausgabeformat ist YUV422. Bitte ändern Sie die Einstellungen rund um WLAN.
app_main.c
#include <string.h>
#include <esp_wifi.h>
#include <esp_event_loop.h>
#include <esp_log.h>
#include <esp_system.h>
#include <nvs_flash.h>
#include <sys/param.h>
#include <esp_http_server.h>
#include <esp_camera.h>
#include "mbedtls/base64.h"
#include "cJSON.h"
#include "sensor.h"
#include "sccb.h"
/********* io ***********/
#define CAM_PIN_PWDN 2
#define CAM_PIN_RESET 15
#define CAM_PIN_XCLK 27
#define CAM_PIN_SIOD 25
#define CAM_PIN_SIOC 23
#define CAM_PIN_VSYNC 22
#define CAM_PIN_HREF 26
#define CAM_PIN_PCLK 21
#define CAM_PIN_D9 19
#define CAM_PIN_D8 36
#define CAM_PIN_D7 18
#define CAM_PIN_D6 39
#define CAM_PIN_D5 5
#define CAM_PIN_D4 34
#define CAM_PIN_D3 32
#define CAM_PIN_D2 35
/********* wifi ***********/
#define EXAMPLE_WIFI_SSID "*"
#define EXAMPLE_WIFI_PASS "*"
static const char *TAG = "APP";
sensor_t* sensor = NULL;
static camera_config_t camera_config = {
.pin_pwdn = CAM_PIN_PWDN,
.pin_reset = CAM_PIN_RESET,
.pin_xclk = CAM_PIN_XCLK,
.pin_sscb_sda = CAM_PIN_SIOD,
.pin_sscb_scl = CAM_PIN_SIOC,
.pin_d7 = CAM_PIN_D9,
.pin_d6 = CAM_PIN_D8,
.pin_d5 = CAM_PIN_D7,
.pin_d4 = CAM_PIN_D6,
.pin_d3 = CAM_PIN_D5,
.pin_d2 = CAM_PIN_D4,
.pin_d1 = CAM_PIN_D3,
.pin_d0 = CAM_PIN_D2,
.pin_vsync = CAM_PIN_VSYNC,
.pin_href = CAM_PIN_HREF,
.pin_pclk = CAM_PIN_PCLK,
.xclk_freq_hz = 6000000,
.ledc_timer = LEDC_TIMER_0,
.ledc_channel = LEDC_CHANNEL_0,
.pixel_format = PIXFORMAT_YUV422,
.frame_size = FRAMESIZE_VGA,
.jpeg_quality = 12,
.fb_count = 1
};
esp_err_t index_get_handler(httpd_req_t *req)
{
extern const unsigned char index_start[] asm("_binary_index_html_start");
extern const unsigned char index_end[] asm("_binary_index_html_end");
const size_t index_size = (index_end - index_start);
httpd_resp_send_chunk(req, (const char *)index_start, index_size);
httpd_resp_sendstr_chunk(req, NULL);
return ESP_OK;
}
esp_err_t image_post_handler(httpd_req_t *req)
{
int content_buf_size = 10 * 1000;
char *content_buf = calloc(content_buf_size, sizeof(char));
if(content_buf == NULL){
ESP_LOGE(TAG, "Failed to allocate frame buffer - content_buf");
httpd_resp_send_500(req);
return ESP_FAIL;
}
if(httpd_req_recv(req, content_buf, req->content_len) <= 0){
ESP_LOGE(TAG, "httpd_req_recv failed");
httpd_resp_send_500(req);
return ESP_FAIL;
}
ESP_LOGE(TAG, "httpd_req_recv content=%s", content_buf);
cJSON *content_json = cJSON_Parse(content_buf);
for(int i = 0; i <= 172; i++){
char key[4];
itoa(i,key,10);
int value = strtol(cJSON_GetObjectItem(content_json, key)->valuestring, NULL, 16);
SCCB_Write(sensor->slv_addr, i, value);
}
cJSON_Delete(content_json);
free(content_buf);
camera_fb_t *fb = NULL;
esp_err_t res = ESP_OK;
int64_t fr_start = esp_timer_get_time();
fb = esp_camera_fb_get();
if( ! fb){
ESP_LOGE(TAG, "Camera capture failed");
httpd_resp_send_500(req);
return ESP_FAIL;
}
uint8_t *buf = NULL;
size_t buf_len = 0;
bool converted = frame2bmp(fb, &buf, &buf_len);
esp_camera_fb_return(fb);
if( ! converted){
ESP_LOGE(TAG, "BMP conversion failed");
httpd_resp_send_500(req);
return ESP_FAIL;
}
ESP_LOGI(TAG, "esp_get_free_heap_size (%d bytes)", esp_get_free_heap_size());
ESP_LOGI(TAG, "esp_get_minimum_free_heap_size (%d bytes)", esp_get_minimum_free_heap_size());
ESP_LOGI(TAG, "heap_caps_get_free_size(MALLOC_CAP_8BIT) (%d bytes)", heap_caps_get_free_size(MALLOC_CAP_8BIT));
ESP_LOGI(TAG, "heap_caps_get_minimum_free_size(MALLOC_CAP_8BIT) (%d bytes)", heap_caps_get_minimum_free_size(MALLOC_CAP_8BIT));
ESP_LOGI(TAG, "heap_caps_get_largest_free_block(MALLOC_CAP_8BIT) (%d bytes)", heap_caps_get_largest_free_block(MALLOC_CAP_8BIT));
int image_buf_size = 1300 * 1000;
uint8_t *image_buf = calloc(image_buf_size, sizeof(char));
if(image_buf == NULL){
free(buf);
ESP_LOGE(TAG, "Failed to allocate frame buffer - image_buf");
httpd_resp_send_500(req);
return ESP_FAIL;
}
size_t olen = 0;
int base64_err = mbedtls_base64_encode(image_buf, image_buf_size, &olen, buf, buf_len);
free(buf);
if (base64_err != 0) {
ESP_LOGE(TAG, "error base64 encoding, error %d, buff size: %d", base64_err, olen);
httpd_resp_send_500(req);
return ESP_FAIL;
}
ESP_LOGI(TAG, "esp_get_free_heap_size (%d bytes)", esp_get_free_heap_size());
ESP_LOGI(TAG, "esp_get_minimum_free_heap_size (%d bytes)", esp_get_minimum_free_heap_size());
ESP_LOGI(TAG, "heap_caps_get_free_size(MALLOC_CAP_8BIT) (%d bytes)", heap_caps_get_free_size(MALLOC_CAP_8BIT));
ESP_LOGI(TAG, "heap_caps_get_minimum_free_size(MALLOC_CAP_8BIT) (%d bytes)", heap_caps_get_minimum_free_size(MALLOC_CAP_8BIT));
ESP_LOGI(TAG, "heap_caps_get_largest_free_block(MALLOC_CAP_8BIT) (%d bytes)", heap_caps_get_largest_free_block(MALLOC_CAP_8BIT));
uint8_t *image_json = calloc(image_buf_size, sizeof(char));
if(image_json == NULL){
free(image_buf);
ESP_LOGE(TAG, "Failed to allocate frame buffer - image_json");
httpd_resp_send_500(req);
return ESP_FAIL;
}
sprintf((char *)image_json, "{\"image\":\"%s\"}", (const char *)image_buf);
free(image_buf);
ESP_LOGI(TAG, "image_json length=%d", strlen((const char*)image_json));
res = httpd_resp_set_type(req, "application/json") || httpd_resp_set_hdr(req, "Access-Control-Allow-Origin", "*") || httpd_resp_send(req, (const char *)image_json, strlen((const char*)image_json));
free(image_json);
int64_t fr_end = esp_timer_get_time();
ESP_LOGI(TAG, "BMP: %uKB %ums", (uint32_t)(buf_len/1024), (uint32_t)((fr_end - fr_start)/1000));
return res;
}
esp_err_t config_get_handler(httpd_req_t *req)
{
int data_json_size = 10 * 1000;
char *data_json = calloc(data_json_size, sizeof(char));
if(data_json == NULL){
ESP_LOGE(TAG, "Failed to allocate frame buffer - data_json");
httpd_resp_send_500(req);
return ESP_FAIL;
}
strcat(data_json, "{");
for(int i = 0; i <= 172; i++){
char data_json_buf[255] = {'\0'};
sprintf(data_json_buf, "\"%d\":\"%d\"", i, SCCB_Read(sensor->slv_addr, i));
strcat(data_json, data_json_buf);
if(i != 172) strcat(data_json, ",");
}
strcat(data_json, "}");
ESP_LOGI(TAG, "data_json=%s", data_json);
ESP_LOGI(TAG, "data_json length=%d", strlen((const char*)data_json));
esp_err_t res = httpd_resp_set_type(req, "application/json") || httpd_resp_set_hdr(req, "Access-Control-Allow-Origin", "*") || httpd_resp_send(req, (const char *)data_json, strlen((const char*)data_json));
free(data_json);
return res;
}
httpd_uri_t index_uri = {
.uri = "/",
.method = HTTP_GET,
.handler = index_get_handler,
};
httpd_uri_t image_uri = {
.uri = "/image",
.method = HTTP_POST,
.handler = image_post_handler,
};
httpd_uri_t config_uri = {
.uri = "/config",
.method = HTTP_GET,
.handler = config_get_handler,
};
httpd_handle_t start_webserver(void)
{
httpd_handle_t server = NULL;
httpd_config_t config = HTTPD_DEFAULT_CONFIG();
ESP_LOGI(TAG, "Starting server on port: '%d'", config.server_port);
if(httpd_start(&server, &config) == ESP_OK){
ESP_LOGI(TAG, "Registering URI handlers");
httpd_register_uri_handler(server, &index_uri);
httpd_register_uri_handler(server, &image_uri);
httpd_register_uri_handler(server, &config_uri);
return server;
}
ESP_LOGI(TAG, "Error starting server!");
return NULL;
}
void stop_webserver(httpd_handle_t server)
{
httpd_stop(server);
}
static esp_err_t event_handler(void *ctx, system_event_t *event)
{
httpd_handle_t *server = (httpd_handle_t *) ctx;
switch(event->event_id){
case SYSTEM_EVENT_STA_START:
ESP_LOGI(TAG, "SYSTEM_EVENT_STA_START");
ESP_ERROR_CHECK(esp_wifi_connect());
break;
case SYSTEM_EVENT_STA_GOT_IP:
ESP_LOGI(TAG, "SYSTEM_EVENT_STA_GOT_IP");
ESP_LOGI(TAG, "Got IP: '%s'", ip4addr_ntoa(&event->event_info.got_ip.ip_info.ip));
if(*server == NULL){
*server = start_webserver();
}
break;
case SYSTEM_EVENT_STA_DISCONNECTED:
ESP_LOGI(TAG, "SYSTEM_EVENT_STA_DISCONNECTED");
ESP_ERROR_CHECK(esp_wifi_connect());
if(*server){
stop_webserver(*server);
*server = NULL;
}
break;
default:
break;
}
return ESP_OK;
}
static void initialise_wifi(void *arg)
{
tcpip_adapter_init();
ESP_ERROR_CHECK(esp_event_loop_init(event_handler, arg));
wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT();
ESP_ERROR_CHECK(esp_wifi_init(&cfg));
ESP_ERROR_CHECK(esp_wifi_set_storage(WIFI_STORAGE_RAM));
wifi_config_t wifi_config = {
.sta = {
.ssid = EXAMPLE_WIFI_SSID,
.password = EXAMPLE_WIFI_PASS,
},
};
ESP_LOGI(TAG, "Setting WiFi configuration SSID %s...", wifi_config.sta.ssid);
ESP_ERROR_CHECK(esp_wifi_set_mode(WIFI_MODE_STA));
ESP_ERROR_CHECK(esp_wifi_set_config(ESP_IF_WIFI_STA, &wifi_config));
ESP_ERROR_CHECK(esp_wifi_start());
}
void app_main()
{
static httpd_handle_t server = NULL;
ESP_ERROR_CHECK(nvs_flash_init());
esp_err_t err = esp_camera_init(&camera_config);
if(err != ESP_OK){
ESP_LOGE(TAG, "Camera Init Failed");
return;
}
sensor = esp_camera_sensor_get();
initialise_wifi(&server);
}
index.html
<!doctype html>
<html lang="ja">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.6.4/css/all.css">
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css" integrity="sha384-ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T" crossorigin="anonymous">
<title>OV7725</title>
<style>
.alert{
display:none;
}
#overlay{
position: fixed;
top: 0;
z-index: 100;
width: 100%;
height:100%;
display: none;
background: rgba(0,0,0,0.6);
}
.cv-spinner{
height: 100%;
display: flex;
justify-content: center;
align-items: center;
}
.spinner{
width: 40px;
height: 40px;
border: 4px #ddd solid;
border-top: 4px #2e93e6 solid;
border-radius: 50%;
animation: sp-anime 0.8s infinite linear;
}
@keyframes sp-anime{
0% {
transform: rotate(0deg);
}
100% {
transform: rotate(359deg);
}
}
.is-hide{
display:none;
}
.ov_a{
height:600px;
overflow-y:auto;
}
</style>
</head>
<body>
<div id="overlay">
<div class="cv-spinner">
<span class="spinner"></span>
</div>
</div>
<div class="text-center mt-3 mb-3">
<h1>OV7725</h1>
</div>
<div class="container-fluid">
<div class="row">
<div class="col-lg-6 text-center mb-4">
<div class="row">
<div class="col-md-12">
<div class="alert alert-success" role="alert">success</div>
<div class="alert alert-danger" role="alert">failed</div>
</div>
<div class="col-md-12">
<img id="img" class="mw-100">
</div>
<div class="col-md-12 mt-4">
<button id="image_button" type="button" class="btn btn-success w-100">Take a Picture</button>
</div>
</div>
</div>
<div class="col-lg-6">
<div class="ov_a">
<form id="form">
<table id="table_regs" class="table table-striped">
<tr>
<th>Address(Hex)</th>
<th>Value(Hex)</th>
</tr>
</table>
</form>
</div>
</div>
</div>
</div>
<script src="https://code.jquery.com/jquery-3.3.1.slim.min.js" integrity="sha384-q8i/X+965DzO0rT7abK41JStQIAqVgRVzpbzo5smXKp4YfRvH+8abtTE1Pi6jizo" crossorigin="anonymous"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.7/umd/popper.min.js" integrity="sha384-UO2eT0CpHqdSJQ6hJty5KVphtPhzWj9WO1clHTMGa3JDZwrnQq4sF86dIHNDz0W1" crossorigin="anonymous"></script>
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/js/bootstrap.min.js" integrity="sha384-JjSmVgyd0p3pXB1rRibZUAYoIIy6OrQ6VrjIEaFf/nJGzIxFDsf4x0xIM+B07jRM" crossorigin="anonymous"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script>
<script type="text/javascript">
$(function(){
var parseJson = function(data) {
var returnJson = {};
for(idx = 0; idx < data.length; idx++){
returnJson[data[idx].name] = data[idx].value
}
return returnJson;
};
$(document).ready(function(){
read_config();
get_image();
});
$("#image_button").on("click", get_image);
function get_image(){
$.ajax({
url: "./image",
type: "POST",
data: JSON.stringify(parseJson($("#form").serializeArray())),
dataType: "json",
beforeSend: function() {
$(".alert").css("display", "none");
$("#overlay").fadeIn(300);
}
})
.done((data) => {
$(".alert").css("display", "none");
$(".alert-success").css("display", "block");
$("#img").attr("src", "data:image/jpeg;base64," + data["image"]);
})
.fail((data) => {
$(".alert").css("display", "none");
$(".alert-danger").css("display", "block");
console.log(data);
})
.always((data) => {
setTimeout(function(){
$("#overlay").fadeOut(300);
},500);
});
}
function read_config(){
$.ajax({
url: "./config",
type: "GET",
dataType: "json",
async: false,
})
.done((data) => {
$.each(data, function(i, item){
$("#table_regs").append('<tr><td>0x' + Number(i).toString(16) + '</td><td><div class="input-group"><div class="input-group-prepend"><span class="input-group-text" id="text1a">0x</span></div><input name="' + i + '" value="' + Number(item).toString(16) + '" type="text" class="form-control"></div></td></tr>');
});
})
}
});
</script>
</body>
</html>
Recommended Posts