1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

OV2640を使ってjpegデータ表示と設定変更(ESP32-WROVER-B)

Posted at

概要

ESP32-WROVER-Bを使ってOV2640からjpegデータを取得してみました。ESP32-WROVER-Bでサーバーを立てて、ブラウザから各レジスタを制御できるようにしています。

aa1.jpg

コードは下記に公開しています。
https://github.com/koki-iwaizumi/esp32-ov2640-stream/tree/v1.0

OV7725を使って同様のことをしています。
https://qiita.com/koki-iwaizumi/items/146b8b08f9146327f657

公式
https://github.com/espressif/esp32-camera

設定

esp-idfのフォルダ内でsubmoduleをクローンします。

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

ESP32(サーバー)

ESP32でサーバーを立てて、ローカルアドレスでアクセスできるようにしました。ブラウザで<ローカルアドレス>/へアクセスすると画像及び各レジスタの値が表示されます。

image,config0,config1,writeはajax及びXMLHttpRequestでサーバと通信しています。

  • <ローカルアドレス>/ html
  • <ローカルアドレス>/image image/jpegのバイナリデータ
  • <ローカルアドレス>/config0 0xFF==0の場合のレジスタ情報のjson
  • <ローカルアドレス>/config1 0xFF==1の場合のレジスタ情報のjson
  • <ローカルアドレス>/write レジスタ変更
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 const uint8_t regs_0[][1] = {
	{0x05},
	{0x44},
	{0x50},
	{0x51},
	{0x52},
	{0x53},
	{0x54},
	{0x55},
	{0x56},
	{0x57},
	{0x5A},
	{0x5B},
	{0x5C},
	{0x7C},
	{0x7D},
	{0x86},
	{0x87},
	{0x8C},
	{0xC0},
	{0xC1},
	{0xC2},
	{0xC3},
	{0xD3},
	{0xDA},
	{0xE0},
	{0xED},
	{0xF0},
	{0xF7},
	{0xF8},
	{0xF9},
	{0xFA},
	{0xFB},
	{0xFC},
	{0xFD},
	{0xFE},
	{0xFF}
};

static const uint8_t regs_1[][1] = {
	{0x00},
	{0x03},
	{0x04},
	{0x08},
	{0x09},
	{0x0A},
	{0x0B},
	{0x0C},
	{0x10},
	{0x11},
	{0x12},
	{0x13},
	{0x14},
	{0x15},
	{0x17},
	{0x18},
	{0x19},
	{0x1A},
	{0x1C},
	{0x1D},
	{0x24},
	{0x25},
	{0x26},
	{0x2A},
	{0x2B},
	{0x2D},
	{0x2E},
	{0x2F},
	{0x32},
	{0x34},
	{0x45},
	{0x46},
	{0x47},
	{0x48},
	{0x49},
	{0x4B},
	{0x4E},
	{0x4F},
	{0x50},
	{0x5D},
	{0x5E},
	{0x5F},
	{0x60},
	{0x61},
	{0x62}
};

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_JPEG,
	.frame_size = FRAMESIZE_SVGA, //FRAMESIZE_UXGA

	.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_get_handler(httpd_req_t *req)
{
	camera_fb_t *fb = esp_camera_fb_get();
	if( ! fb){
		ESP_LOGE(TAG, "Camera capture failed");
		httpd_resp_send_500(req);
		return ESP_FAIL;
	}

	esp_err_t res = httpd_resp_set_type(req, "image/jpeg") || httpd_resp_set_hdr(req, "Access-Control-Allow-Origin", "*") || httpd_resp_send(req, (const char *)fb->buf, fb->len);
	esp_camera_fb_return(fb);

	return res;
}

esp_err_t config0_get_handler(httpd_req_t *req)
{
	esp_err_t res = SCCB_Write(sensor->slv_addr, 0xFF, 0);
	if(res != ESP_OK){
		ESP_LOGE(TAG, "Failed SCCB_Write - 0xFF 0");
		httpd_resp_send_500(req);
		return ESP_FAIL;
	}

	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;
	}

	
	int regs_0_num = sizeof regs_0 / sizeof regs_0[0];
	strcat(data_json, "{");
	for(int i = 0; i < regs_0_num; i++){
		char data_json_buf[255] = {'\0'};
		sprintf(data_json_buf, "\"%d\":\"%d\"", regs_0[i][0], SCCB_Read(sensor->slv_addr, regs_0[i][0]));
		strcat(data_json, data_json_buf);
		if(i != regs_0_num - 1) 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));

	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;
}

esp_err_t config1_get_handler(httpd_req_t *req)
{
	esp_err_t res = SCCB_Write(sensor->slv_addr, 0xFF, 1);
	if(res != ESP_OK){
		ESP_LOGE(TAG, "Failed SCCB_Write - 0xFF 1");
		httpd_resp_send_500(req);
		return ESP_FAIL;
	}

	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;
	}

	
	int regs_1_num = sizeof regs_1 / sizeof regs_1[0];
	strcat(data_json, "{");
	for(int i = 0; i < regs_1_num; i++){
		char data_json_buf[255] = {'\0'};
		sprintf(data_json_buf, "\"%d\":\"%d\"", regs_1[i][0], SCCB_Read(sensor->slv_addr, regs_1[i][0]));
		strcat(data_json, data_json_buf);
		if(i != regs_1_num - 1) 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));

	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;
}

esp_err_t write_get_handler(httpd_req_t *req)
{
	size_t buf_len = httpd_req_get_url_query_len(req) + 1;
	if(buf_len <= 1){
		ESP_LOGE(TAG, "Failed buf_len");
		httpd_resp_send_500(req);
		return ESP_FAIL;	
	}

	char* buf = malloc(buf_len);
	if(httpd_req_get_url_query_str(req, buf, buf_len) != ESP_OK){
		free(buf);
		ESP_LOGE(TAG, "Failed httpd_req_get_url_query_str");
		httpd_resp_send_500(req);
		return ESP_FAIL;
	}

	char bank[4], key[4], value[4];
	ESP_LOGI(TAG, "Found URL query => %s", buf);
	if(httpd_query_key_value(buf, "bank", bank, sizeof(bank)) != ESP_OK || httpd_query_key_value(buf, "key", key, sizeof(key)) != ESP_OK || httpd_query_key_value(buf, "value", value, sizeof(value)) != ESP_OK){
		free(buf);
		ESP_LOGE(TAG, "Failed httpd_query_key_value");
		httpd_resp_send_500(req);
		return ESP_FAIL;
	}
	free(buf);

	int key_i = atoi(key);
	int value_i = atoi(value);
	int bank_i = atoi(bank);

	ESP_LOGI(TAG, "Found URL query parameter => key=%s, value=%s, bank=%s", key, value, bank);
	ESP_LOGI(TAG, "Found URL query parameter => key=%d, value=%d, bank=%d", key_i, value_i, bank_i);

	if(SCCB_Write(sensor->slv_addr, 0xFF, bank_i) != ESP_OK || SCCB_Write(sensor->slv_addr, key_i, value_i) != ESP_OK){
		ESP_LOGE(TAG, "Failed SCCB_Write");
		httpd_resp_send_500(req);
		return ESP_FAIL;
	}

	const char *resp = "{\"status\":\"success\"}";
	esp_err_t res = httpd_resp_set_type(req, "application/json") || httpd_resp_set_hdr(req, "Access-Control-Allow-Origin", "*") || httpd_resp_send(req, resp, strlen(resp));
	return res;
}

httpd_uri_t index_uri = {
	.uri = "/",
	.method = HTTP_GET,
	.handler = index_get_handler,
};

httpd_uri_t image_uri = {
	.uri = "/image",
	.method = HTTP_GET,
	.handler = image_get_handler,
};

