Streaming Images from ESP32-CAM for viewing on a CYD-esp32
I recently had a few wifi-enabled microcontrollers (ESP32) dropped into my lap, and with a bit of free time, set out to find a use for them, and barring that, at least have some fun playing around with them.
There are many, many different development boards centered around Esperiff's ESP32 chip. In todays post I'm going to be taking a look at two of them: The ESP32-CAM, which sports an onboard OV5660 3MP camera, and the ESP32 CYD (Cheap Yellow Display*), with its integrated 240x320 TFT.
The Client
#include <TJpg_Decoder.h>
#include <WiFi.h>
#include <TFT_eSPI.h>
#include <HTTPClient.h>
#include "mbedtls/base64.h"
const int width = 320;
const int height = 240;
const char* ssid = "WIFI_NETWORK_NAME";
const char* password = "WIFI_PASSWORD";
TFT_eSPI tft = TFT_eSPI();
HTTPClient http;
bool tft_output(int16_t x, int16_t y, uint16_t w, uint16_t h, uint16_t *bitmap) {
tft.pushImage(x, y, w, h, bitmap);
return 1;
}
void setupTFT() {
Serial.begin(112500);
tft.init();
tft.setRotation(1);
tft.fillScreen(TFT_BLACK);
tft.setTextColor(TFT_GREEN, TFT_BLACK);
tft.setTextWrap(true, true);
tft.drawString("Dip SET!", 5,10, 2);
}
void setupWiFi() {
WiFi.mode(WIFI_STA);
WiFi.begin(ssid, password);
tft.drawString("Connecting", 5, 50, 2);
tft.setCursor(tft.getCursorX(), tft.getCursorY());
while (WiFi.status() != WL_CONNECTED) {
tft.print(".");
delay(1000);
}
tft.print("Connected!");
}
void setup() {
setupTFT();
setupWiFi();
TJpgDec.setCallback(tft_output);
TJpgDec.setSwapBytes(true);
}
void loop() {
http.begin("http://192.168.4.1/img");
int respCode = http.GET();
if (respCode == HTTP_CODE_OK) {
String payload = http.getString();
size_t out_len;
mbedtls_base64_decode(
NULL,
0,
&out_len,
(const unsigned char*)payload.c_str(),
payload.length()
);
unsigned char* imgbytes = (unsigned char*) malloc(out_len);
if (imgbytes) {
mbedtls_base64_decode(
imgbytes,
out_len,
&out_len,
(const unsigned char*)payload.c_str(),
payload.length()
);
TJpgDec.drawJpg(0,0,imgbytes,out_len);
free(imgbytes);
} else {
Serial.print("Malloc failed");
}
} else {
Serial.println("HTTP request failed");
}
http.end();
delay(1600);
}
Server
#include <esp32cam.h>
#include <WiFi.h>
#include <WebServer.h>
#include <DNSServer.h>
#include <base64.h>
const byte DNS_PORT = 53;
const int WEBSERVER_PORT = 80;
IPAddress apIP(192, 168, 4, 1);
IPAddress netMsk(255, 255, 255, 0);
DNSServer dnsServer;
WebServer server(WEBSERVER_PORT);
char* netname = "WIFI_NETWORK_NAME";
char* netpass = "WIFI_PASSWORD";
const auto RES = esp32cam::Resolution::find(320, 240);
TaskHandle_t webServerTaskHandle = NULL;
void handleFourOhFour() {
server.send(404, "text/plain", "yo whats really good with you fam? DIP SET");
}
void handleJustImg() {
server.sendHeader("Cache-Control", "no-cache, no-store, must-revalidate");
server.sendHeader("Pragma", "no-cache");
server.sendHeader("Expires", "-1");
auto frame = esp32cam::capture();
if (frame != nullptr) {
String retval = base64::encode(frame->data(),frame->size());
server.send(200, "text/plain", retval);
Serial.println("Sent down the line...");
Serial.println(retval);
} else {
Serial.println("Frame failed.");
}
}
void setupWebServer() {
server.on("/", handleJustImg);
server.on("/img", handleJustImg);
server.onNotFound(handleFourOhFour);
server.begin();
}
void setupCamera() {
using namespace esp32cam;
Config cfg;
cfg.setPins(pins::AiThinker);
cfg.setResolution(RES);
cfg.setJpeg(80);
bool ok = Camera.begin(cfg);
Serial.println(ok ? "CAMERA OK" : "CAMERA FAIL");
}
void setupWifi() {
// put your setup code here, to run once:
WiFi.softAP(netname,netpass);
Serial.print("Starting webserver on ");
Serial.println( WiFi.softAPIP());
dnsServer.setErrorReplyCode(DNSReplyCode::NoError);
dnsServer.start(DNS_PORT, "*", apIP);
}
void webServerTask(void* pvParameters) {
setupWebServer();
while (true) {
dnsServer.processNextRequest();
server.handleClient();
vTaskDelay(pdMS_TO_TICKS(50));
}
}
void setup() {
Serial.begin(115200);
setupCamera();
setupWifi();
xTaskCreatePinnedToCore(
webServerTask,
"WebServerTask",
8192,
NULL,
1,
&webServerTaskHandle,
1
);
}
void loop() {
delay(2);
}
Search
Recent Posts
-
Streaming Images from ESP32-CAM for viewing on a CYD-esp32
-
Constructing the Firsts Set of a Context Free Grammar
-
Inchworm Evaluation, Or Evaluating Prefix-Expressions with a Queue
-
Data Structures For Representing Context Free Grammar
-
A B Tree of Binary Search Trees
-
Implementing enhanced for loops in Bytecode
-
Top-Down Deletion for Red/Black Trees
-
Function Closures For Bytecode VMs: Heap Allocated Activation Records & Access Links
-
Pascal & Bernoulli & Floyd: Triangles
-
A Quick tour of MGCLex
Meta
Leave A Comment