Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Solution for "Add sensor or other dynamic data to HTML or stream #114" #241

Open
wants to merge 5 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
62 changes: 53 additions & 9 deletions app_httpd.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,10 @@
#include "src/logo.h"
#include "storage.h"

// #define HAS_BME280 here and in esp32-cam-webserver.ino to include the function
// #define HAS_BME280


// Functions from the main .ino
extern void flashLED(int flashtime);
extern void setLamp(int newVal);
Expand Down Expand Up @@ -91,6 +95,14 @@ uint8_t temprature_sens_read();
}
#endif

#if defined (HAS_BME280)
// external function to get the values from sensor
extern float getBME280_hum();
extern float getBME280_temp();
extern float getBME280_pres();

#endif

void serialDump() {
Serial.println();
// Module
Expand Down Expand Up @@ -253,7 +265,7 @@ static esp_err_t stream_handler(httpd_req_t *req){
httpd_resp_set_hdr(req, "Access-Control-Allow-Origin", "*");

if(res == ESP_OK){
res = httpd_resp_send_chunk(req, _STREAM_BOUNDARY, strlen(_STREAM_BOUNDARY));
res = httpd_resp_send_chunk(req, _STREAM_BOUNDARY, HTTPD_RESP_USE_STRLEN);
}

while(true){
Expand All @@ -278,7 +290,7 @@ static esp_err_t stream_handler(httpd_req_t *req){
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));
res = httpd_resp_send_chunk(req, _STREAM_BOUNDARY, HTTPD_RESP_USE_STRLEN);
}
if(fb){
esp_camera_fb_return(fb);
Expand Down Expand Up @@ -643,15 +655,15 @@ static esp_err_t stop_handler(httpd_req_t *req){
static esp_err_t style_handler(httpd_req_t *req){
httpd_resp_set_type(req, "text/css");
httpd_resp_set_hdr(req, "Content-Encoding", "identity");
return httpd_resp_send(req, (const char *)style_css, style_css_len);
return httpd_resp_send(req, (const char *)style_css, HTTPD_RESP_USE_STRLEN);
}

static esp_err_t streamviewer_handler(httpd_req_t *req){
flashLED(75);
Serial.println("Stream viewer requested");
httpd_resp_set_type(req, "text/html");
httpd_resp_set_hdr(req, "Content-Encoding", "identity");
return httpd_resp_send(req, (const char *)streamviewer_html, streamviewer_html_len);
return httpd_resp_send(req, (const char *)streamviewer_html, HTTPD_RESP_USE_STRLEN);
}

static esp_err_t error_handler(httpd_req_t *req){
Expand All @@ -667,7 +679,7 @@ static esp_err_t error_handler(httpd_req_t *req){
s.replace(index, strlen("<ERRORTEXT>"), critERR.c_str());
httpd_resp_set_type(req, "text/html");
httpd_resp_set_hdr(req, "Content-Encoding", "identity");
return httpd_resp_send(req, (const char *)s.c_str(), s.length());
return httpd_resp_send(req, (const char *)s.c_str(), HTTPD_RESP_USE_STRLEN);
}

static esp_err_t index_handler(httpd_req_t *req){
Expand Down Expand Up @@ -711,16 +723,20 @@ static esp_err_t index_handler(httpd_req_t *req){
if (critERR.length() > 0) return error_handler(req);
httpd_resp_set_type(req, "text/html");
httpd_resp_set_hdr(req, "Content-Encoding", "identity");
return httpd_resp_send(req, (const char *)index_simple_html, index_simple_html_len);
#if defined(HAS_BME280)
return httpd_resp_send(req, (const char *)index_simple_sensor_html, HTTPD_RESP_USE_STRLEN);
#else
return httpd_resp_send(req, (const char *)index_simple_html, HTTPD_RESP_USE_STRLEN);
#endif
} else if(strncmp(view,"full", sizeof(view)) == 0) {
Serial.println("Full index page requested");
if (critERR.length() > 0) return error_handler(req);
httpd_resp_set_type(req, "text/html");
httpd_resp_set_hdr(req, "Content-Encoding", "identity");
if (sensorPID == OV3660_PID) {
return httpd_resp_send(req, (const char *)index_ov3660_html, index_ov3660_html_len);
return httpd_resp_send(req, (const char *)index_ov3660_html, HTTPD_RESP_USE_STRLEN);
}
return httpd_resp_send(req, (const char *)index_ov2640_html, index_ov2640_html_len);
return httpd_resp_send(req, (const char *)index_ov2640_html, HTTPD_RESP_USE_STRLEN);
} else if(strncmp(view,"portal", sizeof(view)) == 0) {
//Prototype captive portal landing page.
Serial.println("Portal page requested");
Expand All @@ -734,7 +750,7 @@ static esp_err_t index_handler(httpd_req_t *req){
s.replace(index, strlen("<CAMNAME>"), myName);
httpd_resp_set_type(req, "text/html");
httpd_resp_set_hdr(req, "Content-Encoding", "identity");
return httpd_resp_send(req, (const char *)s.c_str(), s.length());
return httpd_resp_send(req, (const char *)s.c_str(), HTTPD_RESP_USE_STRLEN);
} else {
Serial.print("Unknown page requested: ");
Serial.println(view);
Expand All @@ -743,6 +759,23 @@ static esp_err_t index_handler(httpd_req_t *req){
}
}

#if defined(HAS_BME280)
static esp_err_t readSensor_handler(httpd_req_t *req){
flashLED(75);
httpd_resp_set_type(req, "text/plane");
float hum_result = getBME280_hum();
float temp_result = getBME280_temp();
float pres_result = getBME280_pres();

String valuesStrg = String(hum_result) + '#'+ String(temp_result) + '#' + String(pres_result) + '#';
int strgLength = valuesStrg.length();
char values_as_char[strgLength];
valuesStrg.toCharArray(values_as_char, strgLength);

return httpd_resp_send(req, (const char *)values_as_char, HTTPD_RESP_USE_STRLEN);
}
#endif

void startCameraServer(int hPort, int sPort){
httpd_config_t config = HTTPD_DEFAULT_CONFIG();
config.max_uri_handlers = 16; // we use more than the default 8 (on port 80)
Expand Down Expand Up @@ -843,6 +876,14 @@ void startCameraServer(int hPort, int sPort){
.handler = error_handler,
.user_ctx = NULL
};
#if defined(HAS_BME280)
httpd_uri_t readSensor_uri = {
.uri = "/readSensor",
.method = HTTP_GET,
.handler = readSensor_handler,
.user_ctx = NULL
};
#endif

// Request Handlers; config.max_uri_handlers (above) must be >= the number of handlers
config.server_port = hPort;
Expand All @@ -864,6 +905,9 @@ void startCameraServer(int hPort, int sPort){
httpd_register_uri_handler(camera_httpd, &logo_svg_uri);
httpd_register_uri_handler(camera_httpd, &dump_uri);
httpd_register_uri_handler(camera_httpd, &stop_uri);
#if defined(HAS_BME280)
httpd_register_uri_handler(camera_httpd, &readSensor_uri);
#endif
}

config.server_port = sPort;
Expand Down
6 changes: 5 additions & 1 deletion css.h
Original file line number Diff line number Diff line change
Expand Up @@ -362,6 +362,10 @@ select {
@keyframes spin {
0% { transform: rotate(0deg); }
100% { transform: rotate(360deg); }
}
.card {
width: 500px;
background: grey #424949;
box-sizing: border-box;
})=====";

size_t style_css_len = sizeof(style_css)-1;
90 changes: 88 additions & 2 deletions esp32-cam-webserver.ino
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,23 @@
stationList[] = {{"ESP32-CAM-CONNECT","InsecurePassword", true}};
#endif


/*
* use of BME280 Sensor on ESPCAM32, need https://github.com/finitespace/BME280 LIB to run, please install with Arduion LIB Manager
*
* Connection diagram, can be change in main source code
* ESP32CAM -- BME280 Sensor
* GPIO 14 -> SDA
* GPIO 15 -> SCL
* GND -> GND
* 5V -> VIN (3.3V was not working ???
*
* #define HAS_BME280 here and in app_httpd.cpp to include the function
*/

// #define HAS_BME280


// Upstream version string
#include "src/version.h"

Expand Down Expand Up @@ -228,6 +245,30 @@ const int pwmMax = pow(2,pwmresolution)-1;
// will be returned for all http requests
String critERR = "";


#if defined(HAS_BME280)
// (set these in myconfig.h)

#include <BME280I2C.h>
#include <Wire.h>

#define I2C_SDA 14
#define I2C_SCL 15
#define I2C_Freq 400000

BME280I2C::Settings settings(
BME280::OSR_X1,
BME280::OSR_X1,
BME280::OSR_X1,
BME280::Mode_Forced,
BME280::StandbyTime_1000ms,
BME280::Filter_Off,
BME280::SpiEnable_False,
BME280I2C::I2CAddr_0x76 // I2C address. I2C specific.
);
BME280I2C bme(settings);
#endif

// Debug flag for stream and capture data
bool debugData;

Expand All @@ -241,6 +282,7 @@ void debugOff() {
Serial.println("Camera debug data is disabled (send 'd' for status dump, or any other char to enable debug)");
}


// Serial input (debugging controls)
void handleSerial() {
if (Serial.available()) {
Expand Down Expand Up @@ -335,7 +377,7 @@ void StartCamera() {
config.pin_reset = RESET_GPIO_NUM;
config.xclk_freq_hz = xclk * 1000000;
config.pixel_format = PIXFORMAT_JPEG;
config.grab_mode = CAMERA_GRAB_LATEST;
// config.grab_mode = CAMERA_GRAB_LATEST; // not sure, I got an error, maby I have an old driver hansju
// Pre-allocate large buffers
if(psramFound()){
config.frame_size = FRAMESIZE_UXGA;
Expand Down Expand Up @@ -635,19 +677,63 @@ void WifiSetup() {
}
}


#if defined(HAS_BME280)

float getBME280_hum() {
return bme.hum();
}

float getBME280_temp() {
BME280::TempUnit tempUnit(BME280::TempUnit_Celsius); // you can change Unit to TempUnit_Fahrenheit
return bme.temp(tempUnit);
}

float getBME280_pres(){
BME280::PresUnit presUnit(BME280::PresUnit_hPa); // you can change Unit here https://github.com/finitespace/BME280#tempunit-enum
return bme.pres(presUnit);
}

#endif

void setup() {
Serial.begin(115200);
Serial.setDebugOutput(true);
Serial.println();
Serial.println("====");
Serial.print("esp32-cam-webserver: ");
Serial.print("Nistkasten-ESP32Cam Server: ");
Serial.println(myName);
Serial.print("Code Built: ");
Serial.println(myVer);
Serial.print("Base Release: ");
Serial.println(baseVersion);
Serial.println();


#if defined(HAS_BME280)
Wire.begin(I2C_SDA , I2C_SCL);
while(!bme.begin())
{
Serial.println("Could not find BME280I2C sensor!");
delay(1000);
}

switch(bme.chipModel())
{
case BME280::ChipModel_BME280:
Serial.println("Found BME280 sensor! Success.");
break;
case BME280::ChipModel_BMP280:
Serial.println("Found BMP280 sensor! No Humidity available.");
break;
default:
Serial.println("Found UNKNOWN sensor! Error!");
}
// Change some settings before using.
settings.tempOSR = BME280::OSR_X4;
bme.setSettings(settings);
#endif

// Warn if no PSRAM is detected (typically user error with board selection in the IDE)
if(!psramFound()){
Serial.println("\r\nFatal Error; Halting");
Expand Down