httpd_uri_t config0_uri = {
	.uri = "/config0",
	.method = HTTP_GET,
	.handler = config0_get_handler,
};

httpd_uri_t config1_uri = {
	.uri = "/config1",
	.method = HTTP_GET,
	.handler = config1_get_handler,
};

httpd_uri_t write_uri = {
	.uri = "/write",
	.method = HTTP_GET,
	.handler = write_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, &config0_uri);
		httpd_register_uri_handler(server, &config1_uri);
		httpd_register_uri_handler(server, &write_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();

	vTaskDelay(1000 / portTICK_RATE_MS);
	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>OV2640</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>OV2640</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"></div>
							<div class="alert alert-danger" role="alert"></div>
						</div>
						<div class="col-md-12">
							<img id="img" class="mw-100">
						</div>
					</div>
				</div>

				<div class="col-lg-6">
					<div class="ov_a">
						<div class="text-center mt-1 mb-1">
							<span>0xFF=00</span>
						</div>
						<table id="table_regs0" class="table table-striped">
							<tr>
								<th>Address(Hex)</th>
								<th>Name</th>
								<th>Value(Hex)</th>
								<th></th>
							</tr>
						</table>
						<div class="text-center mt-1 mb-1">
							<span>0xFF=01</span>
						</div>
						<table id="table_regs1" class="table table-striped">
							<tr>
								<th>Address(Hex)</th>
								<th>Name</th>
								<th>Value(Hex)</th>
								<th></th>
							</tr>
						</table>
					</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 regs0 = {
					0x05: "R_BYPASS",
					0x44: "Qs",
					0x50: "CTRLI",
					0x51: "HSIZE",
					0x52: "VSIZE",
					0x53: "XOFFL",
					0x54: "YOFFL",
					0x55: "VHYX",
					0x56: "DPRP",
					0x57: "TEST",
					0x5A: "ZMOW",
					0x5B: "ZMOH",
					0x5C: "ZMHH",
					0x7C: "BRADDR",
					0x7D: "BPDATA",
					0x86: "CTRL2",
					0x87: "CTRL3",
					0x8C: "SIZEL",
					0xC0: "HSIZE8",
					0xC1: "VSIZE8",
					0xC2: "CTRL0",
					0xC3: "CTRL1",
					0xD3: "R_DVP_SP",
					0xDA: "IMAGE_MODE",
					0xE0: "RESET",
					0xED: "REGED",
					0xF0: "MS_SP",
					0xF7: "SS_ID",
					0xF8: "SS_CTRL",
					0xF9: "MC_BIST",
					0xFA: "MC_AL",
					0xFB: "MC_AH",
					0xFC: "MC_D",
					0xFD: "P_CMD",
					0xFE: "P_STATUS",
					0xFF: "RA_DLMT",
				};

				var regs1 = {
					0x0: "GAIN",
					0x3: "COM1",
					0x4: "REG04",
					0x8: "REG08",
					0x9: "COM2",
					0xA: "PIDH",
					0xB: "PIDL",
					0xC: "COM3",
					0xC: "COM3",
					0x10: "AEC",
					0x11: "CLKRC",
					0x12: "COM7",
					0x13: "COM8",
					0x14: "COM9",
					0x15: "COM10",
					0x17: "HREFST",
					0x18: "HREFEND",
					0x19: "VSTART",
					0x1A: "VEND",
					0x1C: "MIDH",
					0x1D: "MIDL",
					0x24: "AEW",
					0x25: "AEB",
					0x26: "VV",
					0x2A: "REG2A",
					0x2B: "FRARL",
					0x2D: "ADDVSL",
					0x2E: "ADDVSH",
					0x2E: "ADDVSH",
					0x2F: "YAVG",
					0x32: "REG32",
					0x34: "ARCOM2",
					0x45: "REG45",
					0x46: "FLL",
					0x47: "FLH",
					0x48: "COM19",
					0x49: "ZOOMS",
					0x4B: "COM22",
					0x4E: "COM25",
					0x4F: "BD50",
					0x50: "BD60",
					0x5D: "REG5D",
					0x5E: "REG5E",
					0x5F: "REG5F",
					0x60: "REG60",
					0x61: "HISTO_LOW",
					0x62: "HISTO_HIGH",
				};

				function get_image(){
					var xhr = new XMLHttpRequest();
					xhr.onreadystatechange = function(){
						if(this.readyState == 4 && this.status == 200){
							var img = document.getElementById("img");
							img.src = window.URL.createObjectURL(this.response);
							get_image();
						}
					}
					xhr.open('GET', "./image");
					xhr.responseType = 'blob';
					xhr.send();
				};

				function write_config(bank, k, v){
					$.ajax({
						url: "./write",
						type: "GET",
						dataType: "json",
						data: {
							bank: bank,
							key: k,
							value: v
						},
						beforeSend: function() {
							$(".alert").css("display", "none");
						}
					})
					.done((data) => {
						$.each(data, function(i, item){
							if(item == "success"){
								$(".alert-success").css("display", "block");
								$(".alert-success").text('bank:' + bank + ' key:0x' + Number(k).toString(16) + ' value:0x' + Number(v).toString(16) + ' success');
							}else{
								$(".alert-danger").css("display", "block");
								$(".alert-danger").text('bank:' + bank + ' key:0x' + Number(k).toString(16) + ' value:0x' + Number(v).toString(16) + ' failed');
							}
						});
					})
                    .fail((data) => {
						$(".alert-danger").css("display", "block");
						$(".alert-danger").text('bank:' + bank + ' key:0x' + Number(k).toString(16) + ' value:0x' + Number(v).toString(16) + ' failed');
                    });
				};

				$(document).ready(function(){
					$.ajax({
						url: "./config0",
						type: "GET",
						dataType: "json",
						async: false,
					})
					.done((data) => {
						$.each(data, function(i, item){
							$("#table_regs0").append('<tr><td>0x' + Number(i).toString(16) + '</td><td>' + regs0[i] + '</td><td id="value_0_' + i + '">0x' + Number(item).toString(16) + '(0b' + Number(item).toString(2) + ')</td><td><input type="range" class="w-100 slider0" name="' + i + '" value="' + item + '" min="0" max="255" step="1"></td></tr>');
						});
					});

					$.ajax({
						url: "./config1",
						type: "GET",
						dataType: "json",
						async: false,
					})
					.done((data) => {
						$.each(data, function(i, item){
							$("#table_regs1").append('<tr><td>0x' + Number(i).toString(16) + '</td><td>' + regs1[i] + '</td><td id="value_1_' + i + '">0x' + Number(item).toString(16) + '(0b' + Number(item).toString(2) + ')</td><td><input type="range" class="w-100 slider1" name="' + i + '" value="' + item + '" min="0" max="255" step="1"></td></tr>');
						});
					});

					get_image();

					$(".slider0").on("input change", function(){
						$("#value_0_" + $(this).attr("name")).text("0x" + Number($(this).val()).toString(16) + "(0b" + Number($(this).val()).toString(2) + ")");
					});

					$(".slider1").on("input change", function(){
						$("#value_1_" + $(this).attr("name")).text("0x" + Number($(this).val()).toString(16) + "(0b" + Number($(this).val()).toString(2) + ")");
					});

					$(".slider0").on("change", function(){
						write_config(0, $(this).attr("name"), $(this).val())
					});

					$(".slider1").on("change", function(){
						write_config(1, $(this).attr("name"), $(this).val())
					});
				});
			});
		</script>
	</body>
</html>

これから

・50Hzのバンドフィルターが上手く動作していないため、原因を探る
・色彩が少し淡いので、もう少しはっきりさせたい
・Qsの限界値を探る
・暗闇時の赤外線を当てた場合

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?