Week 13
For the next section of my documentation that we develop as a group. I will show how a message was sent between 2 projects by cables and by wifi. We developed the first one through I2C communication, which is what we were able to achieve success with between wired communication and for Wi-Fi, we will use MQTTX so that both boards can communicate. Below is the process of each of them.
To develop communication, we decided to use the Motion Sensor input that is connected to my board and a neopixel that we connect to Silvana's board. Before starting the communication between the 2 boards, we had to carry out a test on each board to see if it worked and whether the input and output were working correctly. Here is a screenshot of the neopixel on Silvana's board.
For programming, I2C communication was taken into account so that both can work via cables. The XIAO ESP32 C3 was used on my board and a XIAO RP2040 was used on Silvana's board. Here the programming of both boards.
#include Wire.h
const int sensorPin = D10; // PIN OF XIAO ESP32 C3
void setup() {
Wire.begin(); // Start I2C communication
pinMode(sensorPin, INPUT);
}
void loop() {
int sensorValue = digitalRead(sensorPin);
Wire.beginTransmission(9); // Slave address
Wire.write(sensorValue);
Wire.endTransmission();
delay(1000); // Wait for 1 second before reading the sensor again
}
#include Wire.h
#include Adafruit_NeoPixel.h
#define PIN 10 // PIN XIAO RP2040
#define NUMPIXELS 1
Adafruit_NeoPixel pixels(NUMPIXELS, PIN, NEO_GRB + NEO_KHZ800);
void setup() {
pixels.begin();
Wire.begin(9); // Slave address
Wire.onReceive(receiveEvent);
}
void loop() {
// There's no need to do anything in the slave's loop
}
void receiveEvent(int bytes) {
if (Wire.available()) {
int sensorValue = Wire.read();
if (sensorValue == 1) {
// If motion is detected, set Neopixel color to red
pixels.setPixelColor(0, pixels.Color(255, 0, 0)); // Red
pixels.show();
} else {
// If no motion is detected, set Neopixel color to green
pixels.setPixelColor(0, pixels.Color(0, 255, 0)); // Green
pixels.show();
}
}
Here I show you the result of the connection between the 2 plates. We can see that when the motion sensor detects movement, it changes the color of the neopixel from green to red. Here are some videos of the results.
To achieve the message between the 2 boards via WIFI, we decided to communicate between 2 XIAO ESP32 C3 microcontrollers, where Silvana's board worked as a subscriber, since it contained the neopixel as output and my board worked as a publisher, with a switch that I have. on the board to send messages via MQTTX. To achieve communication we use MQTTX, where we must have a publisher (my board) and a subscriber (silvana's board), where the latter receives information from the publisher, processes and performs the action that was programmed. Here I leave the work process between both plates. First we connect both boards to a different computer and begin to program it so that they have communication between them via MQTTX.
For programming, both boards have the XIAO ESP32 C3, where we previously carried out tests on the input and output that we were going to communicate. From there we created a TOPIC in the MQTTX to be able to read the message sent by the publisher and the subscriber read those messages and performed an action.
#include WiFi.h
#include PubSubClient.h
const char* ssid = "YourSSID";
const char* password = "YourPassword";
const char* mqtt_server = "broker.emqx.io";
const char* topic = "week13/wifi"; // Topic
const int switchPin = D2; // Switch Pin
WiFiClient espClient;
PubSubClient client(espClient);
int lastSwitchState = HIGH; // Previous switch state
void setup() {
Serial.begin(115200);
pinMode(switchPin, INPUT_PULLUP);
setup_wifi();
client.setServer(mqtt_server, 1883);
}
void setup_wifi() {
delay(10);
Serial.println();
Serial.print("Connecting to ");
Serial.println(ssid);
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
Serial.println("");
Serial.println("WiFi connected");
Serial.println("IP Address: ");
Serial.println(WiFi.localIP());
}
void reconnect() {
while (!client.connected()) {
Serial.print("Connecting to MQTT server...");
if (client.connect("switchClient")) {
Serial.println("Connected");
} else {
Serial.print("failed, rc=");
Serial.print(client.state());
Serial.println(" trying again in 5 seconds");
delay(5000);
}
}
}
void loop() {
if (!client.connected()) {
reconnect();
}
client.loop();
int switchState = digitalRead(switchPin);
if (switchState != lastSwitchState) { // If there's a change in switch state
if (switchState == LOW) {
client.publish(topic, "a");
Serial.println("Switch pressed");
} else {
client.publish(topic, "b");
Serial.println("Switch released");
}
lastSwitchState = switchState;
}
delay(100); // Small delay to avoid switch bounce
}
#include WiFi.h
#include PubSubClient.h
#include Adafruit_NeoPixel.h
const char* ssid = "YourSSID";
const char* password = "YourPassword";
const char* mqtt_server = "broker.emqx.io";
const char* topic = "week13/wifi"; // same topic to publisher
#define NEOPIXEL_PIN D10
#define NUM_PIXELS 1
WiFiClient espClient;
PubSubClient client(espClient);
Adafruit_NeoPixel pixels(NUM_PIXELS, NEOPIXEL_PIN, NEO_GRB + NEO_KHZ800);
void setup() {
Serial.begin(115200);
setup_wifi();
client.setServer(mqtt_server, 1883);
client.setCallback(callback);
pixels.begin();
}
void setup_wifi() {
delay(10);
Serial.println();
Serial.print("Connecting to ");
Serial.println(ssid);
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
Serial.println("");
Serial.println("WiFi connected");
Serial.println("IP Address: ");
Serial.println(WiFi.localIP());
}
void callback(char* topic, byte* payload, unsigned int length) {
String message = "";
for (int i = 0; i < length; i++) {
message += (char)payload[i];
}
Serial.print("Message received from topic ");
Serial.print(topic);
Serial.print(": ");
Serial.println(message);
if (message == "a") {
pixels.setPixelColor(0, pixels.Color(255, 0, 0)); // Red
pixels.show();
} else {
pixels.setPixelColor(0, pixels.Color(0, 255, 0)); // Green
pixels.show();
}
}
void reconnect() {
while (!client.connected()) {
Serial.print("Connecting to MQTT server...");
if (client.connect("neopixelClient")) {
Serial.println("Connected");
client.subscribe(topic);
} else {
Serial.print("Failed, rc=");
Serial.print(client.state());
Serial.println(" trying again in 5 seconds");
delay(5000);
}
}
}
void loop() {
if (!client.connected()) {
reconnect();
}
client.loop();
}
Here I show you the result of the connection between the 2 plates. We can see that when the motion sensor detects movement, it changes the color of the neopixel from green to red. Here are some videos of the results.
In this step it is crucial to activate sharing within your account, as interaction will be required. An invitation was made to another person, in my case a colleague from Fabacademy
Once sharing is enabled, we proceed to create the dashboard, device and thing on the Arduino IoT Cloud platform and then configure them according to our needs.
Once the interaction is configured and created, which can include anything from an LED to actuators, the next step is to configure the WiFi credentials, password and security key. Subsequently, we proceed to load the program into the XIAO ESP32 with the desired interaction
A key lesson I learned in this activity was the importance of making sure the Arduino Cloud virtual agent is installed correctly. I did not initially notice this detail, as the program loading seemed successful, but the final installation did not complete. I later discovered that I had completely skipped installing the necessary agent. Once I installed the agent correctly, everything ran smoothly and was ready to test.
For this assignment I worked with my colleague Maria Angela Mejia, she will use a servo motor in her project and I will use an infrared sensor in my project.
We thought we could make an interesting remote connection between our devices using the MQTT protocol.
We start by choosing the mqtt application that we are going to use.
We start by choosing the MQTTX application. You can visit their website to start using it.
MQTTX is an open-source, cross-platform MQTT 5.0 desktop client initially developed by EMQ, which can run on macOS, Linux, and Windows.
The user interface (UI) of MQTTX adopts a chat-based layout, simplifying operational logic. It enables users to establish multiple MQTT connections, thereby facilitating swift testing of MQTT/MQTTS connections, as well as message subscription and publication.
We begin to download the application.
We select the software according to our operating system and install it using the default configuration.
In my case I use Windows and install X86-64
Once the application is installed, we open it and create a new connection.
1. We must give our connection a name, this field is required.
We can leave all other fields by default.
2. Once the name has been set, we proceed to connect it.
We will see that when we connect it will show us:
1. The name of the connection we assumed.
2. Client ID.
3. the button to disconnect.
Now that we are connected, we will be prompted to add a new subscription.
1. Now we must create a mandatory topic. In this exercise we will use: cristian/test1
We can leave the other fields by default.
2. we confirm
In order to publish we must:
1. select the type of data that we are going to send.
2. Write the Topic in which we want to publish.
3. Write the message.
4. Publish.
My colleague Maria Angela Mejia followed the same steps:
1. Added a subscription to the same topic cristian/test1.
2. received a welcome message in Spanish that says "Greetings Maria Angela"
My colleague Maria Angela Mejia responds with a message in Spanish that says: "hello Cristian." With this message we confirm the two-way communication through the mqtt protocol, each one being in a different place in the city of Lima.
It is time to test the connection of the infrared sensor and the servo motor, I will write code in Arduino for the operation of the infrared sensor and Maria Angela will write code in Arduino for the servo motor.
When the infrared sensor detects an object, it will send a signal for the micro servo motor to rotate 90° and return to its place.
We write the code in Arduino and make sure to install the PubSubClient library, we will use the Xiao ESP32C3 microcontroller.
We will connect to the broker to publish the information collected by the infrared sensor and we will send the number "1" as a published message.
#include <WiFi.h> #include <PubSubClient.h> const char* ssid = "MOVISTAR_0CD0"; // Replace with your SSID const char* password = "6pN5745BmUSLphq"; // Replace with your password const char* mqtt_server = "broker.emqx.io"; WiFiClient espClient; PubSubClient client(espClient); const int sensorPin = D8; // Infrared sensor Pin void setup() { Serial.begin(115200); pinMode(sensorPin, INPUT); setup_wifi(); client.setServer(mqtt_server, 1883); } void setup_wifi() { delay(10); Serial.println(); Serial.print("Connecting to "); Serial.println(ssid); WiFi.begin(ssid, password); while (WiFi.status() != WL_CONNECTED) { delay(500); Serial.print("."); } Serial.println(""); Serial.println("WiFi connected"); Serial.println("IP address: "); Serial.println(WiFi.localIP()); } void loop() { if (!client.connected()) { reconnect(); } client.loop(); int sensorState = digitalRead(sensorPin); if (sensorState == HIGH) { Serial.println("Object detected"); client.publish("cristian/test1", "1"); delay(1000); // Wait to avoid multiple quick posts } } void reconnect() { while (!client.connected()) { Serial.print("Attempting MQTT connection..."); if (client.connect("ESP32Client")) { Serial.println("connected"); } else { Serial.print("failed, rc="); Serial.print(client.state()); Serial.println(" try again in 5 seconds"); delay(5000); } } }
In Arduino we upload the code to the XIAO ESP32C3 microcontroller and connect to the Wi-Fi network.
The connection result was satisfactory and we are ready to publish a message when the sensor captures a signal.
Prueba del sensor infrarojo con el microcontrolador XIAO ESP32C3, cada vez que detecta un objeto se enciende la luz LED verde y envia una señal "1".
As we can see, we performed the object detection test, published the message and it was received successfully, causing the servo motor to rotate 90° and return to its place.
Final result, the servomotor moves after receiving the published signal via MQTT protocol using MQTTX....how cool!!!...
What I learned?
- It doesn't matter where you are as long as there is an internet signal you can control devices in different parts of the world.
- The importance of this communication protocol for the Internet of Things IOT.
- There are many mqtt services, we must see which one serves our needs.
- you can control a large number of devices.
- The services of this protocol are increasingly more practical to use and not much programming knowledge is needed.