Are you interested in making a remote-controlled car using ESP32 and NodeMCU? In this project, we will use a joystick module to control a car wirelessly. This is a fun and simple way to explore ESP-NOW communication and motor control!
What You Need
To build this joystick-controlled car, you will need:
ESP32 (for the remote controller)
NodeMCU (ESP8266) (for the car)
Joystick module
L298N motor driver
Two DC motors (500 RPM Johnson motors)
Two wheels (70mm diameter, 20mm width)
LM2596 voltage regulator (to power NodeMCU)
Power source (3S battery or similar)
Jumper wires
How It Works
The ESP32 reads joystick movements and sends commands wirelessly using ESP-NOW.
The NodeMCU receives these commands and controls the motors accordingly.
The car moves forward, backward, left, and right based on joystick input.
Wiring Connections
Remote (ESP32 + Joystick Module)
Joystick VCC → ESP32 3.3V
Joystick GND → ESP32 GND
Joystick X-axis → ESP32 GPIO 34
Joystick Y-axis → ESP32 GPIO 35
Car (NodeMCU + L298N Motor Driver + Motors)
Motor 1 IN1 → NodeMCU D1
Motor 1 IN2 → NodeMCU D2
Motor 2 IN1 → NodeMCU D3
Motor 2 IN2 → NodeMCU D4
Motor 1 ENA → NodeMCU D5
Motor 2 ENB → NodeMCU D6
LM2596 Output (3.3V/5V) → NodeMCU Vin
LM2596 Ground → NodeMCU GND
ESP32 Code for the Remote
#include <esp_now.h>
#include <WiFi.h>
// Define DEBUG to enable or disable serial debug statements
//#define DEBUG // Comment this line to disable debug statements
const int xPin = 34; // X-axis connected to GPIO 34
const int yPin = 35; // Y-axis connected to GPIO 35
// Define thresholds for dead zone (adjust as needed)
const float DEAD_ZONE_THRESHOLD = 0.2; // Joystick values within ±0.2V are considered centered
uint8_t broadcastAddress[] = {0xCC, 0x50, 0xE3, 0x0D, 0x15, 0x09};
typedef struct struct_message {
char command[32];
int b;
} struct_message;
struct_message myData;
esp_now_peer_info_t peerInfo;
void OnDataSent(const uint8_t *mac_addr, esp_now_send_status_t status) {
#ifdef DEBUG
Serial.print("\r\nLast Packet Send Status:\t");
Serial.println(status == ESP_NOW_SEND_SUCCESS ? "Delivery Success" : "Delivery Fail");
#endif
}
void setup() {
#ifdef DEBUG
Serial.begin(115200);
#endif
WiFi.mode(WIFI_STA);
if (esp_now_init() != ESP_OK) {
#ifdef DEBUG
Serial.println("Error initializing ESP-NOW");
#endif
return;
}
esp_now_register_send_cb(OnDataSent);
memcpy(peerInfo.peer_addr, broadcastAddress, 6);
peerInfo.channel = 0;
peerInfo.encrypt = false;
if (esp_now_add_peer(&peerInfo) != ESP_OK) {
#ifdef DEBUG
Serial.println("Failed to add peer");
#endif
return;
}
}
void loop() {
int xValue = analogRead(xPin); // Read X-axis value
int yValue = analogRead(yPin); // Read Y-axis value
float xVoltage = (xValue * 3.3) / 4095; // Convert to voltage (0-3.3V)
float yVoltage = (yValue * 3.3) / 4095; // Convert to voltage (0-3.3V)
#ifdef DEBUG
Serial.print("X Voltage: "); Serial.print(xVoltage);
Serial.print(" | Y Voltage: "); Serial.println(yVoltage);
#endif
// Check if the joystick is within the dead zone (centered)
if (abs(xVoltage - 1.65) < DEAD_ZONE_THRESHOLD && abs(yVoltage - 1.65) < DEAD_ZONE_THRESHOLD) {
strcpy(myData.command, "S"); // Stop (centered)
myData.b = 0; // No movement
}
// Check for movement outside the dead zone
else if (xVoltage > (1.65 + DEAD_ZONE_THRESHOLD)) {
strcpy(myData.command, "F"); // Forward
myData.b = xVoltage;
} else if (xVoltage < (1.65 - DEAD_ZONE_THRESHOLD)) {
strcpy(myData.command, "B"); // Backward
myData.b = xVoltage;
} else if (yVoltage > (1.65 + DEAD_ZONE_THRESHOLD)) {
strcpy(myData.command, "L"); // Left
myData.b = yVoltage;
} else if (yVoltage < (1.65 - DEAD_ZONE_THRESHOLD)) {
strcpy(myData.command, "R"); // Right
myData.b = yVoltage;
}
// Send the command via ESP-NOW
esp_err_t result = esp_now_send(broadcastAddress, (uint8_t *) &myData, sizeof(myData));
#ifdef DEBUG
if (result == ESP_OK) {
Serial.println("Sent with success");
} else {
Serial.println("Error sending the data");
}
#endif
delay(20); // Small delay to make output readable
}
NodeMCU Code for the Car
#include <ESP8266WiFi.h>
#include <espnow.h>
// Structure to receive data
typedef struct struct_message {
char a[32];
int b;
float c;
bool d;
} struct_message;
struct_message myData;
// Pin definitions
#define LED_PIN 2 // Onboard LED pin (D4 on ESP8266)
#define M1_ENA D5 // Motor 1 PWM (Speed)
#define M2_ENB D6 // Motor 1 PWM (Speed)
#define M1_IN1 D1 // Motor 1 input 1
#define M1_IN2 D2 // Motor 1 input 2
#define M2_IN1 D3 // Motor 2 input 1
#define M2_IN2 D4 // Motor 2 input 2
// Default speeds (adjust these values experimentally)
int speedLeft = 800; // 0-1023 (80% speed)
int speedRight = 700; // Right motor slightly slower
// Callback function when data is received
void OnDataRecv(uint8_t *mac, uint8_t *incomingData, uint8_t len) {
memcpy(&myData, incomingData, sizeof(myData));
Serial.print("Bytes received: ");
Serial.println(len);
Serial.print("Data received: ");
Serial.println(myData.a);
Serial.print("value received: ");
Serial.println(myData.b);
// Control motors based on received character
if (strcmp(myData.a, "F") == 0) {
// Move forward
analogWrite(M1_ENA, speedLeft);
analogWrite(M2_ENB, speedRight);
digitalWrite(M1_IN1, HIGH); digitalWrite(M1_IN2, LOW);
digitalWrite(M2_IN1, HIGH); digitalWrite(M2_IN2, LOW);
digitalWrite(LED_PIN, LOW); // Turn on LED (inverted logic on ESP8266)
} else if (strcmp(myData.a, "B") == 0) {
// Move backward
analogWrite(M1_ENA, speedLeft);
analogWrite(M2_ENB, speedRight);
digitalWrite(M1_IN1, LOW); digitalWrite(M1_IN2, HIGH);
digitalWrite(M2_IN1, LOW); digitalWrite(M2_IN2, HIGH);
digitalWrite(LED_PIN, HIGH); // Turn off LED (inverted logic on ESP8266)
} else if (strcmp(myData.a, "L") == 0) {
// Turn left
analogWrite(M1_ENA, speedLeft);
analogWrite(M2_ENB, speedRight);
digitalWrite(M1_IN1, LOW); digitalWrite(M1_IN2, HIGH);
digitalWrite(M2_IN1, HIGH); digitalWrite(M2_IN2, LOW);
} else if (strcmp(myData.a, "R") == 0) {
// Turn right
analogWrite(M1_ENA, speedLeft);
analogWrite(M2_ENB, speedRight);
digitalWrite(M1_IN1, HIGH); digitalWrite(M1_IN2, LOW);
digitalWrite(M2_IN1, LOW); digitalWrite(M2_IN2, HIGH);
}
else if (strcmp(myData.a, "S") == 0) {
// Turn right
analogWrite(M1_ENA, 0);
analogWrite(M2_ENB, 0);
digitalWrite(M1_IN1, HIGH); digitalWrite(M1_IN2, LOW);
digitalWrite(M2_IN1, LOW); digitalWrite(M2_IN2, HIGH);
} else {
// Stop motors
analogWrite(M1_ENA, 0);
analogWrite(M2_ENB, 0);
// digitalWrite(M1_IN1, LOW); digitalWrite(M1_IN2, LOW);
// digitalWrite(M2_IN1, LOW); digitalWrite(M2_IN2, LOW);
}
}
void setup() {
// Initialize Serial Monitor
Serial.begin(115200);
// Initialize pins
pinMode(LED_PIN, OUTPUT);
pinMode(M1_IN1, OUTPUT);
pinMode(M1_IN2, OUTPUT);
pinMode(M2_IN1, OUTPUT);
pinMode(M2_IN2, OUTPUT);
// Ensure motors and LED are off initially
digitalWrite(LED_PIN, HIGH); // LED off (inverted logic on ESP8266)
digitalWrite(M1_IN1, LOW); digitalWrite(M1_IN2, LOW);
digitalWrite(M2_IN1, LOW); digitalWrite(M2_IN2, LOW);
// Set device as a Wi-Fi Station
WiFi.mode(WIFI_STA);
// Initialize ESP-NOW
if (esp_now_init() != 0) {
Serial.println("Error initializing ESP-NOW");
return;
}
// Register the receive callback
esp_now_set_self_role(ESP_NOW_ROLE_SLAVE);
esp_now_register_recv_cb(OnDataRecv);
}
void loop() {
// Nothing to do here
}
How to Upload the Code
Upload the remote code to your ESP32.
Upload the car code to your NodeMCU.
Power up both devices and check serial monitor outputs for debugging.
Testing the Car
Move the joystick forward → The car moves forward.
Move the joystick backward → The car moves backward.
Move the joystick left → The car turns left.
Move the joystick right → The car turns right.
Release the joystick (center position) → The car stops.
3d Printed parts
Since when i made this car. I had Johnson motors of 500RPM. But i did not had any bracket so i designed the brackets in FreeCAD and printed on Creality ender 3 v3 KE printer.
I bought the printer from wol3d’s New Delhi office. I am a electronics guy but i have inclination towards the 3d printing world. The feeling that you can design and make something in front of you. It’s a slow process but this printer comes with a slicer software which is fast.
Build Volume : 220 x 220 x 240 mm
The best thing is the auto bed leveling on this printer. I do not have to adjust the four corner bolts and rub a paper under the nozzle. It is done automatically done.
Till now the results are amazing.
I have noticed that the prints depends upon a lot of things:
Filament Quality : I have used a few filaments samples i got my hand on they were old and new. The old one which are above one year old open packet are just brittle they clog the printer every now and then. and one time it was so break while in the extruder which set my heart racing as i don’t want new printer to clog and change its nozzle. Thankfully the nozzle clogged removed when i inserted the fresh PLA and forced it into the extruder. So yes always use new filament. And also some filament are bad weather they are new or old.
Kartoffeln Bockshornkleeblätter Rezept auf Deutsch
Zutaten:
Kartoffeln (Aloo) – 3 mittelgroße, geschält und in kleine Würfel geschnitten
Bockshornkleeblätter (Methi) – 2 Tassen, frisch und gehackt
Öl – 2-3 Esslöffel
Kreuzkümmelsamen (Jeera) – 1 Teelöffel
Asafoetida (Hing) – eine Prise (optional)
Grüne Chilis – 2, fein gehackt (je nach Geschmack anpassen)
Knoblauch – 3-4 Zehen, gehackt (optional, aber geschmackvoll)
Korianderpulver (Dhaniya) – 1 Teelöffel
Salz – nach Geschmack
Anleitung:
Bockshornkleeblätter vorbereiten: Die Bockshornkleeblätter gründlich waschen, um Schmutz zu entfernen, und fein hacken. Beiseitestellen.
Öl erhitzen: Öl in einer Pfanne oder einem Topf bei mittlerer Hitze erhitzen.
Gewürze hinzufügen: Kreuzkümmelsamen in das heiße Öl geben und anbraten, bis sie anfangen zu knistern. Optional Asafoetida hinzufügen.
Knoblauch und Chilis anbraten: Gehackten Knoblauch und grüne Chilis dazugeben. Anbraten, bis der Knoblauch goldbraun wird.
Kartoffeln kochen: Die gewürfelten Kartoffeln hinzufügen. Gut vermischen und mit Korianderpulver würzen. Alles gleichmäßig vermengen.
Abdecken und kochen: Die Pfanne abdecken und die Kartoffeln bei niedriger bis mittlerer Hitze etwa 7-10 Minuten kochen lassen. Gelegentlich umrühren, damit nichts anbrennt.
Bockshornkleeblätter hinzufügen: Sobald die Kartoffeln halb gar sind, die gehackten Bockshornkleeblätter hinzufügen. Gut vermischen.
Zusammen kochen: Wieder abdecken und weitere 5-7 Minuten kochen lassen, dabei gelegentlich umrühren, bis die Kartoffeln weich sind und die Bockshornkleeblätter gut eingearbeitet sind.
Abschmecken: Mit Salz abschmecken und gut vermischen. Noch eine Minute kochen lassen.
Servieren: Vom Herd nehmen und heiß mit Roti, Paratha oder Reis servieren.
Guten Appetit! 😊
Ingredients:
Potatoes (Aloo) – 3 medium-sized, peeled and diced into small cubes
Fenugreek Leaves (Methi) – 2 cups, fresh and chopped
Oil – 2-3 tablespoons
Cumin Seeds (Jeera) – 1 teaspoon
Asafoetida (Hing) – a pinch (optional)
Green Chilies – 2, finely chopped (adjust to taste)
Garlic – 3-4 cloves, minced (optional but adds flavor)
Coriander Powder (Dhaniya) – 1 teaspoon
Salt – to taste
Instructions:
Prepare Fenugreek Leaves: Wash the methi leaves thoroughly to remove dirt and chop them finely. Set aside.
Heat Oil: Heat oil in a pan or kadai on medium heat.
Add Aromatics: Add cumin seeds and let them splutter. Add a pinch of asafoetida if using.
Sauté Garlic and Chilies: Add the minced garlic and green chilies. Sauté until the garlic turns golden.
Cook Potatoes: Add the diced potatoes to the pan. Mix well and add coriander powder. Stir everything to coat the potatoes evenly with spices.
Cover and Cook: Cover the pan and let the potatoes cook on low-medium heat for about 7-10 minutes, stirring occasionally to prevent sticking.
Add Fenugreek Leaves: Once the potatoes are partially cooked, add the chopped methi leaves. Mix well.
Cook Together: Cover and cook for another 5-7 minutes, stirring occasionally, until the potatoes are fully cooked and the methi leaves are well incorporated.
Season: Add salt and mix well. Cook for another minute.
Serve: Remove from heat and serve hot with roti, paratha, or rice.
#define led 2
void setup() {
// put your setup code here, to run once:
pinMode(2, OUTPUT);
}
void loop() {
// put your main code here, to run repeatedly:
digitalWrite(led, 1);
delay(1000);
digitalWrite(led, 0);
delay(200);
}
OpenCV, or Open Source Computer Vision Library, is a powerful and widely-used open-source computer vision and machine learning software library. It provides a plethora of tools and functions for image and video processing, making it an essential resource for developers, researchers, and hobbyists. Installing OpenCV on a Windows system can be a straightforward process when using the Python package manager, pip. In this article, we’ll walk you through the steps to install OpenCV on your Windows machine using pip.
Prerequisites:
Before diving into the installation process, ensure that you have the following prerequisites:
A Windows operating system.
Python installed on your machine. You can download the latest version of Python from the official website: https://www.python.org/downloads/.
Installation Steps:
Follow these step-by-step instructions to install OpenCV using pip in Windows:
Step 1: Open a Command Prompt
Press Win + R to open the Run dialog, type cmd, and press Enter. This will open the Command Prompt.
Step 2: Upgrade pip
Ensure that your pip is up-to-date by running the following command:
pip install --upgrade pip
This ensures that you have the latest version of pip installed.
Step 3: Install NumPy
NumPy is a prerequisite for OpenCV, as it is used for numerical operations. Install it by running:
pip install numpy
Step 4: Install OpenCV
Now, you can install the OpenCV package using the following command:
pip install opencv-python
This command will download and install the latest stable version of OpenCV along with its dependencies.
Step 5: Verify the Installation
To ensure that OpenCV has been successfully installed, open a Python interpreter or create a simple Python script and import the cv2 module:
import cv2
print(cv2.__version__)
This should print the installed OpenCV version, confirming that the installation was successful.
#define m1p 7
#define m1n 6
#define m2p 5
#define m2n 4
#define echopin 9
#define trigpin 10
void motor_forward();
void motor_stop();
void motor_left();
void motor_right();
void motor_back();
void setup() {
// put your setup code here, to run once:
Serial.begin(9600);
pinMode(m1p, OUTPUT);
pinMode(m1n, OUTPUT);
pinMode(m2p, OUTPUT);
pinMode(m2n, OUTPUT);
pinMode(echopin, INPUT);
pinMode(trigpin, OUTPUT);
}
long duration, distance;
void loop() {
// put your main code here, to run repeatedly:
digitalWrite(trigpin, LOW);
delayMicroseconds(2);
digitalWrite(trigpin, HIGH);
delayMicroseconds(10);
digitalWrite(trigpin, LOW);
duration = pulseIn(echopin, HIGH);
distance = (duration *0.0343 / 2);
Serial.println(distance);
// Serial.println(" cm");
//delay(1000);
//Serial.println(distance); //print data serially
if (distance > 25) { // if distance is more than 25 move bot forward
motor_forward();
delay(20);
motor_forward();
}
else {
// motor_stop();
//delay(500);
// motor_back();
// delay(3000);
motor_stop(); // if distance is less than 25 move bot right
delay(50);
motor_back();
delay(100);
motor_right();
delay(100);
}
}
void motor_back(){
digitalWrite(m1p, LOW);
digitalWrite(m1n, HIGH);
digitalWrite(m2p, HIGH);
digitalWrite(m2n, LOW);
}
void motor_forward(){
digitalWrite(m1p, HIGH);
digitalWrite(m1n, LOW);
digitalWrite(m2p, LOW);
digitalWrite(m2n, HIGH);
}
void motor_stop(){
digitalWrite(m1p, LOW);
digitalWrite(m1n, LOW);
digitalWrite(m2p, LOW);
digitalWrite(m2n, LOW);
}
void motor_left(){
digitalWrite(m1p, HIGH);
digitalWrite(m1n, LOW);
digitalWrite(m2p, LOW);
digitalWrite(m2n, LOW);
}
void motor_right(){
digitalWrite(m1p, LOW);
digitalWrite(m1n, LOW);
digitalWrite(m2p, HIGH);
digitalWrite(m2n, LOW);
}
Code Explanation
The code is a simple obstacle avoidance program for a robot using an ultrasonic sensor and two motors. Let’s break down the code and explain each section:
In this section, the code defines constants for motor pins (m1p, m1n, m2p, m2n) and pins for the ultrasonic sensor (echopin for echo and trigpin for trigger).
Here, the code declares five functions (motor_forward, motor_stop, motor_left, motor_right, motor_back) that will be used to control the movement of the robot.
In the loop function, the ultrasonic sensor is triggered to measure the distance. If the measured distance is greater than 25, the robot moves forward. Otherwise, it stops, moves back a bit, and then turns right.
These functions define the motor control logic for moving the robot in different directions. For example, motor_forward makes the robot move forward by setting the appropriate motor pins.
In summary, this code implements a basic obstacle avoidance mechanism for a robot using an ultrasonic sensor. If the robot detects an obstacle within 25 cm, it stops, moves back a bit, and then turns right. Otherwise, it continues moving forward. The motor control is achieved through the defined functions that set the appropriate pin states for the motor driver.
Arduino, with its user-friendly environment and a vast array of libraries, opens up a world of possibilities for electronic enthusiasts and hobbyists. One of the key features that makes Arduino a versatile platform is the ability to use interrupts. In this blog post, we will explore the use of attachInterrupt() in the Arduino IDE to toggle an LED with the press of a button.
Understanding attachInterrupt()
The attachInterrupt() function in Arduino is a powerful tool that allows you to execute a specified function (interrupt service routine or ISR) when a certain condition occurs on a digital pin. This capability is particularly useful for handling external events without constantly polling the pin in the main loop, thus improving efficiency and responsiveness.
Before we delve into the code, let’s gather the necessary components for this project:
Arduino board (e.g., Arduino Uno)
LED
Resistor (220-330 ohms)
Push button
Jumper wires
Wiring the Circuit
Connect the components as follows:
Connect the longer leg of the LED (anode) to a current-limiting resistor (220-330 ohms) then the other end of the resistor to pin A2 on the Arduino.
Connect the shorter leg of the LED (cathode) GND on the Arduino.
Connect one side of the push button to pin 2 on the Arduino.
Connect the other side of the push button to the GND on the Arduino.
The Arduino Sketch
Now, let’s dive into the Arduino sketch that utilizes attachInterrupt() to toggle the LED state when the button is pressed.
int led=A2;
int button=2;
volatile byte state = LOW;
void setup()
{
pinMode(LED_BUILTIN, OUTPUT);
pinMode(led, OUTPUT);
pinMode(button, INPUT_PULLUP);
attachInterrupt(digitalPinToInterrupt(2),blink,CHANGE);
}
void blink()
{
state = !state;
}
void loop()
{
digitalWrite(led, !state);
}
Breaking Down the Code
We define led and button as the respective pin numbers for the LED and the push button.
volatile byte state is a variable that holds the state of the LED, and it’s marked as volatile to indicate that it can be modified in an ISR.
In the setup() function, we set the LED pin and button pin modes. Additionally, we attach an interrupt to the button using attachInterrupt(), specifying the function blink to be executed on a state change (CHANGE) of the button pin.
The blink() function toggles the state variable when the interrupt is triggered.
In the loop() function, we continuously update the LED state based on the value of the state variable.
1 Tasse Kidneybohnen über Nacht (mindestens 8 Stunden) in 3-4 Tassen Wasser einweichen.
Kochen Sie die Kidneybohnen in einem Schnellkochtopf. Wenn Sie einen Schnellkochtopf im indischen Stil haben, warten Sie mindestens fünf Pfiffe.
Bereiten Sie das Masala vor A. Öl in einer Pfanne erhitzen B. Fügen Sie Kreuzkümmel hinzu und warten Sie, bis er seine Farbe ändert (lassen Sie ihn nicht schwarz werden). C. Gehackten Knoblauch und Ingwer hinzufügen und braten, bis sie eine hellbraune Farbe haben. D. Zwiebeln dazugeben und anbraten, bis sie leicht goldbraun sind. e. Trockene Gewürze, Nelken, schwarzen Pfeffer, rotes Chilipulver, grünes Korianderpulver und Kurkuma hinzufügen F. Lassen Sie die Mischung 30–45 Sekunden lang bei mittlerer Hitze kochen. G. Gehackte Tomaten hinzufügen und die Mischung braten, bis sich das Öl trennt
Die gekochten Kidneybohnen zum Masala hinzufügen
Weitere 10-15 Minuten kochen lassen
Mit Reis oder Roti servieren.
Kidney Bean(Rajma) Recipe
Ingredients
1 cup kidney bean 1 medium onion(chopped) 1 small ginger(chopped) 2-3 cloves of garlic(chopped) 2 Tomatoes(chopped)
Dry Spices: Cumin 2 cloves 5-6 Black pepper red chilli powder green coriander powder turmeric salt
Method
Soak the 1 cup Kidney Bean overnight(at least 8 hours) in 3-4 cup of water.
Cook the Kidney Bean in a pressure cooker. If you have a indian style pressure cooker wait at least 5 whistles.
Prepare the Masala a. Heat Oil in a pan b. Add Cumin and wait till it changes colour(Do not let it turn Black) c. Add chopped garlic and ginger and fry till they are light brown in colour. d. Add Onions and fry till they are slightly golden brown. e. Add dry spices cloves, black pepper, red chilli powder, green coriander powder, turmeric f. Let the mixture cook for 30-45 seconds on a medium heat. g. Add chopped tomatoes and fry the mixture till the oil separates
From the schematics, we see that there are three pins associated with the USB port. 1. PA11 2. PA12 3. PD2
The Pins PA11 and PA12 are PA11 – USB D- PA12 – USB D+
These two pins will be configured by the stm32cube ide when you enable the USB device.
PD2 should be configured as GPIO pin. Because the USB FS implementation says to pull up the D+ line to 3.3V. The pull up is performed by the S8550 PNP transistor. So by making the PD2 pin LOW, we enable the USB FS, since it makes the D+ pull up.
We also need to select the Communication Device Class as Class For FS IP.
After configuring the cube mx project. we can proceed to generate code.
The code needs to add the following header file
/* USER CODE BEGIN Includes */
#include "usbd_cdc_if.h"
#include "string.h"
/* USER CODE END Includes */
and then in the main() function. you can write this code in while loop
/* USER CODE BEGIN 2 */
HAL_GPIO_WritePin(GPIOD, GPIO_PIN_2, GPIO_PIN_RESET);
/* USER CODE END 2 */
/* USER CODE BEGIN WHILE */
uint8_t *data = "Hello World from USB CDC\r\n";
while (1)
{
CDC_Transmit_FS(data, strlen(data));
HAL_Delay (1000);
/* USER CODE END WHILE */
/* USER CODE BEGIN 3 */
}
/* USER CODE END 3 */
After uploading the code to your microcontroller. It will be displayed in your windows device manager as “USB Serial Device”.
You can Connect to the Com port using the serial terminal software such as YAT, Putty or CoolTerm etc. Note: Since it is a virtual com port, you dont have to set a specific baud rate.