Cannot get UDP to work between two Photons

Hello, I am kinda new to Photon and have read the documentation on the firmware, but the examples I found are not complete and do not seem to work.

I have two photons one as a temp server and the other as a display. I want to use UDP to send data between the two.

The temp code is, right now it just has a temp number in it:

UDP Udp;
IPAddress ipAddress = '192.168.1.4';
int port = 23;

void setup() {
    
    pinMode(D2, INPUT);
    Particle.variable("tempHotWater", &fahrenheit, DOUBLE);
    Serial.begin(115200);
    Udp.begin(23);
}

void loop() {

    Serial.println(WiFi.localIP());
    Serial.println("Sending");
    int c = 66;
    Udp.beginPacket(ipAddress, port);
    Udp.write(c);
    Serial.println(Udp.endPacket());
    delay(1000);

}

Display Photon:

UDP Udp;

void setup() {
    Serial.begin(9600);
    Udp.begin(0);
    
    tempDisplay.begin(0x70);
}


void loop() {

    Serial.println("Hottub Display");
    Serial.println(WiFi.localIP());
    Serial.println(Udp.parsePacket());
    
    Udp.parsePacket();
    Serial.println("Read");

    // Read first char of data received
    int temp = Udp.read();
    // Ignore other chars
    Udp.flush();
    
    Serial.println(temp);

    tempDisplay.print(temp, DEC);
    
    // Now push out to the display the new values that were set above.
    tempDisplay.writeDisplay();
    
    delay(3000);
}

All I get on the display is -1 or error, the Temp photon seems to send it as the sending code returned is 1.

I cannot seem to find any complete examples on how to do this between two photons. I am not sure why it doesnt display the number I put in from the temp photon.

These are the latest photons and firmware. Any assistance would be appreciated. Thanks, Chris

Here’s a working UDP example. I prefer to use udp.receivePacket() as it works more reliably and efficiently than the parsePacket() method. Also, this example uses Publish and Subscribe to find the IP address of the other side, so you don’t need to hard code it.

Sender:

#include "Particle.h"

// UDP Receiver Sample App

SYSTEM_THREAD(ENABLED);

void findUdpReceiverHandler(const char *event, const char *data); // forward declaration

const size_t UDP_BUFFER_SIZE = 512;
const unsigned long RETRY_RECEIVER_TIME_MS = 20000;
const unsigned long SEND_PERIOD_TIME_MS = 1000;

UDP udp;
char udpBuffer[UDP_BUFFER_SIZE + 1];
IPAddress serverAddr;
int serverPort = 0;
unsigned long lastRequest = 0 - RETRY_RECEIVER_TIME_MS;
int seq = 0;

void setup() {
	Serial.begin(9600);
	Particle.subscribe("udpSendReceiveReceiver", findUdpReceiverHandler, MY_DEVICES);

	waitUntil(WiFi.ready);
	udp.begin(0);
}

void loop() {
	if (serverPort == 0 && millis() - lastRequest >= RETRY_RECEIVER_TIME_MS) {
		lastRequest = millis();
		Serial.println("requesting udpSendReceiveLocate");
		Particle.publish("udpSendReceiveLocate", "", PRIVATE);
	}

	if (serverPort != 0 && millis() - lastRequest >= SEND_PERIOD_TIME_MS) {
		lastRequest = millis();

		snprintf(udpBuffer, sizeof(udpBuffer), "testing %d", seq++);

		int count = udp.sendPacket(udpBuffer, strlen(udpBuffer) + 1, serverAddr, serverPort);
		if (count > 0) {
			Serial.printlnf("sent %s", udpBuffer);
		}
		else {
			Serial.printlnf("error sending %d, requesting IP address again", count);
			serverPort = 0;
		}
	}
}


void findUdpReceiverHandler(const char *event, const char *data) {

	int addr[4], port;

	if (sscanf(data, "%u.%u.%u.%u:%u", &addr[0], &addr[1], &addr[2], &addr[3], &port) == 5) {
		serverAddr = IPAddress(addr[0], addr[1], addr[2], addr[3]);
		serverPort = port;

		Serial.printlnf("got serverAddr=%s port=%d", serverAddr.toString().c_str(), serverPort);
	}
	else {
		Serial.printlnf("unknown data format for udpSendReceiveReceiver %s", data);
	}
}

Receiver:

#include "Particle.h"

// UDP Receiver Sample App

SYSTEM_THREAD(ENABLED);

void findUdpReceiverHandler(const char *event, const char *data); // forward declaration

const int UDP_PORT = 7123;
const size_t UDP_BUFFER_SIZE = 512;
UDP udp;
char udpBuffer[UDP_BUFFER_SIZE + 1];

void setup() {
	Serial.begin(9600);
	Particle.subscribe("udpSendReceiveLocate", findUdpReceiverHandler, MY_DEVICES);

	waitUntil(WiFi.ready);
	udp.begin(UDP_PORT);
}

void loop() {
	int count = udp.receivePacket(udpBuffer, UDP_BUFFER_SIZE);
	if (count > 0) {
		// udpBuffer is actually 1 byte larger than UDP_BUFFER_SIZE so there's room for the null terminator
		udpBuffer[count] = 0;
		IPAddress remoteAddr = udp.remoteIP();

		Serial.printlnf("## packet size=%d addr=%s data=%s", count, remoteAddr.toString().c_str(), udpBuffer);
	}
	else
	if (count == -1 || count == 0) {
		// No packet
	}
	else {
		Serial.printlnf("** receivePacket error %d", count);
		udp.begin(UDP_PORT);
	}
}


void findUdpReceiverHandler(const char *event, const char *data) {

	char responseBuf[64];
	snprintf(responseBuf, sizeof(responseBuf), "%s:%d", WiFi.localIP().toString().c_str(), UDP_PORT);

	Particle.publish("udpSendReceiveReceiver", responseBuf, PRIVATE);

	Serial.printlnf("got udpSendReceiveLocate, returning %s", responseBuf);
}

1 Like

One possible reason for your code not working might be this

IPAddress ipAddress = '192.168.1.4';

That’s not how IPAddress is initialized.

It’d rather look like this (that’s a sample out the docs)

IPAddress remoteIP(192, 168, 1, 100);

I also suspect your first code didn’t build at all - for above reason and for farenheit not being declared.
So doesn’t the second for similar reasons.

On the other hand, this doc sample seems to do what it’s supposed to

// EXAMPLE USAGE

// UDP Port used for two way communication
unsigned int localPort = 8888;

// An UDP instance to let us send and receive packets over UDP
UDP Udp;

void setup() {
  // start the UDP
  Udp.begin(localPort);

  // Print your device IP Address via serial
  Serial.begin(9600);
  Serial.println(WiFi.localIP());
}

void loop() {
  // Check if data has been received
  if (Udp.parsePacket() > 0) {

    // Read first char of data received
    char c = Udp.read();

    // Ignore other chars
    Udp.flush();

    // Store sender ip and port
    IPAddress ipAddress = Udp.remoteIP();
    int port = Udp.remotePort();

    // Echo back data to sender
    Udp.beginPacket(ipAddress, port);
    Udp.write(c);
    Udp.endPacket();
  }
}

Ok That is what it was, the IPAddress format, I do not remember seeing that format in the examples, but could have missed it or typed it wrong, it works correctly now. Now I have to hook up the other code to that display which should be trivial. Thanks!