Embedded Networking and Communications
Group Assignment:
send a message between two projects
Document your work to the group work page and reflect on your individual page what you learned
Individual Assignment:
design, build and connect wired or wireless node(s) with network or bus addresses and a local input and/or output devices
Have you answered these questions?
Linked to the group assignment page ✅
Documented your project and what you have learned from implementing networking and/or communication protocols. ✅
Explained the programming process(es) you used.✅
Ensured and documented that your addressing for boards works.✅
Outlined problems and how you fixed them.✅
Included design files (or linked to where they are located if you are using a board you have designed and fabricated earlier) and original source code. ✅
Included a ‘hero shot’ of your network and/or communications setup. ✅
Group assignment
send a message between two projects
Document your work to the group work page and reflect on your individual page what you learned
In this group project, Jhonatan and I collaborated on a project that involved using MQTT technology to integrate components like a servomotor, RGB LED, and a buzzer. Even though we were in different countries, remote communication was key to completing the task. My project involved programming a neopixel, while Jhonatan worked with a servomotor and automated control systems. We learned to overcome distance and apply the MQTT protocol to manage communication between devices efficiently.
Here is the link to learn more about the group project.
Reflections
In this group project, we worked with the implementation of MQTT technology to facilitate communication between different devices. Using this lightweight messaging protocol, we were able to establish a communication network between Jhonatan's servomotor and the neopixel integrated into my project. MQTT's ability to efficiently manage data transmission between remote devices was essential for the successful execution of the assigned tasks.
During the development, I faced the challenge of coordinating the programming of a neopixel and its integration into a network communication system, which involved precise interaction with the physical components. Through this experience, I deepened my understanding of standard communication protocols, recognizing the importance of synchronization between connected systems and how it impacts the overall performance of the project.
Additionally, remote collaboration allowed me to improve my skills in managing distributed teams, a crucial aspect in technological projects. I learned to optimize real-time communication, use shared development tools, and coordinate tasks efficiently to ensure both projects progressed smoothly. This experience emphasized the importance of system interoperability and teamwork in distributed development environments.
Individual assignment
design, build and connect wired or wireless node(s) with network or bus addresses and a local input and/or output devices
We started week 11, and the great Ulises gave us a masterclass on Embedded Networking and Communications. In the video, he provides a detailed explanation of the MQTT protocol, programming to make sensors and modules work, the roles of publishers and subscribers, and how to manage the Arduino IDE development environment.
Link to watch the video.
MQTT Protocol
MQTT consists of several layers within networking and communication. Networks enable the interconnection of devices in various configurations, facilitating communication between them. Communication protocols operate at different layers of the OSI model. The transport layer, such as TCP (Transmission Control Protocol), is responsible for ensuring the reliable transmission of data between devices. Meanwhile, the network layer, such as IP (Internet Protocol), handles packet addressing across the network.
MQTT operates in the application layer, which is a higher layer in the OSI model. This means that MQTT relies on transport protocols like TCP for message transmission between devices. Within the communication protocols, MQTT uses a broker, which is a central server that facilitates communication between devices such as sensors, controllers, and users.
In this system, topics are variables that represent messages or communication channels. Devices can publish messages to a specific topic or subscribe to a topic to receive updates. Topics help organize and manage the flow of messages between devices efficiently.
1. Download MQTT
The first thing I do is go to the website MQTTand click on the "Download" button.
I select the "Desktop" option, and in my case, I choose the "x86-64" version.
The download starts, and I install the program on my computer.
Done! The program is installed, so let's get started.
I open a new connection. Here, I explain the step-by-step process using rectangles and green arrows.
As soon as the new connection opens, a screen appears with mandatory fields that must be filled out, as this information will allow others in different locations to make connections via MQTT. In the "name" field, I enter practicaMQTT. The host I’m using is EMQX.IO, which is the server, and the port would be 1883. The port is very important as it will allow others to connect through it.
Now, I click on "New Subscriber".
Here, in the "topic" field, I enter a name that is easy to remember and that another person can also use to be connected in the network, so we can both act as subscribers and publishers.
Done. In the lower part, I select plaintext. This format means the message will be sent as plain text, without any special formatting or additional encoding, making it easier to read and understand the content. Then, I type "Hello World" and click on Send.
Now I’ve posted the message to the topic, and as expected, I received the message on the same device. This confirms that the communication between the publisher and the subscriber is working correctly. The message I sent, in this case "Hello World", was transmitted through the MQTT broker, and I was able to receive it right after I posted it.
Now, with this, the MQTT protocol can be understood more clearly. If someone publishes a message to the topic fabacademy/neopixel, all the people who are subscribed to that topic will receive the same information, creating a broadcast communication through the broker. The publisher sends the message to the MQTT broker, and the subscribers, being connected to the same broker and subscribed to the relevant topic, will automatically receive the information. Additionally, subscribers also have the ability to send information back to the MQTT broker, enabling bidirectional communication.
In this process, the MQTT broker plays a crucial role in managing the distribution of messages between publishers and subscribers, ensuring that the information reaches all interested devices correctly. This model is efficient because it minimizes the communication load by transmitting only the relevant messages to subscribers interested in a specific topic.
2. Development of applications with MQTT on platforms like Arduino, ESP32.
Subscriber
For this project, I will use the Xiao ESP32-C3 board, as indicated in week 4. This board has the advantage of being able to connect to Wi-Fi thanks to its built-in Wi-Fi module based on IEEE 802.11 b/g/n, making it ideal for IoT (Internet of Things) applications. The ESP32-C3 board is one of the more affordable and compact variants within the ESP32 family, equipped with a RISC-V based microcontroller that offers efficient performance and low power consumption. This allows connected devices to communicate wirelessly, easily handling both local and remote tasks.
Now, I open the Arduino IDE and input the NeoPixel code to test and ensure that it functions correctly. The code will control a set of NeoPixel LEDs through the communication protocol, ensuring that the connection and LED control work properly via the ESP32-C3.
#include // No install, it's ready
#include // Install library PubSubClient
#include // Install Adafruit NeoPixel library
// Setup your WIFI with SSID/Password
const char* ssid = "CHAYITOPOWER";
const char* password = "CHIHUAY123";
// Setup your MQTT Protocol
const char* mqttServer = "broker.emqx.io";
const char* mqttClient = "evkusi";
const char* mqttTopicSub = "fabacademy/neopixel";
WiFiClient espClient;
PubSubClient client(espClient);
// Setup NeoPixel Pin
#define PIN A0 // Pin de datos al que está conectada la tira NeoPixel
#define NUM_PIXELS 30 // Número de LEDs en la tira (ajústalo a tus necesidades)
#define BRILLO 255 // Brillo máximo (puedes ajustar este valor)
Adafruit_NeoPixel strip(NUM_PIXELS, PIN, NEO_GRB + NEO_KHZ800);
// Variable to handle MQTT messages
String mqttMessage = "";
void setup() {
Serial.begin(115200);
// Connecting to Wifi
Serial.print("Connecting to ");
Serial.println(ssid);
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
Serial.println("");
Serial.println("Connected with IP ");
Serial.println(WiFi.localIP());
// Setup MQTT
client.setServer(mqttServer, 1883);
client.setCallback(callback);
// Initial connection to MQTT
connectMQTT();
// Setup NeoPixel
strip.begin();
strip.show(); // Apaga todos los LEDs al inicio
}
void callback(char* topic, byte* message, unsigned int length) {
String messageTemp = "";
for (int i = 0; i < length; i++) {
messageTemp += (char)message[i];
}
Serial.print("Arrived on ");
Serial.print(topic);
Serial.print(" the message ");
Serial.println(messageTemp);
// Store the message to process in the loop
mqttMessage = messageTemp;
// Create algorithm for controlling LEDs
if (String(topic) == mqttTopicSub) {
if (mqttMessage == "on") {
strip.fill(strip.Color(0, 255, 0)); // Verde
strip.show();
}
else if (mqttMessage == "off") {
strip.fill(strip.Color(0, 0, 0)); // Apagar
strip.show();
}
else if (mqttMessage == "random") {
cambiarColorAleatorio();
}
}
}
void connectMQTT() {
while (!client.connected()) {
Serial.print("Connecting to MQTT Server... ");
if (client.connect(mqttClient)) {
Serial.println("Connected");
// Subscribe to the MQTT topic
client.subscribe(mqttTopicSub);
} else {
Serial.print("Failed, rc=");
Serial.print(client.state());
Serial.println(" Try again in 5 seconds");
delay(5000);
}
}
}
void loop() {
if (!client.connected()) {
connectMQTT();
}
client.loop();
}
// Function to set a random color to all NeoPixels
void cambiarColorAleatorio() {
for (int i = 0; i < strip.numPixels(); i++) {
// Generate random values for red, green, and blue (from 0 to 255)
int rojo = random(0, 256);
int verde = random(0, 256);
int azul = random(0, 256);
// Set the color of each LED with the random values
strip.setPixelColor(i, strip.Color(rojo, verde, azul));
}
strip.show(); // Update the strip with the new colors
}
This is the code I use to control the NeoPixel.
Done! Now, I go to the File menu and click on Preferences. In this menu, I can adjust various settings of the Arduino IDE, such as compilation options, the preferences file location, and management of additional URLs for board and library managers. This step is important to correctly add the necessary URLs for the library installation and to ensure that the development environment is properly set up.
In Preferences, I click on the icon where two small squares appear. This icon allows me to open the advanced settings window, where I can add or modify the URLs needed to install additional libraries and boards. By clicking this icon, I can paste the library link I copied earlier so that Arduino IDE can access the necessary files and install it correctly.
In Additional Boards Manager URLs, I paste the link I copied earlier and then click OK. This adds the URL to the Arduino IDE, allowing the program to access the necessary installation packages for the board and library I am using. After this, the URL will be registered and ready to be used for installing the corresponding libraries.
Now, I go to the menu in the sidebar by clicking on the second icon. There, I search for the ESP32 microcontroller. This step is necessary to select the correct board in the Arduino IDE development environment. Once I find ESP32, I can choose the specific board model I am using, in this case, the Xiao ESP32-C3, to ensure that the code compiles and uploads correctly to the board.
Now, in the main menu, I go to Tools, select the Board option, and within the ESP32 submenu, I search for the Xiao ESP32-C3 board. This is necessary to properly configure the program, ensuring that the code compiles and uploads correctly to the specific board I am using. By selecting Xiao ESP32-C3, I ensure that the Arduino IDE development environment is set up for this particular board, allowing everything to work properly.
Previously, I connect my PCB board to the NeoPixel. This involves connecting the output pin of the board to the data pin of the NeoPixel strip, ensuring that the power (VCC) and ground (GND) are also properly connected. This way, I ensure that the communication between the board and the LEDs is stable, and the data is transmitted correctly to control the colors and effects.
Once the board and NeoPixel are connected, I configure the program and connect it to the available Wi-Fi network by entering the corresponding password. Other important elements to configure are the server, in this case emqx.io, the client name, which in my case is evkusi, and the topic to which I will be subscribed, which is fabacademy/neopixel. These configurations allow the board to connect properly to the MQTT broker and receive or send messages through the corresponding topic.
In the sidebar menu, I click on the third icon, search for the PubSubClient library, and install it. This library is essential for communication with the MQTT broker, as it provides the necessary functions for the device to act as a publisher or subscriber and send or receive messages via MQTT.
I click on Verify to compile the code and make sure there are no errors. This step is important because it allows me to check if the programming and the required libraries are properly configured before uploading the code to the board. After verifying, I click on Upload to upload the code to the same Xiao ESP32-C3 board.
Done, the message "Done compiling" appears, which means the code has compiled correctly.
Did I have complications while doing this assignment?
Yes, I had some issues, but ChatGPT helped me improve and follow some steps I had forgotten. One of the issues was installing the necessary library to ensure everything worked properly. Thanks to ChatGPT's guidance, I was able to solve that problem and continue with the process.
Done, I entered the MQTT program to perform a test. When I set it to ON, the NeoPixel lit up in green, and when I set it to OFF, it turned off. Also, when I selected RANDOM, the LEDs started lighting up in different colors, which confirms that the communication with the MQTT server and the control of the LEDs are working correctly through the sent messages.
Now, the subscriber is working correctly, as it is stored in the memory of the Xiao ESP32-C3 board. Now, I need to configure the publisher so that it works correctly as well.
Publish
For the publisher, I will use an infrared sensor module that I will connect to my PCB. This sensor will be responsible for detecting signals, and upon receiving an action (such as pressing a button), it will send a message to the MQTT broker. In this way, the publisher will interact with the subscriber and send data effectively.
#include // Librería WiFi
#include // Librería para el protocolo MQTT
#include // Librería NeoPixel
// Configuración WiFi
const char* ssid = "CHAYITOPOWER";
const char* password = "CHIHUAY123";
// Configuración MQTT
const char* mqttServer = "broker.emqx.io";
const char* mqttClient = "grullas";
const char* mqttTopicPub = "fabacademy/neopixel"; // Tema de publicación
WiFiClient espClient;
PubSubClient client(espClient);
// Configuración de NeoPixel
#define SENSOR_PIN D10 // Pin del sensor IR
#define NEOPIXEL_PIN 4 // Pin de datos para el NeoPixel (ajustado al pin 4)
#define NUM_PIXELS 1 // Solo un LED
#define BRILLO 255 // Brillo máximo
Adafruit_NeoPixel strip(NUM_PIXELS, NEOPIXEL_PIN, NEO_GRB + NEO_KHZ800);
// Variables para el control de tiempo y estados
int varNum = 0;
long nowTime, lastTime;
String status = "off"; // Estado inicial del LED
void setup() {
Serial.begin(115200);
// Conectar a WiFi
Serial.print("Conectando a WiFi ");
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
Serial.println(" Conectado");
Serial.println("IP: " + WiFi.localIP().toString());
// Conectar a MQTT
client.setServer(mqttServer, 1883);
connectMQTT();
// Inicializar el NeoPixel
strip.begin();
strip.show(); // Apagar el LED al inicio
// Configurar pin del sensor IR
pinMode(SENSOR_PIN, INPUT);
}
void connectMQTT() {
Serial.print("Conectando a servidor MQTT ... ");
while (!client.connected()) {
if (client.connect(mqttClient)) {
Serial.println("Conectado");
} else {
Serial.print("fallo, rc=");
Serial.print(client.state());
Serial.println(" Reintentando en 5 segundos");
delay(5000);
}
}
client.subscribe(mqttTopicPub); // Suscribirse al tema (si es necesario)
}
void loop() {
if (!client.connected()) {
connectMQTT();
}
client.loop();
nowTime = millis();
// Enviar un mensaje cada 5 segundos
if (nowTime - lastTime > 5000) {
lastTime = nowTime;
varNum = varNum + 1;
// Alternar entre "on" y "off" según el contador
if (varNum % 2) {
status = "on";
} else {
status = "off";
}
char numString[8];
strncpy(numString, status.c_str(), sizeof(numString));
Serial.print("Variable numérica: ");
Serial.println(varNum);
client.publish(mqttTopicPub, numString); // Publicar el estado del LED
}
// Leer el valor del sensor IR
int estado = digitalRead(SENSOR_PIN);
if (estado == LOW) {
// Si el sensor detecta un obstáculo, enciende el LED
Serial.println("¡Obstáculo detectado!");
strip.setPixelColor(0, strip.Color(255, 0, 0)); // LED rojo
strip.show();
client.publish(mqttTopicPub, "on"); // Publicar estado "on"
} else {
// Si no hay obstáculo, apaga el LED
Serial.println("Sin obstáculo.");
strip.setPixelColor(0, strip.Color(0, 0, 0)); // Apagar LED
strip.show();
client.publish(mqttTopicPub, "off"); // Publicar estado "off"
}
delay(1000); // Espera medio segundo antes de la siguiente lectura
}
For the publisher code, I also connect it to the same Wi-Fi network with its corresponding password. The server I use is emqx.io, and I assign a different name to the client, in this case, grullas. This is done to avoid any interference or complications when saving the configuration and ensuring that it works correctly. The topic will be the same as the one used by the subscriber so that both can communicate properly over the network. In this case, the topic is fabacademy/neopixel.
The code is ready, and I proceed to verify it in the same application.
Did I have complications?
Yes, I had some again, so I asked ChatGPT to fix the errors. After making the corrections, I verified the code again and then uploaded it (Upload) to the ESP32-C3 microcontroller.
All of this is achieved through the Internet connection, which allows both the subscriber and the publisher to communicate via the MQTT protocol. Both ESP32-C3 microcontrollers are connected to the same Wi-Fi network, allowing them to exchange signals effectively. The subscriber receives the signal sent by the publisher through the MQTT server (in this case, emqx.io), enabling remote communication without cables, thanks to the Internet connection.
Both in MQTT and Arduino IDE, the sensor worked very well.
El programa que utiliza el suscriptor y el publicador está funcionando correctamente, pero ahora el objetivo es que ambos estén conectados a través de una red de Internet, sin necesidad de usar una sola placa. Por lo tanto, es necesario crear una segunda placa que me ayude a cumplir con los requerimientos de este proyecto.
Steps to design the second board:
1. Design of a board
The first step was to open KiCad and create a basic design for a second board.
Now, I am creating a port that connects 5V, GND, 3V, and two pins. This will allow me to connect to the infrared sensor.
Now that this is done, I move on to designing the PCB. Once the design is complete, I export it using the plotter function and save the file. If you want to learn more about these steps, feel free to visit the following link. week 06
2. CNC Router
For this practice, I used the 1220 mm x 2440 mm router, which is quite large, but I didn’t have the necessary equipment to efficiently carry out this project.
For this, I used the ArtCAM software to convert the file saved in DXF format to G-code. Then, I ran several tests with the iFurniture router from the Fab Lab.
Since the design was simple, I took the opportunity to make a half dozen. My instructor, Cristian, who was supervising me, was really enjoying the process, but I always prioritized safety before potentially ruining another board. The milling turned out great; some lines were a bit thin, but overall it was very good.
Now, I proceeded to take measurements with the multimeter to ensure everything was correct.
And really, I’m glad I made several because it took me a while to solder.
Did I face difficulties?
Yes, I did have some problems. The solder I had was too thick, 0.8 mm, and the pliers were also thick. Furthermore, the tip of the soldering iron wasn’t heating properly, only the sides of the tip heated up, which made the soldering process much harder.
But in the end, this practice was very useful because I was able to improve my technique and solder the last board I had with more efficiency.
3. CNC Router PCB
It turns out that my instructor Cristian told me there were some CNC routers for PC, but they were broken, so we also decided to try them out to see what would happen. Honestly, I was quite nervous, crossing my fingers to make progress and finish this assignment.
So we proceeded to download a program that would help us fabricate another PCB board in bakelite.
Do you want to know which program we used? I leave the link here.
For this, it is also necessary to download Java for the program to work.
Once that was done, we started with the program 🤞.
Now, let's leave this little machine to work its magic! ✨
The design was simple, but it turned out great! I could say it came out much better than what we cut with the CNC router.
And for this board, I already had a bit more experience with soldering.
Now I securely connect the pins and proceed to do the final exercise with both boards.
3. Final result: Communication between the subscriber and the publisher over the Wi-Fi network.
Now, what I did according to the NeoPixel code and the infrared sensor code was to connect both to the same Wi-Fi network and with the same password. What changed was the client name: for the NeoPixel subscriber, the name was "evkusi," and for the infrared sensor publisher, it was "grullas." This allowed both networks to connect properly.
Great! Now it works correctly. 🎉
This assignment was connected to my home internet network. The board connected to the NeoPixel was plugged into a socket, while the other board was being powered from my computer.
Reflections
In this project, I learned to implement the MQTT protocol for communication between devices. Through the setup of a broker and using an ESP32-C3 as a subscriber, I was able to connect a neopixel and manage the transmission of messages efficiently. This protocol facilitated communication between devices through topics, where the publisher sends a message and the subscribers receive it, optimizing data distribution in distributed networks.
During the implementation, I worked with Arduino IDE and various libraries to control the neopixel via the MQTT protocol. This allowed me to understand how to integrate Wi-Fi connectivity with IoT communication and how to manage the receiving and sending of messages through an MQTT server. This experience improved my programming skills and my ability to design communication networks for electronic devices.
Finally, this project taught me the importance of interoperability and efficiency in communication systems. The use of MQTT enabled effective bidirectional communication and reduced data overload by transmitting only relevant information to the subscribed devices. This experience provided me with a clearer vision of how devices can interact efficiently in an Internet of Things (IoT) environment.