$ diff -u main/main.c.org main/main.c
--- main/main.c.org 2019-01-17 21:45:21.789814800 +0900
+++ main/main.c 2019-01-17 22:06:08.603979600 +0900
@@ -15,6 +15,8 @@
#include "esp_event_loop.h"
#include "esp_http_server.h"
+#include <lwip/sockets.h>
+
static const char* TAG = "camera";
//M5STACK_CAM PIN Map
@@ -40,10 +42,14 @@
#define CAM_USE_WIFI
-#define ESP_WIFI_SSID "m5stack-cam"
-#define ESP_WIFI_PASS ""
+#define ESP_WIFI_SSID "ssid"
+#define ESP_WIFI_PASS "passowrd"
#define MAX_STA_CONN 1
+#define DEVICE_IP "192.168.1.123"
+#define DEVICE_GW "192.168.1.1"
+#define DEVICE_NETMASK "255.255.255.0"
+
#define PART_BOUNDARY "123456789000000000000987654321"
static const char* _STREAM_CONTENT_TYPE = "multipart/x-mixed-replace;boundary=" PART_BOUNDARY;
static const char* _STREAM_BOUNDARY = "\r\n--" PART_BOUNDARY "\r\n";
@@ -233,19 +239,8 @@
esp_wifi_connect();
break;
case SYSTEM_EVENT_STA_GOT_IP:
- ESP_LOGI(TAG, "got ip:%s", ip4addr_ntoa(&event->event_info.got_ip.ip_info.ip));
- s_ip_addr = event->event_info.got_ip.ip_info.ip;
- xEventGroupSetBits(s_wifi_event_group, CONNECTED_BIT);
- break;
- case SYSTEM_EVENT_AP_STACONNECTED:
- ESP_LOGI(TAG, "station:" MACSTR " join, AID=%d", MAC2STR(event->event_info.sta_connected.mac) ,
- event->event_info.sta_connected.aid);
xEventGroupSetBits(s_wifi_event_group, CONNECTED_BIT);
- break;
- case SYSTEM_EVENT_AP_STADISCONNECTED:
- ESP_LOGI(TAG, "station:" MACSTR "leave, AID=%d", MAC2STR(event->event_info.sta_disconnected.m ac),
- event->event_info.sta_disconnected.aid);
- xEventGroupClearBits(s_wifi_event_group, CONNECTED_BIT);
+ s_ip_addr = event->event_info.got_ip.ip_info.ip;
break;
case SYSTEM_EVENT_STA_DISCONNECTED:
esp_wifi_connect();
@@ -262,30 +257,36 @@
s_wifi_event_group = xEventGroupCreate();
tcpip_adapter_init();
+ tcpip_adapter_dhcpc_stop(TCPIP_ADAPTER_IF_STA);
+ tcpip_adapter_ip_info_t ipInfo;
+
+ inet_pton(AF_INET, DEVICE_IP, &ipInfo.ip);
+ inet_pton(AF_INET, DEVICE_GW, &ipInfo.gw);
+ inet_pton(AF_INET, DEVICE_NETMASK, &ipInfo.netmask);
+ tcpip_adapter_set_ip_info(TCPIP_ADAPTER_IF_STA, &ipInfo);
+
+ s_wifi_event_group = xEventGroupCreate();
+
ESP_ERROR_CHECK(esp_event_loop_init(event_handler, NULL));
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 = {
- .ap = {.ssid = ESP_WIFI_SSID,
- .ssid_len = strlen(ESP_WIFI_SSID),
+ .sta = {.ssid = ESP_WIFI_SSID,
.password = ESP_WIFI_PASS,
- .max_connection = MAX_STA_CONN,
- .authmode = WIFI_AUTH_WPA_WPA2_PSK},
+ },
};
- if (strlen(ESP_WIFI_PASS) == 0) {
- wifi_config.ap.authmode = WIFI_AUTH_OPEN;
- }
- ESP_ERROR_CHECK(esp_wifi_set_mode(WIFI_MODE_AP));
- ESP_ERROR_CHECK(esp_wifi_set_config(ESP_IF_WIFI_AP, &wifi_config));
+ ESP_ERROR_CHECK(esp_wifi_set_mode(WIFI_MODE_STA));
+ ESP_ERROR_CHECK(esp_wifi_set_config(WIFI_IF_STA, &wifi_config));
ESP_ERROR_CHECK(esp_wifi_start());
+ ESP_ERROR_CHECK(esp_wifi_set_ps(WIFI_PS_NONE));
- uint8_t addr[4] = {192, 168, 4, 1};
- s_ip_addr = *(ip4_addr_t*)&addr;
-
- ESP_LOGI(TAG, "wifi_init_softap finished.SSID:%s password:%s",
- ESP_WIFI_SSID, ESP_WIFI_PASS);
+ ESP_LOGI(TAG, "Connecting to \"%s\"", wifi_config.sta.ssid);
+ xEventGroupWaitBits(s_wifi_event_group, CONNECTED_BIT, false, true, portMAX_DELAY);
+ ESP_LOGI(TAG, "Connected");
}
Created
January 17, 2019 13:19
-
-
Save yoggy/0bd1f5d22e79ec84f8bf890cbb880bf4 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #include <stdio.h> | |
| #include "freertos/FreeRTOS.h" | |
| #include "freertos/event_groups.h" | |
| #include "freertos/semphr.h" | |
| #include "freertos/task.h" | |
| #include "driver/gpio.h" | |
| #include "sdkconfig.h" | |
| #include "esp_log.h" | |
| #include "esp_wifi.h" | |
| #include "nvs_flash.h" | |
| #include "esp_timer.h" | |
| #include "esp_camera.h" | |
| #include "esp_event_loop.h" | |
| #include "esp_http_server.h" | |
| #include <lwip/sockets.h> | |
| static const char* TAG = "camera"; | |
| //M5STACK_CAM PIN Map | |
| #define CAM_PIN_RESET 15 //software reset will be performed | |
| #define CAM_PIN_XCLK 27 | |
| #define CAM_PIN_SIOD 22 | |
| #define CAM_PIN_SIOC 23 | |
| #define CAM_PIN_D7 19 | |
| #define CAM_PIN_D6 36 | |
| #define CAM_PIN_D5 18 | |
| #define CAM_PIN_D4 39 | |
| #define CAM_PIN_D3 5 | |
| #define CAM_PIN_D2 34 | |
| #define CAM_PIN_D1 35 | |
| #define CAM_PIN_D0 32 | |
| #define CAM_PIN_VSYNC 25 | |
| #define CAM_PIN_HREF 26 | |
| #define CAM_PIN_PCLK 21 | |
| #define CAM_XCLK_FREQ 20000000 | |
| #define CAM_USE_WIFI | |
| #define ESP_WIFI_SSID "ssid" | |
| #define ESP_WIFI_PASS "password" | |
| #define MAX_STA_CONN 1 | |
| #define DEVICE_IP "192.168.1.123" | |
| #define DEVICE_GW "192.168.1.1" | |
| #define DEVICE_NETMASK "255.255.255.0" | |
| #define PART_BOUNDARY "123456789000000000000987654321" | |
| 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"; | |
| static EventGroupHandle_t s_wifi_event_group; | |
| static ip4_addr_t s_ip_addr; | |
| const int CONNECTED_BIT = BIT0; | |
| static camera_config_t camera_config = { | |
| .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_D7, | |
| .pin_d6 = CAM_PIN_D6, | |
| .pin_d5 = CAM_PIN_D5, | |
| .pin_d4 = CAM_PIN_D4, | |
| .pin_d3 = CAM_PIN_D3, | |
| .pin_d2 = CAM_PIN_D2, | |
| .pin_d1 = CAM_PIN_D1, | |
| .pin_d0 = CAM_PIN_D0, | |
| .pin_vsync = CAM_PIN_VSYNC, | |
| .pin_href = CAM_PIN_HREF, | |
| .pin_pclk = CAM_PIN_PCLK, | |
| //XCLK 20MHz or 10MHz | |
| .xclk_freq_hz = CAM_XCLK_FREQ, | |
| .ledc_timer = LEDC_TIMER_0, | |
| .ledc_channel = LEDC_CHANNEL_0, | |
| .pixel_format = PIXFORMAT_JPEG,//YUV422,GRAYSCALE,RGB565,JPEG | |
| .frame_size = FRAMESIZE_QVGA,//QQVGA-UXGA Do not use sizes above QVGA when not JPEG | |
| .jpeg_quality = 2, //0-63 lower number means higher quality | |
| .fb_count = 3 //if more than one, i2s runs in continuous mode. Use only with JPEG | |
| }; | |
| static void wifi_init_softap(); | |
| static esp_err_t http_server_init(); | |
| void app_main() | |
| { | |
| esp_log_level_set("wifi", ESP_LOG_INFO); | |
| esp_err_t err = nvs_flash_init(); | |
| if (err != ESP_OK) { | |
| ESP_ERROR_CHECK( nvs_flash_erase() ); | |
| ESP_ERROR_CHECK( nvs_flash_init() ); | |
| } | |
| err = esp_camera_init(&camera_config); | |
| if (err != ESP_OK) { | |
| ESP_LOGE(TAG, "Camera Init Failed"); | |
| } | |
| wifi_init_softap(); | |
| vTaskDelay(100 / portTICK_PERIOD_MS); | |
| http_server_init(); | |
| } | |
| #ifdef CAM_USE_WIFI | |
| esp_err_t jpg_httpd_handler(httpd_req_t *req){ | |
| camera_fb_t * fb = NULL; | |
| esp_err_t res = ESP_OK; | |
| size_t fb_len = 0; | |
| 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; | |
| } | |
| res = httpd_resp_set_type(req, "image/jpeg"); | |
| if(res == ESP_OK){ | |
| res = httpd_resp_set_hdr(req, "Content-Disposition", "inline; filename=capture.jpg"); | |
| } | |
| if(res == ESP_OK){ | |
| fb_len = fb->len; | |
| res = httpd_resp_send(req, (const char *)fb->buf, fb->len); | |
| } | |
| esp_camera_fb_return(fb); | |
| int64_t fr_end = esp_timer_get_time(); | |
| ESP_LOGI(TAG, "JPG: %uKB %ums", (uint32_t)(fb_len/1024), (uint32_t)((fr_end - fr_start)/1000)); | |
| return res; | |
| } | |
| esp_err_t jpg_stream_httpd_handler(httpd_req_t *req){ | |
| camera_fb_t * fb = NULL; | |
| esp_err_t res = ESP_OK; | |
| size_t _jpg_buf_len; | |
| uint8_t * _jpg_buf; | |
| char * part_buf[64]; | |
| static int64_t last_frame = 0; | |
| if(!last_frame) { | |
| last_frame = esp_timer_get_time(); | |
| } | |
| res = httpd_resp_set_type(req, _STREAM_CONTENT_TYPE); | |
| if(res != ESP_OK){ | |
| return res; | |
| } | |
| while(true){ | |
| fb = esp_camera_fb_get(); | |
| if (!fb) { | |
| ESP_LOGE(TAG, "Camera capture failed"); | |
| res = ESP_FAIL; | |
| } else { | |
| if(fb->format != PIXFORMAT_JPEG){ | |
| bool jpeg_converted = frame2jpg(fb, 80, &_jpg_buf, &_jpg_buf_len); | |
| if(!jpeg_converted){ | |
| ESP_LOGE(TAG, "JPEG compression failed"); | |
| esp_camera_fb_return(fb); | |
| 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->format != PIXFORMAT_JPEG){ | |
| free(_jpg_buf); | |
| } | |
| esp_camera_fb_return(fb); | |
| if(res != ESP_OK){ | |
| break; | |
| } | |
| int64_t fr_end = esp_timer_get_time(); | |
| int64_t frame_time = fr_end - last_frame; | |
| last_frame = fr_end; | |
| frame_time /= 1000; | |
| ESP_LOGI(TAG, "MJPG: %uKB %ums (%.1ffps)", | |
| (uint32_t)(_jpg_buf_len/1024), | |
| (uint32_t)frame_time, 1000.0 / (uint32_t)frame_time); | |
| } | |
| last_frame = 0; | |
| return res; | |
| } | |
| static esp_err_t http_server_init(){ | |
| httpd_handle_t server; | |
| httpd_uri_t jpeg_uri = { | |
| .uri = "/jpg", | |
| .method = HTTP_GET, | |
| .handler = jpg_httpd_handler, | |
| .user_ctx = NULL | |
| }; | |
| httpd_uri_t jpeg_stream_uri = { | |
| .uri = "/", | |
| .method = HTTP_GET, | |
| .handler = jpg_stream_httpd_handler, | |
| .user_ctx = NULL | |
| }; | |
| httpd_config_t http_options = HTTPD_DEFAULT_CONFIG(); | |
| ESP_ERROR_CHECK(httpd_start(&server, &http_options)); | |
| ESP_ERROR_CHECK(httpd_register_uri_handler(server, &jpeg_uri)); | |
| ESP_ERROR_CHECK(httpd_register_uri_handler(server, &jpeg_stream_uri)); | |
| return ESP_OK; | |
| } | |
| static esp_err_t event_handler(void* ctx, system_event_t* event) | |
| { | |
| switch (event->event_id) { | |
| case SYSTEM_EVENT_STA_START: | |
| esp_wifi_connect(); | |
| break; | |
| case SYSTEM_EVENT_STA_GOT_IP: | |
| xEventGroupSetBits(s_wifi_event_group, CONNECTED_BIT); | |
| s_ip_addr = event->event_info.got_ip.ip_info.ip; | |
| break; | |
| case SYSTEM_EVENT_STA_DISCONNECTED: | |
| esp_wifi_connect(); | |
| xEventGroupClearBits(s_wifi_event_group, CONNECTED_BIT); | |
| break; | |
| default: | |
| break; | |
| } | |
| return ESP_OK; | |
| } | |
| static void wifi_init_softap() | |
| { | |
| s_wifi_event_group = xEventGroupCreate(); | |
| tcpip_adapter_init(); | |
| tcpip_adapter_dhcpc_stop(TCPIP_ADAPTER_IF_STA); | |
| tcpip_adapter_ip_info_t ipInfo; | |
| inet_pton(AF_INET, DEVICE_IP, &ipInfo.ip); | |
| inet_pton(AF_INET, DEVICE_GW, &ipInfo.gw); | |
| inet_pton(AF_INET, DEVICE_NETMASK, &ipInfo.netmask); | |
| tcpip_adapter_set_ip_info(TCPIP_ADAPTER_IF_STA, &ipInfo); | |
| s_wifi_event_group = xEventGroupCreate(); | |
| ESP_ERROR_CHECK(esp_event_loop_init(event_handler, NULL)); | |
| 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 = ESP_WIFI_SSID, | |
| .password = ESP_WIFI_PASS, | |
| }, | |
| }; | |
| ESP_ERROR_CHECK(esp_wifi_set_mode(WIFI_MODE_STA)); | |
| ESP_ERROR_CHECK(esp_wifi_set_config(WIFI_IF_STA, &wifi_config)); | |
| ESP_ERROR_CHECK(esp_wifi_start()); | |
| ESP_ERROR_CHECK(esp_wifi_set_ps(WIFI_PS_NONE)); | |
| ESP_LOGI(TAG, "Connecting to \"%s\"", wifi_config.sta.ssid); | |
| xEventGroupWaitBits(s_wifi_event_group, CONNECTED_BIT, false, true, portMAX_DELAY); | |
| ESP_LOGI(TAG, "Connected"); | |
| } | |
| #endif |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment