Friday, April 28, 2006

Averaging, Smoothing




I used Flex sensor and same Processing code for Sensors and Time.

Averaging and finding the median Pic Code

' Analog median and average
' by Tom Igoe

' This program reads an analog input and gives the average of 9 readings,
' and sorts the list of readings and delivers the median number.

' Created 17 October 2005
' Updated

' 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

TRISA = %11111111 ' Set PORTA to all input
ADCON1 = %10000010 ' Set PORTA analog and right justify result


numReadings con 9 ' number of samples to take
median var byte ' median of the sorted samples
readingNumber var byte ' counter for the sample array
' serial variables and constants:
tx var portc.6
rx var portc.7
inv9600 con 16468

' variables for subroutines:
i var byte
j var byte
position var byte
analogValues var word[numReadings]
total var word
average var word
out var byte
in var byte
swapper var word

main:
for readingNumber = 0 to (numReadings - 1)
' get the reading:
adcin 0,analogValues[readingNumber]
' increment the counter:
readingNumber = readingNumber + 1
next
' sort the array using a bubble sort:
gosub bubbleSort

' get the middle element:
median = analogValues[numReadings / 2]

' print the results:
' print the array, nicely ASCII-formatted:
serout2 tx, inv9600,["Array: ["]
for j = 0 to (numReadings - 1)
serout2 tx, inv9600, [DEC analogValues[j], ", "]
next
serout2 tx, inv9600,["]", 10, 13]
' average the array:
gosub averageArray
serout2 tx, inv9600, ["Average: ", DEC average, 10, 13]
serout2 tx, inv9600, ["Median: ", DEC median, 10, 13]
GOTO MAIN

' average the values in the array:
averageArray:
total = 0
average = 0
for i = 0 to (numReadings - 1)
total = total + analogValues[i]
next
average = total/numReadings
RETURN

bubbleSort:
for out = 0 to (numReadings - 2) ' outer loop
for in = out+1 to (numReadings - 1) ' inner loop
if analogValues[out] > analogValues[in] then 'out of order?
swapper = analogValues[out]
analogValues [out] = analogValues[in]
analogValues[in] = swapper
endif
next
next
return

Next one is Eliminating the pick points

Written in PicBasic Pro, tested on a PIC 18F252:


' Analog smoothing algorithm
' by Tom Igoe

' This program reads an analog input and smooths out the result by averaging
' the result with past values of the analog input.

' uses a potentiometer on analog in 2 to generate the value for alpha,
' the number of samples to average.

' n.b. the variable "smoothed" needs to be a global, since it's modified
' each time a new smoothing is done. So if you want to use this for multiple
' inputs, you'll need a "smoothed" variable for each input.

' Created 17 October 2005
' Updated 27 March 2006


' 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

TRISA = %11111111 ' Set PORTA to all input
ADCON1 = %10000010 ' Set PORTA analog and right justify result


analogVal var word ' the value from the ADC
smoothed var word ' a nicely smoothed result. This needs to be a global variable
byteVar var byte ' a byte variable to send out serially
alpha var byte ' the number of past samples to average by
trimPotValue var word ' the trimmer pot input

' serial variables and constants:
tx var portc.6
rx var portc.7
inv9600 con 16468

' Variables for subroutines:
i var byte
LEDPin var portb.7

gosub blink

main:
' read the trim pot to determine alpha between 1 and 10:
adcin 1, trimPotValue
alpha = (trimPotValue / 114) + 1
' get an analog reading:
adcin 0, analogVal
' smooth it:
gosub smoothValue

' to see the difference, try outputting analogVal
' instead of smoothed here, and graph the difference.
' divide by 4 to print the result as a byte:
byteVar = smoothed /4
serout2 tx, inv9600, [byteVar]

' delay before next reading
pause 10
goto main

' Blink the reset LED:
blink:
for i=0 to 3
high LEDPin
pause 200
low LEDPin
pause 200
next
return

' Smooth out an analog reading:
smoothValue:
if (analogVal > smoothed) then
smoothed = smoothed + (analogVal - smoothed)/alpha
else
smoothed = smoothed - (smoothed - analogVal)/alpha
endif
return

Processing Code(same as Sensors and time)

import processing.serial.*;

Serial myPort; // The serial port

// initial variables:
int i = 1; // counter
int inByte = -1; // data from serial port

void setup () {
size(400, 300); // window size

// List all the available serial ports
println(Serial.list());
// I know that the third port in the serial list on my mac
// is always my Keyspan adaptor, so I open Serial.list()[2].
// Open whatever port is the one you're using.
myPort = new Serial(this, Serial.list()[0], 9600);

// set inital background:
background(0);
}
void draw () {
if (myPort.available() > 0) {
inByte = myPort.read();
serialEvent();
}
}

void serialEvent () {
// draw the line:
stroke(0,255,0);
line(i, height, i, height - inByte);
// at the edge of the screen, go back to the beginning:
if (i >= width) {
i = 0;
background(0);
}
else {
i++;
}
}

