It was modified from Daniel Shiffman's code by Keunyoung Oh

This Processing code reads data sent by a mircocontroller attached to a SHT11 Temperature and humidity sensor and displays the result as dandelions blowing in the wind. Basic Stamp code can be found here.

//daniel Shiffman's Multiple Particle Systems Class used ;;
// modified by Kay Oh.
import processing.serial.*;

Serial myPort;  // The serial port

// initial variables:
int i = 1;                   // counter
int inByte = -1;             // data from serial port
int threshold = 0;    // threshold of Humid
int j = 0;
int myinByte = 0;
int margin = 10;
int num;
PImage dand,dandcover;
ArrayList psystems; 
void setup () {
  size(600, 400);        // window size
  println(Serial.list());

  myPort = new Serial(this, Serial.list()[2], 9600);
  framerate(30); 
  colorMode(RGB,255,255,255,100); 
  psystems = new ArrayList(); 
  dand = loadImage("dand.gif");
  dandcover = loadImage("dand_cover2.gif");
  smooth();

}

void draw () {
if (myPort.available() > 0) {
    inByte = myPort.read();
  }

  if(j <33){
  if (j>21 && j <32){ //collacting samples
      myinByte += inByte;
    }
    j++;
  }
  threshold = myinByte/10;
  background(50); 
  image(dand, 0 , 0,800, 600);

  for (int i = psystems.size()-1; i >= 0; i--) { 
      ParticleSystem psys = (ParticleSystem) psystems.get(i); 
      psys.run(); 
      if (psys.dead()) { 
          psystems.remove(i); 
        } 
    }
    if(inByte>threshold+margin){
    //println(inByte);
    num = int(inByte/30);
   // println(num);
    makeIt(num);
   // psystems.add(new ParticleSystem(int(random(3)),new Vector3D(width/2,height/2,0)));  
   }
 //image(dandcover,368, 364, 63,51);
}
void makeIt(int _num){
num= _num;
psystems.add(new ParticleSystem(int(random(num)),new Vector3D(width/2,height-200,0)));  
}

class CrazyParticle extends Particle { 

  // Just adding one new variable to a CrazyParticle 
  // It inherits all other fields from "Particle", and we don't have to retype them! 
  float theta; 

  // The CrazyParticle constructor can call the parent class (super class) constructor 
  CrazyParticle(Vector3D l) { 
    // "super" means do everything from the constructor in Particle 
    super(l); 
    // One more line of code to deal with the new variable, theta 
    theta = 0.0; 

  } 

  // Notice we don't have the method run() here; it is inherited from Particle 

  // This update() method overrides the parent class update() method 
  void update() { 
    super.update(); 
    // Increment rotation based on horizontal velocity 
    float theta_vel = (vel.x * vel.magnitude()) / 250.0f; 
    theta += theta_vel; 
  } 

  // Override timer 
  void timer() { 
   // timer -= 1;
    timer -= 1; 
  } 

  // Method to display 
  void render() { 
    // Render the ellipse just like in a regular particle 
    super.render(); 
  //image(dand, 0, 0, 100, 100);
    // Then add a rotating line 
    pushMatrix(); 
    translate(loc.x,loc.y); 
    rotate(theta); 
    ellipseMode(CENTER);
    ellipse(-r/2,-r/2,1.5*r,r/2);
   // image(dand, 0, 0, 100, 100);

    stroke(255,timer); 
    strokeWeight(2); 
    line(-r/2,-r/2,45,r/2); 
    translate(45,r/2);
    int mylineWidth = 5;
    float a = 0.0; 
    float inc = TWO_PI/15.0; 
    strokeWeight(1);  
    for(int i=5; i<45; i=i+1) { 
      stroke(255,random(10)+timer/2);
      line(0, 0, i, 2+sin(a)*40.0); 
        a = a + inc; 
    } 

    popMatrix(); 
  } 
} 





// A simple Particle class 

class Particle { 
  Vector3D loc; 
  Vector3D vel; 
  Vector3D acc; 
  float r; 
  float timer; 

  // One constructor 
  Particle(Vector3D a, Vector3D v, Vector3D l, float r_) { 
    acc = a.copy(); 
    vel = v.copy(); 
    loc = l.copy(); 
    r = r_; 
    timer =100.0; 
  } 

  // Another constructor (the one we are using here) 
  Particle(Vector3D l) { 
    acc = new Vector3D(0,0.05,0);
   //  vel = new Vector3D(random(-1,1),random(-2,0),0);  
    vel = new Vector3D(random(-8,8),random(-8,0),0); 
    loc = l.copy(); 
    r = 10.0; 
    timer =90.0; 
  } 


  void run() { 
    update(); 
    render(); 
  } 

