MQTT Working

This commit is contained in:
Sam 2020-10-27 16:23:55 -05:00
parent f0485ebbed
commit 79c9c5b623
5 changed files with 182 additions and 82 deletions

View File

@ -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"

View File

@ -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();

149
mqtt_client.cpp Normal file
View File

@ -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);
}

View File

@ -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

View File

@ -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;