Processing to Arduino over remote network

Hi,
My first post at this forum I hope you can help me understand what is the best way to run Processing to control an Arduino Mega switching on and off some relays over a remote network.

I have a Processing sketch controlling Arduino via USB/serial. According to a series if words found online Processing send integers to Arduino which in turn switches on and off some relays.
I managed to make this work via Ethernet with an Arduino Ethernet shield mounted on the Mega and in my local network.
Now I need to make this work on a remote network where Processing will be run by a computer in one place and Arduino will receive the integers in another place.
What would the be best way be to get this working?
I bought a dynamic DNS at dyn.com by the way.
Thanks for all your help.
Elso

I bought a dynamic DNS at dyn.com by the way.

For what? Are they hosting a web site for you?

I managed to make this work via Ethernet with an Arduino Ethernet shield mounted on the Mega and in my local network.

With the Arduino as server or as client? If the Arduino is a client, is the Processing app running on the server? If so, then it appears that you simply want to move the Processing app to a different server, not on your local network.

Thanks for all your help.

It is not really clear how your current network is set up, which apps are running where, or what you want the new configuration to be.

You will need to have something at the remote address to update the dyn dns site of the current IP assignment. Many routers have this capability now days. You should be able to test the dyn dns on your current network by using the dyn dns url instead of the ip address assigned to your arduino.

Thanks Zoomkat, I have downloaded an app from the dyn site which should allow me to update the ip address at this location, I will give it a go, I am at the remote location now; will see what the IP adress here is and then probably tell the dyn to name it so that it will be updated from this position but I will always see it with the same name and address I guess. I will give it a go and let you know!

Hi Paul,
I had Processing parsing a website (ie google.news), looking for some words.

Then passing the amount of words found to Arduino (via Serial port); Arduino was using those integers to switch on and off some relays. My laptop was connected to the Arduino via USB cable.
As second step I added an Ethernet shield on the Arduino to basically do exactly the same thing but through Ethernet (UDP send/receive) rather than serial as I wanted the laptop to be physically disconnected from the board.

I am now trying to have the Arduino at a different place than my studio, with a different network than my LAN and I would like Processing to send groups of integers to Arduino, to be used to switch the relays on and off.

I thought about running the Processing app online and have Arduino listening to it, would that be the case of having Arduino as a Web Client? I am still getting to know Ethernet and Arduino. I would consider all options available, would love to go for the simplest as I am still learning how to code properly.

Anyway.
The script in Processing at the moment does this:

import hypermedia.net.*;
UDP udp;  // define the UDP object
String feed = "http://news.google.com/....";
int interval = 5; // this variable will be used to retrieve content;
int lastTime; // var to be used as the last time we fetched the content

// the 4 main categories of words to be found
int categ4 = 0; //word4
int categ3 = 0; //word3
int categ2 = 0; //word2
int categ1 = 0; //word1

// variables that represent the four above mentioned categories

//Serial port;
int c1; // preparing category 1 to be sent
int c2; // preparing category 2 to be sent
int c3; // preparing category 3 to be sent
int c4; // preparing category 3 to be sent

String buffer = ""; // This accumulates characters coming from Arduino
PFont font; // This visualisation needs a font to display the informations collected

void setup() {
  size(1200, 480); 
  frameRate(10); // regulates the speed at which the code is played
  font = loadFont("Akkurat-12.vlw");
  fill(60);
  textFont(font, 12);
  noStroke();
  
  udp = new UDP( this, 6000 );  // create a new datagram connection on port 6000
 //udp.log( true );         // <-- printout the connection activity
 udp.listen( true );           // and wait for incoming message  

  
  lastTime = 1000;
  fetchData();
}
void draw() {
  background(255);
  int n = (interval - ((millis()-lastTime)/500)); // timer
  
  c1 = categ1; // Prepares the values for each category to be sent to Arduino
  c2 = categ2; 
  c3 = categ3; 
  c4 = categ4; 
  
//  println(c1);
  
  text("Data reading from CSS", 55, 40); // diagram of the categories 
  text("Reading feed:", 55, 60);
  text(feed, 55, 80);
  
  text("Word 1", 55, 400);
  text(categ1, 55, 420);
  rect(55, 380, 150, categ1*(-2.5));
  
  text("Word 2", 245, 400);
  text(categ2, 245, 420);
  rect(245, 380, 150, categ2*(-2.5));
  
  text("Word 3", 435, 400);
  text(categ3, 435, 420);
  rect(435, 380, 150, categ3* (-2.5));
  
   text("Word 4", 625, 400);
  text(categ4, 625, 420);
  rect(625, 380, 150, categ4* (-2.5));
  

  if (n <= 0) { // It sends data to Arduino every 1 second
    fetchData();
    lastTime = millis();
    
    String ip       = "192.168.1.167"; // the remote IP address
    int port        = 8888;        // the destination port
 
    String cone="P"+categ1;
    println(cone);
    udp.send(cone, ip, port );   // the message to send
    myDelay(250);
    
    String ctwo="Q"+c2;
    println(ctwo);
    udp.send(ctwo, ip, port );   // the message to send
    myDelay(250);
    
    String cthree="R"+c3;
    println(cthree);
    udp.send(cthree, ip, port );   // the message to send
    myDelay(250);
    
    String cfour="S"+categ4;
    println(cfour);
    udp.send(cfour, ip, port );   // the message to send
    myDelay(250);

if (port.available() > 0) { // this checks if there is data waiting
    int inByte = port.read(); // then it reads one byte
    if (inByte != 10) { // if byte is not newline
      buffer = buffer + char(inByte); // it adds it to the buffer
    }
    else {
      // when a newline reached, it processes the data
      if (buffer.length() > 1) { // it makes sure there is enough data
        // this chops off the last character
        buffer = buffer.substring(0, buffer.length() -1);
        //clean the buffer for the next read cycle
        buffer = ""; 
        // it refreshes the port
        port.clear();
      }
    }
  }
}

void fetchData() {
  
  // the code uses these strings to parse the feed
  String data;
  String chunk;
  
  // it zeroes the counters
  categ3 = 0;
  categ3 = 0;
  categ2 = 0;
  categ1 = 0;
  
  
  try {
    URL url = new URL(feed); // An object that represents the URL
    URL url2 = new URL(feed2); // Another one for anothert website t connect to
    // it prepares a connection
    URLConnection conn = url.openConnection();
    conn.connect(); // it connects to google website
    // it connects the data coming from the connection to a buffered
    // reader that reads the data one line at a time.
    URLConnection conn2 = url2.openConnection();
    conn2.connect();
    BufferedReader in = new
      BufferedReader(new InputStreamReader(conn.getInputStream()));
    BufferedReader in2 = new
      BufferedReader(new InputStreamReader(conn2.getInputStream())); 
    // it reads each line from the feed
    while ( (data = in.readLine ()) != null) {
      StringTokenizer st =
        new StringTokenizer(data, "\"<>,.()[] ");// it breaks it down
      while (st.hasMoreTokens ()) {
        // each chunk of data is made lowercase
        chunk= st.nextToken().toLowerCase() ;
    
// and then the words every time they are found they add 1 to the category    
 if (chunk.indexOf("word4") >= 0)
          categ4++; // increment categ4 by 1
 if (chunk.indexOf("word3) >= 0)
          categ3++; // increment categ3 by 1
 if (chunk.indexOf("word2) >= 0)
          categ2++; // increment categ2 by 1
 if (chunk.indexOf("word1) >= 0)
          categ1++; // increment categ1 by 1

// It sets 100 to be the maximum number of references considered
    if (categ4 > 99) categ4 = 99;
    if (categ3 > 99) categ3 = 99;
    if (categ2 > 99) categ2 = 99;
    if (categ1 > 99) categ1 = 99;

  }
  catch (Exception ex) { // If there was an error, it stops the sketch
    ex.printStackTrace();
    System.out.println("ERROR: "+ex.getMessage());
  }
}

void myDelay(int ms) //This a delay which will used after each category (c1, c2, c3, c4, c5)
// is sent to Arduino
{
   try
  {    
    Thread.sleep(ms);
  }
  catch(Exception e){}
}

void receive( byte[] data ) {          // <-- default handler
 //void receive( byte[] data, String ip, int port ) {   // <-- extended handler
 
 for(int i=0; i < data.length; i++) 
 print(char(data[i]));  
 println();   
 }

And then the Arduino through Ethernet.
By the way... on the Arduino I am receiving some strange reading when I try translate the string coming from Processing.
Am I doing a wrong interpretation of that string into an integer?

#include <SPI.h>         // needed for Arduino versions later than 0018
#include <Ethernet.h>
#include <EthernetUdp.h>         // UDP library from: bjoern@cs.stanford.edu 12/30/2008
#define numBufSize 3


// Enter a MAC address and IP address for your controller below.
// The IP address will be dependent on your local network:
byte mac[] = { 0x90, 0xA2, ... }; //MAC address of the shield to be found on the box of the shield
IPAddress ip(192, 168, 1, 167); //IP address of Arduino on the Network

unsigned int localPort = 8888;      // local port to listen on

// buffers for receiving and sending data
char packetBuffer[UDP_TX_PACKET_MAX_SIZE]; //buffer to hold incoming packet,
char  ReplyBuffer[] = "acknowledged";       // a string to send back

// An EthernetUDP instance to let us send and receive packets over UDP
EthernetUDP Udp;

long sequenceDelay = 500;
long flashDelay = 500;

boolean REL1state = true;     // the RELAY will turn ON in the first iteration of loop()
boolean REL2state = true;     
boolean REL3state = true;     
boolean REL4state = true;     

long waitUntil1 = 0; // the seed will determine time flashing of the RELAYS
long waitUntil2 = 3000; 
long waitUntil3 = 3000; 
long waitUntil4 = 3000; 

// These are motor variables
int r1val = 0; //variable controlling position of motor 1
int oldr1val = 0; // old variable controlling position of motor 1
int r2val = 0; //variable controlling position of motor 2
int oldr2val = 0; // old variable controlling position of motor 2 
int r3val = 0; //variable controlling position of motor 3
int oldr3val = 0; // old variable controlling position of motor 3
int r4val = 0; //variable controlling position of motor 3
int oldr4val = 0; // old variable controlling position of motor 3

boolean startLine = true; // this controls that all motors are reset to '0' at the beginning, 
                          // this function happens at the end of the code

char numStr[numBufSize] = { '0','1', '2' }; // just as an example

int ledState = LOW;             // ledState used to set the LED
long previousMillis = 0;        // will store last time LED was updated


void setup() {
  // start the Ethernet and UDP:
  Ethernet.begin(mac,ip);
  Udp.begin(localPort);

  Serial.begin(9600); //or 9600?
  
  pinMode(2, OUTPUT);
  pinMode(3, OUTPUT);
  pinMode(5, OUTPUT);
  pinMode(6, OUTPUT);
  delay(4000); //Check that all relays are inactive at Reset
  
 
   
}

void loop() {
  // if there's data available, read a packet
  int packetSize = Udp.parsePacket();
  if(packetSize)
  {
    Serial.print("Received packet of size ");
    Serial.println(packetSize);
    Serial.print("From ");
    IPAddress remote = Udp.remoteIP();
    for (int i =0; i < 5; i++)
    {
      Serial.print(remote[i], DEC);
      if (i < 3)
      {
        Serial.print(".");
      }
    }
    Serial.print(", port ");
    Serial.println(Udp.remotePort());

    // read the packet into packetBufffer
    Udp.read(packetBuffer,UDP_TX_PACKET_MAX_SIZE);
//    Serial.println("Contents:");
//    Serial.println(packetBuffer);
    
    // Convert decimal string in numStr to an unsigned integer in num.
    // The string is in a fixed size buffer.
    // There is no checking for invalid digit characters or number too large.
    unsigned long num = 0;
    for (int i = 0; i < numBufSize; i++) {
    num = num * 10 + (packetBuffer[i] - '0');
    }
  
//  Serial.println(num);
  
    if (packetBuffer[0]=='P') {
    r1val=int(num - 3200);
    }
    if (packetBuffer[0]=='Q') {
    r2val=num - 3300; 
    }
    if (packetBuffer[0]=='R') {
    r3val=num - 3400; // reads the value coming from Processing related to category 3
    }
    if (packetBuffer[0]=='S') {
    r4val=num - 3500;
    }
    
//    Serial.print("Relays");
    Serial.println(r1val);
    Serial.println(r2val);
    Serial.println(r3val);
    Serial.println(r4val);

 digitalWrite(2, REL1state);     // each iteration of loop() will set the IO pins,
  digitalWrite(3, REL2state);
  digitalWrite(5, REL3state);
  digitalWrite(6, REL4state);
   // checking to see if enough time has elapsed
   if (millis() >= r1val*500) {
      REL1state = !(REL1state);
      r1val += flashDelay;
      // this if-statement will not execute for another 1000 milliseconds
   }
  // keep in mind, waitUntil5 was already seeded with a value of 500
   if (millis() >= r2val*500) {
      REL2state = !(REL2state);
      r2val += flashDelay;

  }
  if (millis() >= r3val*500) {
      REL3state = !(REL3state);
      r3val += flashDelay;

  }
  if (millis() >= r4val*500) {
      REL4state = !(REL4state);
      r4val += flashDelay;

  }
    
  oldr1val = r1val; // stores the value of r1val
  oldr2val = r2val; // stores the value of r2val
  oldr3val = r3val; // stores the value of r3val
  oldr4val = r4val; // stores the value of r4val
    
 
   Udp.beginPacket(Udp.remoteIP(), Udp.remotePort());
    Udp.write(ReplyBuffer);
    Udp.endPacket();
  }
  
  }

With this type of relation Processing > Arduino I would like Processing to be able to control the second from a remote location.

I hope this wan't too much information.

many thanks

Hi zoomkat,
when you say

to have something at the remote address to update the dyn dns site of the current IP assignment.

do you mean that I have to have the dyn dns updater running on a computer at the remote location?
Or, as you mention the router, should I just ask the administrator of the remote network to port forward the address of my arduino and get it updated automatically it every now and then so I can access it when I am away?
I am afraid I am a bit confused, just going through dynDNS's guidelines. I have created a new host name with dynDNS and I have assigned the IP of the Arduino to it, however it shows the router's address whenever I run the updater. Is this the right procedure? Thanks for your help!

Okay,
I think I made it, I was able to do the portforwarding on my network, the problem was my modem Thomson 585 v7 which wasn't allowing me to input an IP.
A phone call to the online help service of my internet provider helped solving the problem, I had to reinstall the latest firmware.
Thanks everyone for your help.

Elso