Socket Communication

I'm trying to send and receive data to and from an arduino yun via wifi. I'm using sockets for this purpose, and I have only been able to send data to the Yun but could not receive data from it. Any ideas on how to receive data from the Yun through wifi sockets?

1 Like

What does receive your data? A process on the linux side or the sketch on the Atmega?

You can send to the Yun, but not receive from it? Are you trying to send back on the same socket that works in one direction? Or is the Yun trying to open the socket but can't send?

Seeing your code so far (both sides) would help.

I'm trying to get an android device to communicate with a yun through wifi socket. Sending data from the Android to the Yun and receiving data from the Yun on the android device.

So far, I can only send data from the Android to the Yun but not the other way around.

#include <Bridge.h>
#include <YunServer.h>
#include <YunClient.h>

#define PORT1 4444

YunServer server(PORT);

void setup() {
  Serial.begin(115200);
  Bridge.begin();

  server.noListenOnLocalhost();
  server.begin();
}

void loop() {
  YunClient client = server.accept();

  if(client.connected()){
    Serial.println("CLIENT CONNECTED!");

    String string = "";

    while(client.connected()){
      if(client.available()){
        char received = client.read();
        if(received != '\n' && received != 4){
          string += received;
        }
        if(received == '\n'){
          int val = atoi(&string[0]);
          analogWrite(13, val);
          analogWrite(6, val);
          Serial.println(val);
          string = "";
        }
        if(received == 4){
          break;
        }
        
        //data sending
        client.write(val);
      }//end if client available
    }//end while connected
    client.stop();

  }
  else {
    Serial.println("no client connected, retrying");
  }

  delay(1000);

}

Above is the Arduino Code based off an online example

What are you trying to send back? I see a few things that don't make sense, I don't think you really want what you're asking the code to do.

From reading the code in your while loop, this is how I understand that the program works every time a character is received:

  • add the character to the string if not newline or EOT
  • if newline, convert string to number, print it and set output pins
  • if EOT break out of loop and close connection
  • always write the "val" value to the client, whether or not a value was set

I see two problems with the way that "val" is written to the client: val is declared inside the code block for the if statement, but it is used outside of that block -- this is not correct. But worse is that val is sent on every character received, but val is only set to a meaningful value when a newline is received. Most of the time you will be sending out whatever garbage is in your uninitialized variable.

I'm going to guess that the client.write(val) call should be inside the if newline block?

Another question: when is the EOT character sent to the Yun? If it's sent immediately after sending the line of data, then the while loop will exit and the connection will be closed, probably before the sent value has a chance to go out. If the EOT is only sent when the Android device closes the connection, then this shouldn't be an issue.

Can you describe the protocol and what you are expecting to do? I'm guessing your description is going to be somewhat different than the code.

The EOT is sent to the Yun only after the Android device closes the connection.

What I'm trying to do in the code is to send values from the Android device to the Yun and receive those same values back from the Yun.

It is the first time for me to do this, so the purpose is just to get acquainted to the Yun's wifi socket communication.

Hope this is a lot more clearer for a description.

I would suggest this re-write of the code block:

        if(received == 4){
          break;
        }
        if(received == '\n'){
          int val = atoi(&string[0]);
          analogWrite(13, val);
          analogWrite(6, val);
          Serial.println(val);
          //data sending
          client.write(val);
          // clear out variables
          string = "";
          val = 0;
        } else {
          string += received;
	}

The idea is to always leave variables in a known state.
Floating variables are a bad idea - especially in embedded systems.

Lastly, in-stream signaling (the EOT) is not a good idea. UNLESS your
plan is to write a entire protocol. This is my suggestion.

Jesse

Thank you Jesse. I will try that and get back to you.

Catalyst0001:
Thank you Jesse. I will try that and get back to you.

I'm also learning sockets (and Android) and managed to send data to Arduino Yun via Wifi from android tablet (4.0.3) with a similar code.

Now I want to learn how to receive info too. Would you share some of your android code to sending and receiving data?

Here's mine (only the sending socket part):

private void enviarSocket (String command, String received_data){

        Socket socket = null;
        DataOutputStream dataOutputStream = null;
        DataInputStream dataInputStream = null;

        try{
            socket = new Socket("192.168.50.13",5555);
            dataOutputStream = new DataOutputStream(socket.getOutputStream());
            dataInputStream = new DataInputStream(socket.getInputStream());
            dataOutputStream.writeBytes(command);


        } catch (UnknownHostException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } finally{
            if (socket != null){

                try{
                    socket.close();

                } catch (IOException e) {
                    e.printStackTrace();
                }

            }

            if(dataOutputStream != null){

                try{
                    dataOutputStream.close();

                } catch (IOException e) {
                    e.printStackTrace();
                }
            }

            if(dataInputStream != null){
                try{
                    dataInputStream.close();

                } catch (IOException e) {
                    e.printStackTrace();
                }

            }
        }

    }

This function only sends but I want to "listen" to any incoming socket too. Any help from android programmers is appreciated.

I finally managed to get it to work Thanks again jessemonroy650. I'm still playing with it to try and understand it.
@mart256

To read from the socket on Andrid app u may add

DataInputStream.read();

under you try block
So, it might be something like this

try{
socket = new Socket("192.168.50.13",5555);
dataOutputStream = new DataOutputStream(socket.getOutputStream());
dataInputStream = new DataInputStream(socket.getInputStream());
dataOutputStream.writeBytes(command);
DataInputStream.read();
}
Hope that helps

For Catalyst0001 & mart256,
the link below is for working python code. This is used as a "base test" because it is a "KNOWN GOOD".

If you can run python, start with the code in simple_ex
https://github.com/jessemonroy650/multicast-boilerplate/tree/master/simple_ex

Then try these.
Simple examples for sockets using UDP, TCP, and UPD multicast, & UDP unicast to multicast

If you can work your way through them, you'll have alot covered.

As stated in NOTES, we used this code to get multi-cast working on google Glass, which is much more tedious.

Jesse