Arduino UDP "client" code, Change the UDPServer variable to the IP of the RPi.
#include <SPI.h>
#include <Ethernet.h>
#include <EthernetUdp.h>
// Enter a MAC address for your controller below.
// Newer Ethernet shields have a MAC address printed on a sticker on the shield
byte mac[] = {
0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED
};
unsigned int UDPport = 5005;// local port to listen for UDP packets
IPAddress UDPServer(192, 168, 1, 253); // destination device server
const int UDP_PACKET_SIZE = 64;
byte packetBuffer[ UDP_PACKET_SIZE] = "0";
unsigned int noChange = 0;
// A UDP instance to let us send and receive packets over UDP
EthernetUDP Udp;
unsigned long currentTime;
unsigned long secondTime;
unsigned long msPerSecond = 100UL;
int UDPCount = 0;
void setup()
{
Serial.begin(115200);
pinMode(4, OUTPUT);
digitalWrite(4, HIGH);
Serial.print(F("Starting w5100..."));
// Ethernet.begin(mac,ip,gateway,gateway,subnet);
while (!Ethernet.begin(mac)) {
Serial.println(F("failed. Retrying in 5 seconds."));
delay(5000);
Serial.print(F("Starting w5100..."));
}
Serial.println(Ethernet.localIP());
Udp.begin(UDPport);
delay(2000);
currentTime = millis();
secondTime = currentTime;
Serial.println("Ready");
}
boolean packetOut = false;
void loop()
{
currentTime = millis();
getUDPpacket();
if (currentTime - secondTime > msPerSecond) {
byte rtnVal = Ethernet.maintain();
switch (rtnVal) {
case 1: Serial.println(F("\r\nDHCP renew fail"));
break;
case 2: Serial.println(F("\r\nDHCP renew ok"));
break;
case 3: Serial.println(F("\r\nDHCP rebind fail"));
break;
case 4: Serial.println(F("\r\nDHCP rebind ok"));
break;
}
Serial.println(F("\r\nUDP send"));
sendUDPpacket(UDPServer); // send an NTP packet to a time server
packetOut = true;
secondTime += msPerSecond;
}
}
unsigned int udpCount = 0;
// send an NTP request to the time server at the given address
void sendUDPpacket(IPAddress& address)
{
if(packetOut) Serial.println("Missed packet");
udpCount++;
// set all bytes in the buffer to 0
memset(packetBuffer, 0, UDP_PACKET_SIZE);
sprintf((char*)packetBuffer, "Arduino count %u", udpCount);
if(Udp.beginPacket(address, UDPport) == 0)
{
Serial.println(F("BeginPacket fail"));
return;
}
Udp.write(packetBuffer, UDP_PACKET_SIZE);
if(Udp.endPacket() == 0)
{
Serial.println(F("endPacket fail"));
return;
}
packetOut = true;
}
void getUDPpacket() {
if ( Udp.parsePacket() ) {
// We've received a packet, read the data from it
if (Udp.remoteIP() == UDPServer) {
Serial.print(F("UDP IP OK "));
}
else {
Serial.println(F("UDP IP Bad"));
return;
}
if (Udp.remotePort() == UDPport) {
Serial.println(F("Port OK"));
}
else {
Serial.println(F("Port Bad"));
return;
}
Udp.read(packetBuffer, UDP_PACKET_SIZE); // read the packet into the buffer
Serial.print(F("Received: "));
Serial.println((char*)packetBuffer);
packetOut = false;
}
}
RPi "server" code. Should work on just about any Linux box.
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <err.h>
int main(int argc, char *argv[]) {
if(argc < 2) {
// if(daemon(0,0) == -1) err(1,NULL);
}
int sock, n, nr;
socklen_t fromlen;
struct sockaddr_in server;
struct sockaddr_in from;
sock = socket(AF_INET, SOCK_DGRAM, 0);
if (sock < 0)
printf("Can not create socket in server\n");
memset(&server, 0, sizeof(struct sockaddr_in));
server.sin_family = AF_INET;
server.sin_port = htons(5005);
server.sin_addr.s_addr = INADDR_ANY;
if(bind(sock, (struct sockaddr *)&server, sizeof(server)) < 0)
printf("Can not bind in server!\n");
memset(&from, 0, sizeof(struct sockaddr_in));
fromlen = sizeof(struct sockaddr_in);
while(1) {
int n, l1;
unsigned char tBuf[64];
unsigned char outBuf[64];
// fflush(stdout);
n = recvfrom(sock, tBuf, 64, 0, (struct sockaddr*) &from, &fromlen);
if (n < 0) {
printf("Can not receive in server!\n");
}
printf("%s from IP:%s, Port:%hu\r\n",&tBuf[0],inet_ntoa(from.sin_addr), ntohs(from.sin_port));
strcpy(outBuf,"127 127 0 0\n\0");
socklen_t length = sizeof(struct sockaddr_in);
n = sendto(sock, tBuf, 64, 0, (const struct sockaddr *)&from, fromlen);
if(n < 0) {
printf("Can not send from client");
}
}
}
To compile
cc udpbasic.c -o udpbasic
To run
./udpbasic
edit: Both were connected to the network via ethernet, but either or both could be connected via wifi just as easily, as long as the wifi module/shield for the Arduino can use UDP. The first (original wifi shield had some problems with UDP.