Photon doesn't send udp packages to nodejs server

I’m trying to use UDP to wirelessly send files from a SD card attached to my photon to a computer running a node.js server, but right now my goal is just to send basically anything from a photon to a computer. I’m trying to use about the simplest code that I can to minimize anywhere there might be an error, and the code for the photon and the server both run fine and appear to be working, except that nothing is actually sent.

Photon code:

UDP Udp;

unsigned char TxMsg[12] = { 1, 254, 1, 254, 1, 254, 43, 212, 71, 184, 3, 252 };

void setup() {
    Udp.begin(9000);
}

void loop() {
    Udp.beginPacket(IPAddress(0,0,0,0), 9000);
    Udp.write(TxMsg, 12);
    Udp.endPacket();
    delay(500);
}

Nodejs:

var dgram = require('dgram');
var udpServer = dgram.createSocket('udp4');

udpServer.on('listening',function(){
  var address = udpServer.address();
  var port = address.port;
  var family = address.family;
  var ipaddr = address.address;
  console.log('Server is listening at port: ' + port);
  console.log('Server ip: ' + ipaddr);
  console.log('Server is IP4/IP6: ' + family);
});

udpServer.on('message', function(message, remote){ 
  console.log('recieved message:');
  console.log(message);
  console.log('\nremote:');
  console.log(remote);
});

udpServer.on('close',function(){
  console.log('Socket is closed !');
});
  
udpServer.on('error',function(error) {
  console.log('Error: ' + error);  
  udpServer.close();
});

udpServer.bind(9000);  

I’m a complete beginner at this stuff, so please excuse the dumb question, but what IP should I use? I thought 0.0.0.0 was the ip that every device on the network could communicate with for some reason but all the example code I found online didn’t use it. Running hostname -I in terminal (my laptop runs Ubuntu) gives me two different IP addresses.

I also think part of the problem might be that i’m using an iPhone hotspot for internet right now, as i’m not at home and there’s no other internet. I saw a post saying if your router doesn’t have UDP enabled your code won’t work, but i’m not sure how to check that on an iPhone. I’ll try tonight at home on an actual wifi network where I can be sure UDP is enabled, but any other ideas for why this isn’t working?

Thanks in advance
Ben

You should not use 0.0.0.0. You should definetly get your subnet address (e.g. 192.168.x.?) and for that subnet 255 would be the broadcast IP 192.168.x.255.
You could also use UDP multicast (within the muticast IP range).

However, I’m not sure whether your iPhone hotspot would allow broadcast or multicast.
Hence it would be safest to have some means to target the server directly.

Thanks so much for the quick response!

I tried getting my subnet address with this command:

ben@localhost:~$ ip -o -f inet addr show | awk '/scope global/ {print $4}'
172.20.10.2/28
100.115.92.1/30

I assumed it was the first one, but I tried both and the broadcast IP 172.20.10.255 just to be sure, and none of them worked.

I also noticed something weird, which is that when viewing the particle console for this photon online, it doesn’t emit events after a successful flash like it was doing a half hour ago. I can still ping it and see that it’s online and the LED is breathing cyan, it just doesn’t emit events.

Not really sure if that relates at all to the problem but I thought i’d throw it in.

Should I be listening on a different port? Like, should I try hosting the server on 172.20.10.2:28?

The /28 does not refer to a port, but rather the size of your local subnet. A /28 subnet means there are 16 IP addresses in your subnet, so they range from 172.20.10.0 - 172.20.10.15. The last IP address in the range is your broadcast address, and is 172.20.10.15.

Rather than broadcasting to all IP addresses on your subnet, it would probably be better to target the server’s IP address directly. Is your server also listening on port 9000?

1 Like

My server is listening at port 9000, yes.

I tried targeting the server’s IP address directly, still doesn’t work.

nodejs output

(xenial)ben@localhost:~/Downloads/key/mantabot code$ node test-udp-nodejs.js 
Server is listening at port: 9000
Server ip: 172.20.10.2
Server is IP4/IP6: IPv4

photon code

    Udp.beginPacket(IPAddress(172,20,10,2), 9000);

so it’s the same IP and port, the message just doesn’t get through somehow.

