UDP and Photon/Core

Hi! Im experimenting with UDP and the Photon/. I’ve been reading on some of the online help Particle supplies about UDP, but I’m still a bit confused. Can anyone explain to me or supply code that would simple read in say, the value of a photoresister and then send that data? How can I view whats being sent on my computer vs using another photon?

Reading a phitoresistor is done via analogRead() and there are docs.

UDP usage samples are also shown in the docs
https://docs.particle.io/reference/firmware/photon/#udp
https://docs.particle.io/reference/firmware/photon/#sendpacket-

To receive UDP packets on your PC you’d need a dedicated client program or generic tools like WireShark.

There are also other resources on the web about UDP traffic/monitoring/…

Hi @invaderzim15

If you are looking for a simple way to read the value of a photoresists, why not use the Particle cloud? Much easier than trying to roll-your-own UDP solution.

If you need UDP and you get stuck, post some code here and we will help you!

Thanks for the info so far. The reason Im not using the cloud is being this is an assignemnt where im supposed to implement UDP. Here’s the code I have but I honeslty have no idea if it’s right or not. I get an error saying there’s too many decimals. I also don’t know how to get my computer to eventually get data back to the photon. Any information would be really helpful.

unsigned int localPort = 8888;
UDP Udp;

void setup() {
    pinMode(A0, INPUT);
  Udp.begin(localPort);
  Serial.begin(9600);
  Serial.println(WiFi.localIP());
}

void loop() {
  char light = analogRead(A0);
  //This is just gettin any sent data, im still trying to get the photon to send data before I have it read anything going back to it.
  if (Udp.parsePacket() > 0) {
    char c = Udp.read();
    Udp.flush();
//this is where I want to have my photon send data to my computer. The IP and port are that of my computer.
    IPAddress ipAddress = 192.168.1.186 
    int port = "60151"
    Udp.beginPacket(ipAddress, port);
    Udp.write(light);
    Udp.endPacket();
  }
}

I think it's not a problem with your UDP insight but rather with the C side of things :wink:

You are writing this IP address as if it was a number literal and for that reason you are providing too many decimal seperators (".") and you are missing several semicolons (";") too.
I've reformatted your code snippet so that you can see what I mean with the number literal.

Further more you'd need to use an int for your analogRead() since it will return a numeric value between 0 and 4095 and not a char.

You need to read the code samples a bit more careful.

For sending back UDP packets, you could use Particle CLI particle udp send or again a dedicated application (selfmade or downloaded ... Google helps :wink: )


