UDP Unicast woes with Photon

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