Hello group,
I am not getting UDP receive to actually receive anything on the Electron. At some level it has to because that is how it talks to the Particle cloud servers. But it does not seem to work for me in my app.
I have reduced my code down to this test. When compiled for, and run on, the Photon it works as expected. But when compiled for the Electron I never received any UDP datagrams.
The code sends a UDP datagram every 10 seconds to the public IP address of a server out at AWS. I use the log from that server to send a UDP datagram back to the Electron.
In order to test with the Photon, I have configured my home router to forward the datagrams that arrive from that AWS server to the Photon’s IP address on my home network. As I say, that all works as expected.
There could be several things that will prevent me from receiving UDP on the Electron: The cellular provider, the code inside the UBLOX module, etc. But all of these have been solved because the Particle cloud services work great on the Electron, right?
Does the cellular provider implement a UDP port white-list that Particle has an entry in that allows the Particle cloud communication to work?
Thinking there might be a conflict inside the firmware or the UBLOX, the test code pasted here uses MANUAL mode in an attempt to keep the firmware from starting up any of the UDP objects/code. But this has not helped.
I’ve since read the UBLOX documentation and it looks like it supports 7 sockets of mixed TCP or UDP type, so perhaps that is not an issue.
Note that I create a #define for “Network” so that the code works on either the Particle or the Electron. I get the same results if I change those references to “Cellular” and compile only for the Electron.
Any ideas?
My test code:
SYSTEM_MODE(MANUAL);
#if defined(SPARK)
#if defined(PLATFORM_ID)
#if (PLATFORM_ID == 0)
//Core
#define Network WiFi
#elif (PLATFORM_ID == 6)
//Photon
#define Network WiFi
#elif (PLATFORM_ID == 10)
//Electron
#define Network Cellular
#endif
#endif //PLATFORM_ID
#endif //SPARK
struct myLoc {
float p_lat;
float p_long;
short speed;
short track;
short alt;
unsigned short seq;
};
#define htons(n) (((((unsigned short)(n) & 0xFF)) << 8) | (((unsigned short)(n) & 0xFF00) >> 8))
#define ntohs(n) (((((unsigned short)(n) & 0xFF)) << 8) | (((unsigned short)(n) & 0xFF00) >> 8))
IPAddress remoteIP(54,0,0,0); // Address changed to keep my server private
int remotePort = 32001;
UDP udp;
struct myLoc locBuf;
char udpbuf[40];
unsigned long lastCom;
void myUdp()
{
static unsigned short seq = 1;
locBuf.seq = htons(seq);
seq++;
if (udp.sendPacket((char *)&locBuf, sizeof(locBuf), remoteIP, remotePort)<0) {
digitalWrite(D7, HIGH);
}
}
void setup()
{
pinMode(D7, OUTPUT);
digitalWrite(D7, HIGH);
Serial.begin(9600); // USB Serial
for(int yy = 0; yy < 25; yy++)
{
digitalWrite(D7, LOW);
delay(200);
digitalWrite(D7, HIGH);
delay(200);
}
digitalWrite(D7, HIGH);
Network.on();
Network.connect();
while(Network.connecting())
{
delay(500);
}
delay(700);
udp.begin(32001);
digitalWrite(D7, LOW);
lastCom = millis();
}
void loop()
{
int ulen;
struct myLoc *ml;
ulen = udp.receivePacket(udpbuf, 30);
if (ulen > 0)
{
Serial.print("udp length: ");
Serial.println(ulen);
if(ulen == 16)
{
ml = (struct myLoc *)udpbuf;
locBuf.speed = ntohs(ml->speed);
locBuf.track = ntohs(ml->track);
locBuf.alt = ntohs(ml->alt);
locBuf.p_lat = ml->p_lat;
locBuf.p_long = ml->p_long;
Serial.print("Got speed: ");
Serial.println(locBuf.speed);
}
}
digitalWrite(D7, LOW);
// Send our request UDP packet every 10 seconds
if((millis() - lastCom) > 10000)
{
locBuf.speed = htons(-2);
locBuf.track = htons(-2);
locBuf.alt = htons(-2);
Serial.println("Sending UDP request.");
myUdp();
lastCom = millis();
}
}
I compile via the Particle cli with:
particle compile photon .
or
particle compile electron .