UDP Unicast woes with Photon

Hi,
I’ve got a Photon that I’m trying to send NON broadcast UDP with, and I’ve got a simple app that shows the issue. I was wondering if anyone can shed some light on it.

Using

nc -u -l 10.0.1.13 1310

to listen

This program fails to send

UDP _udp;

SYSTEM_MODE(MANUAL);



void setup() {
    WiFi.on();
    if (Particle.connected() == false) {
        Particle.connect();
        WiFi.ping(WiFi.gatewayIP());
        _udp.begin(13130);
    }
}

void loop() {
    _udp.beginPacket("10.0.1.13", 13130);
    _udp.write("Hello World");
    _udp.endPacket();
    Particle.process();
    delay(1000);
}

However, the following works:

UDP _udp;
void setup() {
    _udp.begin(13130);
}

void loop() {
    _udp.beginPacket("10.0.1.13", 13130);
    _udp.write("Hello World");
    _udp.endPacket();
    delay(1000);
}

Any help would be great.

You need to wait until WiFi.connected() returns true before calling udp.begin(port).

Here’s a sample program that does sending, but it works the same for receiving.

#include "Particle.h"

SYSTEM_THREAD(ENABLED);
SYSTEM_MODE(MANUAL);

const unsigned long SEND_PERIOD_MS = 5000;
const size_t UDP_BUFFER_SIZE = 128;

enum WifiState { WIFI_STATE_NOT_CONNECTED, WIFI_STATE_CONNECTING, WIFI_STATE_CONNECTED, WIFI_STATE_RUNNING };

IPAddress serverAddr(192,168,2,4);
const int serverPort = 7123;

WifiState wifiState = WIFI_STATE_NOT_CONNECTED;
unsigned long lastSend = 0;
UDP udp;
byte udpBuffer[UDP_BUFFER_SIZE] = { 0 };
int seq = 0;

void setup() {
	Serial.begin(9600);

	WiFi.on();
}

void loop() {
	switch(wifiState) {
	case WIFI_STATE_NOT_CONNECTED:
		Serial.println("connecting");
		WiFi.connect();
		wifiState = WIFI_STATE_CONNECTING;
		break;

	case WIFI_STATE_CONNECTING:
		if (WiFi.ready()) {
			wifiState = WIFI_STATE_CONNECTED;
		}
		// The WiFi.connect() call never times out, it will keep trying forever so there's
		// no need to call WiFi.connect() again here.
		break;

	case WIFI_STATE_CONNECTED:
		// Do any one-time initialization here like calling udp.begin() or tcpServer.begin()
		Serial.println("connected");
		udp.begin(0);
		wifiState = WIFI_STATE_RUNNING;
		break;

	case WIFI_STATE_RUNNING:
		if (!WiFi.ready()) {
			Serial.println("disconnected during connected state");
			wifiState = WIFI_STATE_CONNECTING;

			// No need to call WiFi.connect() again, it will keep retrying forever
			break;
		}

		// Running with WiFi enabled here
		if (millis() - lastSend >=  SEND_PERIOD_MS) {
			lastSend = millis();

			Serial.printlnf("sending seq=%d", seq);

			snprintf((char *)udpBuffer, UDP_BUFFER_SIZE, "seq %d", seq++);

			udp.sendPacket(udpBuffer, UDP_BUFFER_SIZE, serverAddr, serverPort);
		}
		break;


	}
}

Also, receivePacket works much better than beginPacket/write/endPacket. That’s described here:

1 Like