Skip to content

nopnop2002/esp-idf-vcp2udp

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

9 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

esp-idf-vcp2udp

VCP to UDP bridge for ESP-IDF.

Image

ESP-IDF supports VCP hosts.
VCP hosts can communicate with VCP devices using the USB port.
Representative VCP devices include Arduino Uno and Arduino Mega, which have a UART-USB conversion chip.
I based it on this.

This project uses the following components.
Other UART-USB converter chips are not supported.

Software requirements

ESP-IDF V5.0 or later.
ESP-IDF V4.4 release branch reached EOL in July 2024.

Hardtware requirements

ESP32-S2/S3

This project only works with ESP32S2/S3.
The ESP32S2/S3 has USB capabilities.

USB Type-A Femail connector

USB connectors are available from AliExpress or eBay.
I used it by incorporating it into a Universal PCB.
USBConnector

We can buy this breakout on Ebay or AliExpress.
usb-conector-11 usb-conector-12

Installation

git clone https://github.com/nopnop2002/esp-idf-vcp2udp
cd esp-idf-vcp2udp
idf.py set-target {esp32s2/esp32s3}
idf.py menuconfig
idf.py flash

Configuration

Image Image

WiFi Setting

Set the information of your access point.
Image

VCP Setting

Set the information of VCP Connection.
Image

UDP Setting

Set the information of UDP Connection.
Image

There are the following four methods for specifying the UDP Address.

  • Limited broadcast address
    The address represented by 255.255.255.255, or <broadcast>, cannot cross the router.
    Both the sender and receiver must specify a Limited broadcast address.

  • Directed broadcast address
    It is possible to cross the router with an address that represents only the last octet as 255, such as 192.168.10.255.
    Both the sender and receiver must specify the Directed broadcast address.
    Note that it is possible to pass through the router.

  • Multicast address
    Data is sent to all PCs belonging to a specific group using a special address (224.0.0.0 to 239.255.255.255) called a multicast address.
    I've never used it, so I don't know anything more.

  • Unicast address
    It is possible to cross the router with an address that specifies all octets, such as 192.168.10.41.
    Both the sender and receiver must specify the Unicast address.

Write this sketch on Arduino Uno.

You can use any AtMega microcontroller that has a USB port.

unsigned long lastMillis = 0;

void setup() {
  Serial.begin(115200);
}

void loop() {
  while (Serial.available()) {
    String command = Serial.readStringUntil('\n');
    Serial.println(command);
  }

  if(lastMillis + 1000 <= millis()){
    Serial.print("Hello World ");
    Serial.println(millis());
    lastMillis += 1000;
  }

  delay(1);
}

Strings from Arduino to ESP32 are terminated with CR(0x0d)+LF(0x0a).

I (1482) VCP: Receiving data through CdcAcmDevice
I (1482) VCP: 0x3fcba0a8   48 65 6c 6c 6f 20 57 6f  72 6c 64 20 36 36 30 30  |Hello World 6600|
I (1492) VCP: 0x3fcba0b8   30 0d 0a                                          |0..|

The Arduino sketch inputs data with LF as the terminator.
So strings from the ESP32 to the Arduino must be terminated with LF (0x0a).
If the string output from the ESP32 to the Arduino is not terminated with LF (0x0a), the Arduino sketch will complete the input with a timeout.
The default input timeout for Arduino sketches is 1000 milliseconds.
If the string received from UDP does not have a LF at the end, this project will add a LF to the end and send it to Arduino.
The Arduino sketch will echo back the string it reads.

I (78212) VCP: Sending data through CdcAcmDevice
I (78222) VCP: 0x3fcb7930   61 62 63 64 65 66 67 0a                           |abcdefg.|
I (78232) VCP: Receiving data through CdcAcmDevice
I (78232) VCP: 0x3fcba0a8   61 62 63 64 65 66 67 0d  0a                       |abcdefg..|

Wireing

Arduino Uno connects via USB connector.
The USB port on the ESP32S2/S3 development board does not function as a USB-HOST.

