Need UDP Help, IP Electron

Hi, I read all the different articles and form for the udp but still can get one set up, can someone help break it down for my and how to read it. using this and trying to just get some udp set up from Electron
How do you post the electron ip address, how often does it change if mounted to a Car ? Any Help would be great.


/*
 ******************************************************************************
  Copyright (c) 2017 Particle Industries, Inc.  All rights reserved.

  This program is free software; you can redistribute it and/or
  modify it under the terms of the GNU Lesser General Public
  License as published by the Free Software Foundation, either
  version 3 of the License, or (at your option) any later version.

  This program is distributed in the hope that it will be useful,
  but WITHOUT ANY WARRANTY; without even the implied warranty of
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  Lesser General Public License for more details.

  You should have received a copy of the GNU Lesser General Public
  License along with this program; if not, see <http://www.gnu.org/licenses/>.
  ******************************************************************************
 */

#include "application.h"

#define PARTICLE_CLOUD 1

Serial1LogHandler logHandler(115200, LOG_LEVEL_ALL);

// UDP Port used for two way communication
unsigned int localPort1 = 5000;
unsigned int localPort2 = 6000;
IPAddress serverIPaddress(1**,1**,0,157 ); // IMPORTANT SET THIS!!! (is this my Comp or Electron ) ? 

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

SYSTEM_MODE(SEMI_AUTOMATIC);

void callHomeUDP1()
{
    static String msg;
    static int count = 1;
    LOG(INFO,"UDP 1 HELLO SENDING\r\n");
    Udp1.beginPacket(serverIPaddress, localPort1);
    msg = "hello from electron " + String(count++);
    Udp1.write(msg);
    Udp1.endPacket();
    LOG(INFO,"UDP 1 HELLO SENT\r\n");
}

void checkUDP1() {
  // Check if data has been received
  if (Udp1.parsePacket() > 0) {

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

    String temp = String(c);

    // Ignore other chars
    while(Udp1.available()) {
        c = Udp1.read();
        temp.concat(String(c));
    }

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

    // Log complete message
    LOG(INFO,"UDP 1 MESSAGE FROM %s:%d \"%s\"", String(ipAddress).c_str(), port, temp.c_str());

    // Echo back data to sender
    // Udp1.beginPacket(ipAddress, port);
    // Udp1.write(temp.c_str());
    // Udp1.endPacket();
  }
}

void callHomeUDP2()
{
    static String msg;
    static int count = 1;
    LOG(INFO,"UDP 2 HELLO SENDING\r\n");
    Udp2.beginPacket(serverIPaddress, localPort2);
    msg = "hello from electron " + String(count++);
    Udp2.write(msg);
    Udp2.endPacket();
    LOG(INFO,"UDP 2 HELLO SENT\r\n");
}

void checkUDP2() {
  // Check if data has been received
  if (Udp2.parsePacket() > 0) {

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

    String temp = String(c);

    // Ignore other chars
    while(Udp2.available()) {
        c = Udp2.read();
        temp.concat(String(c));
    }

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

    // Log complete message
    LOG(INFO,"UDP 2 MESSAGE FROM %s:%d \"%s\"", String(ipAddress).c_str(), port, temp.c_str());

    // Echo back data to sender
    // Udp2.beginPacket(ipAddress, port);
    // Udp2.write(temp.c_str());
    // Udp2.endPacket();
  }
}

void setup()
{
    Cellular.on();
    Cellular.connect();
    waitUntil(Cellular.ready);

    pinMode(B0, INPUT_PULLUP);
    pinMode(B1, INPUT_PULLUP);

    Udp1.begin(localPort1);
    callHomeUDP1();

#if PARTICLE_CLOUD
    Particle.connect();
    waitUntil(Particle.connected);
#endif

    Udp2.begin(localPort2);
    callHomeUDP2();
}

void loop()
{
    if (digitalRead(B1)==LOW) {
        callHomeUDP2();
        delay(1000);
    }
    if (digitalRead(B0)==LOW) {
        callHomeUDP1();
        delay(1000);
    }

    checkUDP1();
    checkUDP2();
}

UDP with Electrons is tricky, and won’t work the way you’ve implemented it here.

Electron are located on a private LAN operated by the mobile carrier. It’s not possible to route packets within this LAN (between Electrons, for example). You can send UDP to the Internet. However, your Electron shares an IP address with thousands of other devices. When you send a UDP packet to the Internet, a temporary back-channel is allocated to allow response packets to be returned.

Your server can only send to the IP address and port the packet was sent from, not the port you are listening on! This is because of the port mapping. This backchannel will exist for a varying amount of time - 23 minutes for the Particle SIM or as low as 30 seconds for some mobile carriers (AT&T, not using the Particle SIM).

Note that with the Particle SIM, the backchannel is restricted to the server and port you sent to, so you can’t do arbitrary hole punching or three-way communication.

More info here

2 Likes

There is a way to send something to the cloud server per say and have them send data of packets back down to the Electron to populate some data points ?

Hi @SolarChamp

Why not just use the Particle cloud on Electron? It works great and has all these problems (and more) fully solved for you.

If you want to roll your own cloud connection on Electron, particularly over UDP, then you really need to have detailed knowledge of how the cellular network routes packets. @rickkas7 document linked above is great resource and has working UDP code, but as you can see, it is complex and the cellular network does not function like a WiFi or wired network, so different strategies are needed.

Maybe if you explained what your goal is and why the Particle cloud does not meet that goal, we could help better. If not, you should start from the working code (client and server) in the link above and expand to meet your needs.

1 Like

I would like to use OSC to control some NeoPixels on my Particle Electron, the problem of the Particle Cloud in my project is that there is a 2 second delay between posting on the Cloud and the device actually receiving this. I was thinking about using OSC because I used this in previous projects with Adafruit Feather microcontrollers. Any recommendations on this?

You mean the OpenSoundControl protocol over UDP, correct?

The biggest problem you’ll run into is that you can’t, out of the blue, send a UDP packet to an Electron. Electrons (also phones) share public IP addresses and use port forwarding. There’s no permanent channel to your Electron.

When you send a packet by UDP from the Electron to the Internet, a return channel is created to get a packet back. The lifetime of this channel ranges from 23 minutes for the Particle SIM to 30 seconds for an AT&T SIM and some others.

Furthermore, this back-channel is port and IP address restricted, so only the IP address and port you send to can send you UDP packets back. This is fine for protocols like DNS. I don’t know enough about how OSC works to know if that will be an issue or not.

Also, even with direct UDP you’ll probably find at least a few second latency if you’re not sending and receiving data periodically. I think the threshold is sending every 8 seconds. That’s caused by the mobile carrier networks, not the Electron. If you’re sending frequently by UDP you’ll get low latency.

2 Likes

So there should be a way to get a lower latency? Any documentation on this? I would like to use the Particle Electron for my thesis as part of a DIY mobile VJ Setup.

As long as you make sure you send a UDP packet from the Electron every 8 seconds or less, you’ll get low latency in both directions. It’s just when you go idle the next Internet to Electron packet will be delayed by the mobile network.

1 Like

Hi rickkas

Where does the 8 secs come from

8 seconds is just how the mobile carrier network happens to work; we don’t have any control over it.

I have not re-tested this using the LTE Cat M1 devices. It may behave differently, as it uses a different carrier.

Thanks

I just tested it, and it dropped latency from 1500mS to 250mS

I was just wondering where the 8sec is documented, so that I can put a link to it in my documentation.

1 Like