Skip to content
Snippets Groups Projects
Commit 37fc22d7 authored by Vladislav Vlasuk's avatar Vladislav Vlasuk
Browse files

init

parents
Branches
No related tags found
1 merge request!1init
.vscode
build
README.md 0 → 100644
# thk_EspCamServer
Zunächst muss die Bibliothek im Sketch inkludiert werden.
#include "thk_EspCamServer.h" // WIFI und HTTP-Server
Anschließend wird das WiFI-Netzwerk konfiguriert und (optional) der Name des HTTP-Ressource festgelegt.
const char *ssid = "FRITZBOX";
const char *password = "qqqqqqqq";
const char *uri = "/stream";
Nun kann das Objekt erzeugt werden.
thk_EspCamServer server(ssid, password, uri);
Für die Verwendung der Klasse ist ein sogenannter Handler erforderlich. Dieser regelt das Verhalten beim Aufrufen der Internetressource (bspw. beim eintippen von http://172.02.11/server im Browser innerhalb des lokalen Netzwerks).\
Hier kann für den Anfang die folgende Funktion außerhalb der setup() und loop() Routine erstellt werden:
static esp_err_t get_helloworld_handler(httpd_req_t *req)
{
/* Send a simple response */
Serial.println("Ein HTTP Request hat uns erreicht!");
return ESP_OK;
}
Hier erfolgt beim Aufrufen der Internetressource eine Textausgabe durch den ESP32 im Seriellen Monitor.
In der Setup Routine wird die Verbindung zum WiFi-Netzwerk aufgebaut
server.connect();
und der Webserver mit einer Referenz auf den benutzerdefinierten Handler (hier unser HelloWorld Beispiel) aufgerufen.
server.start_webserver(&get_stream_handler);
## CameraWebServer
Das Beispiel *cameraserver.ino* streamt das Kamerabild mittels eines lokalen Webservers.
Hierfür ist die Bibliothek thk_EspCamDriver erforderlich!
https://git-ce.rwth-aachen.de/thk_libs/microcontrollers/thk_espcamdriver.git
Zum Verwenden des Skriptes muss das Netzwerk vorab angepasst werden
const char* ssid = "iPhone von Vladislav";
const char* password = "qqqqqqqq";
Im Anschluss den Sketch auf den ESP32 One hochladen. Hierbei als Board "ESP32 DEV MODULE(esp32)" wählen. Nun kann mit einem im Netzwerk befindlichen Gerät über die Https-Adresse das Bild im Webserver angezeigt und gespeichert werden.
Im Seriellen Monitor wird hier durch das Neustarten des ESP (Reset-Button) die Adresse ausgegeben.
[OK] WiFi verbunden: 172.20.10.2
[OK] HTTP_Get-Server bereit ( Port 80 ) HTTP: 172.20.10.2/stream
### Erläuterung des Skripts
Zunächst wird die erforderliche Bibliothek zum Interagieren mit der Kamera und Starten des Servers inkludiert
#include "thk_EspCamDriver.h" // ESP32 Kamera
#include "thk_EspCamServer.h" // WIFI und HTTP-Server
Im Anschluss wird das Netzwerk eingerichtet
const char *ssid = "iPhone von Vladislav";
const char *password = "qqqqqqqq";
Optional kann auch die Internetressource unbenannt werden. Diese wird beim Aufruf des Servers benötigt.
const char *uri = "/stream";
Die folgenden Objekte sind für den Datenaustausch mit der Kamera notwendig
camera_config_t cameraconfig; // Konfig
esp_err_t cameraerror; // Fehler
camera_fb_t *fb = NULL; // Framebuffer
Um sowohl die Kamera als auch den Server möglichst kompakt für den Anwender nutzbar zu machen, sind zwei benutzerdefinierten Klassen vorhanden
thk_EspCamDriver camera(&cameraconfig, &cameraerror, fb);
thk_EspCamServer server(ssid, password, uri);
Anschließend kann in der Setup-Routine die Kamera initialisiert
camera.init();
Und mit dem WiFi-Netzwerk verbunden werden
server.connect();
Abschließend wird der Webserver gestartet. Dafür ist ein sogenannter Handler erforderlich. Dieser bildet die Antwort auf den Zugriff über HTTP. Hier kann neben dem Stream-Handler für das Kamerabild
server.start_webserver(&get_stream_handler);
auch stattdessen das HelloWorld Beispiel ausprobiert werden. Hierzu die Referenz entsprechend anpassen.
server.start_webserver(&get_helloworld_handler);
Das Kamerabild wird hier als Buffer gespeichert. Die Länge und der Inhalt (Pixel) können über die Server-Bibliothek bezogen werden.
camera.getBufLen()
camera.getJpgBuf()
// Beschreibung:
// Beispiel Sketch für das Auslesen der ESP32One Waveshare Kamera
// und lokales Streamen des Kamerabildes per HTTP
// Abhängigkeiten:
// thk_EspCamDriver.h, thk_EspCamServer.h
// Autor:
// Vladislav Vlasuk (TH Köln, Labor für Assistenzsysteme)
// Datum:
// 05.07.2022
// Bitte ESP32 Kameramodell auskommentieren
#include <thk_EspCamDriver.h> // ESP32 Kamera
#include <thk_EspCamServer.h> // WIFI und HTTP-Server
// Wlan-Netzwerk und Internetressource (URI) festlegen
const char *ssid = "iPhone von Vladislav";
const char *password = "qqqqqqqq";
const char *uri = "/stream";
// ESP32 Kameraspezifisch
esp_image_t image;
camera_config_t cameraconfig; // Konfig
esp_err_t cameraerror; // Fehler
camera_fb_t *fb = NULL; // Framebuffer
// Objekte erzeugen
thk_EspCamDriver camera(&cameraconfig, &cameraerror, fb, &image);
thk_EspCamServer server(ssid, password, uri);
void setup()
{
Serial.begin(115200);
camera.set_hmirror(1);
camera.set_vflip(1);
camera.set_grayscale(1);
camera.init(); // Kamera starten
server.connect(); // Wifi verbinden
server.start_webserver(&get_stream_handler); // Server starten
};
void loop()
{
// Do nothing. Everything is done in another task by the web server
delay(1e4);
}
// Handler für das Auslesen des Kameramoduls am ESP32One Waveshare
esp_err_t get_stream_handler(httpd_req_t *req)
{
Serial.println("Starte Kamera Handler");
esp_err_t res = ESP_OK;
size_t _jpg_buf_len = 0;
uint8_t *_jpg_buf = NULL;
char *part_buf[128];
res = httpd_resp_set_type(req, _STREAM_CONTENT_TYPE);
if (res != ESP_OK)
return res;
while (true)
{
// Schieße Bild
camera.take_picture();
_jpg_buf_len = camera.get_fb()->len;
_jpg_buf = camera.get_fb()->buf;
// This API will send the data as an HTTP response to the request in the form of chunks with chunked-encoding
if (res == ESP_OK)
{
res = httpd_resp_send_chunk(req, _STREAM_BOUNDARY, strlen(_STREAM_BOUNDARY));
}
if (res == ESP_OK)
{
size_t hlen = snprintf((char *)part_buf, 128, _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);
}
// close stream
if (camera.get_fb())
{
camera.close_stream();
_jpg_buf = NULL;
}
else if (_jpg_buf)
{
free(_jpg_buf);
_jpg_buf = NULL;
}
if (res != ESP_OK)
{
Serial.println("send frame failed failed");
break;
}
}
return res;
}
// Bare Minimum Handler
static esp_err_t get_helloworld_handler(httpd_req_t *req)
{
/* Send a simple response */
Serial.println("Ein HTTP Request hat uns erreicht!");
return ESP_OK;
}
#include "esp_http_server.h"
#include <WiFi.h>
// Von Espresif Systems (Shanghei) PTE LTD für Stream vorgegeben
#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\nX-Timestamp: %d.%06d\r\n\r\n";
// Ermöglicht die Datenübertragung per WIFI mittels HTTP
class thk_EspCamServer
{
private:
const char *ssid = NULL;
const char *password = NULL;
const char *uri = NULL;
IPAddress address;
public:
// Ein Server benötigt immer eine ssid, pw, uri
thk_EspCamServer(const char *a_ssid, const char *a_pw, const char *a_uri) : ssid(a_ssid), password(a_pw), uri(a_uri)
{
}
// Startet die Verbindung zum Netzwerk.
bool connect()
{
WiFi.mode(WIFI_STA);
WiFi.begin(ssid, password);
WiFi.setSleep(false);
Serial.print("Verbinde mit Netzwerk >");
Serial.print(ssid);
Serial.print("< [");
while (WiFi.status() != WL_CONNECTED)
{
delay(500);
Serial.print(".");
}
Serial.println("]");
Serial.print("[OK] WiFi verbunden: ");
Serial.println(WiFi.localIP());
address = WiFi.localIP();
return true;
}
// Startet für den URI Handler einen Server, der über HTTP erreicht werden kann
// @param func Handler, welcher ausgeführt werden soll
//
httpd_handle_t start_webserver(esp_err_t (*func)(httpd_req_t *req))
{
/* Generate default configuration */
httpd_config_t config = HTTPD_DEFAULT_CONFIG();
/* Empty handle to esp_http_server */
httpd_handle_t server = NULL;
/* URI handler structure for GET /uri */
httpd_uri_t uri_get = {
.uri = this->uri,
.method = HTTP_GET,
.handler = func,
.user_ctx = NULL};
/* Start the httpd server */
if (httpd_start(&server, &config) == ESP_OK)
{
Serial.printf("[OK] HTTP_Get-Server bereit ( Port %d ) HTTP: ", config.server_port);
Serial.print(address);
Serial.println(uri);
/* Register URI handlers */
httpd_register_uri_handler(server, &uri_get);
}
/* If server failed to start, handle will be NULL */
return server;
}
/* Function for stopping the webserver */
void stop_webserver(httpd_handle_t server)
{
/* Stop the httpd server */
Serial.println("Schließe Server");
httpd_stop(server);
}
};
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment