Filip is Making Anything...in MAS 863.11

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
Week 8 Input Devices

This week I made use of the hello.Mic.45, hello.Light.45, and both the hello.load.45 and hello.TxRx.45 input sensor boards. I programmed these using the Arduino environment and then used the serial output to send the sensor data into Processing for visualization.

Processing is a Java based visualization program that can be used to develop interactive media, parametric form, and web or networked apps. Arduino was developed based on Processing - so the syntax is almost identical. You can actually program the ATtiny chip through Processing. This was my first experience with the software and I had a great time. SO much potential in linking Processing with MicroControllers!!!

SoftwareSerial

David Mellis has a great set of instructions for programming the ATtiny using the FabIsp and Arduino 1.0. The only thing I would add is a note about the softwareSerial.h library and begin.Serial command if not using an "Official" Arduino board.

Note When beginning an Arduino sketch intended for use on an ATtiny based hello.board, start by importing the software.Serial library - it is in the Tools dialog. Then define the pinMode for the tx and rx pins

Using the Serial Monitor in Arduino is an easy way to test if the board is working - maybe not as intended. If you see a string of running numbers it means that the board is most likely OK. If symbols appear or nothing happens its time to check connections and code.

#include SoftwareSerial.h

#define rxPin 7
#define txPin 2

// set up a new serial port
SoftwareSerial mySerial =  SoftwareSerial(rxPin, txPin);

void setup()  {
  // define pin modes for tx, rx:
  pinMode(rxPin, INPUT);
  pinMode(txPin, OUTPUT);
  // set the data rate for the SoftwareSerial port
  mySerial.begin(9600);
}
        

hello.Mic.45

As mentioned, one of the boards I made and programmed with Arduino and Processing was the hello.Mic.45. This is the Arduino Sketch - it is based on a version in Arduino Cookbook by Michael Margolis and published by O'Reilly. The original sketch used the Mic breakout board made by SparkFun and used as-is had WAY too much background noise. I added a THRESHOLD limit and increased the number of samples taken

#include SoftwareSerial.h

#define rxPin 7
#define txPin 2

// set up a new serial port
SoftwareSerial mySerial =  SoftwareSerial(rxPin, txPin);

void setup()  {
  // define pin modes for tx, rx:
  pinMode(rxPin, INPUT);
  pinMode(txPin, OUTPUT);
  // set the data rate for the SoftwareSerial port
  mySerial.begin(9600);
}


int val = 0;                         // variable to store the value read

const int THRESHOLD = 512;           // I limited the range of the input in hopes of cutting down on background noise

const int middleValue = 256;         //mid-range of analog values

const int numberOfSamples = 64;     //number of readings taken each time

int sample;                         // value read from microphone
long signal;                        // reading with DC offset removed
long averageReading;                //average of the analogRead loop

long runningAverage = 0;             // running average - surprise! - of calculated values
const int averagedOver = 16;         //how quickly new values affect the running avergae



void loop()
{
  val = analogRead(rxPin);
  if (val < THRESHOLD)
      {                              // read the input pin
  long sumOfSquares = 0;             
  for (int i=0; i < numberOfSamples; i++) 
  {
    sample = val;                    // take a sample...reminder: val = analogRead
    signal = (sample - middleValue); // work out its offset from center, 1024 is the max. analog value, 512 is half of that.
    signal *= signal;                // square number to make all values postive
    sumOfSquares += signal;          // add to the total
  }
  
  averageReading = sumOfSquares/numberOfSamples; //calculate the running average
  runningAverage = ((((averagedOver -1)*runningAverage)+averageReading)/averagedOver);
  
  
  
  mySerial.println(runningAverage); 
  
 // delay 10 milliseconds before the next reading:

  delay(10);  // debug value
}

}
           

I then used a bar-graph drawing Processing Sketch to visualize the serial data

 
 // Graphing sketch
 
 
 // This program takes ASCII-encoded strings
 // from the serial port at 9600 baud and graphs them. It expects values in the
 // range 0 to 1023, followed by a newline, or newline and carriage return
 
 // Created 20 Apr 2005
 // Updated 18 Jan 2008
 // by Tom Igoe
 // This example code is in the public domain.
 
 import processing.serial.*;
 
 Serial myPort;        // The serial port
 int xPos = 1;         // horizontal position of the graph
 int portindex=1; 
 
 void setup () {
 // set the window size:
 size(1024, 300);        
 

 // I know that the first port in the serial list on my mac
 // is always my  Arduino, so I open Serial.list()[0].
 // Open whatever port is the one you're using.
 myPort = new Serial(this, Serial.list()[1], 9600);
 // don't generate a serialEvent() unless you get a newline character:
 myPort.bufferUntil('\n');
 // set inital background:
 background(0);
 }
 void draw () {
 // everything happens in the serialEvent()
 }
 
 void serialEvent (Serial myPort) {
 // get the ASCII string:
 String inString = myPort.readStringUntil('\n');
 
 if (inString != null) {
 // trim off any whitespace:
 inString = trim(inString);
 // convert to an int and map to the screen height:
 float inByte = float(inString); 
 inByte = map(inByte, 0, 1023, 0, height);
 
 // draw the line:
 stroke(127,34,255);
 line(xPos, height, xPos, height - inByte);
 
 // at the edge of the screen, go back to the beginning:
 if (xPos >= width) {
 xPos = 0;
 background(0); 
 } 
 else {
 // increment the horizontal position:
 xPos++;
 }
 }
 }
 
 

