Consolidated here by jamie allen, Feb 2007

(Written by Tom Igoe)

Below is three code listings you can use to write sensor data to a txt file on the network

  1. Processing code that takes in Serial from the Arduino and then calls a PHP script on the network.
  2. The Arduion code that produces the serial sensor data stream.
  3. A php/cgi script that when passed data, writes that data to a textfile on the network.


/* datalogging client
 by Tom Igoe

  All of this is described here:
  http://www.tigoe.net/pcomp/code/archives/php/000713.shtml

  Communicates between a microcontroller reading a 10-bit analog sensor and
  a CGI script that timestamps the reading and writes it to a text file resident 
  on the server.  Note that the text file needs to be writeable!

  The program starts by sending to the sensor for an initial value.
  When a good sensor value is obtained, the program checks to see if there's 
  a net send in progress.  If there's not, it sends the sensor reading to the net
  by starting a network client that connects to a server on port 80,
  sends an HTTP 1.1 GET request, and prints the results. 

  Once the sensor request is done, the client waits 3 seconds before the next send
  so as not to overwhelm the server.

 created 18 March 2005
 updated 24 Oct. 2005
 Jamie Allen added the code consolidation for Sensor Workshop, Feb 2007

 */

import processing.net.*;
import processing.serial.*;

Serial port;                            // The serial port
Client client;                          // the net client
int[] serialInArray = new int[2];       // Where we'll put what we receive
int serialCount = 0;                    // A count of how many bytes we receive
int sensorValue = 0;                    // value of the sensor
boolean firstContact = false;           // whether we've heard from the microcontroller
boolean netSendInProgress = false;      // whether or not the last net request is finished
boolean newSensorData = false;          // whether or not we have new sensor data

void setup()
{
  size(200, 200);
  // Print a list of the serial ports, for debugging purposes:
  println(Serial.list());

  // I know that the first port in the serial list on my mac
  // is always my  Keyspan adaptor, so I open Serial.list()[0].
  // On Windows machines, this generally opens COM1.
  // Open whatever port is the one you're using.
  port = new Serial(this, Serial.list()[2], 9600);
  port.write(65);    // Send a capital A to start the microcontroller sending
}

void draw()
{
  background(0);

// if there's any serial data available, get it:
  if (port.available() > 0) {
    serialEvent();
    // Note that we heard from the microntroller at least once:
    firstContact = true;
  }
  // If there's no serial data, send again until we get some incoming data.
  // (in case you tend to start Processing before you start your 
  // external device):
  if (firstContact == false) {
    delay(300);
    port.write(65);
  }

  // if we have new sensor data, check to see that there's no open
  // net connections. If there aren't, send the data.
  if (newSensorData) {
    if (!netSendInProgress) {
      sendToNet(sensorValue);
    }
  }


  // print the results of the net send:
  if (netSendInProgress) {
    if (client.available() > 0) {
      int inByte = client.read();
      print((char)inByte);
      // when we get a byte of value 0, it's the end of the response
      // from the server.  Stop listening and get some more data:
      if (inByte == 0) {
      netSendInProgress = false;
      // don't overwhelm the server:
      delay(3000);
      // Send a capital A to request new sensor readings:
      port.write(65);
      }
    }
  }
}


void serialEvent() {
  // Add the latest byte from the serial port to array:
  serialInArray[serialCount] = port.read();
  serialCount++;
  // If we have 2 bytes, combine them into one value:
  if (serialCount > 1 ) {
    sensorValue = serialInArray[1] * 256 + serialInArray[0];
    newSensorData = true;

    // Reset serialCount:
    serialCount = 0;
  } 
  else {
  // if we have only one byte, don't let the main loop 
  // send out yet:
    newSensorData = false;
  }
}

void sendToNet(int sensorValue) {

  // open a TCP socket to the host:
  client = new Client(this, "itp.nyu.edu", 80);

  //formatting 
  println();
  println();

  //print the IP address of the host:
  println(client.ip());

  // send the HTTP GET request:
  // These net two lines form a standard Request-URI used to request a resource after a 
  // TCP Client is created (above)
  // The particular resource that we're requesting is a php script, which is passed the 
  // variable 'tempValue'.

  client.write("GET /~ja771/sensorworkshop/datalogger/logger.php?tempValue=" + sensorValue + " HTTP/1.1\n"); 
  client.write("HOST: itp.nyu.edu\n\n");
  netSendInProgress = true;
}

////////////////////////////////////////////////////////////
// BELOW IS THE ARDUINO CODE THAT WORKS WITH THIS EXAMPLE //
////////////////////////////////////////////////////////////

/*
analog Call-and-Response for 10 bit sensor readings
by Tom Igoe

Created 26 Sept. 2005
Updated 30 May 2006

Cleaned up for use with the Network Data Logging Suite
by Jamie Allen, Feb 2007

Waits for serial input.  If the incoming value
is a valid byte (i.e. "A"), the program then
reads two analog inputs and one digital input.
It slices up the data into Most and Least Significant
BYTES and sends them out sequential to the
serial port

Arduino hardware connections:
A0: analog sensor on analog in 0

*/

/*
int firstSensor = 0;    // first analog sensor
int inByte = 0;         // incoming serial byte
byte firstSensorLSB;    //LSB for the analog sensor value
byte firstSensorMSB;    //MSB for the analog sensor value

void setup()
{
  // start serial port at 9600 bps:
  Serial.begin(9600);
}

void loop()
{
  // if we get a valid byte, read analog ins:
  if (Serial.available() > 0) {
    // get incoming byte:
    inByte = Serial.read();

    if (inByte == 65)  //i.e.: it's an ASCII "A"
    {
    firstSensor = analogRead(0);
    firstSensorLSB = firstSensor;
    firstSensorMSB = firstSensor >> 8;

    Serial.print(firstSensorLSB, BYTE);
    Serial.print(firstSensorMSB, BYTE);
    }
  }
}
*/


//////////////////////////////////////////////////
// BELOW IS THE PHP CGI THAT IS IN THIS EXAMPLE //
//////////////////////////////////////////////////

/* Copy the script below into a file called logger.php
and put it somewhere on your webserver mine was here 
(YOU NEED TO CHANGE THIS TO YOUR OWN SERVER, php locations):
/~ja771/sensorworkshop/logger.php

Create a text file in this same directory with the same name as 
$filename = 'datalog.txt';
and change  its permissions so that it can be written to (octal 666). 

*/

/*
<?php
$filename = 'datalog.txt';
// compose the data string from the date and the incoming value:
  $dataString = date("Y-m-d h:i:s\t");
  $dataString = $dataString.$_REQUEST['tempValue'];
  // add a linefeed and carriage return
  $dataString = $dataString."\r\n";

//  make sure the file exists and is writable first:
if (is_writable($filename)) {

   // Open $filename in append mode. anything you add 
   // will be appended to the end of the file:
   if (!$handle = fopen($filename, 'a')) {
         echo "Can't open file $filename";
         exit;
   }

   // Write $dataString to the opened file.
   if (fwrite($handle, $dataString) == FALSE) {
       echo "Can't write to file $filename";
       exit;
   }
  // data successfully written:
   echo "Wrote $dataString to file $filename";
   // send a 0 to tell the remote side we're done:
  echo "\0";
  // close the file
   fclose($handle);

} else {
   echo "The file $filename is not write-enabled.";
}
end;
?>

*/