Communicating between Raspberry Pi and Arduino over LAN

16,491

After digging around, I found my solution, and some more details. So both the R-Pi and the Arduino can do TCP, and I found the source of my errors.

1) I believe the delay I set after server.begin() in my Arduino Code was giving me the error, since it pauses the program and so probably pauses the listening process.

2) The while loop in my R-Pi client code was giving me a broken pipe error.

3) The if (client == True) test in my Arduino's loop() was not working. The R-Pi could connect and send messages with no error, but the Arduino didn't seem to be responding properly. Once I pulled everything out of the if statement, the R-Pi started receiving my messages and I saw everything respond. Here's my final code:

R-Pi:

from socket import *
import select

data = None

timeout = 3 # timeout in seconds
msg = "test"

host = "192.168.1.113"
print ("Connecting to " + host)

port = 23

s = socket(AF_INET, SOCK_STREAM)
print "Socket made"

ready = select.select([s],[],[],timeout)


s.connect((host,port))
print("Connection made")


if ready[0]:        #if data is actually available for you
    print("[INFO] Sending message...")
    s.sendall(msg)
    print("[INFO] Message sent.")

    data = s.recv(4096)
    print("[INFO] Data received")
    print data

Arduino:

#include <SPI.h>
#include <Ethernet.h>

//90-a2-da-0f-25-E7
byte mac[] = {0x90, 0xA2, 0xDA, 0x0f, 0x25, 0xE7};

//ip Address for shield
byte ip[] = {192,168,1,113};

//Use port 23 for telnet
EthernetServer server = EthernetServer(23);

void setup() {
  Serial.begin(9600);     //For visual feedback on what's going on
  while(!Serial){
    ;   //wait for serial to connect -- needed by Leonardo
  }

  Ethernet.begin(mac,ip); // init EthernetShield
  delay(1000);

  server.begin();
  if(server.available()){
    Serial.println("Client available");
  }
}

void loop() {
  // put your main code here, to run repeatedly:
  EthernetClient client = server.available();
  message = client.read();

  server.write(message);
  server.write("Testu ");
  Serial.println(message);

//  if (client == true){                    <----- This check screwed it up. Not needed.
//    Serial.println("Client Connected.");
//    server.write(client.read());        //send back to the client whatever     the client sent to us.
//  }
}
Share:
16,491
David Tran
Author by

David Tran

Updated on June 04, 2022

Comments

  • David Tran
    David Tran almost 2 years

    I'm doing image processing with a raspberry pi, and I want it to be able to talk to my arduino over LAN to steer a light beam based on the pi's instructions. The only things I've seen a lot are direct connections between the Pi and the Arduino. It may seem naive of me, but I was trying to have them communicate using the Arduino as a server, programmed with the Ethernet library, and the Raspberry Pi as the client through the socket library. I gave them both static IP's on my router, and used the following code to try and get through, but I was met with socket.error: [Errno 113] No route to host when my python line came to the command to connect to the Arduino's IP through a specific port.

    Any ideas on how I could more properly do this connection? The main goal for me is to be able to do this over LAN, so the USB connections and the direct I2C connections aren't helpful, though they would definitely get the job done.

    Raspberry Pi:

    from socket import *
    import select
    
    data = None
    
    timeout = 3 # timeout in seconds
    msg = "test"
    
    host = "192.168.1.113"
    print ("Connecting to " + host)
    
    port = 23
    
    s = socket(AF_INET, SOCK_STREAM)
    print "Socket made"
    
    ready = select.select([s],[],[],timeout)
    
    
    s.connect((host,port))
    print("Connection made")
    
    while True:
    
        if data != None:
            print("[INFO] Sending message...")
            s.sendall(msg)
            data = None
            print("[INFO] Message sent.")
            continue
    
        if ready[0]:        #if data is actually available for you
            data = s.recv(4096)
            print("[INFO] Data received")
            print data
            continue
    

    Arduino:

    //90-a2-da-0f-25-E7
    byte mac[] = {0x90, 0xA2, 0xDA, 0x0f, 0x25, 0xE7};
    
    //ip Address for shield
    byte ip[] = {192,168,1,113};
    
    //Use port 23
    EthernetServer server = EthernetServer(23);
    
    void setup() {
      //init device
      Ethernet.begin(mac,ip);
      //start listening for clients
      server.begin();
    
      Serial.begin(9600);     //For visual feedback on what's going on
      while(!Serial){
        ;   //cause Leonardo
      }
      delay(1000);
      if(server.available()){
      Serial.write("Client available");
    }
    }
    
    void loop() {
      // put your main code here, to run repeatedly:
      EthernetClient client = server.available();
        if (client == true){
          Serial.write("Client Connected.");
    
          if(client.read() > 0){
            Serial.write(client.read());        
          }
          else{
            server.write("ping");
          }
        }
        else{
          Serial.println("No one's here yet...");
        }
        delay(1500);
    }