I figured I might as well update this post in case it helps someone figure out what the problem is.

I wanted to see if I could get a node.js server working at all, so I set up a node.js UDP client and server on my laptop and was able to send and receive data easily.

Client code

var PORT = 33333;
var HOST = '172.20.10.2';

var dgram = require('dgram');
var message = 'ok swag time';

var client = dgram.createSocket('udp4');

client.send(message, 0, message.length, PORT, HOST, function(err, bytes) {
    if (err) throw err;
    console.log('UDP message sent to ' + HOST +':'+ PORT);
    client.close();
});

server code

var PORT = 33333;
var HOST = '172.20.10.2';

var dgram = require('dgram');
var server = dgram.createSocket('udp4');

server.on('listening', function() {
    var address = server.address();
    console.log('UDP Server listening on ' + address.address + ':' + address.port);
});

server.on('message', function(message, remote) {
    console.log(remote.address + ':' + remote.port +' - ' + message);
});

server.bind(PORT, HOST);

I tried a different port as well (33333 instead of 9000) because it was in the example node.js client code I found online. Like I said, this code worked perfectly and I was able to send and recieve messages using these programs.

Going back to the photon, I updated my code to look like this:

UDP Udp;

unsigned char please_work[12] = "pls";

IPAddress remoteIP(172,20,10,2);
int port = 33333;

void setup() {
    Udp.begin(port);
}

void loop() {
    if (WiFi.ready()) {        
        Udp.beginPacket(remoteIP, port);
        Udp.write(please_work, sizeof(please_work));
        Udp.endPacket();
        
        delay(500);
    } else {
        Particle.publish("wifi not ready");
    }
}

I changed the char it was sending to see if that would help, I changed the port, I changed it from Udp.sendPacket() to the beginPacket, write, and endPacket sequence. I also took Udp.begin() out of my loop. None of that helped, it still doesn’t work.

Does anyone have ideas? Is it just that I have a faulty photon, because I haven’t gotten error messages or LED error codes or anything.

Just a note on that: If WiFi.ready() is not true, Particle.publish() will work even less :wink:
You could use Serial.println() instead.

I’m not sure whether your remoteIP address is correct, but when I try this running locally (e.g. providing a broadcast IP in the same subnet) it works as expected

UDP Udp;

char buffer[] = "Particle powered";

IPAddress remoteIP;
int port = 33333;
bool hasIP = false;

void setup() {
  // Required for two way communication
  Udp.begin(port);
  Particle.function("setIP", setIP);
}

void loop() {
  static uint32_t ms = 0;
  if (millis() - ms < 1000) return;
  ms = millis();

  if (hasIP) {  
    if (Udp.sendPacket(buffer, sizeof(buffer), remoteIP, port) < 0) {
      Particle.publish("Error");
    }
  }
  else {
    Serial.printlnf("Photon's local IP %s", (const char*)WiFi.localIP().toString());
  }
}

int setIP(const char* arg) {
  uint8_t ip[4];
  int ret = sscanf(arg, "%u.%u.%u.%u", &ip[0], &ip[1], &ip[2], &ip[3]);
  if (4 == ret) {
    remoteIP = IPAddress(ip);
    hasIP = true;
  }
  return ret;
}

(for your subnet the broadcast IP should be 172.20.255.255 - assuming a (semi)standard 172.20/16 subnet, with 172.20/12 it would be 172.31.255.255)

Your IP seems to fall into the range that can pose some issues depending on your provider - see here

1 Like

@bean, apologies in advance, have not had time to read your full post, but have you checked for basic connectivity between the PC and the photon?

If not:

  • publish or log the ip address of the photon and ping this ip from the PC
  • ping the PC ip address from the photon and publish or log the result

Sorry for not responding for a couple days, I was on vacation w/out a computer.

After coming back and trying a couple things, I realized that it might be because I was running the node.js code on a Linux chroot on my chromebook, and the chroot might be messing things up somehow. Sure enough, installing GalliumOS and dual-booting instead of using a chroot fixed the issue, and now I can ping and transfer data.

There’s another issue now where some of the data sent doesn’t show up correctly, but I made a new topic for that here.