Assignment 1: Serial into Processing with peak detection


This assignment was very interesting!
It took a while at the beginning to get used tothe new Processing91 environment. There are some new formatting rules for integrating serial information, but following the initial struggles success was made.


In the first assignment I used a simple photocell to generate distortions of a 20x20 3D mesh created in Processing. At first, all I wanted to accomplish was to simply get readings from the photocell in a range I could use. The initial set up was to construct a breadboard with a photocell on porta.0 and read the values generated in HyperTerm. My ranges varied greatly with the use of different resistors in line with the photocell. I eventually decided on using a 10K resistor... It gave the best readings (range 0-~550 in normal indoor light). Once the range of values were generated I then proceeded to integrate it with my Processing code as follows:

Processing code: 3d DataMesh and Planes.

int maxCols = 20;
int maxRows = 20;
int xcount = 0;
int ycount = 0;
int [][] yvalues = new int [20][20];
int val;

import processing.serial.*;
Serial port;
//int serial = val;

void setup(){

  println (Serial.list());
  port = new Serial (this, Serial.list()[0], 9600);

  size (600,600,P3D);
  for ( int i = 0; i<20; i++){
    for ( int j = 0; j<20; j++){
      yvalues[i][j] = 0;

    }
  }

}

void draw(){

  //smooth();
  //framerate(5);
  background(255);
  strokeWeight(4); 
  yvalues[xcount][ycount] = val/10;
  xcount++;

  if (xcount == maxCols) {
    ycount++;
    xcount = 0;
    if (ycount == maxRows) {
      ycount = 0;
    }
  }

  //FILL ALL THE RANDOM NUMBERS
  //for ( int i = 0; i < 20; i++){
  //for (int j = 0; j < 20; j++){
  //yvalues[i][j] = int (random (-10,10));



  //GO TO A STARTING POINT
  translate(300,300,100);                      //rotation box
  rotateX(radians(mouseX));
  rotateZ(radians(mouseY));
  stroke(150);
  noFill();
  box (250);

  //GO AND DO "ROWS"
  pushMatrix();
  translate(-100,-100);
  stroke(55,130,250);


  for (int j = 0; j < maxRows; j++) {
    pushMatrix();
    translate(0,j*10);
    rotateX(radians(90));
    for (int i = 0; i < maxCols-1; i++){
      int x = i*10;
       line (x, -yvalues[j][i], x+10, -yvalues[j][i+1]);
      //rectMode(CORNERS);
      //fill (102,200,150,155);
      //rect(x, -yvalues[j][i], x+10, -yvalues[j][i+1]);
    }
    popMatrix();
  }
  popMatrix();

  //GO AND DO "COLS"
  pushMatrix();
  translate(-100,-100);
  stroke(55,170,100);

  for (int i = 0; i < maxCols; i++) {
    pushMatrix();
    translate(i*10,0);
    rotateY(radians(90));
    for (int j = 0; j < maxRows-1; j++){
      int y = j*10;
       //line (x, -yvalues[j][i], x+10, -yvalues[j][i+1]);
      line (yvalues[j][i], y, yvalues[j+1][i],y+10);
     // rectMode(CORNERS);
      //fill (102,200,150,155);
      //rect(yvalues[j][i], y, yvalues[j+1][i],y+10);
    }
    popMatrix();

  }
  popMatrix();

}

void serialEvent(Serial port){

  if (port.available() > 0) {
    val = port.read();
    println(val);
    //val = 0
  }

} void mousePressed(){ }

Pic Code: Simple analog in.

' Define ADCIN parameters
DEFINE ADC_BITS 10 ' Set number of bits in result
DEFINE ADC_CLOCK 3 ' Set clock source (3=rc)
DEFINE ADC_SAMPLEUS 50 ' Set sampling time in uS
TopVal con 300
ADCvar VAR WORD ' Create variable to store result
SendMeVar VAR byte
TRISA = %11111111 ' Set PORTA to all input
ADCON1 = %10000010 ' Set PORTA analog and right justify result
Pause 250 ' Wait .5 second
main:
ADCIN 0, ADCvar ' Read channel 0 to adval
if ADCvar > 300 then
ADCvar = TopVal
endif
SendmeVar = ADCvar*255/TopVal
serout2 PORTC.6, 16468, [SendMeVar] ' print it to serial out,\\ pause 20
goto main

Once the Processing was running with Serial into it (the values in the Pic code were bracketed in order to make the readings in processing visually manageable), then I felt brave enough to attempt the peak finding with the photocell and wind sensor (which I would use further down the line in the datalogging assignment...)

Here are some visuals followed by the peak finding code I used with the Pic. The 3D graph displaces sequentially at every vertex point based on the readings from the sensor, thus creating a type of landscape of data after every cycle throgh the mesh.
Simple analog in...with mesh

With peak detection...Mesh would only change if peak value was detected(with planes and wire mesh)

Peak detection code for Pic:

Based on code by Tom Igoe.

' Define ADCIN parameters DEFINE ADC_BITS 10 ' Set number of bits in result
DEFINE ADC_CLOCK 3 ' Set clock source (3=rc)
DEFINE ADC_SAMPLEUS 20 ' Set sampling time in uS
PeakValue var word
SensorValue var word
LastSensorValue var word
Threshold var word
Noise var word
' serial pins and data reate:
tx var portc.6
rx var portc.7
n9600 con 16468
Threshold = 70 ' set your own value based on your sensors
PeakValue = 0 ' initialize peakValue
noise = 5 ' set a noise value based on your particular sensor
' Set PORTA to all input
TRISA = %11111111
' Set up ADCON1
ADCON1 = %10000010

Main:

    ' read sensor on pin RA0:
    ADCin 0, sensorValue
    'serout2 tx, n9600, ["sensor value", SensorVAlue] 
     's above the threshold:
    If sensorValue >= threshold + noise then 
        ' if it's greater than the last reading,
        ' then make it our current peak:

        If sensorValue >= lastSensorValue + Noise then 
            PeakValue = sensorValue
           ' serout2 tx, n9600, ["peak reading1", peakValue]
        endif
    ' if the sensorValue is not above the threshold,
    ' then the last peak value we got would be the actual peak:
    Else
        If peakValue >= threshold then 
            ' this is the final peak value; take action
            serout2 tx, n9600, [peakValue]
        endif

        ' reset peakValue, since we've finished with this peak:
        peakValue = 0
    Endif

    ' store the current sensor value for the next loop:
    lastSensorValue = sensorValue
    pause 20

Goto main

Assignment 3:

Datalogging with the wind speed sensor:

With this peak value detection code working well for the photocell, I then began to think of how I could hook up the wind sensor in order get some datalogging going. The wind sensor is activated by a small hermetically sealed reed switch encased underneath the rotor, thus the code had to be adjusted for digital output... but then there is a slight problem... there are no real peaks with the sensor because it just sends out pulses (1's and 0's)at different rates depending on the speed of the wind over any given period.This raised some interesting questions in terms of datalogging. What would I do with all those 1's and 0's? How could the speed of wind be translated and recorded over time in an interesting way that is not just another simple conversion program of rotions per second to speed/time? How can this information that the wind sensor gives us effect our sensory experience through space and sound? The wind sensor creates patterns of information over time in a binary output activated by the reed switch...so how could this pattern or rhythm generate some sensory experience of our environment besides just generating a huge text file? (Although a huge text file would be kind of interesting in 0's and 1's...you might be able to see variances in visual textures if the "drawing" was let's say printed on a 6' x6' piece of paper). But I chose to see how the patterns and rhythms of the wind sensor could be experienced through the pacing of sound and 3D video projection through the use of MAX/MSP/JITTER. The sound files could then be recorded and act as a record of the wind sensor's activity over any period of time...After many days of attempting to program with php to my MYSQL account this seemed like a viable and interesting alternative. Although the sound files could also be uploaded to a server after they were completed. Necessity is the mother of invention!! Following is the digital pic code for the anenometer sending binary data through the serial port to the Max program. (The Max program takes video of light patterns generated by sunlight reflecting on a river and based on those light patterns, filters the velocity, pitch and duration of a sonic field recording of that immediate environment through comb filters. The wind sensor was used to create a pacing or rhythm of the sound and video as they played by attatching the serial information to different swiches in the patch.) The eventual output could then be recorded and logged using "sfrecord~" and "jit.qt record" in Max.It's also an interesting way to combine readouts from various sensors at a given time and place and to see how their patterns relate to each other (like light, wind and sound patterns) by manipulating something all at once...Here are some photographs of the process and the digital pic code that I used.(it also lit an led on the board so that I could see what I was getting.)

Pic Code: Digital out (w/ LED).

Based on code by Tom Igoe.

  include "modedefs.bas"
   define debug_REG PORTC
   define debug_BIT 6
   define debug_BAUD 9600
   define debug_MODE 1

   X var byte



   input portb.0 
   output portd.1
    tx var portc.6
    n9600 con 16468

main:

	if portB.0 = 1 then ' if the switch is closed on pin RB0
		low portd.1 ' set pin RD1 low
		X=1
	else
		high portd.1	' set RD1 high
        x=0 
	endif 

serout2 tx, n9600, [X] goto main

Max/MSP/Jitter Patch: