Receiving UDP packets on the Photon


#1

Hey,

I’ve got a very simple bit of code that listens for UDP packets and uses them to turn the LED attached to digital pin 7 on or off.

This code works fine on my two Cores, however when I run the same code on my Photon it never receives any UDP packets. Is there anything different I need to do for the Photon to receive UDP messages?

Here is my code:

int led = D7;

// UDP Port used for two way communication
unsigned int localPort = 12348;
// An UDP instance to let us send and receive packets over UDP
UDP Udp;

void setup() 
{
    pinMode(led, OUTPUT);

    // start the UDP
    Udp.begin(localPort);

    // Print your device IP Address via serial 
    Serial.begin(9600);
    delay(1000); //to give the serial port time to open

    Serial.println(WiFi.localIP());
    Serial.println(WiFi.SSID());
    Serial.println(localPort);
}

void loop() 
{
    // Check if data has been received
    if (Udp.parsePacket() > 0) 
    {
        // Read first char/byte of data received
        int i = Udp.read();
    
        Serial.println(i);

        // Ignore other chars
        Udp.flush();
    
        //set LED based on received data
        if (i == 0)
            digitalWrite(led, LOW);
        else if (i == 1)
            digitalWrite(led, HIGH);

    }
}

Thanks in advance,
Liam.


Sending real-time audio data using particle photon
Getting an ethermega (essentially an Arduino with built in ethernet) talking to a Photon/Core
#2

Hi @millenliam

I don’t think UDP is working on Photon yet. I know that my UDP-based NTP library never gets data back either.


#3

Hey @bko,

Ah, I wasn’t aware of this.
Is this mentioned somewhere in any documentation, TODO list, etc…?


#4

Is there a fix in the works for the next major firmware release? We can do a lot of things from the basics with TCP and UDP…but only if they’re there!


#5

Hey guys! I asked and this is being worked on for the next Photon release. I know a github issue was created based on this thread so that will help track it, but it was being looked at before.

Sorry it is not working right now.


#6

Thanks a lot. I understand full well what it’s like to have dozens of different “issues” pulling at you. . .and prioritizing becomes difficult. Debugging is a full time job!

Will look forward to the next firmware release.


#7

Is there a thread or github issue we can track for Photon UDP support? Looking forward to porting my quadcopter project to the Photon but it relies on UDP.


#8

Nevermind, found it:


#9

Hi
I wrote a piece of code that listens on UDP packets, it works under certain scenarios (e.g., when it’s the main code in the sketch). But when I tried adding my code into another existing piece of code (https://github.com/sparcules/Spark_Pixels/blob/master/Firmware/SparkPixels.ino) I never get anything back from parsePacket(). I wonder if there’s something obvious I may have overlooked.

#include "neopixel/neopixel.h"

//NEOPIXEL Defines
#define PIXEL_CNT       512
#define PIXEL_PIN       D0
#define PIXEL_TYPE      WS2812B

#define NR_OF_PANELS    8

Adafruit_NeoPixel strip = Adafruit_NeoPixel(PIXEL_CNT, PIXEL_PIN, PIXEL_TYPE);

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

// Define some tpm2.net constants
#define TPM2NET_LISTENING_PORT  65506
#define TPM2NET_HEADER_SIZE     6
#define TPM2NET_HEADER_IDENT    0x9C
#define TPM2NET_CMD_DATAFRAME   0xDA
#define TPM2NET_CMD_COMMAND     0xC0
#define TPM2NET_CMD_ANSWER      0xAC
#define TPM2NET_FOOTER_IDENT    0x36
#define TPM2NET_PACKET_TIMEOUT  0xFA    // 1/4 of a second

#define PIXELS_PER_PANEL        (PIXEL_COUNT / NR_OF_PANELS)

// 3 bytes per pixel or 24bit (RGB)
#define BPP                     3

// Package size we expect. The footer byte is not included here!
#define EXPECTED_PACKED_SIZE    (PIXELS_PER_PANEL * BPP + TPM2NET_HEADER_SIZE)

float timeLastPacketReceived;

void setup() {
    cube.begin();
    cube.background(black);
    cube.show();

    // Start the UDP
    if(Udp.setBuffer(EXPECTED_PACKED_SIZE))
        Udp.begin(TPM2NET_LISTENING_PORT);
}

void loop() {
    // Checks for the presence of a UDP packet, and reports the buffer size
    int32_t bytes = Udp.parsePacket();
    /* 
     * I want any smaller packets to be ignored. This is intentional because 
     * the TMP2.NET protocol dictates a fixed packet size. It works as expected.
     */
    if(bytes >= EXPECTED_PACKED_SIZE) {
        // Read 198 bytes of data from the buffer
        char data[EXPECTED_PACKED_SIZE];
        Udp.read(data, EXPECTED_PACKED_SIZE);

        // Ignore all other chars
        Udp.flush();
        timeLastPacketReceived = millis();

        /*------------------*/
        /*-- Header check --*/
        /*------------------*/
        // Block Start Byte
        if(data[0] == TPM2NET_HEADER_IDENT) {
            // Block Type: Command Packet
            if(data[1] == TPM2NET_CMD_COMMAND)
                return; // Don't care

            // Block Type: Frame Data Packet - that's what we want
            if(data[1] == TPM2NET_CMD_DATAFRAME) {
                // Calculate frame size
                char frameSize = data[2];
                frameSize = (frameSize << 8) + data[3];

                // Use packetNumber to calculate offset
                char packetNumber = data[4];
                char totalPackets = data[5];

                // Calculate offset
                uint16_t index = packetNumber * PIXELS_PER_PANEL;
                uint16_t voxelIdx = TPM2NET_HEADER_SIZE;

                // Start drawing!!
                for(uint16_t z = NR_OF_PANELS-1; z >= 0; z--) {                  // We're only dealing in 2 dimensions (width & height)
                    for(uint16_t col = 0; col < NR_OF_PANELS; col++) {           // Linewise, starting from leftmost index
                        for(uint16_t row = NR_OF_PANELS - 1; row >= 0; row--) {  // Columnwise, starting from topmost index
                            uint16_t stripIdx = (row * PIXELS_PER_PANEL) + (z * NR_OF_PANELS) + col;
                            // Take 3 color bytes from buffer
                            strip.setPixelColor(stripIdx, strip.Color(data[voxelIdx], data[voxelIdx + 1], data[voxelIdx + 2]));   //(z, col, row, pixelColor);
                        }
                        voxelIdx+=3; // Increment buffer index by 3 bytes
                        if(stop == TRUE) {return;}
                    }
                }
                // Display!!
                if(packetNumber == totalPackets) {strip.show();}
            }
        }
    }
    else if(millis() - timeLastPacketReceived > TPM2NET_PACKET_TIMEOUT) {
        // No data, nothing to do
        for(uint16_t i=0; i<strip.numPixels(); i++)
            strip.setPixelColor(i, 0);  // Turn Off all pixels
        strip.show();
        if(stop == TRUE) {return;}
    }
}

#10

You posted this also in a github issue in the firmware repo. For discussions like this regarding problem solving some code, this forum is the ideal place!

Thanks :smile:


#11

Thanks for letting me know. It was exactly for not knowing this that I’ve posted it on both these forums and github (following a link from an earlier post by loopj in here).