MQTT Working
This commit is contained in:
parent
f0485ebbed
commit
79c9c5b623
|
@ -1,16 +1,3 @@
|
|||
// Copyright 2015-2016 Espressif Systems (Shanghai) PTE LTD
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
#include "esp_http_server.h"
|
||||
#include "esp_timer.h"
|
||||
#include "esp_camera.h"
|
||||
|
|
|
@ -5,30 +5,6 @@
|
|||
|
||||
#define APP_CPU 1
|
||||
#define PRO_CPU 0
|
||||
/* This sketch is a extension/expansion/reork of the 'official' ESP32 Camera example
|
||||
* sketch from Expressif:
|
||||
* https://github.com/espressif/arduino-esp32/tree/master/libraries/ESP32/examples/Camera/CameraWebServer
|
||||
*
|
||||
* It is modified to allow control of Illumination LED Lamps's (present on some modules),
|
||||
* greater feedback via a status LED, and the HTML contents are present in plain text
|
||||
* for easy modification.
|
||||
*
|
||||
* A camera name can now be configured, and wifi details can be stored in an optional
|
||||
* header file to allow easier updated of the repo.
|
||||
*
|
||||
* The web UI has had changes to add the lamp control, rotation, a standalone viewer,
|
||||
* more feeedback, new controls and other tweaks and changes,
|
||||
* note: Make sure that you have either selected ESP32 AI Thinker,
|
||||
* or another board which has PSRAM enabled to use high resolution camera modes
|
||||
*/
|
||||
|
||||
/*
|
||||
* FOR NETWORK AND HARDWARE SETTINGS COPY OR RENAME 'myconfig.sample.h' TO 'myconfig.h' AND EDIT THAT.
|
||||
*
|
||||
* By default this sketch will assume an AI-THINKER ESP-CAM and create
|
||||
* an accesspoint called "ESP32-CAM-CONNECT" (password: "InsecurePassword")
|
||||
*
|
||||
*/
|
||||
|
||||
// Primary config, or defaults.
|
||||
#if __has_include("myconfig.h")
|
||||
|
@ -73,6 +49,8 @@ IPAddress gw;
|
|||
extern void startCameraServer();
|
||||
// Declare external function from esp32-streamserver.cpp
|
||||
extern void startStreamServer();
|
||||
// Declare external function from esp32-streamserver.cpp
|
||||
void startMQTTClient(const char *, int, const char *, const char *, const void *);
|
||||
|
||||
// A Name for the Camera. (set in myconfig.h)
|
||||
#if defined(CAM_NAME)
|
||||
|
@ -471,10 +449,10 @@ void setup()
|
|||
delay(10000);
|
||||
ESP.restart();
|
||||
}
|
||||
sensor_t *s = esp_camera_sensor_get();
|
||||
sensor_t *espCamSensor = esp_camera_sensor_get();
|
||||
|
||||
// Dump camera module, warn for unsupported modules.
|
||||
switch (s->id.PID)
|
||||
switch (espCamSensor->id.PID)
|
||||
{
|
||||
case OV9650_PID:
|
||||
Serial.println("WARNING: OV9650 camera module is not properly supported, will fallback to OV2640 operation");
|
||||
|
@ -493,11 +471,11 @@ void setup()
|
|||
}
|
||||
|
||||
// OV3660 initial sensors are flipped vertically and colors are a bit saturated
|
||||
if (s->id.PID == OV3660_PID)
|
||||
if (espCamSensor->id.PID == OV3660_PID)
|
||||
{
|
||||
s->set_vflip(s, 1); //flip it back
|
||||
s->set_brightness(s, 1); //up the blightness just a bit
|
||||
s->set_saturation(s, -2); //lower the saturation
|
||||
espCamSensor->set_vflip(espCamSensor, 1); //flip it back
|
||||
espCamSensor->set_brightness(espCamSensor, 1); //up the blightness just a bit
|
||||
espCamSensor->set_saturation(espCamSensor, -2); //lower the saturation
|
||||
}
|
||||
|
||||
// M5 Stack Wide has special needs
|
||||
|
@ -516,7 +494,7 @@ void setup()
|
|||
|
||||
// set initial frame rate
|
||||
#if defined(DEFAULT_RESOLUTION)
|
||||
s->set_framesize(s, DEFAULT_RESOLUTION);
|
||||
espCamSensor->set_framesize(espCamSensor, DEFAULT_RESOLUTION);
|
||||
#else
|
||||
s->set_framesize(s, FRAMESIZE_SVGA);
|
||||
#endif
|
||||
|
@ -605,6 +583,14 @@ void setup()
|
|||
else
|
||||
Serial.println("Camera debug data is disabled (send any char to enable)");
|
||||
|
||||
/*
|
||||
* Main camera streams running, now enable MQTT
|
||||
* */
|
||||
|
||||
#if defined(MQTT_HOST)
|
||||
startMQTTClient(MQTT_HOST, MQTT_PORT, MQTT_TOPIC, myName, MQTT_CERT);
|
||||
#endif
|
||||
|
||||
// Used when dumping status; these are slow functions, so just do them once during startup
|
||||
sketchSize = ESP.getSketchSize();
|
||||
sketchSpace = ESP.getFreeSketchSpace();
|
||||
|
|
|
@ -0,0 +1,149 @@
|
|||
#include "Arduino.h"
|
||||
#include <WiFiClientSecure.h>
|
||||
#include "PubSubClient.h"
|
||||
#include <ESPmDNS.h>
|
||||
#include <cstring>
|
||||
|
||||
extern UBaseType_t activeClients;
|
||||
|
||||
WiFiClient wifiClient;
|
||||
PubSubClient mqttClient(wifiClient);
|
||||
uint16_t mqtt_port = 1883;
|
||||
char *mqtt_host = new char[64];
|
||||
char *mqtt_pub_topic = new char[256];
|
||||
char *mqtt_client_id = new char[64];
|
||||
const char *MQTT_JSON = "{\"ClientId\":\"%s\",\"ActiveClients\":%d}";
|
||||
|
||||
void startMQTTClient(char *host, char *topic, char *cert);
|
||||
void mqttconnect();
|
||||
void mqttCB(void *pvParameters);
|
||||
|
||||
TaskHandle_t tMQTT; // handles client connection to the MQTT Server
|
||||
void mqttCB(void *pvParameters)
|
||||
{
|
||||
TickType_t xLastWakeTime = xTaskGetTickCount();
|
||||
TickType_t xFrequency = pdMS_TO_TICKS(60000); //Every minute
|
||||
|
||||
while (true)
|
||||
{
|
||||
/* if client was disconnected then try to reconnect again */
|
||||
if (!mqttClient.connected())
|
||||
{
|
||||
mqttconnect();
|
||||
}
|
||||
|
||||
Serial.printf("ActiveClients %d\n", activeClients);
|
||||
|
||||
char msg[64] = "";
|
||||
snprintf(msg, 64, MQTT_JSON, mqtt_client_id, activeClients);
|
||||
Serial.printf("Publishing message %s\n", msg);
|
||||
/* publish the message */
|
||||
mqttClient.publish(mqtt_pub_topic, msg);
|
||||
|
||||
// Let other tasks run after serving every client
|
||||
taskYIELD();
|
||||
vTaskDelayUntil(&xLastWakeTime, xFrequency);
|
||||
}
|
||||
}
|
||||
|
||||
void mqttconnect()
|
||||
{
|
||||
u32_t defaultIp = 0;
|
||||
IPAddress noConnIP = IPAddress(defaultIp);
|
||||
IPAddress serverIp = IPAddress(defaultIp);
|
||||
unsigned long period = 5000;
|
||||
unsigned long lastRun = 0;
|
||||
|
||||
/* Loop until reconnected */
|
||||
while (!mqttClient.connected())
|
||||
{
|
||||
|
||||
if (millis() - lastRun < period)
|
||||
{
|
||||
yield();
|
||||
continue;
|
||||
}
|
||||
|
||||
lastRun = millis();
|
||||
|
||||
/* Configure the MQTT server with IPaddress and port. */
|
||||
while (noConnIP == serverIp)
|
||||
{
|
||||
Serial.printf("Querying '%s:%d'...\n", mqtt_host, mqtt_port);
|
||||
|
||||
serverIp = MDNS.queryHost(mqtt_host);
|
||||
|
||||
Serial.printf("IP address of server: %s\n", serverIp.toString().c_str());
|
||||
|
||||
if (noConnIP == serverIp)
|
||||
{
|
||||
WiFi.hostByName(mqtt_host, serverIp);
|
||||
Serial.printf("IP address of server: %s\n", serverIp.toString().c_str());
|
||||
if ((uint32_t)serverIp == 0)
|
||||
{
|
||||
serverIp = noConnIP;
|
||||
}
|
||||
}
|
||||
|
||||
if (noConnIP != serverIp)
|
||||
{
|
||||
break;
|
||||
}
|
||||
yield();
|
||||
}
|
||||
|
||||
mqttClient.setServer(serverIp, mqtt_port);
|
||||
|
||||
/* connect now */
|
||||
char clientId[100] = {};
|
||||
char random[32] = {'-'};
|
||||
|
||||
srand((unsigned int)(time(NULL)));
|
||||
int index = 0;
|
||||
|
||||
char char1[] = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
|
||||
for (index = 1; index < 31; index++)
|
||||
{
|
||||
random[index] = char1[rand() % (sizeof char1 - 1)];
|
||||
}
|
||||
Serial.println(random);
|
||||
sprintf(clientId, "%s", mqtt_client_id);
|
||||
strcat(clientId, random);
|
||||
|
||||
Serial.printf("MQTT connecting as '%s'...\n", clientId);
|
||||
if (mqttClient.connect(clientId, "testUser", "1234")) //, "security/healthcheck", 20, true, "WillMessage", true))
|
||||
{
|
||||
Serial.println("connected");
|
||||
}
|
||||
else
|
||||
{
|
||||
mqttClient.disconnect();
|
||||
Serial.print("failed, status code =");
|
||||
Serial.print(mqttClient.state());
|
||||
Serial.printf("try again in %d seconds/n", 5);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void startMQTTClient(const char *host, int port, const char *topic, const char *client_id, const void *cert)
|
||||
{
|
||||
mqtt_port = port;
|
||||
strcpy(mqtt_pub_topic, topic);
|
||||
strcpy(mqtt_host, host);
|
||||
strcpy(mqtt_client_id, client_id);
|
||||
|
||||
Serial.printf("Starting MQTT Client '%s'\n", client_id);
|
||||
|
||||
/* Set SSL/TLS certificate */
|
||||
// wifiClient.setCACert(ca_cert);
|
||||
|
||||
/* Start main task. */
|
||||
xTaskCreatePinnedToCore(
|
||||
mqttCB,
|
||||
"mqtt",
|
||||
4096,
|
||||
NULL,
|
||||
2,
|
||||
&tMQTT,
|
||||
1);
|
||||
}
|
|
@ -1,13 +1,13 @@
|
|||
; PlatformIO Project Configuration File
|
||||
;
|
||||
; Build options: build flags, source filter
|
||||
; Upload options: custom upload port, speed and extra flags
|
||||
; Library options: dependencies, extra library storages
|
||||
; Advanced options: extra scripting
|
||||
;
|
||||
; Please visit documentation for the other options and examples
|
||||
; https://docs.platformio.org/page/projectconf.html
|
||||
|
||||
; The esp32-cam-webserver project is intended to be easily compilable
|
||||
; with the stock Arduino IDE.
|
||||
; - Maintaining compatibility with other development environments
|
||||
; is important, but I wont accept changes to the PlatformIO build that
|
||||
; break compatibilty with the stock IDE. Eg by using non-standard
|
||||
; partition schemes or overriding Arduino defined limits, etc.
|
||||
|
||||
[platformio]
|
||||
src_dir = ./
|
||||
|
||||
|
@ -19,4 +19,4 @@ monitor_speed = 115200
|
|||
build_flags =
|
||||
-DBOARD_HAS_PSRAM
|
||||
-mfix-esp32-psram-cache-issue
|
||||
|
||||
lib_deps = knolleary/PubSubClient@^2.8
|
||||
|
|
|
@ -1,25 +1,3 @@
|
|||
/*
|
||||
|
||||
This is a simple MJPEG streaming webserver implemented for AI-Thinker ESP32-CAM
|
||||
and ESP-EYE modules.
|
||||
This is tested to work with VLC and Blynk video widget and can support up to 10
|
||||
simultaneously connected streaming clients.
|
||||
Simultaneous streaming is implemented with FreeRTOS tasks.
|
||||
|
||||
Inspired by and based on this Instructable: $9 RTSP Video Streamer Using the ESP32-CAM Board
|
||||
(https://www.instructables.com/id/9-RTSP-Video-Streamer-Using-the-ESP32-CAM-Board/)
|
||||
|
||||
Board: AI-Thinker ESP32-CAM or ESP-EYE
|
||||
Compile as:
|
||||
ESP32 Dev Module
|
||||
CPU Freq: 240
|
||||
Flash Freq: 80
|
||||
Flash mode: QIO
|
||||
Flash Size: 4Mb
|
||||
Patrition: Minimal SPIFFS
|
||||
PSRAM: Enabled
|
||||
*/
|
||||
|
||||
// ESP32 has two cores: APPlication core and PROcess core (the one that runs ESP32 SDK stack)
|
||||
#define APP_CPU 1
|
||||
#define PRO_CPU 0
|
||||
|
@ -29,7 +7,6 @@
|
|||
#include <WiFi.h>
|
||||
#include <WebServer.h>
|
||||
#include <WiFiClient.h>
|
||||
|
||||
#include <esp_bt.h>
|
||||
#include <esp_wifi.h>
|
||||
#include <esp_sleep.h>
|
||||
|
@ -74,6 +51,7 @@ SemaphoreHandle_t frameSync = NULL;
|
|||
|
||||
// Queue stores currently connected clients to whom we are streaming
|
||||
QueueHandle_t streamingClients;
|
||||
UBaseType_t activeClients;
|
||||
|
||||
// We will try to achieve 25 FPS frame rate
|
||||
const int FPS = 14;
|
||||
|
@ -91,6 +69,7 @@ void handleJPG(void);
|
|||
void handleNotFound();
|
||||
void startStreamServer(int sPort);
|
||||
|
||||
|
||||
// ==== Memory allocator that takes advantage of PSRAM if present =======================
|
||||
char *allocateMemory(char *aPtr, size_t aSize)
|
||||
{
|
||||
|
@ -142,6 +121,7 @@ void mjpegCB(void *pvParameters)
|
|||
|
||||
// Creating a queue to track all connected clients
|
||||
streamingClients = xQueueCreate(10, sizeof(WiFiClient *));
|
||||
activeClients = 0;
|
||||
|
||||
//=== setup section ==================
|
||||
|
||||
|
@ -358,15 +338,13 @@ void streamCB(void *pvParameters)
|
|||
xFrequency = pdMS_TO_TICKS(1000 / FPS);
|
||||
|
||||
// Only bother to send anything if there is someone watching
|
||||
UBaseType_t activeClients = uxQueueMessagesWaiting(streamingClients);
|
||||
activeClients = uxQueueMessagesWaiting(streamingClients);
|
||||
|
||||
if (activeClients)
|
||||
{
|
||||
// Adjust the period to the number of connected clients
|
||||
xFrequency /= activeClients;
|
||||
|
||||
Serial.printf("ActiveClients %d\n", activeClients);
|
||||
|
||||
// Since we are sending the same frame to everyone,
|
||||
// pop a client from the the front of the queue
|
||||
WiFiClient *client;
|
||||
|
|
Loading…
Reference in New Issue