wbcrisman:
I want to stream data from my arduino uno/w Ethernet shield using a more reliable version of UDP.
Theoretically, UDP is unreliable. Pragmatically, in many real World applications UDP proves no less reliable than TCP. For UDP to be unreliable, the failure modes which cause UDP to be unreliable, must be present within the usage scenario.
I don't care to lose some packets (as long as i get about 80%) but i would like for them to arrive in order and be dropped if they come in late. Is there a way to add a time stamp and sequence number to the current UDP library? Or could I write this a function in my sketch?
Fundamentally, the answer is yes. You can add whatever you want to a UDP packet, subject to a packet length limitation specific to the Arduino. Obviously the receiving application needs to be able to decode the packet it has been sent. You may need to check endianess and reorder bytes accordingly.
Here is some code I wrote a few weeks ago to answer a different forum question, which may help to get you started. A sequence field can be easily added to the DCB structure and populated with a global counter. It would make sense to move the guts of the loop() function to your own function.
#include <Streaming.h>
#include <SPI.h>
#include <Ethernet.h>
#include <EthernetUdp.h>
//#define _DEBUG
byte mac[] = { 0x00, 0xAA, 0xBB, 0xCC, 0xDE, 0x02 };
IPAddress ip(192, 168, 200, 64);
EthernetUDP udp;
void setup()
{
Serial.begin(9600);
Ethernet.begin(mac);
}
typedef struct DCB {
int pinA0;
int pinA1;
int pinA2;
int pinA3;
int pinA4;
int pinA5;
uint32_t timeStamp;
char stringData[32];
byte endData;
} DCB;
uint32_t period = 0L;
uint32_t periodStart = 0L;
void loop()
{
periodStart = millis();
//grab some memory from the heap
DCB* dcbData = (DCB*) malloc(sizeof(DCB));
// populate device control block
dcbData->pinA0 = analogRead(A0);
dcbData->pinA1 = analogRead(A1);
dcbData->pinA2 = analogRead(A2);
dcbData->pinA3 = analogRead(A3);
dcbData->pinA4 = analogRead(A4);
dcbData->pinA5 = analogRead(A5);
dcbData->timeStamp = millis();
strcpy(dcbData->stringData, "Matt's Uno\r\n\0");
dcbData->endData = 0;
//send once every 40 ms
period += millis() - periodStart;
if (period >= 40) {
udp.begin(2000);
udp.beginPacket(ip, 2000);
udp.write( (byte*) dcbData, sizeof(DCB) );
udp.endPacket();
udp.stop();
period = 0;
};
//always free memory grabbed from the heap
free(dcbData);
}
I provided a more sophisticated example of doing roughly the same thing using class inheritance, on this thread
http://forum.arduino.cc/index.php?topic=201523.msg1485490#msg1485490
HTH