Quick and Dirty datalogging
Well, this mostly works.
Here's the story. Using processing and arduino code linked below, I'm sending data fom the ever easy-to-use potentiometer and using a php file to write to a text file in my NYU account. Then using this applet, I am displaying it as, well, a rotating line. Very exciting.
When you start the applet, you see the history of all the data, and then it shifts into a live updating mode. Theoretically, if you click on the applet, it shows you the whole history again.
The biggest modification I made is that the data-sending program only sends data to the server when the value changes, rather than sending at regular intervals.
There are all sorts of issues with timing, and obviously the pot is not the right sensor for this setup. I am imagining that this would work in a setup where the value of the sensor changes in very small increments and only occasionally. Ideally, the feedback would weight the duration of the line by how long it sat at that value, which would be possible, because the data is time stamped.
This is the second time I've worked with using Processing and the network, never mind sensor data and a network, so at the moment this is more of a 'hello world' assignment for me.
Arduino Code:
(unchanged from the tigoe version)
/*
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 sequentially 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);
}
}
}
Processing Code for sending data live:
/* datalogging client
modified from code by Tom Igoe
Only sends if the sensor value has changed
*/
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
int lastValue = 0;
void setup()
{
size(200, 200);
// Print a list of the serial ports, for debugging purposes:
println(Serial.list());
port = new Serial(this, Serial.list()[0], 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) {
if (abs(sensorValue - lastValue) > 2){
sendToNet(sensorValue);
lastValue = sensorValue;
}
else{
delay(100);
port.write(65);
}
}
}
// 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(500);
// 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);
//print the IP address of the host:
println(client.ip());
// send the HTTP GET request:
client.write("GET /~ds1935/Sensor/datalog.php?tempValue=" + sensorValue + " HTTP/1.1\n");
client.write("HOST: itp.nyu.edu\n\n");
lastValue = sensorValue;
netSendInProgress = true;
}
php file (unchanged from example code)
(someday i should learn some 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;
?>