I've been working on a project in which i need a gateway. So to emulate the functionalities of a gateway, I have decided to use esp32. I have been using esp32c3 mini by xiao studio for my smart sensors to transmit data using bluetooth. My gateway comprises of two esp32 devices connected to each other through I2C. So one of these esp32 devices receives the data using BLE and sends this data to the next esp32 using I2C
The second esp32 receives the data through I2C and transmits the data to aws
But i noticed how when the aws connection is established, the sensor data are not read and vice versa. What do i do? I'm assuming i'm going to face the same problem for sending the messages received by ble using I2C as well.
I really could use your help on this
#include <Wire.h>
#include <ArduinoJson.h>
#include <WiFiClientSecure.h>
#include <MQTTClient.h>
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "secrets.h"
#define RECEIVER_ADDRESS 0x42
#define MAX_JSON_LENGTH 256
#define AWS_IOT_PUBLISH_TOPIC "sensordatapub"
#define AWS_IOT_SUBSCRIBE_TOPIC "sensordatasub"
WiFiClientSecure net;
MQTTClient client;
char receivedData[MAX_JSON_LENGTH];
bool newData = false;
void i2cTask(void *pvParameters);
void awsTask(void *pvParameters);
void setup() {
Serial.begin(9600);
Wire.begin(RECEIVER_ADDRESS);
xTaskCreatePinnedToCore(i2cTask, "i2cTask", 4096, NULL, 1, NULL, 0);
xTaskCreatePinnedToCore(awsTask, "awsTask", 8192, NULL, 1, NULL, 1);
}
void loop() {}
void i2cTask(void *pvParameters) {
while (true) {
int byteCount = Wire.available();
if (byteCount > 0) {
int bytesRead = Wire.readBytes(receivedData, MAX_JSON_LENGTH);
receivedData[bytesRead] = '\0';
newData = true;
Serial.println("Received data from I2C:");
Serial.println(receivedData);
}
vTaskDelay(10 / portTICK_PERIOD_MS);
}
}
void awsTask(void *pvParameters) {
connectAWS();
while (true) {
if (newData) {
processData();
newData = false;
Serial.println("Data processed and published to AWS.");
}
client.loop();
vTaskDelay(10 / portTICK_PERIOD_MS);
}
}
void connectAWS() {
WiFi.mode(WIFI_STA);
WiFi.begin(WIFI_SSID, WIFI_PASSWORD);
Serial.println("Connecting to Wi-Fi");
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
Serial.println("Wi-Fi connected.");
net.setCACert(AWS_CERT_CA);
net.setCertificate(AWS_CERT_CRT);
net.setPrivateKey(AWS_CERT_PRIVATE);
client.begin(AWS_IOT_ENDPOINT, 8883, net);
client.onMessage(messageHandler);
Serial.print("Connecting to AWS IoT... ");
while (!client.connect(THINGNAME)) {
Serial.print(".");
delay(100);
}
if (!client.connected()) {
Serial.println("\nFailed to connect to AWS IoT!");
return;
}
client.subscribe(AWS_IOT_SUBSCRIBE_TOPIC);
Serial.println("\nAWS IoT Connected!");
}
void publishMessage(const char* id, int max_lvl, int min_lvl, int data) {
StaticJsonDocument<200> doc;
doc["id"] = id;
doc["max_lvl"] = max_lvl;
doc["min_lvl"] = min_lvl;
doc["data"] = data;
char jsonBuffer[512];
serializeJson(doc, jsonBuffer);
Serial.print("Publishing JSON data to AWS IoT: ");
Serial.println(jsonBuffer);
client.publish(AWS_IOT_PUBLISH_TOPIC, jsonBuffer);
}
void processData() {
StaticJsonDocument<200> doc;
DeserializationError error = deserializeJson(doc, receivedData);
if (error) {
Serial.print("deserializeJson() failed: ");
Serial.println(error.c_str());
return;
}
const char* id = doc["id"];
int max_lvl = doc["max_lvl"];
int min_lvl = doc["min_lvl"];
int data = doc["data"];
publishMessage(id, max_lvl, min_lvl, data);
}
void messageHandler(String &topic, String &payload) {
Serial.println("Incoming message on topic: " + topic + ", payload: " + payload);
}
I created two tasks here. I wanted to use both the cores
This is something that is addressed here but I can't seem to find the solution
This is the architecture