hello.Mic.board from MAS 863.11 on Vimeo.

hello.Load.45

I also made a step-response board, with a nifty plate. Below is the Arduino Sketch. This was a difficult one for two reasons, the original sketch made use of long signed numbers, making the program too large to load onto the ATtiny 45. I changed everything to an int, which is probably killing any kind of accuracy. Biggest problem? Its way too sensitive!

 *  RCTiming_capacitance_meter
 *   Paul Badger 2008
 *  Demonstrates use of RC time constants to measure the value of a capacitor 
 *
 * Theory   A capcitor will charge, through a resistor, in one time constant, defined as T seconds where
 *    TC = R * C
 * 
 *    TC = time constant period in seconds
 *    R = resistance in ohms
 *    C = capacitance in farads (1 microfarad (ufd) = .0000001 farad = 10^-6 farads ) 
 *
 *    The capacitor's voltage at one time constant is defined as 63.2% of the charging voltage.
 *
 *  Hardware setup:
 *  Test Capacitor between common point and ground (positive side of an electrolytic capacitor  to common)
 *  Test Resistor between chargePin and common point
 *  220 ohm resistor between dischargePin and common point
 *  Wire between common point and analogPin (A/D input)
 */
#include SoftwareSerial.h

#define rxPin 7
#define txPin 2


#define analogPin      2         // analog pin for measuring capacitor voltage
#define chargePin      7        // pin to charge the capacitor - connected to one end of the charging resistor
#define dischargePin   3        // pin to discharge the capacitor
#define resistorValue  10000.0   // change this to whatever resistor value you are using
// F formatter tells compliler it's a floating point value

SoftwareSerial mySerial =  SoftwareSerial(rxPin, txPin);


//unsigned long startTime;
//unsigned long elapsedTime;

 int startTime;
 int elapsedTime;
//float microFarads;                // floating point variable to preserve precision, make calculations
//float nanoFarads;

int microFarads;
//int nanoFarads;

void setup(){
  pinMode(chargePin, OUTPUT);     // set chargePin to output
  digitalWrite(chargePin, LOW);  
  pinMode(rxPin, INPUT);
  //pinMode(txPin, OUTPUT);

  mySerial.begin(9600);             // initialize serial transmission for debugging
}

void loop(){
  digitalWrite(chargePin, HIGH);  // set chargePin HIGH and capacitor charging
  startTime = millis();

  while(analogRead(analogPin) < 1023){       // 647 is 63.2% of 1023, which corresponds to full-scale voltage 
  }

  elapsedTime= millis() - startTime;
  // convert milliseconds to seconds ( 10^-3 ) and Farads to microFarads ( 10^6 ),  net 10^3 (1000)  
  microFarads = (elapsedTime / resistorValue) * 10;   
  mySerial.print(elapsedTime);       // print the value to serial port
  //mySerial.print(" mS    ");         // print units and carriage return


  if (microFarads > 1){
    mySerial.print((long)microFarads);       // print the value to serial port
    //mySerial.println(" microFarads");         // print units and carriage return
  }
  else
  {
//    // if value is smaller than one microFarad, convert to nanoFarads (10^-9 Farad). 
//    // This is  a workaround because Serial.print will not print floats
//
//    nanoFarads = microFarads * 1000.0;      // multiply by 1000 to convert to nanoFarads (10^-9 Farads)
//    mySerial.print((long)nanoFarads);         // print the value to serial port
//    mySerial.println(" nanoFarads");          // print units and carriage return
//  }

  /* dicharge the capacitor  */
  digitalWrite(chargePin, LOW);             // set charge pin to  LOW 
  pinMode(dischargePin, OUTPUT);            // set discharge pin to output 
  digitalWrite(dischargePin, LOW);          // set discharge pin LOW 
  while(analogRead(analogPin) > 0){         // wait until capacitor is completely discharged
  }

  pinMode(dischargePin, INPUT);            // set discharge pin back to input
} 

}