Skip to content

Commit

Permalink
Merge pull request #29 from JiriBilek/UDP_Multicast
Browse files Browse the repository at this point in the history
Add UDP Multicast support
  • Loading branch information
JiriBilek authored Jan 25, 2021
2 parents 58ab6c5 + eee08a8 commit b898103
Show file tree
Hide file tree
Showing 9 changed files with 353 additions and 10 deletions.
18 changes: 15 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,10 @@ The library allows Arduino to be client or server on the WiFi network.

## News

#### 2021-01-25

Added UDP Multicast support

#### 2021-01-02

Fixed a bug with closing server connection when closing asynchronously opened another client.
Expand Down Expand Up @@ -255,11 +259,14 @@ Default constuctor.
- **uint8_t begin(uint16_t port)**
Initializes the instance, starts listening on specified *port*. Returns 1 if successful, 0 on error.

- **uint8_t begin(uint16_t multicastIP, uint16_t port)**
Initializes the instance, starts listening on specified *port* for multicast messages from *multicastIP* address. Returns 1 if successful, 0 on error.

- **void stop()**
Stops listening on the UDP port, frees the UDP socket used.

- **int beginPacket(IPAddress ip, uint16_t port)**
Starts building up a packet to send to the remote host specific in *ip* and *port*. Returns 1 if successful, 0 if there was a problem with the connection.
Starts building up a packet to send to the remote host specific in *ip* and *port*. Returns 1 if successful, 0 if there was a problem with the connection. This function works for both unicast and multicast communication.

- **int endPacket()**
Finishes the packet and sends it. Returns 1 if the packet was sent successfully, 0 if there was an error.
Expand Down Expand Up @@ -306,6 +313,12 @@ Simple mqtt messaging.
- **UdpNTPClient**
Reads current time and date from a NTP server.

- **UDP_Multicast_Transmitter**
Peridically transmits a short messaage via UDP multicast.

- **UDP_Multicast_Receiver**
Listens for multicast messages, reads them and prints them out.

More examples to come soon. But you can easily use the ones from WiFi library. Don't forget to add a line *WiFiSpi.init();* before using other library functions.

