the following uses a W5500 connected to a Heltec LoRa V3 to transmit data over LoRa P2P and over Ethernet using UDP datagrams
file main.ino
// Heltec LoRa SX1262 transmit test
// File>Examples>RadioLib>SX126x>SX126x_Transmit_Interrupt
// EDITs:
// radio.begin frequency set to 868.0
// transmitting byte array and printing it
/*
RadioLib SX126x Transmit with Interrupts Example
This example transmits LoRa packets with one second delays
between them. Each packet contains up to 256 bytes
of data, in the form of:
- Arduino String
- null-terminated char array (C-string)
- arbitrary binary data (byte array)
Other modules from SX126x family can also be used.
For default module settings, see the wiki page
https://github.com/jgromes/RadioLib/wiki/Default-configuration#sx126x---lora-modem
For full API reference, see the GitHub Pages
https://jgromes.github.io/RadioLib/
*/
// include the library
#include <RadioLib.h>
#include "ESP32_UDP_transmit.h"
// Heltec LoRa V3 SX1262 has the following connections:
// NSS pin: 8
// DIO1 pin: 14
// NRST pin: 12
// BUSY pin: 13
SX1262 radio = new Module(8, 14, 12, 13);
// or detect the pinout automatically using RadioBoards
// https://github.com/radiolib-org/RadioBoards
/*
#define RADIO_BOARD_AUTO
#include <RadioBoards.h>
Radio radio = new RadioModule();
*/
// save transmission state between loops
int transmissionState = RADIOLIB_ERR_NONE;
// flag to indicate that a packet was sent
volatile bool transmittedFlag = false;
// this function is called when a complete packet
// is transmitted by the module
// IMPORTANT: this function MUST be 'void' type
// and MUST NOT have any arguments!
#if defined(ESP8266) || defined(ESP32)
ICACHE_RAM_ATTR
#endif
void setFlag(void) {
// we sent a packet, set the flag
transmittedFlag = true;
}
void setup() {
Serial.begin(115200);
delay(2000);
W5500setup(); // setup W5500 Erthernet
// initialize SX1262 with default settings
Serial.print(F("\n\nHeltec LoRa V3 [SX1262] Initializing ... "));
int state = radio.begin(868.0);
if (state == RADIOLIB_ERR_NONE) {
Serial.println(F("success!"));
} else {
Serial.print(F("failed, code "));
Serial.println(state);
while (true) { delay(10); }
}
// set the function that will be called
// when packet transmission is finished
radio.setPacketSentAction(setFlag);
// start transmitting the first packet
Serial.print(F("[SX1262] Sending first packet ... "));
// you can transmit C-string or Arduino string up to
// 256 characters long
transmissionState = radio.startTransmit("Hello World!");
// you can also transmit byte array up to 256 bytes long
/*
byte byteArr[] = {0x01, 0x23, 0x45, 0x67,
0x89, 0xAB, 0xCD, 0xEF};
state = radio.startTransmit(byteArr, 8);
*/
}
// counter to keep track of transmitted packets
int count = 0;
void loop() {
// check if the previous LoRa transmission finished
if (transmittedFlag) {
// reset flag
transmittedFlag = false;
if (transmissionState == RADIOLIB_ERR_NONE) {
// packet was successfully sent
Serial.println(F("transmission finished!"));
// NOTE: when using interrupt-driven transmit method,
// it is not possible to automatically measure
// transmission data rate using getDataRate()
} else {
Serial.print(F("failed, code "));
Serial.println(transmissionState);
}
// clean up after transmission is finished
// this will ensure transmitter is disabled,
// RF switch is powered down etc.
radio.finishTransmit();
// wait before transmitting again
delay(5000);
// send another one
Serial.print(F("[SX1262] Sending another packet ... "));
// you can transmit C-string or Arduino string up to
// 256 characters long
//String str = "Hello World! #" + String(count++);
//transmissionState = radio.startTransmit(str);
// you can also transmit byte array up to 256 bytes long
static byte byteArr[] = { 0x01, 0x23, 0x45, 0x67,
0x89, 0xAB, 0xCD, 0xEF };
for (int i = 0; i < sizeof(byteArr); i++)
Serial.printf("0x%02X ", byteArr[i]);
transmissionState = radio.startTransmit(byteArr, 8);
byteArr[0]++;
W5500loop(byteArr); // transmit W5500 Ethernet
}
}
file ESP32_UDP_transmit.h (in same directory as main.ino)
// ESP32_UDP_transmit.h UDP ESP32 W5500 ethernet transmit test data
#ifndef ESP32_UDP_TRANSMIT
#define ESP32_UDP_TRANSMIT
// function prototypes
void W5500setup(void);
void W5500loop(byte *byteArr);
void displayIPaddress(const IPAddress address, unsigned int port);
void displayMACaddress(byte address[]);
#endif
file ESP32_UDP_transmit.cpp (in same directory as main.ino)
// ESP32_UDP_transmit.cpp UDP ESP32 W5500 ethernet transmit test data
// UDP chat program using ESP32-ETH01 tested on UNO and Nano
// **** change IP addresses and ports to suit requirements *****
#include <EthernetESP32.h>
#include <EthernetUdp.h> // for UDP
#include "ESP32_UDP_transmit.h" // include W5500 ethernet header file
// define Heltec LoRa V3 W5500 SPI pins
#define W5500_SCK 40
#define W5500_MISO 42
#define W5500_MOSI 39
#define W5500_CS 41
W5500Driver driver(W5500_CS); // SPI SS is GPIO34
SPIClass hspi(HSPI); // HSPI object used by W5500
// ***** IP of this machine and remote machine *********
IPAddress localIP(192, 168, 1, 167); // local static localIP address
IPAddress remoteIP(192, 168, 1, 65); // local static localIP address
// Enter a MAC address
byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0x32 };
unsigned int localPort = 999; //10000; // local port to listen on
unsigned int remotePort = 999; //10000; // remote port to transmiit too
// An EthernetUDP instance to let us send and receive packets over UDP
EthernetUDP Udp;
void W5500setup(void) {
// Open serial communications and wait for port to open:
Serial.begin(115200);
delay(2000);
while (!Serial)
;
Serial.println("\n\nUDP ESP32 ethernet transmit test data ");
hspi.begin(W5500_SCK, W5500_MISO, W5500_MOSI, W5500_CS);
driver.setSPI(hspi); // specify driver SPI interface
Ethernet.init(driver); // for ESP32-ETH01
Serial.println("Initialize Ethernet with DHCP:");
if (Ethernet.begin()) {
Serial.print(" DHCP assigned IP ");
Serial.println(Ethernet.localIP());
} else {
Serial.println("Failed to configure Ethernet using DHCP");
Ethernet.begin(localIP);
Serial.print("configured Ethernet static IP ");
Serial.println(Ethernet.localIP());
// while (true) {
// delay(1);
}
if (Udp.begin(localPort)) // start UDP
Serial.print("Ethernet UDP started ");
else Serial.println("UDP begin() failed!");
displayIPaddress(Ethernet.localIP(), localPort);
}
void W5500loop(byte* byteArr) {
Serial.print("\n Transmitting datagram to ");
displayIPaddress(remoteIP, remotePort);
Udp.beginPacket(remoteIP, remotePort); // send to remote localIP and port 999
Udp.write((const uint8_t*)byteArr, 8);
Udp.endPacket();
delay(10);
}
// read IP address from keyboard and check it
IPAddress getIPaddress(const char* prompt) {
IPAddress ip;
while (1) { // read IP (end with new line)
Serial.print(prompt);
while (Serial.available() == 0) delay(10);
char text[40] = { 0 };
Serial.readBytesUntil('\n', (char*)text, 40);
for (int i = 0; i < 40; i++)
if (text[i] < ' ') text[i] = 0; // remove CR or LF
Serial.print(text);
if (ip.fromString(text)) break; // if IP OK break while
Serial.println(" invalid IP try again");
}
return ip;
}
// print IPAdress and port
void displayIPaddress(const IPAddress address, unsigned int port) {
Serial.print(" IP ");
Serial.print(address);
Serial.print(" port ");
Serial.println(port);
}
void displayMACaddress(byte address[]) {
Serial.print("MAC address ");
for (int i = 0; i < 6; i++) {
Serial.print("0x");
Serial.print(address[i], HEX);
if (i < 5) Serial.print(".");
}
Serial.println();
}
Heltec serial monitor output
UDP ESP32 ethernet transmit test data
Initialize Ethernet with DHCP:
DHCP assigned IP 192.168.1.245
Ethernet UDP started IP 192.168.1.245 port 999
Heltec LoRa V3 [SX1262] Initializing ... success!
[SX1262] Sending first packet ... transmission finished!
[SX1262] Sending another packet ... 0x01 0x23 0x45 0x67 0x89 0xAB 0xCD 0xEF
Transmitting datagram to IP 192.168.1.65 port 999
transmission finished!
[SX1262] Sending another packet ... 0x02 0x23 0x45 0x67 0x89 0xAB 0xCD 0xEF
Transmitting datagram to IP 192.168.1.65 port 999
transmission finished!
[SX1262] Sending another packet ... 0x03 0x23 0x45 0x67 0x89 0xAB 0xCD 0xEF
Transmitting datagram to IP 192.168.1.65 port 999
transmission finished!
[SX1262] Sending another packet ... 0x04 0x23 0x45 0x67 0x89 0xAB 0xCD 0xEF
Transmitting datagram to IP 192.168.1.65 port 999
transmission finished!
[SX1262] Sending another packet ... 0x05 0x23 0x45 0x67 0x89 0xAB 0xCD 0xEF
Transmitting datagram to IP 192.168.1.65 port 999
transmission finished!
[SX1262] Sending another packet ... 0x06 0x23 0x45 0x67 0x89 0xAB 0xCD 0xEF
Transmitting datagram to IP 192.168.1.65 port 999
transmission finished!
[SX1262] Sending another packet ... 0x07 0x23 0x45 0x67 0x89 0xAB 0xCD 0xEF
Transmitting datagram to IP 192.168.1.65 port 999
Java program to receive and display UDP datagrams
// UDPchat.java - simple peer-to-peer chat program using UDP
// - given remote IP address can send strings using UDP datagrams
// - will also wait for datagrams and display contents
// remote IP and port are specified via command line - default IP is 127.0.0.1 (i.e. localhost) and port is 1000
//
// e.g. to send datagrams to IP 146.227.59.130 port 1006
// java chat 146.227.59.130 1006
import java.io.*;
import java.util.*;
import java.net.*;
public class UDPchat extends Thread
{
private final static BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
int port=10000;//999;//10001;// 100006 // port to send/receive datagrams on
String remoteIPaddress= "192.168.1.176";//"169.254.144.20";//("192.168.1.8");//127.0.0.1"); // IP to send datagrams
// constructor, parameter is command line parameters
public UDPchat(String args[]) throws Exception
{
// get remote IP address and port from command line parameters
if (args.length > 0) remoteIPaddress = (args[0]); // get IPaddress
if (args.length > 1) port = Integer.parseInt(args[1]); // get port number
System.out.println("chat program: IP address " + InetAddress.getLocalHost().toString() + " port " + port );
start(); // start thread to receive and display datagrams
// loop waiting for keyboard input, send datagram to remote IP
while(true)
try
{
String s = in.readLine(); // read a String
System.out.println("Sending to " + remoteIPaddress + " socket " + port + " data: " + s);
byte[] data = s.getBytes(); // convert to byte array
DatagramSocket theSocket = new DatagramSocket(); // create datagram socket and the datagram
DatagramPacket theOutput = new DatagramPacket(data, data.length, InetAddress.getByName(remoteIPaddress), port);
theSocket.send(theOutput); // and send the datagram
}
catch (Exception e) {System.out.println("Eroor sending datagram " + e);}
}
// thread run method, receives datagram and display contents as a string and HEX
public void run()
{
try
{
// open DatagramSocket to receive
DatagramSocket ds = new DatagramSocket(port);
// loop forever reading datagrams from the DatagramSocket
while (true)
{
byte[] buffer = new byte[65507]; // array to put datagrams in
DatagramPacket dp = new DatagramPacket(buffer, buffer.length); // DatagramPacket to hold the datagram
ds.receive(dp); // wait for next datagram
String s = new String(dp.getData(),0,dp.getLength()); // get contenets as a String
System.out.println("UDP datagram length " + s.length()+ " from IP " + dp.getAddress() + " received: " + s );
// and display HEX values
System.out.print(" in HEX ");
for(int i=0;i<dp.getLength();i++)
System.out.printf("0x%02X ", buffer[i]);
System.out.println();
}
}
catch (SocketException se) {System.err.println("chat error " + se); }
catch (IOException se) {System.err.println("chat error " + se);}
System.exit(1); // exit on error
}
public static void main(String args[]) throws Exception
{
UDPchat c=new UDPchat(args);
}
Java console output
E:\temp>java UDPchat.java 192.168.1.245 999
chat program: IP address DELL_win_11/192.168.1.65 port 999
UDP datagram length 8 from IP /192.168.1.245 received: #Eg????
in HEX 0x02 0x23 0x45 0x67 0x89 0xAB 0xCD 0xEF
UDP datagram length 8 from IP /192.168.1.245 received: #Eg????
in HEX 0x03 0x23 0x45 0x67 0x89 0xAB 0xCD 0xEF
UDP datagram length 8 from IP /192.168.1.245 received: #Eg????
in HEX 0x04 0x23 0x45 0x67 0x89 0xAB 0xCD 0xEF
UDP datagram length 8 from IP /192.168.1.245 received: #Eg????
in HEX 0x05 0x23 0x45 0x67 0x89 0xAB 0xCD 0xEF
UDP datagram length 8 from IP /192.168.1.245 received: #Eg????
in HEX 0x06 0x23 0x45 0x67 0x89 0xAB 0xCD 0xEF
UDP datagram length 8 from IP /192.168.1.245 received: #Eg????
in HEX 0x07 0x23 0x45 0x67 0x89 0xAB 0xCD 0xEF
UDP datagram length 8 from IP /192.168.1.245 received: #Eg????
in HEX 0x08 0x23 0x45 0x67 0x89 0xAB 0xCD 0xEF
UDP datagram length 8 from IP /192.168.1.245 received: #Eg????
in HEX 0x09 0x23 0x45 0x67 0x89 0xAB 0xCD 0xEF
UDP datagram length 8 from IP /192.168.1.245 received: #Eg????
in HEX 0x0A 0x23 0x45 0x67 0x89 0xAB 0xCD 0xEF
UDP datagram length 8 from IP /192.168.1.245 received: #Eg????
in HEX 0x0B 0x23 0x45 0x67 0x89 0xAB 0xCD 0xEF
UDP datagram length 8 from IP /192.168.1.245 received: #Eg????
in HEX 0x0C 0x23 0x45 0x67 0x89 0xAB 0xCD 0xEF
photo of test setup

Heltec LoRa V2 P2P receiver output
Heltec LoRa V2 SX1276 [SX1276] Initializing ... success!
[SX1276] Starting to listen ... success!
[SX1276] Received packet!
[SX1276] Data: 3 35 69 103 137 171 205 239
[SX1276] RSSI: -50.00 dBm
[SX1276] SNR: 12.00 dB
[SX1276] Frequency error: -2149.58 Hz
[SX1276] Received packet!
[SX1276] Data: 4 35 69 103 137 171 205 239
[SX1276] RSSI: -49.00 dBm
[SX1276] SNR: 10.00 dB
[SX1276] Frequency error: -2153.78 Hz
[SX1276] Received packet!
[SX1276] Data: 5 35 69 103 137 171 205 239
[SX1276] RSSI: -50.00 dBm
[SX1276] SNR: 12.25 dB
[SX1276] Frequency error: -2162.16 Hz
[SX1276] Received packet!
[SX1276] Data: 6 35 69 103 137 171 205 239
[SX1276] RSSI: -51.00 dBm
[SX1276] SNR: 9.50 dB
[SX1276] Frequency error: -2170.55 Hz