+---------+  +-------------+  +-----------+
|ESP BOARD|==|USB CONNECTOR|==|Arduino Uno|
+---------+  +-------------+  +-----------+
ESP BOARD          USB CONNECTOR (type A)
                         +--+
5V        -------------> | || VCC
[GPIO19]  -------------> | || D-
[GPIO20]  -------------> | || D+
GND       -------------> | || GND
                         +--+

Image

Windows Application

I used this app.
This application runs both a UDP-Listener (UDP-Server) and a UDP-Client simultaneously.

  • Listen from ESP32
    Specify the port number and press the Start Listening button.
    This application works as a UDP-Listener (UDP-Server) and communicates with the UDP-Client of ESP32.
    Image
    Image

  • Send to ESP32
    Specify the IP Address of ESP32 and port number and press the Send button.
    This application works as a UDP-Client and communicates with the UDP-Server of ESP32.
    Image
    Instead of an IP address, you can use an mDNS hostname.
    Image

We can use this app.
This application runs both a UDP-Listener (UDP-Server) and a UDP-Client simultaneously.
Image

Python script

udp-client.py is UDP-Client.
udp-server.py is UDP-Listener (UDP-Server).

Linux Application

I searched for a GUI tool that can be used with ubuntu or debian, but I couldn't find one.

Android Application

I used this app.
Image

Using linux rsyslogd as logger

We can forward the USB input to rsyslogd on your Linux machine.

+-------------+         +-------------+         +-------------+ 
| Arduino Uno |--(USB)->|    ESP32    |--(UDP)->|  rsyslogd   |
+-------------+         +-------------+         +-------------+ 

Configure with port number = 514.
Image

The rsyslog server on linux can receive logs from outside.
Execute the following command on the Linux machine that will receive the logging data.
Please note that port 22 will be closed when you enable ufw.
I used Ubuntu 22.04.

$ cd /etc/rsyslog.d/

$ sudo vi 99-remote.conf
module(load="imudp")
input(type="imudp" port="514")

if $fromhost-ip != '127.0.0.1' and $fromhost-ip != 'localhost' then {
    action(type="omfile" file="/var/log/remote")
    stop
}

$ sudo ufw enable
Firewall is active and enabled on system startup

$ sudo ufw allow 514/udp
Rule added
Rule added (v6)

$ sudo ufw allow 22/tcp
Rule added
Rule added (v6)

$ sudo systemctl restart rsyslog

$ ss -nulp | grep 514
UNCONN 0      0            0.0.0.0:514        0.0.0.0:*
UNCONN 0      0               [::]:514           [::]:*

$ sudo ufw status
Status: active

To                         Action      From
--                         ------      ----
514/udp                    ALLOW       Anywhere
22/tcp                     ALLOW       Anywhere
514/udp (v6)               ALLOW       Anywhere (v6)
22/tcp (v6)                ALLOW       Anywhere (v6)

UART input goes to /var/log/remote.

$ tail -f /var/log/remote
Jun  6 11:05:04 Hello World 6721000
Jun  6 11:05:05 Hello World 6722000
Jun  6 11:05:06 Hello World 6723000
Jun  6 11:05:07 Hello World 6724000
Jun  6 11:05:08 Hello World 6725000
Jun  6 11:05:09 Hello World 6726000
Jun  6 11:05:10 Hello World 6727000
Jun  6 11:05:11 Hello World 6728000
Jun  6 11:05:12 Hello World 6729000
Jun  6 11:05:13 Hello World 6730000
Jun  6 11:05:14 Hello World 6731000
Jun  6 11:05:15 Hello World 6732000

One advantage of using rsyslogd is that you can take advantage of log file rotation.
Rotating log files prevents the log files from growing forever.
The easiest way to rotate logs is to add /var/log/remote to /etc/logrotate.d/rsyslog.
There are many resources available on the Internet about rotating log files.

$ ls -l /var/log/remote*
-rw-r--r-- 1 syslog syslog    6264 Jun  6 10:35 /var/log/remote
-rw-r--r-- 1 syslog syslog 1219823 Jun  6 10:33 /var/log/remote.1

About

VCP to UDP bridge for ESP-IDF

Topics

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published