## Debugging
Expand All @@ -314,8 +327,7 @@ For some debugging information on Serial output uncomment line 23 (#define _DEBU

## ToDo and Wish Lists

- TLS connection
- SPI protocol optimization
- more SPI protocol optimization

## Credits

Expand Down
137 changes: 137 additions & 0 deletions examples/UDP_Multicast_Receiver/UDP_Multicast_Receiver.ino
Original file line number Diff line number Diff line change
@@ -0,0 +1,137 @@
/*
Receive multicast UDP packets
This sketch receives multicast UDP packets from address 239.1.74.74, port 7474
Uses WiFi ESP8266 module.
This example is written for a network using WPA encryption.
Circuit:
1. On ESP8266 must be running (flashed) WiFiSPIESP application.
2. Connect the Arduino to the following pins on the esp8266:
ESP8266 |
GPIO NodeMCU Name | STM32F103
===================================
15 D8 SS | PA4
13 D7 MOSI | PA7
12 D6 MISO | PA6
14 D5 SCK | PA5
RESET | PB12
Note: If the ESP is booting at the moment when the SPI Master (i.e. Arduino) has the Select line HIGH (deselected)
the ESP8266 WILL FAIL to boot!
*/

#include <WiFiSpi.h>

char ssid[] = "your ssid here"; // your network SSID (name)
char pass[] = "your password here"; // your network password

#if defined(MCU_STM32F103C8)
const uint8_t RESET_PIN = PB12; // For STM32F103
#endif

// Note: remoteIP is a multicast address, it should begin with 239.x.x.x or some other
// appropriate multicast address.
// It's not the same as your local IP address (192.168.x.x, for example)!
IPAddress remoteIP(239, 1, 74, 74);

// The remote port must be otherwise unused on any machine that is receiving these packets
int remotePort = 7474;

// Create the UDP object
WiFiSpiUdp udp;

void setup() {
#if defined(MCU_STM32F103C8)
// Reset PIN
pinMode(RESET_PIN, OUTPUT);
digitalWrite(RESET_PIN, HIGH);
#endif

//Initialize serial and wait for port to open:
Serial.begin(115200);
while (!Serial.available()) {
; // wait for serial port to connect. Needed for native USB port only
}

Serial.println("Reset ESP8266");

#if defined(MCU_STM32F103C8)
// Reset the ESP
digitalWrite(RESET_PIN, LOW);
delay(100);
digitalWrite(RESET_PIN, HIGH);
delay(500);
#endif

// Initialize the library
WiFiSpi.init(SS, 100000);

// check for the presence of the shield:
if (WiFiSpi.status() == WL_NO_SHIELD) {
Serial.println("Error in communication with the ESP board, halted");
WiFiSpi.status();
// don't continue:
while (true);
}

if (! WiFiSpi.checkProtocolVersion())
Serial.println("Please upgrade the firmware");

// attempt to connect to Wifi network:
uint8_t status;
do {
Serial.print("Attempting to connect to SSID: ");
Serial.println(ssid);
// Connect to WPA/WPA2 network.
status = WiFiSpi.begin(ssid, pass);
} while (status != WL_CONNECTED);

Serial.println("Connected to wifi");

// Start listening for multicast messages
udp.beginMulticast(remoteIP, remotePort);
}

void loop() {
// If there's data available, read a packet
int packetSize = udp.parsePacket();

// If there's data, read them and print them
if (packetSize > 0) {
Serial.print("Incoming packet, size="); Serial.println(packetSize);
while (udp.available()) {
int inp = udp.read();
if (inp >= ' ' && inp <= 0x7f)
Serial.print(char(inp));
else {
Serial.print(inp); Serial.print(' ');
}
}
Serial.println();
}

delay(100);
}


void printWifiStatus() {
// print the SSID of the network you're attached to:
Serial.print("SSID: ");
Serial.println(WiFiSpi.SSID());

// print your WiFi shield's IP address:
IPAddress ip = WiFiSpi.localIP();
Serial.print("IP Address: ");
Serial.println(ip);

// print the received signal strength:
long rssi = WiFiSpi.RSSI();
Serial.print("signal strength (RSSI): ");
Serial.print(rssi);
Serial.println(" dBm");
}
146 changes: 146 additions & 0 deletions examples/UDP_Multicast_Transmitter/UDP_Multicast_Transmitter.ino
Original file line number Diff line number Diff line change
@@ -0,0 +1,146 @@
/*
Transmit multicast UDP packets
This sketch transmits multicast UDP packets to address 239.1.74.74, port 7474
Uses WiFi ESP8266 module.
This example is written for a network using WPA encryption.
Circuit:
1. On ESP8266 must be running (flashed) WiFiSPIESP application.
2. Connect the Arduino to the following pins on the esp8266:
ESP8266 |
GPIO NodeMCU Name | STM32F103
===================================
15 D8 SS | PA4
13 D7 MOSI | PA7
12 D6 MISO | PA6
14 D5 SCK | PA5
RESET | PB12
Note: If the ESP is booting at the moment when the SPI Master (i.e. Arduino) has the Select line HIGH (deselected)
the ESP8266 WILL FAIL to boot!
*/

#include <WiFiSpi.h>

char ssid[] = "your ssid here"; // your network SSID (name)
char pass[] = "your password here"; // your network password

#if defined(MCU_STM32F103C8)
const uint8_t RESET_PIN = PB12;
#endif

// Note: remoteIP is a multicast address, it should begin with 239.x.x.x or some other
// appropriate multicast address.
// It's not the same as your local IP address (192.168.x.x, for example)!
IPAddress remoteIP(239, 1, 74, 74);

// The remote port must be otherwise unused on any machine that is receiving these packets
int remotePort = 7474;

// Create the UDP object
WiFiSpiUdp udp;

void setup() {
#if defined(MCU_STM32F103C8)
// Reset PIN
pinMode(RESET_PIN, OUTPUT);
digitalWrite(RESET_PIN, HIGH);
#endif

//Initialize serial and wait for port to open:
Serial.begin(115200);
while (!Serial.available()) {
; // wait for serial port to connect. Needed for native USB port only
}

Serial.println("Reset ESP8266");

#if defined(MCU_STM32F103C8)
// Reset the ESP
digitalWrite(RESET_PIN, LOW);
delay(100);
digitalWrite(RESET_PIN, HIGH);
delay(500);
#endif

// Initialize the library
WiFiSpi.init(SS, 100000);

// check for the presence of the shield:
if (WiFiSpi.status() == WL_NO_SHIELD) {
Serial.println("Error in communication with the ESP board, halted");
WiFiSpi.status();
// don't continue:
while (true);
}

if (! WiFiSpi.checkProtocolVersion())
Serial.println("Please upgrade the firmware");

// attempt to connect to Wifi network:
uint8_t status;
do {
Serial.print("Attempting to connect to SSID: ");
Serial.println(ssid);
// Connect to WPA/WPA2 network.
status = WiFiSpi.begin(ssid, pass);
} while (status != WL_CONNECTED);

Serial.println("Connected to wifi");

// Start UDP communication. No IP needed, because we are transmitting data
udp.begin(0);
}

void loop() {
static uint16_t counter = 0; // The payload is only a simple counter

// via multicast we send the counter as the UDP message
if (udp.beginPacket(remoteIP, remotePort) == 1) {
uint8_t buffer[2];

++counter;
buffer[0] = counter >> 8;
buffer[1] = (counter && 0xff);

// Write the payload
udp.write(buffer, sizeof(buffer));

// Send the packet
if (udp.endPacket() == 1) {
// Success
Serial.println(counter);
}
else {
Serial.println("send failed");
}
}
else {
Serial.println("open failed");
}

delay(1000);
}


void printWifiStatus() {
// print the SSID of the network you're attached to:
Serial.print("SSID: ");
Serial.println(WiFiSpi.SSID());

// print your WiFi shield's IP address:
IPAddress ip = WiFiSpi.localIP();
Serial.print("IP Address: ");
Serial.println(ip);

// print the received signal strength:
long rssi = WiFiSpi.RSSI();
Serial.print("signal strength (RSSI):");
Serial.print(rssi);
Serial.println(" dBm");
}
4 changes: 2 additions & 2 deletions src/WiFiSpi.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ extern "C" {
}

// Protocol version
const char *WiFiSpiClass::protocolVer = "0.2.3";
const char *WiFiSpiClass::protocolVer = "0.2.4";

// Hardware reset pin
int8_t WiFiSpiClass::hwResetPin = -1;
Expand Down Expand Up @@ -69,7 +69,7 @@ uint8_t WiFiSpiClass::getSocket()
for (uint8_t i = 0; i < MAX_SOCK_NUM; ++i)
{
if (WiFiSpiClass::_state[i] == NA_STATE) // _state is for both server and client
return i;
return i;
}
return SOCK_NOT_AVAIL;
}
Expand Down
23 changes: 22 additions & 1 deletion src/WiFiSpiUdp.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,27 @@ uint8_t WiFiSpiUdp::begin(uint16_t port)
return 0;
}

/*
* Starts WiFiSpiUdp socket, listening at port PORT for multicast messages from IP
* Returns 1 if successful, 0 on failure
*/
uint8_t WiFiSpiUdp::beginMulticast(IPAddress ip, uint16_t port)
{
uint8_t sock = WiFiSpiClass::getSocket();
if (sock != SOCK_NOT_AVAIL)
{
if (ServerSpiDrv::startServerMulticast(uint32_t(ip), port, sock))
{
WiFiSpiClass::_server_port[sock] = port;
WiFiSpiClass::_state[sock] = sock;
_sock = sock;
_port = port;
return 1;
}
}
return 0;
}

/*
* Returns number of bytes available in the current packet
*/
Expand Down Expand Up @@ -211,4 +232,4 @@ uint16_t WiFiSpiUdp::remotePort()
else
return 0;
}


Loading

0 comments on commit b898103

Please sign in to comment.