Friday, April 14, 2006





Wednesday, March 01, 2006

Datalogging, Database, Server...


<--Using Pot


Link to Network Datalogging Suite in Tom's page

To link Mac and Serial: Use USB to Serial Converter (required installing driver)

My pic send values to the computer and I checked from Hyper terminal. The range was from 1 to 1021. But the processing didn't give me the value, instead it said,

Devel Library=========================================
Native lib Version = RXTX-2.1-7pre17
Java lib Version = RXTX-2.1-7pre17
COM1
COM4
128.122.253.189
HTTP/1.1 200
OK
Date: Tue, 07 Mar 2006 04:16:53
GMTServer: Apache/2.0.52 (Red Hat)
Content-Length: 42
Connection: close
Content-Type: text/html;
charset=UTF-8
The file datalog.txt is not write-enabled.


Sending values from Pic to Computer, Computer to Server is the goal of my assignment. Saving space for data is needed. Ex) Range of 1024 per Sec for an hour is 60 times 1024... We are going to use this to analysis the data later.


Processing Code (Red text parts need to be changed for each server address)

/* datalogging client by Tom Igoe Communicates between a microcontroller reading a 10-bit analog sensor and a CGI script that timestamps the reading and writes it to a file. 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 */

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()[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) {
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);

//print the IP address of the host:
println(client.ip());
// send the HTTP GET request:
client.write("GET /~sh1319/logger.php?tempValue=" + sensorValue + " HTTP/1.1\n"); client.write("HOST: itp.nyu.edu\n\n");

netSendInProgress = true;}
}


Pic Code
I changed the code a little bit for my clock, blinky LED on portd.1 and Lowbyte, Highbyte parts.


define osc 4

' serial RX is on pin RC7
' serial TX is on pin RC6

' 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
' constant to set the baud rate:
inv9600 con 16468

' define variables:
adcVar var word
inByte var byte

TRISA = %11111111 ' Set PORTA to all input
ADCON1 = %10000010 ' Set PORTA analog and right justify result



main:

high portd.1
pause 500
low portd.1
pause 500

' read sensors, convert to bytes:
adcin 0, adcVar

' read serial data in:
'serin2 portc.7, inv9600, [inByte]

' if you got the message from the remote device, send out data:
serout2 portc.6, inv9600, [ dec adcVar, 13, 10]


goto main




CGI program, written in PHP, tested using an Apache web server running on a Redhat Linux machine:

$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;
?>

text_datalog.php : Save this file with this name in my server public folder with 'datalog.txt'. 'datalog.txt' file can be started blank.




How to Use Telnet


sol-huhs-powerbook-g4-12:~ sol$ pwd
/Users/sol
sol-huhs-powerbook-g4-12:~ sol$ ls
Desktop Music Sites
Documents Pictures Untitled.txt
Library Public careers.html
Movies Send Registration fish2.html

sol-huhs-powerbook-g4-12:~ sol$ ls /dev/tty.*
/dev/tty.Bluetooth-Modem /dev/tty.modem
/dev/tty.Bluetooth-PDA-Sync
sol-huhs-powerbook-g4-12:~ sol$ screen /dev/tty.KeySerial1.9600

Than, I'm supposed to type in,

telnet itp.nyu.edu 80
get /~sh1319/index.html HTTP/1.1
Host: itp.nyu.edu

I get the blank screen that will show the data from the Pic.

If I want to quit the telnet,
Ctrl + a, Ctrl + /, than Y.

Sunday, February 12, 2006

Data Sheet Reading

The reason I chose the ADXL320 Accelerometer is, it has many datas available, and I have used it before but I haven't look at the datasheet closely.
ADXL320 is 2 axis accelerometer for small devices(+-5g). It can be applied to hand-held devices, mobile phone, sports and health-related devices and pc security and pc peripherals.

Features
Small and thin
4mm x 4mm x 1.45 mm plastic LFCSP(Lead Frate Chip Scale package)
2mg resolution at 60 Hz
Wide supply voltage range 2.4V to 5.25V
Low power:350uA at Vs =2.4V(typ)
Good zero g bias stability
10.000g shock survival
good sensitivity accuracy
X-axis and Y-axis aligned to within 0.1'(degree) (typ)
BW adjustment with a single capasitor
Single-supply operation
Compatible with Sn/Pb and Pb-free solder process

It measures vibration and gravity, typical noise floor is 250 ug/vHz, allowing signal below 2 mg to be resolved intilt sensing application using narrow bandwidths(<60Hz)
We select the bandwidth of the sensor using capasitor Cx, Cy, at the Xout ,Yout pins. Bandwidths of 0.5Hz to 2.5kHz may be sekected.

5pins-one for Power 3V, one for ground, one for X out(X channel outout), one for Y out (Y cahnnel output), and one for the self-test. By measuring this output, the user can verify that the accelerometer is working. If you connect the self-test pin to power, the output values decrease, which means the accelerometer is okay.
There are temperature range for operation and storage, which may cause damage of device in the out of the range. .


