Arduino/iOS Two Way Communication

In this project, I created a system to control and get data to and from your iOS device and an Arduino board. In addition, it allows you to control 

The first part of this project consisted of using Arduino/Processing/Automator to take serial data from a photoresistor, format it as a JSON file, and then upload the data via FTP. Then, a simple iPad app was written to retrieve the .json file, and parse it to correctly display the values from the photoresistor.

On the Arduino, a simple program collected the values and sent them out via serial to Processing.
The Arduino code was:
int photocellPin = 0;     // the cell and 10K pulldown are connected to a0
int photocellReading;     // the analog reading from the analog resistor divider

void setup(void) {
  // We'll send debugging information via the Serial monitor
  Serial.begin(28800);  
  //Serial.print("[");

}
void loop(void) {
  photocellReading = analogRead(photocellPin);  
     Serial.print(photocellReading);
       delay(1000);
}

Then, Processing received the data and formatted the data as a .json file, and wrote it to the hard drive. Here is the Processing code:
import processing.serial.*;
Serial mySerial;
PrintWriter output;
int s = second();
String values;
   
void setup() {
mySerial = new Serial( this, Serial.list()[0], 28800 );
   output = createWriter( "datas4.json" );
   //output.print("[");
   //print("[");
   values = "[";
}

void draw() {
  delay(400); 
    if (mySerial.available() > 0 ) {
         String value = mySerial.readString();
         
         if ( value != null ) {
           values = values + value;
           values = values + ",";
          }
    
    
if (second() == 10 || second() == 20) {
   values = values.substring(0, values.length() - 1);
   values = values + "]"; 
    output.print(values);
     output.flush();
     values = "[";
     //output.close();
   }
}
}



Then, an Automator workflow took the file and uploaded it to a site via FTP.

A simple iPad app then downloaded and parsed the json file, displaying the values of the photoresister.


For the second part of the project, I used OSC and Processing to interface the iPad with the Arduino.
With the oscP5 library for Processing, and the open source iOS app called Mrmr, I was able to use the iPad to control the Arduino board, 
or in this case, just a simple LED. 
Here is the code:
import processing.serial.*;
import oscP5.*;
import netP5.*;
OscP5 oscP5;
NetAddress myRemoteLocation;
Serial mySerial;
PrintWriter output;
int s = second();
String values;
int ledPin = 2;
   
void setup() {
 size(400,400);
 frameRate(25);

 
/* start oscP5, listening for incoming messages at port 12000 */
oscP5 = new OscP5(this,3333);
myRemoteLocation = new NetAddress("127.0.0.1",12000);
mySerial = new Serial( this, Serial.list()[0], 28800);

output = createWriter( "datas4.json" );
   //output.print("[");
   //print("[");
   values = "[";
}

void mousePressed() {
  /* create a new osc message object */
  OscMessage myMessage = new OscMessage("/test");
  
  myMessage.add(123); /* add an int to the osc message */
  myMessage.add(12.34); /* add a float to the osc message */
  myMessage.add("some text"); /* add a string to the osc message */

  /* send the message */
  oscP5.send(myMessage, myRemoteLocation); 
}



void draw() 
{
  delay(400); 
    if (mySerial.available() > 0 ) {
         String value = mySerial.readString();
         
         if ( value != null ) {
           values = values + value;
           values = values + ",";
          }

if (second() == 10 || second() == 20) {
   values = values.substring(0, values.length() - 1);
   values = values + "]"; 
    output.print(values);
    print(values);
     output.flush();
     values = "[";
     //output.close();
   }
}
}

void oscEvent(OscMessage theOscMessage) {
  /* check if theOscMessage has the address pattern we are looking for. */
  
  if(theOscMessage.checkAddrPattern("/test")==true) {
    /* check if the typetag is the right one. */
    if(theOscMessage.checkTypetag("ifs")) {
      /* parse theOscMessage and extract the values from the osc message arguments. */
      int firstValue = theOscMessage.get(0).intValue();  
      float secondValue = theOscMessage.get(1).floatValue();
      String thirdValue = theOscMessage.get(2).stringValue();
      print("### received an osc message /test with typetag ifs.");
      println(" values: "+firstValue+", "+secondValue+", "+thirdValue);
      return;
    }  
  }
 if(theOscMessage.checkAddrPattern("/mrmr/pushbutton/0/iPad")==true) {
   print("0");
   String [] params = {"/Users/andrewrauh/Projects/Arduino/Ftpupload.workflow"};
   open(params);
  println("### received an osc message. with address pattern "+theOscMessage.addrPattern());}
  
  if(theOscMessage.checkAddrPattern("/mrmr/pushbutton/1/iPad")==true) {
   print("YESSSSS");
   String [] params = {"/Applications/Safari.app", "http://www.dcnhs.com/datas4.json"};
   open(params);
  println("### received an osc message. with address pattern "+theOscMessage.addrPattern());}
  
  if(theOscMessage.checkAddrPattern("/mrmr/pushbutton/3/iPad")==true) {
   print("light is turning on now");   
   mySerial.write(1);   
   println("### received an osc message. with address pattern "+theOscMessage.addrPattern());}  
   
 if(theOscMessage.checkAddrPattern("/mrmr/pushbutton/4/iPad")==true) {
   print("light is turing off now");
   mySerial.write(2);
 }
 
}

and the Arduino code:

int photocellPin = 0;     // the cell and 10K pulldown are connected to a0
int photocellReading;
int incomingByte = 0;
int pin = 13;

// the analog reading from the analog resistor divider

void setup(void) {
  // We'll send debugging information via the Serial monitor
  Serial.begin(28800);  
  //Serial.print("[");
  pinMode(pin, OUTPUT);

}

void loop(void) {
  photocellReading = analogRead(photocellPin);  
   Serial.print(photocellReading);
 
  delay(1000);
  int input = Serial.read();
     if(input == 1){
        digitalWrite(pin,HIGH);
  }
  if(input == 2){
  digitalWrite(pin, LOW);
  } 
}

So overall here is what is going on:
On the Arduino side of things, the program sends a light value number from the photoresistor through aserial port to Processing. At the same time, the program is waiting for an character of "1" or "2" sent from Processing through serial. If "1" is sent, the LED light plugged into pin 13 turns on. If "2" is sent, the LED light turns off. 
The Processing program is taking the data, formatting it into a JSON file and writing it to the hard drive. It is also acting as a OSC server and receives information about what buttons are being pressed on the iPad in the OSC client app Mrmr. If a certain button is pressed, then Processing sends either a "1" or "2" through serial to the Arduino. 
An Automator Workflow uploads the JSON file to a server via FTP. I also added the ability for this workflow to be initiated by pressing a button on the iPad.
Another iPad app retrieves the JSON data from the server and parses it. If I would have had more time, I would have added the ability to analyze and graph this data in the app. 
Here is the main portion of the iPad app code 




Comments