In my project I send UDP data every 10 millisecond. Each UDP packet is 2338 bytes. It works great for a few minutes untill my Photon gets “Device went offline”. It takes some time before it comes online again and even though I contintue to send my UDP data it does not receive it as it restarts again. Why does it restart all the time anyway?
Is there a way to restart the code as it comes online again?
Here it my code:
void setup() {
pinMode(led1, OUTPUT);
pinMode(led2, OUTPUT);
myIP = WiFi.localIP();
if (Udp.setBuffer(EXPECTED_PACKED_SIZE))
Udp.begin(localPort);
String ip_str = String(myIP);
Particle.publish(ip_str, "1");
}
void loop() {
int32_t bytes = Udp.parsePacket();
if (bytes >= EXPECTED_PACKED_SIZE) {
// Read first char of data received
char data[EXPECTED_PACKED_SIZE];
Udp.read(data, EXPECTED_PACKED_SIZE);
// Ignore other chars
Udp.flush();
int offset = 0;
int count = 0;
strip.setBrightness(10);
for (int i = 0; i < 167; i++) {
int neopixel = String(String(data[0 + offset]) + String(data[1 + offset]) + String(data[2 + offset])).toInt();
String red = String(data[4 + offset]) + String(data[5 + offset]) + String(data[6 + offset]);
String blue = String(data[7 + offset]) + String(data[8 + offset]) + String(data[9 + offset]);
String green = String(data[10 + offset]) + String(data[11 + offset]) + String(data[12 + offset]);
strip.setPixelColor(neopixel, red.toInt(), blue.toInt(), green.toInt());
offset = offset + 14;
}
// 001:255255255;
strip.show();
}
//Particle.publish("red","1");
// strip.show();
}
Do you see a red flashing SOS pattern on the main LED when it fails? You migth see a red LED flash SOS, followed by a number of flashes (count them) and then another SOS.
If your format is free to be adaped, I’d suggest to going binary rather than text, but if you want to stick to your format then something like this can avoid String completely
char token[4];
int px,r,g,b;
...
for (int i = 0; i < 167; i++)
{
memcpy(token, &data[0+offset], 3); // copy 3bytes over to a single token
token[3] = 0; // terminate that string
px = atoi(token); // convert ASCII to int
memcpy(token, &data[4+offset], 3); // copy 3bytes over to a single token
token[3] = 0; // terminate that string
r = atoi(token); // convert ASCII to int
memcpy(token, &data[7+offset], 3); // copy 3bytes over to a single token
token[3] = 0; // terminate that string
b = atoi(token); // convert ASCII to int
memcpy(token, &data[10+offset], 3); // copy 3bytes over to a single token
token[3] = 0; // terminate that string
g = atoi(token); // convert ASCII to int
strip.setPixelColor(px, r, b, g);
offset = offset + 14;
}
...
And this could be reduced even further if the format used delimiters between each value (e.g. 001:255-255-255;002...) by use of strtok() (instead of memcpy() and manual terminating the string) and an array for your parameters (e.g. int prgb[4]; and strip.setPixelColor(prbg[0], prbg[1], prbg[2], prbg[3]);).
Thanks @ScruffR! Yes I changed to binary so my code looks like this but maybe I should change it even more to resemble your example?
for(int i = 0;i < 167;i++) {
int red = binary2decimal(data[offset]);
offset = offset + 1;
int blue = binary2decimal(data[offset]);
offset = offset + 1;
int green = binary2decimal(data[offset]);
offset = offset + 1;
strip.setPixelColor(i, red, blue, green);
}
int binary2decimal(byte b) {
int dec = 0;
int power = 1;
byte mask;
int weight;
for (mask = 0x01; mask; mask <<= 1) {
if (b & mask) {
weight = 1;
} else {
weight = 0;
}
dec = dec + (power * weight);
power = power * 2;
}
return dec;
}
No, binary is fine (FWIW, I’d prefere it anyway )
Are you sending BCD data? Only then you’d need a binary2decimal conversion. If you are already receiving raw binary, you could just write
Just a note:
You are using mask <<= 1 for the bit to shift, but further down power = power * 2 but actually both do the same thing. Shift left by one is an integer multiplication by two (right shift is integer division by two) - as long the result still fits the data type.
2000+ bytes for a UDP packet is large. You run the risk of the packet being fragemented and parts of it lost. Any reason to chose UDP over TCP for this application?