  // Method to update location 
  void update() { 
    vel.add(acc); 
    loc.add(vel); 
    timer -= 0.5; 
  } 

  // Method to display 
  void render() { 
 /*
    ellipseMode(CORNER); 
    noStroke(); 
    fill(255,timer); 
 */
  } 

  // Is the particle still useful? 
  boolean dead() { 
    if (timer <= 0.0) { 
      return true; 
    } else { 
      return false; 
    } 
  } 
} 


// A class to describe a group of Particles 
// An ArrayList is used to manage the list of Particles 

class ParticleSystem { 

  ArrayList particles;    // An arraylist for all the particles 
  Vector3D origin;        // An origin point for where particles are birthed 

  ParticleSystem(int num, Vector3D v) { 
    particles = new ArrayList();              // Initialize the arraylist 
    origin = v.copy();                        // Store the origin point 
    for (int i = 0; i < num; i++) { 
      particles.add(new CrazyParticle(origin));    // Add "num" amount of particles to the arraylist 
    } 
  } 

  void run() { 
    // Cycle through the ArrayList backwards b/c we are deleting 
    for (int i = particles.size()-1; i >= 0; i--) { 
      Particle p = (Particle) particles.get(i); 
      p.run(); 
      if (p.dead()) { 
        particles.remove(i); 
      } 
    } 
  } 

  void addParticle() { 
    particles.add(new Particle(origin)); 
  } 

  void addParticle(Particle p) { 
    particles.add(p); 
  } 

  // A method to test if the particle system still has particles 
  boolean dead() { 
    if (particles.isEmpty()) { 
      return true; 
    } else { 
      return false; 
    } 
  } 

} 



// Simple Vector3D Class 

public class Vector3D { 
  public float x; 
  public float y; 
  public float z; 

  Vector3D(float x_, float y_, float z_) { 
    x = x_; y = y_; z = z_; 
  } 

  Vector3D(float x_, float y_) { 
    x = x_; y = y_; z = 0f; 
  } 

  Vector3D() { 
    x = 0f; y = 0f; z = 0f; 
  } 

  void setX(float x_) { 
    x = x_; 
  } 

  void setY(float y_) { 
    y = y_; 
  } 

  void setZ(float z_) { 
    z = z_; 
  } 

  void setXY(float x_, float y_) { 
    x = x_; 
    y = y_; 
  } 

  void setXYZ(float x_, float y_, float z_) { 
    x = x_; 
    y = y_; 
    z = z_; 
  } 

  void setXYZ(Vector3D v) { 
    x = v.x; 
    y = v.y; 
    z = v.z; 
  } 
  public float magnitude() { 
    return (float) Math.sqrt(x*x + y*y + z*z); 
  } 

  public Vector3D copy() { 
    return new Vector3D(x,y,z); 
  } 

  public Vector3D copy(Vector3D v) { 
    return new Vector3D(v.x, v.y,v.z); 
  } 

  public void add(Vector3D v) { 
    x += v.x; 
    y += v.y; 
    z += v.z; 
  } 

  public void sub(Vector3D v) { 
    x -= v.x; 
    y -= v.y; 
    z -= v.z; 
  } 

  public void mult(float n) { 
    x *= n; 
    y *= n; 
    z *= n; 
  } 

  public void div(float n) { 
    x /= n; 
    y /= n; 
    z /= n; 
  } 

  public void normalize() { 
    float m = magnitude(); 
    if (m > 0) { 
       div(m); 
    } 
  } 

  public void limit(float max) { 
    if (magnitude() > max) { 
      normalize(); 
      mult(max); 
    } 
  } 

  public float heading2D() { 
    float angle = (float) Math.atan2(-y, x); 
    return -1*angle; 
  } 

  public Vector3D add(Vector3D v1, Vector3D v2) { 
    Vector3D v = new Vector3D(v1.x + v2.x,v1.y + v2.y, v1.z + v2.z); 
    return v; 
  } 

  public Vector3D sub(Vector3D v1, Vector3D v2) { 
    Vector3D v = new Vector3D(v1.x - v2.x,v1.y - v2.y,v1.z - v2.z); 
    return v; 
  } 

  public Vector3D div(Vector3D v1, float n) { 
    Vector3D v = new Vector3D(v1.x/n,v1.y/n,v1.z/n); 
    return v; 
  } 

  public Vector3D mult(Vector3D v1, float n) { 
    Vector3D v = new Vector3D(v1.x*n,v1.y*n,v1.z*n); 
    return v; 
  } 

  public float distance (Vector3D v1, Vector3D v2) { 
    float dx = v1.x - v2.x; 
    float dy = v1.y - v2.y; 
    float dz = v1.z - v2.z; 
    return (float) Math.sqrt(dx*dx + dy*dy + dz*dz); 
  } 

}