Student Idea: The aim was to have an Arduino driven tangible interface which allowed the user to make decisions and as a consequence different screens would output different videos(could be more than 10 screens). I advised the student to build this project with processing due to its ease of compatibility with the Arduino.
Solution: A server / client combo lends itself well to this type of application. I found articulating the basic concepts of networking quite difficult, especially as the students are quite new to programming in general. I wrote this simple example to demonstrate how a distributed system could work. The server starts on application start up and waits for clients to connect. It has the capability to store ip addresses of 10 clients. As soon as a client starts up the user must type the IP address of the server into the app and press enter. Every time a client connects to the server, the server stores the clients IP address in an array in the order of which they connect (first to connect = 0, last to connect = 9). The server acts as if it was the tangible user interface but the choices are made by using the numbers on the keyboard. If the user click the number 4 the server gets the IP address from the list of clients at the index of 4 and sends that along with a random number to every client connected ( format example: 10.0.1.3-4 | ip-number ). It is the clients responsibility to read in the message, check the ip address matchs its own and if it does then change the background colour depending on the random number that was sent in the message.
WARNING: In no way is this a complete system but just a demo for the underlying techniques that would be used to create a distributed video triggering system.
Server:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 |
// University College Falmouth // Alcwyn Parker // http://www.alcwynparker.co.uk // Example: Video Triggering server // Description: // A very basic server that logs 10 clients in the order that they connect // and then is able to send commands to individual clients via their IP // and a number between 1 and 3. This example sprung from a request by a student // to control multiple screens (up to 10) from a users interactions // Import the net libraries import processing.net.*; import processing.net.*; import java.net.InetAddress; // declare Inet address object and a string to store the IP in InetAddress inet; String IP; // Declare a server Server myServer; Boolean serverActive = true; // an array to store connected clients String[] clients = new String[10]; void setup() { size(200, 200); // Starts a myServer on port 1027 myServer = new Server(this, 1027); // Retreive IP adress try { inet = InetAddress.getLocalHost(); IP = inet.getHostAddress(); } catch (Exception e) { e.printStackTrace(); IP = "couldnt get IP"; } } void draw() { background(0); text(IP, 10,20); // UI for server state if( serverActive ) { text("Server Active", 10,50); }else { text("Server OFF", 10,50); } // create a blank screen to read the server message into String connections = ""; // UX for clients connected for (int i = 0; i < clients.length; i++) { if (clients[i] != "" && clients[i] != null) { connections+="[*]"; }else { connections+="[0]"; } } text(connections, 10,80); } // Send user interactions to all of the clients // it is up to the client to decide whether the message is for them or not void keyPressed() { // ascii range for 0 - 9 if ( key > 47 && key < 58) { // make sure the key value parses as an integer int num = int("" + key); // send the IP address of the client this message is intended for and a random number from 0-2 ( this is to represent a choice the user could have made) // IP CHOICE // The format of the message - 10.0.1.3-1 myServer.write(clients[num] + "-" + floor(random(3))); } } // click the window to start or stop the server void mousePressed() { if (serverActive) { // stop server myServer.stop(); serverActive = false; println("Server Stopper"); }else { //Start server myServer = new Server(this, 1027); serverActive = true; println("Server Started"); } // reset the client list for (int i = 0; i < clients.length; i++) { clients[i] = ""; } } // on connection assign ip to array as index void serverEvent(Server someServer, Client someClient) { println("We have a new client: " + someClient.ip()); for (int i = 0; i < clients.length; i++) { if (clients[i] == "" || clients[i] == null) { clients[i] = someClient.ip(); break; } } } |
Client:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 |
// University College Falmouth // Alcwyn Parker // http://www.alcwynparker.co.uk // Example: Video Triggering client // Description: // A client designed to connect to the simple video trigger server // and then listen for messages and then change colour depending on what number is recieved. // the server communicates with all clients so each client must check its IP address with the // one in the message before it acts. // Import the net libraries import processing.net.*; import java.net.InetAddress; // declare Inet address object and a string to store the IP in InetAddress inet; String clientIP; Client myClient; int dataIn; String receivedData = ""; String serverIP =""; color bg = color(0,0,0); void setup() { size(200, 200); // Connect to the local machine at port 5204. // This example will not run if you haven't // previously started a server on this port. // Retreive IP adress try { inet = InetAddress.getLocalHost(); clientIP = inet.getHostAddress(); } catch (Exception e) { e.printStackTrace(); clientIP = "couldnt get IP"; } println(clientIP); } void draw() { background(bg); // UI text(clientIP, 10,20); text(serverIP, 10, 50); text("message: " + receivedData, 10, 80); // Check to see if client is already connected if (myClient != null) { // attempt to read from server try{ // check for incoming data if (myClient.available() > 0) { receivedData =""; while(myClient.available() > 0) { //output data dataIn = myClient.read(); receivedData+= char(dataIn); } // Break the message in to its parts delimited by - String[] parts = split(receivedData, '-'); // if the message is in the right format if (parts.length > 0){ // if the ip address matches this clients if (parts[0].equals(clientIP)) { // check the message sent with the IP address and respond accordingly switch(int(parts[1])) { case 0: bg = color(255,0,0); break; case 1: bg = color(0,255,0); break; case 2: bg = color(0,0,255); break; } } } } }catch (Exception e) { println("server disconnected"); } } } // allow the operator to input the servers IP address void keyPressed() { switch(key) { case '\b': if (serverIP.length() > 0) { serverIP = serverIP.substring(0, serverIP.length()-1); } break; case '\n': connectToServer(); default: serverIP = serverIP + key; break; } } void connectToServer() { myClient = new Client(this, serverIP, 1027); } |