Self Test

When this pin is set to Vs, an electrostatic force is exerted on the acceleormeter beam. The resulting movement of the beam allows the user to test if the accelerometer is functional. The typical change is output is 315mg to 55 mV. This can be open circuit or connected to common in normal use.

Note-The accelerometer measures static acceleration forces, such as gravity, wich allows it to be used as a tilt sensor.
One 0.1 uf capasitor is used for noise decoupling the accelerometer on the power supply.
What's the theory?- It is a polysilicon surface structure built on top of a silicon wafer. Polysilicon spring susppend the structure over the surface of the wafer and provide resistance against acceleration forces.

Use as a Dual-Axis Tilt Sensor

The Accelerometer is most sensitive to tilt when its sensitive axis is perpndicular to the force of gravity.(when it is parallel to the earth surface)
When the accelerometer is oriented so both its X-axis and Y-axis are parallel to the earth's surface, it can be used as a 2 axis tilt sensor with both a roll axis and pitch axis. Once the output signal from the sensor has been converted to an acceleration that varies between -1 g and +1 g, the output tilt in degree is calculated as
Pitch=ASIN(Ax/1g)
Roll=ASIN(Ar/1g)

Setting the bandwidth using Cx and Cy

Bandwidth(Hz) Capasitor(uF)
1 ///4.7
10 ///0.47
50 ///0.10
100 ///0.05
200 ///0.027
500 ///0.01


Question
Design Trade-Off for Selecting Filter Characteristics: The Noise/BW Trade-Off

Peak to peak Value / % of time tha noise exceeds norminal peak to peak value
2 x rms ///32
4 x rms ///4.6
6 x rms ///0.27
8 x rms ///0.006

Pic Code

DEFINE OSC 4
INCLUDE "modedefs.bas"
DEFINE ADC_BITS 10
DEFINE ADC_CLOCK 3
DEFINE ADC_SAMPLEUS 10
TRISA = %11111111
adcon1 = %10000010
output portb.5
low portb.5

adcVar0 VAR Word ' ir Create variable to store result
adcVar1 VAR Word ' ir Create variable to store result
Bytevar1 VAR Byte
Bytevar2 Var Byte
switchVar var byte
inputVar Var BYTE

pause 500
main:
ADCIN 0, adcVar0
pause 30
ADCIN 1, adcVar1
pause 30
Bytevar1=adcVar0/4
Bytevar2=adcVar1/4
high portb.5
pause 500
low portb.5
pause 500
serout2 portb.3, 16468, [DEC Bytevar1, 44,DEC Bytevar2,44,13]

GoTo main



Monday, January 30, 2006

Sensors and Time




Using Flex Sensor
Code Reference from 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 = 50 ' 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, [sensorValue]
'original line was useful when sending data to HyperTerminal.
'original line: serout2 tx, n9600, ["peak reading", DEC peakValue, 13,10]
pause 100
Goto main

Processing code reference

import processing.serial.*;

Serial myPort; // The serial port

// initial variables:
int i = 1; // counter
int inByte = -1; // data from serial port

void setup () {
size(400, 300); // window size

// List all the available serial ports
println(Serial.list());
// I know that the third port in the serial list on my mac
// is always my Keyspan adaptor, so I open Serial.list()[2].
// Open whatever port is the one you're using.
myPort = new Serial(this, Serial.list()[0], 9600);

// set inital background:
background(0);
}
void draw () {
if (myPort.available() > 0) {
inByte = myPort.read();
serialEvent();
}
}

void serialEvent () {
// draw the line:
stroke(0,255,0);
line(i, height, i, height - inByte);
// at the edge of the screen, go back to the beginning:
if (i >= width) {
i = 0;
background(0);
}
else {
i++;
}
}

Monday, January 23, 2006

Sensors in daily life

I'm having trouble figuring out which is sensor and which is switch. What's the border line?

My Roomba, a vacuum cleaner. It certainly has sensors which I don't know what it is exactly.
Remote controls for Roomba, TV, DVD, and a Cable set.-IR...What's IR?
Elevator door, button.
My Mac
My refridge, oven, fire alarm.
At ITP, there's bunch. Cameras...
Treadmill...Speed, heartbeat conter, distance counter...
Cap
Restroom-tap. Motion sensor
etc.

Class Link

My name is Sol Huh

I'm first year ITPier, loving and caring person.
My background is in Fine Art major and Multi media minor.
I participated in the winer show 2005 with my interactive screen using accelerometer.
I wasn't really great at Pcomp last semester though I loved to be creative and productive.
My interests were very much into art stuff such as painting, installation, and video art.
I thought myself was pretty handy which I totally lost the concept of being handy in ITP.
I hope that this class helps me using and learning various types of sensors.
To be honest, I'm bit afraid of physics.
If I can catch up the class until the end of semester, that would represent how much I struggled against my lack of fundamental knowledge.
I am certain that would happen.