Skip to content

Commit

Permalink
Mqtt (#8)
Browse files Browse the repository at this point in the history
* use mqtt instead of ws

* update readme
  • Loading branch information
yuichiroaoki authored Oct 31, 2023
1 parent 7bfeb88 commit 18ba7a3
Show file tree
Hide file tree
Showing 3 changed files with 153 additions and 87 deletions.
55 changes: 49 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,17 +4,60 @@ Stream the sensor data
```mermaid
sequenceDiagram
participant ESP32 as ESP32
participant Client as WebSocket Client
participant Client as MQTT Client
participant TouchSensor as Touch Sensor
ESP32->>+Client: Start WebSocket server
Client->>ESP32: Send message to get sensor data
ESP32->>+ESP32: Start streaming data
Client->>ESP32: Send message to stop streaming
ESP32-->>-ESP32: Stop streaming
ESP32->>+Client: Start streaming data
Client->>ESP32: Send message to sleep
ESP32->>+ESP32: Enter deep sleep mode
TouchSensor->>ESP32: Touch GPIO 4
ESP32-->>-ESP32: Wake up from deep sleep
ESP32->>+ESP32: Start booting
```

## Set up WiFi
1. Connect to the ESP32's WiFi AP
2. Open http://192.168.1.1
3. Select the SSID and enter the password of the WiFi network

Then the ESP32 will connect to the WiFi network and start streaming data.
The WiFi configuration will be saved in the flash memory.

Check if the ESP32 is connected to the WiFi network
```bash
ping opencmm.local
```

## Install Mosquitto MQTT Broker

ref. https://www.vultr.com/docs/install-mosquitto-mqtt-broker-on-ubuntu-20-04-server/

/etc/mosquitto/conf.d/default.conf
```
listener 1883 0.0.0.0
allow_anonymous false
password_file /etc/mosquitto/passwd
```

### Receive data

```bash
mosquitto_sub -t 'sensor/data' -v -h 192.168.10.104 -u opencmm -P opencmm
```

### Send command to ESP32

Update configuration
```bash
mosquitto_pub -t 'sensor/control' -h 192.168.10.104 -u opencmm -P opencmm -m '{"command": "config", "interval": 1000, "threshold": 100 }'
```

Go to sleep
```bash
mosquitto_pub -t 'sensor/control' -h 192.168.10.104 -u opencmm -P opencmm -m '{"command": "deepSleep" }'
```

Reset WiFi
```bash
mosquitto_pub -t 'sensor/control' -h 192.168.10.104 -u opencmm -P opencmm -m '{"command": "resetWifi" }'
```
3 changes: 2 additions & 1 deletion platformio.ini
Original file line number Diff line number Diff line change
Expand Up @@ -16,4 +16,5 @@ monitor_speed = 115200
lib_deps =
links2004/WebSockets@^2.4.1
adafruit/Adafruit ADS1X15@^2.4.0
bblanchon/ArduinoJson@^6.21.3
bblanchon/ArduinoJson@^6.21.3
knolleary/PubSubClient@^2.8
182 changes: 102 additions & 80 deletions src/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,64 +5,100 @@
#include <Sensor.h>
#include <ESPmDNS.h>
#include <ArduinoJson.h>
#include <PubSubClient.h>

void ledBlink();
void callback(char* topic, byte* message, unsigned int length);
void reconnect();
void publishSensorData(int sensorData);

const int touchPin = 4; // GPIO4 as the touch-sensitive pin
int sensorData = 0;
int interval = 1000; // 1 second
int threshold = 100;
const char* hostname = "opencmm";
const char* mqttServer = "192.168.10.104";
const int mqttPort = 1883;
const char* mqttUser = "opencmm";
const char* mqttPassword = "opencmm";

WebSocketsServer webSocket(81);
const char* clientId = "ESP32Client";
const char* sensorTopic = "sensor/data";
const char* controlTopic = "sensor/control";

bool streaming = false;

void webSocketEvent(uint8_t num, WStype_t type, uint8_t *payload, size_t length)
WiFiClient espClient;
PubSubClient client(espClient);

void touchCallback()
{
switch (type)
{
case WStype_DISCONNECTED:
// streaming = false; // Stop streaming data when a client disconnects
break;
case WStype_TEXT:
{
const uint8_t size = JSON_OBJECT_SIZE(3);
StaticJsonDocument<size> json;
DeserializationError err = deserializeJson(json, payload);
if (err)
{
Serial.print(F("deserializeJson() failed with code "));
Serial.println(err.c_str());
}
const char *command = json["command"];
// wake up from deep sleep
Serial.println("Touch detected");
// turn on sensor
switchSensor(true);
ledBlink();
}

if (strcmp(command, "start") == 0)
{
streaming = true; // Start streaming data when "startStreaming" message is received
const int _interval = json["interval"];
void setup()
{
Serial.begin(115200);
checkWifiInfo();
MDNS.begin(hostname);
setupSensor();

client.setServer(mqttServer, mqttPort);
client.setCallback(callback);

touchAttachInterrupt(touchPin, touchCallback, 40); // Attach touch interrupt

// Configure Touchpad as wakeup source
esp_sleep_enable_touchpad_wakeup();

ledBlink();
}

void callback(char* topic, byte* payload, unsigned int length) {
Serial.print("Message arrived on topic: ");
Serial.println(topic);

char receivedJson[200];
for (int i = 0; i < length; i++) {
receivedJson[i] = (char)payload[i];
}
receivedJson[length] = '\0';
// Deserialize the received JSON string
const uint8_t size = JSON_OBJECT_SIZE(3);
StaticJsonDocument<size> jsonDoc;
DeserializationError error = deserializeJson(jsonDoc, receivedJson);

if (error) {
Serial.print("Failed to parse JSON: ");
Serial.println(error.c_str());
} else {
const char *command = jsonDoc["command"];
if (strcmp(command, "config") == 0) {
const int _interval = jsonDoc["interval"];
if (isIntervalValid(_interval))
{
interval = _interval;
Serial.println("Interval: " + String(interval));
}

const int _threshold = json["threshold"];
const int _threshold = jsonDoc["threshold"];
if (isThresholdValid(_threshold))
{
threshold = _threshold;
Serial.println("Threshold: " + String(threshold));
}
Serial.println("Streaming started");
}
else if (strcmp(command, "stop") == 0)
{
streaming = false; // Stop streaming data when "stopStreaming" message is received
Serial.println("Streaming stopped");
}
else if (strcmp(command, "deepSleep") == 0)
Serial.println("Configured");
Serial.print("Received JSON - Threshold: ");
Serial.print(threshold);
Serial.print(", Interval: ");
Serial.print(interval);
Serial.print(", Command: ");
Serial.println(command);
} else if (strcmp(command, "deepSleep") == 0)
{
streaming = false;
Serial.println("Going to sleep now");
delay(1000);
// turn off sensor
Expand All @@ -74,61 +110,33 @@ void webSocketEvent(uint8_t num, WStype_t type, uint8_t *payload, size_t length)
resetWifiCredentialsWithWs();
}
}

break;
default:
break;
}
}

void touchCallback()
{
// wake up from deep sleep
Serial.println("Touch detected");
// turn on sensor
switchSensor(true);
ledBlink();
}

void setup()
{
Serial.begin(115200);
checkWifiInfo();
MDNS.begin(hostname);
setupSensor();

touchAttachInterrupt(touchPin, touchCallback, 40); // Attach touch interrupt

// Configure Touchpad as wakeup source
esp_sleep_enable_touchpad_wakeup();

ledBlink();

webSocket.begin();
webSocket.onEvent(webSocketEvent);
void publishSensorData(int sensorData) {
char message[20];
snprintf(message, 20, "%d", sensorData);
client.publish(sensorTopic, message);
}

void loop()
{
if (WiFi.status() == WL_CONNECTED)
{
webSocket.loop();
if (!client.connected()) {
reconnect();
}
client.loop();

// If streaming is enabled, get sensor data and send it to the client
if (streaming)
{
int currentData = getSensorData();
// if the difference is greater than threshold, send data
if (abs(currentData - sensorData) < threshold)
{
return;
}
sensorData = currentData;
String dataStr = String(currentData);
Serial.println(dataStr);
webSocket.broadcastTXT(dataStr.c_str(), dataStr.length());
delay(interval);
int currentData = getSensorData();
// if the difference is greater than threshold, send data
if (abs(currentData - sensorData) < threshold) {
return;
}
sensorData = currentData;
Serial.println(currentData);
publishSensorData(currentData);

delay(interval);
} else {
runServer();
delay(1000);
Expand All @@ -138,9 +146,23 @@ void loop()
}
}

void reconnect() {
while (!client.connected()) {
Serial.println("Attempting MQTT connection...");
if (client.connect(clientId, mqttUser, mqttPassword)) {
Serial.println("Connected to MQTT broker");
client.subscribe(controlTopic);
} else {
Serial.print("Failed, rc=");
Serial.print(client.state());
Serial.println(" Trying again in 5 seconds...");
delay(5000);
}
}
}

// LED blink
void ledBlink()
{
void ledBlink() {
digitalWrite(LED_BUILTIN, HIGH);
delay(500);
digitalWrite(LED_BUILTIN, LOW);
Expand Down

0 comments on commit 18ba7a3

Please sign in to comment.