Skip to content

Instantly share code, notes, and snippets.

@yoggy
Created January 17, 2019 13:19
Show Gist options
  • Select an option

  • Save yoggy/0bd1f5d22e79ec84f8bf890cbb880bf4 to your computer and use it in GitHub Desktop.

Select an option

Save yoggy/0bd1f5d22e79ec84f8bf890cbb880bf4 to your computer and use it in GitHub Desktop.
$ 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");
 }
#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