BTW: To format a code block in this forum correctly you should wrap it like this

 ```cpp
 // these three symbols are called grave accent, just to google how to type them with your keyboard layout
 // 
 // code block here

Thanks for your help! I got it working. I got the code to send. However, I have a question. I’m sending it without a buffer. When I tried to use the buffer, I got all 0s. This is the code WITH the buffer. When I delete Udp.sendPacket(buffer, bufferSize, remoteIP, port); it works, just without the buffer. Can you explain to me how a buffer works and what its doing? Thanks!

unsigned int localPort = 8888;
UDP Udp;

const size_t bufferSize = 32;
char buffer[bufferSize];

void setup() {
  pinMode(A0, INPUT);
  Udp.begin(localPort);
  Serial.begin(9600);
  Serial.println(WiFi.localIP());
}

void loop() 
{
  int light = analogRead(A0);
//this is where I want to have my photon send data to my computer. The IP and port are that of my computer.
    IPAddress remoteIP(192,168,1,186);
    int port = 60151;
    Udp.beginPacket(remoteIP, port);
    Udp.write(light);
    Udp.endPacket();
    Udp.sendPacket(buffer, bufferSize, remoteIP, port);
    delay(1000);
}

Hmm, I can’t see you putting any data into the buffer.
So when you send a zero-initialized buffer, what else than zeroes do you expect to receive?

There seems to be some confusion between pointers and data.
My suggestion:
Udp.beginPacket(remoteIP, port);
Udp.write(&light, sizeof(int));
Udp.endPacket();

I would give it a try. This code works for me all the time, without the second call.
If the UDP.write-function needs only one argument, it is char. Although the docs don’t explicitely state that it is a single byte I am assuming it. Your value would never fit.

Similar your second call should read:

Udp.sendPacket(&light, sizeof(int), remoteIP, port);

I don’t know what’s the difference between those two versions except for the syntax.

The main difference between Udp.write(buf, len) and Udp.sendPacket(buf, len, remoteIP, port) is that the latter does send the data directly from the buffer, while the earlier first copies the data over into its internal buffer and then sends from there on Udp.endPacket().
Hence there is also no need for Udp.beginPacket() and Udp.endPacket().

1 Like

for the udp.sendPacket, how do I fill the buffer with my data? I’m clearly really new to this and don’t have a lot of experience coding so thanks for being patient. This is what I mean by fill the buffer. The documents just say “fill the buffer.” Also @dial The code with the pointer only works if I change it to a char which makes sense with what you said but the data is complete nonsense when I do that. Basically I just want this to send an int that can go up to 1024, or 10 bits.

const size_t bufferSize = 1024;
char buffer[bufferSize];

// which address and port to send the data to
IPAddress remoteIP(192,168,10,234);
int remotePort = 22;

// fill the buffer with goodness
// ...

// now send the buffer as a packet

if (udp.sendPacket(buffer, bufferSize, remoteIP, remotePort)<0) {
    // opps, packet not sent
}

You definetely are lacking some basics. I would suggest some readings here, but I don’t have any suggestion here.

Your code is entirely from the docs. First point is what ScruffR already mentioned: you declare your buffer, claim it it, but do not fill it.
There has to be something like:

for(int i = 0; i < buffersize: i++)
    *((char *)buffer + i) = *((char *)something + i);

This would fill up your buffer with goodness.
Secondly: Why would you want to use 1024 bytes, if you have only integer? The declaration there claims 1024 bytes (as char). If you want integer, you need 2 bytes, or maybe 4 for as long.
And at last: What do you want with 10 bits? It sound, as if there is really a misunderstanding.

Maybe somebody else could suggest some readings. I have no idea except Kernighan-Ritchie.

Or if you are more the audi-visual type and have lots of time, give these a try
https://www.youtube.com/watch?v=2w-CgyIrjUs

They start very basic (which seems to be needed here, but get on with the subject, just a few “weeks” on in the course).

To get your use-case sorted, I’ll come back …

1 Like

I meant I want up to go up to the actual number 1024, which is 10 bits (bits vs bytes) of data. 2 bytes is good enough. Right now it can’t go up that high. I put in the for loop you suggested but now get sort of random data. Before the data went up and down with the amount of light I shown on the resistor, but would get the error “malformed data” as soon as the value got too high. Now it’s always sending data, but it seems sort of scrambled. Thanks for the help so far though!

unsigned int localPort = 8888;
UDP Udp;

const size_t bufferSize = 2;
char buffer[bufferSize];

void setup() {
  pinMode(A0, INPUT);
  Udp.begin(localPort);
  Serial.begin(9600);
  Serial.println(WiFi.localIP());
}
void loop() 
{
  char light = analogRead(A0);
    IPAddress remoteIP(192,168,1,186);
    int port = 60151;
    for (int i=0; i<bufferSize;i++)
    {
       *((char *)buffer + i) = *((char *)light + i);
    }
    Udp.sendPacket(buffer, bufferSize, remoteIP, port);
    delay(1000);
}

That should be 'int'.

Why bother with the buffer at all:

unsigned int localPort = 8888;
UDP Udp;
IPAddress remoteIP(192,168,1,186);
int port = 60151;

void setup() {
  pinMode(A0, INPUT);
  Udp.begin(localPort);
  Serial.begin(9600);
  Serial.println(WiFi.localIP());
}

void loop() 
{
    int   light = analogRead(A0);

    Udp.sendPacket(&light, sizeof(light), remoteIP, port);
    delay(1000);
}
1 Like

Also, be sure that the “endianess” matches between your Particle device and the device on the receiving end. A mismatch can be very deceiving and look like random data.

@Muskie I tried doing that but it says “no matching function.” It looks like it’s having a problem with the int (“no conversion from ‘int’ to ‘const char’”) but the char seems to mess the data up. Any Suggestions?

If you are referring to the sendPacket() function then it could be how that function is declared. Without seeing the declaration I can’t be sure. My assumption was that it would be declared void * as the first parameter but perhaps not. Anyway, try this:

   Udp.sendPacket((const char *)&light, sizeof(light), remoteIP, port);

If that doesn’t work, then perhaps you can post the exact line causing the error and what the error message says.