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

[WIP] Basic MQTT support #107

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

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions firmware/src/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
secrets.h
6 changes: 6 additions & 0 deletions firmware/src/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
#include "display_task.h"
#include "interface_task.h"
#include "motor_task.h"
#include "mqtt_task.h"

#if SK_DISPLAY
static DisplayTask display_task(0);
Expand All @@ -15,6 +16,10 @@ static MotorTask motor_task(1);

InterfaceTask interface_task(0, motor_task, display_task_p);

#if SK_MQTT
static MQTTTask mqtt_task(0, motor_task, interface_task);
#endif

void setup() {
#if SK_DISPLAY
display_task.setLogger(&interface_task);
Expand All @@ -27,6 +32,7 @@ void setup() {
motor_task.setLogger(&interface_task);
motor_task.begin();
interface_task.begin();
mqtt_task.begin();

// Free up the Arduino loop task
vTaskDelete(NULL);
Expand Down
65 changes: 65 additions & 0 deletions firmware/src/mqtt_task.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
#if SK_MQTT
#include "mqtt_task.h"

#include "motor_task.h"
#include "secrets.h"


MQTTTask::MQTTTask(const uint8_t task_core, MotorTask& motor_task, Logger& logger) :
Task("MQTT", 4096, 1, task_core),
motor_task_(motor_task),
logger_(logger),
wifi_client_(),
mqtt_client_(wifi_client_) {
auto callback = [this](char *topic, byte *payload, unsigned int length) { mqttCallback(topic, payload, length); };
mqtt_client_.setCallback(callback);
}

void MQTTTask::connectWifi() {
WiFi.begin(WIFI_SSID, WIFI_PASSWORD);

while (WiFi.status() != WL_CONNECTED) {
delay(1000);
logger_.log("Establishing connection to WiFi..");
}

char buf[256];
snprintf(buf, sizeof(buf), "Connected to network %s", WIFI_SSID);
logger_.log(buf);
}

void MQTTTask::mqttCallback(char *topic, byte *payload, unsigned int length) {
char buf[256];
snprintf(buf, sizeof(buf), "Received mqtt callback for topic %s, length %u", topic, length);
logger_.log(buf);
}

void MQTTTask::connectMQTT() {
char buf[256];
mqtt_client_.setServer(MQTT_SERVER, 1883);
logger_.log("Attempting MQTT connection...");
if (mqtt_client_.connect(HOSTNAME "-" MQTT_USER, MQTT_USER, MQTT_PASSWORD)) {
logger_.log("MQTT connected");
mqtt_client_.subscribe(MQTT_COMMAND_TOPIC);
} else {
snprintf(buf, sizeof(buf), "MQTT failed rc=%d will try again in 5 seconds", mqtt_client_.state());
logger_.log(buf);
}
}

void MQTTTask::run() {
connectWifi();
connectMQTT();

while(1) {
long now = millis();
if (!mqtt_client_.connected() && (now - mqtt_last_connect_time_) > 5000) {
logger_.log("Reconnecting MQTT");
mqtt_last_connect_time_ = now;
connectMQTT();
}
mqtt_client_.loop();
delay(1);
}
}
#endif
35 changes: 35 additions & 0 deletions firmware/src/mqtt_task.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
#pragma once

#if SK_MQTT

#include <Arduino.h>
#include <PubSubClient.h>
#include <WiFi.h>

#include "logger.h"
#include "motor_task.h"
#include "task.h"


class MQTTTask : public Task<MQTTTask> {
friend class Task<MQTTTask>; // Allow base Task to invoke protected run()

public:
MQTTTask(const uint8_t task_core, MotorTask& motor_task, Logger& logger);

protected:
void run();

private:
MotorTask& motor_task_;
Logger& logger_;
WiFiClient wifi_client_;
PubSubClient mqtt_client_;
int mqtt_last_connect_time_ = 0;

void connectWifi();
void connectMQTT();
void mqttCallback(char *topic, byte *payload, unsigned int length);
};

#endif
12 changes: 12 additions & 0 deletions firmware/src/secrets.h.example
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
// Rename this file to secrets.h and add your secret details.

// Network setup
#define WIFI_SSID "myssid"
#define WIFI_PASSWORD "supersecretpassword"

#define HOSTNAME "smartknob" // e.g. smartknob.local

#define MQTT_SERVER "10.0.0.2"
#define MQTT_USER "mqttuser"
#define MQTT_PASSWORD "megasecretpassword"
#define MQTT_COMMAND_TOPIC "smartknob"
6 changes: 5 additions & 1 deletion platformio.ini
Original file line number Diff line number Diff line change
Expand Up @@ -42,11 +42,12 @@ lib_deps =
bogde/HX711 @ 0.7.5
adafruit/Adafruit VEML7700 Library @ 1.1.1
bakercp/PacketSerial @ 1.4.0
nanopb/Nanopb @ 0.4.6 ; Ideally this would reference the nanopb submodule, but that would require
nanopb/Nanopb @ 0.4.7 ; Ideally this would reference the nanopb submodule, but that would require
; everyone to check out submodules to just compile, so we use the library
; registry for the runtime. The submodule is available for manually updating
; the pre-compiled (checked in) .pb.h/c files when proto files change, but is
; otherwise not used during application firmware compilation.
knolleary/PubSubClient @ 2.8

build_flags =
${base_config.build_flags}
Expand All @@ -66,6 +67,9 @@ build_flags =
; Ambient light sensor (VEML7700) enabled: 1=enable (display/LEDs match ambient brightness), 0=disable (100% brightness all the time)
-DSK_ALS=1

; Enable MQTT (wifi must be configured in secrets.h first)
-DSK_MQTT=1

; Pin configurations
-DPIN_UH=26
-DPIN_UL=25
Expand Down