Difference between revisions of "Tutorial: Raspberry Pi communication with Processing"

From dftwiki3
Jump to: navigation, search
(Client code)
(Typical Output)
 
(2 intermediate revisions by the same user not shown)
Line 146: Line 146:
 
==Client code==
 
==Client code==
 
<br />
 
<br />
The client code is written in [https://processing.org Processing 2] and uses its [http://processing.org/reference/libraries/net/Client.html client] class to create a client that can communicate with our server over a socket.
+
The client code is written in [http://processing.org Processing 2] and uses its [http://processing.org/reference/libraries/net/Client.html client] class to create a client that can communicate with our server over a socket.
 
<br />
 
<br />
 
<source lang="java">
 
<source lang="java">
Line 232: Line 232:
 
</pre></code>
 
</pre></code>
 
<br />
 
<br />
 +
while the applet will show something similar to this:
 +
 
<br />
 
<br />
 +
<center>[[Image:raspberryPiProcessingApplet1.png]]</center>
 
<br />
 
<br />
 
<br />
 
<br />
Line 252: Line 255:
 
<br />
 
<br />
 
<br />
 
<br />
[[Category:Tutorials]][[Category:Rasberry Pi]]
+
[[Category:Tutorials]][[Category:Rasberry Pi]][[Category:Processing]]

Latest revision as of 17:08, 26 July 2013

--D. Thiebaut (talk) 17:26, 26 July 2013 (EDT)


This recipe simply replaces the client.c program of the client-server example in this series of Raspberry Pi tutorials and replaces it by a client written in Processing 2







Hardware Setup


MacToRasberryConnection.png


  • The setup is that proposed in the excellent blog page at http://pihw.wordpress.com/guides/direct-network-connection/ from which the image above is taken.
  • No need to try to copy what they already did very well, so simply follow their recommendations and connect your laptop to the Raspberry Pi using an ethernet cable.





Server/Client setup

  • Here we take the server part of the example from User Moorthy at RPI and adapt it slightly for our use.



Server code


/* A simple server in the internet domain using TCP.
myServer.c
D. Thiebaut
Adapted from http://www.cs.rpi.edu/~moorthy/Courses/os98/Pgms/socket.html
The port number used in 51717.
This code is compiled and run on the Raspberry as follows:
   
    g++ -o myServer myServer.c 
    ./myServer

The server waits for a connection request from a client.
The server assumes the client will send positive integers, which it sends back multiplied by 2.
If the server receives -1 it closes the socket with the client.
If the server receives -2, it exits.
*/

#include <stdio.h>
#include <sys/types.h> 
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>


void error( char *msg ) {
  perror(  msg );
  exit(1);
}

int func( int a ) {
   return 2 * a;
}

void sendData( int sockfd, int x ) {
  int n;

  char buffer[32];
  sprintf( buffer, "%d\n", x );
  if ( (n = write( sockfd, buffer, strlen(buffer) ) ) < 0 )
    error( const_cast<char *>( "ERROR writing to socket") );
  buffer[n] = '\0';
}

int getData( int sockfd ) {
  char buffer[32];
  int n;

  if ( (n = read(sockfd,buffer,31) ) < 0 )
    error( const_cast<char *>( "ERROR reading from socket") );
  buffer[n] = '\0';
  return atoi( buffer );
}

int main(int argc, char *argv[]) {
     int sockfd, newsockfd, portno = 51717, clilen;
     char buffer[256];
     struct sockaddr_in serv_addr, cli_addr;
     int n;
     int data;

     printf( "using port #%d\n", portno );
    
     sockfd = socket(AF_INET, SOCK_STREAM, 0);
     if (sockfd < 0) 
         error( const_cast<char *>("ERROR opening socket") );
     bzero((char *) &serv_addr, sizeof(serv_addr));

     serv_addr.sin_family = AF_INET;
     serv_addr.sin_addr.s_addr = INADDR_ANY;
     serv_addr.sin_port = htons( portno );
     if (bind(sockfd, (struct sockaddr *) &serv_addr,
              sizeof(serv_addr)) < 0) 
       error( const_cast<char *>( "ERROR on binding" ) );
     listen(sockfd,5);
     clilen = sizeof(cli_addr);
  
     //--- infinite wait on a connection ---
     while ( 1 ) {
        printf( "waiting for new client...\n" );
        if ( ( newsockfd = accept( sockfd, (struct sockaddr *) &cli_addr, (socklen_t*) &clilen) ) < 0 )
            error( const_cast<char *>("ERROR on accept") );
        printf( "opened new communication with client\n" );
        while ( 1 ) {
	     //---- wait for a number from client ---
             data = getData( newsockfd );
             printf( "got %d\n", data );
             if ( data < 0 ) 
                break;
                
             data = func( data );

             //--- send new data back --- 
	     printf( "sending back %d\n", data );
             sendData( newsockfd, data );
	}
        close( newsockfd );

        //--- if -2 sent by client, we can quit ---
        if ( data == -2 )
          break;
     }
     return 0; 
}



Client code


The client code is written in Processing 2 and uses its client class to create a client that can communicate with our server over a socket.

/*
   PiMain.java
   D. Thiebaut
   Processing class extending Processing's PApplet and creating a socket with our raspberry Pi server
   that is running a C/C++ server.

   This class is developped and built inside Eclipse.  To use the Processing IDE, simply remove the import 
   statements as well as the enclosing class.
*/
import processing.core.PApplet;
import processing.core.PFont;
import processing.net.*; 

public class PiMain extends PApplet {
	Client myClient; 
	String dataIn; 
	String raspberryPi = "169.254.0.2";  // change to the iP assigned to your Raspberry Pi
	int portNo  = 51717;        // change this to the port used by the server.
	int count   = 0x2;       // some integer sent to the server
	boolean firstTime = true;    // used to make sure setup initializes the connection only once.
	
	public void setup() {
		 size(600, 500);
		 smooth();
		 
		 if ( firstTime ) {
                         // setup communication with server
			 myClient = new Client(this, raspberryPi, portNo ); 
                         // send the server an integer
			 myClient.write( count++ );
			 firstTime = false;
		 }
		 frameRate( 30 );   // 30 frames/sec
	}
	
	public void draw() {
                // clear background
		background( 0 );

                // read the string sent by the server every second...
		if ( myClient.available() > 0 && frameCount % 30 == 0 ) {
                        // get string and remove white space chars
			dataIn = myClient.readString().trim();
                        // transform it into an int
			int x = Integer.parseInt( dataIn.trim() );
                        // send back a new value
			myClient.write( String.format("%d",++count ) );
		} 
                // display last exchange of data on applet
		text( "Received: "  + dataIn, 20, 20 );
		text( "Sent back: " + count, 20, 40 );
	}
}



Typical Output


The console outputs of the Server is shown below:

pi@raspberrypi ~ $ ./myServer4 
using port #51717
waiting for new client...
opened new communication with client
got 0
sending back 0
got 4
sending back 8
got 5
sending back 10
got 6
sending back 12
got 7
sending back 14
got 8
sending back 16
got 9
...


while the applet will show something similar to this:


RaspberryPiProcessingApplet1.png