TCP IP client and server for Arduino (Wemos D1 mini) and Raspberry Pi 3

Hey

I have Wemos D1 mini, few sensors and Pi 3. I want to send sensor data measured on Wemos D1 mini to Raspberry pi3 over wifi. Someone suggested I should use TCP IP client server, How do I do that? what libraries? and any suggested source code? any help ?

Thanks

I prefer UDP. It is easier and faster than trying to maintain a connection. I think I have code for both a RPi and Arduino using an ethernet shield, but the transport is transparent and not a deal if the wifi unit can handle UDP.

Could I please have a look at them? and see if I can put them on ?, also does it mean Rpi and Arduino were connected via ethernet cable when you said ethernet shield?, Thank you so much for the reply.

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.

Thank you so much, I will give these a go and let you know. Thank you so much again, I been stuck for 3 weeks on this.