This week’s personal assignment was to read and understand the data sheet of a microcontroller as well as perform a simulation of the microcontroller in use.
Here’s also the link to our group assignment of this week.
The languages used in embedded programming are c/cc++ and python.
A microcontroller unit (MCU) is essentially a small computer on a single chip. It is designed to manage specific tasks within an embedded system without requiring a complex operating system (Schnider & Smalley, n.d.).
I’ll be using Wokwi for this simulation, so before starting with the simulation we will learn how to use it. For this I’ll be using the RP2040 microcontroller.
You can know certain features with its name like this:
Before choosing any microcontroller, the first thing you can do is go through its datasheet, and see if it works for the type of project that you are developing. Some features you can take into account are these:
You can find the datasheet used here
| FEATURE | RP2040 |
|---|---|
| SRAM | 264 kB |
| Flash Memory | Not internal; supports up to 16 MB |
| GPIO Pins | 30 multifunction GPIO pins |
| Analog Inputs | 4 ADC inputs (12-bit, up to 500 ksps) |
| Communication | 2× UART, 2× SPI, 2× I²C, USB 1.1 Host/Device, Programmable I/O (PIO) |
| Languages | C/C++, MicroPython (official SDK support) |
| Wireless | Not included |
Now, let’s run a small test using Wokwi for our simulation.
Now, let’s make a simulation related to my project.
After researching different microcontrollers for my project, one of my main options is the ESP32. I have not made the final decision yet, but I chose this microcontroller because it has integrated Wi-Fi and Bluetooth, offers high processing power, and is well suited for interactive projects.
You can find the datasheet used here
| FEATURE | ESP32 | Why it matters |
|---|---|---|
| CPU | Dual-core Xtensa LX6 up to 240 MHz | High processing power for multitasking and real-time control |
| SRAM | 520 kB on-chip SRAM | Allows more complex programs and buffering |
| Flash Memory | External flash (commonly 4 MB) | Enough space for firmware and libraries |
| GPIO Pins | Up to 34 programmable GPIOs | Supports multiple sensors and actuators |
| Analog Inputs | Up to 18 ADC channels (12-bit) | Good for reading analog sensors |
| Wireless | Wi-Fi 802.11 b/g/n + Bluetooth (Classic & BLE) | Enables IoT connectivity without extra modules |
| Communication | UART, SPI, I²C, I²S, CAN | Flexible connection with peripherals |
| Low-Power Modes | Light sleep, Deep sleep, Hibernation | Important for battery-powered projects |
| Special Features | Touch sensors, PWM, RTC, ULP coprocessor | Useful for interactive and low-power designs |
| Languages | C/C++, MicroPython, Arduino framework | Flexible development ecosystem |

First, open Wokwi and select the ESP option.
From the available boards, select the ESP32, which will be the microcontroller used in this project.
This project requires an IMU, so we need to add one. Click the “+” button to open the components menu and search for the MPU6050 sensor.
Make the following connections:
With the hardware connected, we can proceed to implement the C++ code that appears after this section.
Don't forget to install the "MPU6050" library for it to run properly.
Here you can see all the steps altogether
#include <Wire.h>
#include <MPU6050.h>
#include <BLEDevice.>
#include <BLEServer.>
#include <BLEUtils.>
#include <BLE2902.>
MPU6050 mpu;
BLECharacteristic *pCharacteristic;
bool deviceConnected = false;
void setup() {
Serial.begin(115200);
Wire.begin(21, 22); // SDA, SCL
// ----- MPU -----
Serial.println("Inicializando MPU6050...");
mpu.initialize();
if (mpu.testConnection()) {
Serial.println("MPU6050 conectado correctamente");
} else {
Serial.println("Error de conexión con MPU6050");
}
// ----- BLE -----
BLEDevice::init("FajaPerritoBLE");
BLEServer *pServer = BLEDevice::createServer();
BLEService *pService = pServer->createService("1234");
pCharacteristic = pService->createCharacteristic(
"5678",
BLECharacteristic::PROPERTY_NOTIFY
);
pCharacteristic->addDescriptor(new BLE2902());
pService->start();
BLEAdvertising *pAdvertising = BLEDevice::getAdvertising();
pAdvertising->start();
Serial.println("BLE listo para conectar");
}
void loop() {
int16_t ax, ay, az;
int16_t gx, gy, gz;
mpu.getMotion6(&ax, &ay, &az, &gx, &gy, &gz);
long movimiento = abs(ax) + abs(ay) + abs(az - 16384);
Serial.print("Movimiento: ");
Serial.print(movimiento);
// -------- ACTIVIDAD --------
if (movimiento > 2000) {
Serial.print(" | EN MOVIMIENTO");
} else {
Serial.print(" | QUIETO");
}
// -------- POSTURA --------
Serial.print(" | Postura: ");
String mensaje;
if (az > 14000) {
mensaje = "NORMAL";
Serial.println("NORMAL (de pie)");
}
else if (az > 6000) {
mensaje = "INCLINADO";
Serial.println("INCLINADO");
}
else {
mensaje = "ACOSTADO";
Serial.println("ACOSTADO o CAIDA");
}
// ----- ENVIO BLE -----
pCharacteristic->setValue(mensaje.c_str());
pCharacteristic->notify();
delay(500);
}