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: