Av's Physical Computing Blog

Monday, December 19, 2005

FINALthoughts

I definitely learned a lot in the process of the labs, the ping pong paddles and the flower. I realize now that I need to learn more about mechanics. I know it was possible to use one or two servos for my flower and after a few instances of servos burning in the future this is the way I will go.

I wasn’t thrilled with the way the flower petals were connected to the gears. It was done in a haphazard fashion, which resulted in the angle and length of the petals being inconsistent.

With the massive amount of ports/parts, labeling everything initially would have saved me lots of time and frustration.

I hope to use a perf board on my next project, it would have been easier to mount and I could have used only one perf board instead of two circuit boards. While the flower didn’t look anything like I expected, that was just the aesthetic end of things. In terms of pcomp, I was satisfied. There was way more involved than I thought and I learned a lot of valuable lessons along the way. Next semester: wearable technologies!

DYEINGflower

The next piece was to find fabric for the petals. I sewed chiffon onto the aluminum frame of one petal. Although I knew how to sew passably, it ended up being significantly harder and more time consuming that I wanted. Terence suggested using pantyhose. I went to Kmart and got a pair of white ladies XL stockings, cut them up and slipped them over the petal frames and it worked liked a charm.


I cut off the tops of the hose slip cover to get a fringy, flowing look. I wanted to add color to the petals so I dyed them…nylon is quite a resistant material so I used my hands to work in the dye. A messy endeavor, but it worked. I used the same method for the leaves/stems. To speed up the drying process, I used a heat gun…which left some odd but cool patterns on the fabric.

REWIREit

The next day I came in with the mission to map out my port assignments and rewire the boards so that things could be easily identified and rewired. Although it took quite a few hours, it was worth it.



The PIC had just enough ports for me, so I avoided using a shift register. I did run into problems with PORT A. After consulting the datasheet, ADCON %111100 to turn the ports all digital

All the servos were getting unwieldy so it was time to make a proper stand. I bought some masonite, which I realized once again such a great material. Thin, light and cheap.

I cut two circular sheets of masonite and spaced them with dowels. I mounted the servos and held them in place with wire going through drilled holes in the top circular piece.

The construction of the stand took a full day, much longer than I expected.

SERVOtime

Now that the clock was working I wanted to integrate the servos with the time. I had only tested with four servos, but with six servos Ben Brown suggested a separate power supply. I went to Radio shack and bought a 6V power supply, stripped the ends and plugged it into a second breadboard to power the servos. Milmoe pointed out the servos and the pic needed to share a common ground.

All this was temporary mounted on a stand I procured from the wonderful shop junk pile. After 13 hours in the lab I called it a day.



Friday, December 16, 2005

CLOCKchip

To keep the time, I used a real time clock module from sparkfun: http://www.sparkfun.com/shop/index.php?shop=1&cat=45

Todd gave me some code/tips for the chip. It was easy to use, note the three pull up 4.7K OHM resistors. (diagram possibly)

I used serout to check the time and debug my code. [see code]

Basically you program the PIC chip with a subroutine to set the time and then reprogram the chip without the subroutine. If you don’t do this, the clock will RESET everytime you turn power on/off.

Todd pointed me to a way to simulate a clock without the IC. I tried this method, but since the chip used in the example was different than the PIC chip I was using, I decided to use the clock chip.

http://www.picbasic.co.uk/forum/showthread.php?t=2129


For the minutes portion of the clock, I wanted to use 12 LEDs (each representing 5 minutes). My plan for the code was to put all the ports into an array and navigate through the array. Unforunately after much discussion, Tom Igoe confirmed this was not possible. Ben Brown suggested I take the long route and code all the conditions. It’s lengthy, but works.



'****************************************************************
'* Name : clock.BAS *
'* Author : Avani Patel *
'* Notice : Copyright (c) 2005 2004 *
'* : All Rights Reserved *
'* Date : 4/21/2005 *
'* Version : 1.0 *
'* Notes : *
'* : *
'****************************************************************
Include "modedefs.bas" ' Include serial modes


TX var portc.6 ' Define serial output pin
SDA var PORTC.4 ' I2C data pin
SCL var PORTC.5 ' I2C clock pin
SQW var portc.3

RTCData VAR BYTE[8] ' Data byte array



input PORTB.6 'hour set
input PORTB.5 'second set
input PORTB.4 'set time

setHour var PORTB.6
setMinute var PORTB.5
setTime var PORTB.4

RTCSec var byte ' Seconds
RTCMin var byte ' Minutes
RTCHour var byte ' Hours
RTCWDay var byte ' Weekday
RTCDay var byte ' Day
RTCMonth var byte ' Months
RTCYear var byte ' Year
RTCCtrl var byte ' Control
DecimalHours var byte
DecimalMinutes var byte
DecimalSeconds var byte
address var byte
dataHours var byte
dataMinutes var byte
dataSeconds var byte

'testLight var PORTB.7 'blink this light at the begining_only happens once
i var byte

'use this subroutine only when programming for the first time
gosub setClock

'LED minutes vars
bSpace CON 200 'between blinks
longBSpace CON 1000 'between rounds
seqSpace CON 2000 ' end of main pause

'PORT SETUP'
'output portb.7 'light once, not neccessary

'set remaining ports to output for LEDs
output portc.2
output portc.3
output portd.0
output portd.1
'output portd.2

ADCON1=%10000111 'makes porta digital

'setting alias for LED ports, all on LEFT side of PIC

p1 var porta.0
p2 var porta.1
p3 var porta.2
p4 var porta.3

p5 var porta.4
p6 var porta.5
p7 var porta.6
p8 var porta.7

p9 var portc.2
p10 var portc.3
p11 var portd.0
p12 var portd.1


potVar VAR word
potMin VAR Byte
potLED Var BYTE
potMod Var BYTE

'inputVar var byte
'i var BYTE
'end LED vars

'servo hour vars
TRISB = %00000000

s1 var portb.7
s2 var portb.6
s3 var portb.5
s4 var portb.4
s5 var portb.3
s6 var portb.2

LotOpening VAR BYTE

pulseWidth VAR BYTE
' set up constants with the minimum and maximum pulsewidths
minPulse CON 140
maxPulse CON 220

openPetal CON 140
closePetal CON 220

'write method for opening and closing

' set up a constant with the time between pulses:
refreshPeriod CON 20

' set an initial pulsewidth:
pulseWidth = closePetal 'start with closed petal stata

LotOpening = 1 ' it's opening


'end servo hour vars
main:

I2CRead SDA,SCL,$D0,$00,[RTCSec,RTCMin,RTCHour,RTCWDay,RTCDay,RTCMonth,RTCYear,RTCCtrl]
gosub bcdtodec
'Serout2 TX,16468,[HEX RTCMonth,"/",HEX RTCDay,"/",HEX RTCYear," - ",HEX RTCHour, ":",HEX RTCMin,":",HEX RTCSec,13,10]
'pause 1000
goto main

bcdtodec:
'Convert BCD to decimal... assume variable RTCSeconds holds the seconds in BCD format...
'Hours
DecimalHours=RTCHour & $70
DecimalHours=DecimalHours>>4
DecimalHours=DecimalHours*10
DecimalHours=DecimalHours+(RTCHour & $0F)
'convert from 24 hr time to 12
if (DecimalHours >= 13) then
low PORTB.7
decimalHours = DecimalHours - 12
else
high PORTB.7
decimalHours = DecimalHours
endif
'address = 2
dataHours = (DecimalHours * 255)/12

'Minutes
DecimalMinutes=RTCMin & $70
DecimalMinutes=DecimalMinutes>>4
DecimalMinutes=DecimalMinutes*10
DecimalMinutes=DecimalMinutes+(RTCMin & $0F)
'address = 1
dataMinutes = (DecimalMinutes * 255)/60

'Seconds
DecimalSeconds=RTCsec & $70
DecimalSeconds=DecimalSeconds>>4
DecimalSeconds=DecimalSeconds*10
DecimalSeconds=DecimalSeconds+(RTCSec & $0F)
'address = 0
dataSeconds = (DecimalSeconds * 255)/60

'GOSUB subdigiout
gosub minLEDs
GOSUB hrServos

Serout2 TX,16468,[dec DecimalHours, ":",dec DecimalMinutes,":",dec DecimalSeconds,13,10]
Serout2 TX,16468,[dec dataHours, ":",dec dataMinutes,":",dec dataSeconds,13,10,13,10]
return

hrServos:
' change the angle for the next time around:
IF (pulseWidth > openPetal) AND (LotOpening=1) THEN 'if the pulse is greater than 50
pulseWidth = pulseWidth-1 ' knock it down
GOSUB move
HIGH portd.2
ENDIF

IF (pulseWidth = openPetal) THEN 'when pulseWidth reaches totally open state
LotOpening=0

PAUSE 1000

pulseWidth = pulseWidth+1
ENDIF

IF (pulseWidth < closePetal) AND (LotOpening=0) THEN
pulseWidth = pulseWidth+1
GOSUB move
HIGH portd.1
ENDIF

IF (pulseWidth = closePetal) THEN 'when pulseWidth reaches totally open state
LotOpening=1

PAUSE 1000

pulseWidth = pulseWidth-1

ENDIF

RETURN

move:
'take the output pin low so we can pulse it high
'LOW PORTC.3
' pulse the pin

if DecimalHours==1 THEN
SEROUT2 portc.6, 16468, ["servo 1", 13,10,13,10]
PULSOUT s1, pulseWidth
ENDIF

IF DecimalHours==2 THEN
PULSOUT s1, pulseWidth
PULSOUT s2, pulseWidth
ENDIF

IF DecimalHours==3 THEN
PULSOUT s1, pulseWidth
PULSOUT s2, pulseWidth
PULSOUT s3, pulseWidth
ENDIF

IF DecimalHours==4 THEN
PULSOUT s1, pulseWidth
PULSOUT s2, pulseWidth
PULSOUT s3, pulseWidth
PULSOUT s4, pulseWidth
ENDIF

IF DecimalHours==5 THEN
PULSOUT s1, pulseWidth
PULSOUT s2, pulseWidth
PULSOUT s3, pulseWidth
PULSOUT s4, pulseWidth
PULSOUT s5, pulseWidth
ENDIF

if DecimalHours==6 THEN
PULSOUT s1, pulseWidth
PULSOUT s2, pulseWidth
PULSOUT s3, pulseWidth
PULSOUT s4, pulseWidth
PULSOUT s5, pulseWidth
PULSOUT s6, pulseWidth
ENDIF

' pause for as long as needed:

PAUSE refreshPeriod

RETURN


minLEDS: 'figures out values for lights
'potMin=23 'temp constant value
' potLED=potMin/5 'to give 1-12 for minutes
'potMod=potMin//5 'modulus value, to give remindar for blinking LED

potLED=DecimalMinutes/5
potMod=DecimalMinutes//5

gosub blinkLEDs
RETURN

'DO NOT CHANGE- this sub works perfect! ONLY mess with pauses!
blinkLEDs:

If potLED==0 THEN 'less than 5 min
SEROUT2 portc.6, 16468, ["in pot=0", 13,10,13,10]

if potMod > 0 THEN
for i=1 to potMod
' high PORTD.2
high p1

pause bspace

' LOW PORTD.2
low p1

pause bspace

next i
pause longBspace ' long blink seperate out minutes
ENDIF

ENDIF


if potLED >=1 AND potLED < 2 then '5 mins

SEROUT2 portc.6, 16468, ["in pot>=1", 13,10,13,10]

HIGH p1

If potMod > 0 THEN
for i=1 to potMod

high p2
pause bspace

low p2
pause bspace

next i
pause longBspace
ENDIF

pause seqSpace

endif

if potLED >=2 AND potLED < 3 then '10 mins
HIGH p1
HIGH p2
SEROUT2 portc.6, 16468, ["in pot>=2", 13,10,13,10]

If potMod > 0 THEN
for i=1 to potMod

high p3
pause bspace

low p3
pause bspace

next i
pause longBspace
ENDIF

pause seqSpace
endif

if potLED >=3 AND potLED < 4 then '15 mins
HIGH p1
HIGH p2
HIGH p3

If potMod > 0 THEN
for i=1 to potMod

high p4
pause bspace

low p4
pause bspace

next i
pause longBspace
ENDIF

pause seqSpace
endif


if potLED >= 4 and potLED < 5 then '20 mins
High p1
high p2
high p3
HIGH p4

If potMod > 0 THEN
for i=1 to potMod

high p5
pause bspace

low p5
pause bspace

next i
pause longBspace
ENDIF

pause seqSpace
endif


if potLED >= 5 AND potLED < 6 then '25 mins
High p1
high p2
high p3
HIGH p4
HIGH p5

If potMod > 0 THEN
for i=1 to potMod

high p6
pause bspace

low p6
pause bspace

next i
pause longBspace
ENDIF

pause seqSpace
endif


if potLED >= 6 AND potLED <7 then '30 mins
High p1
high p2
high p3
HIGH p4
HIGH p5
HIGH p6

If potMod > 0 THEN
for i=1 to potMod

high p7
pause bspace

low p7
pause bspace

next i
pause longBspace
ENDIF

pause seqSpace
endif

if potLED >= 7 AND potLED < 8 then '35 mins
High p1
high p2
high p3
HIGH p4
HIGH p5
HIGH p6
HIGH p7

If potMod > 0 THEN
for i=1 to potMod

high p8
pause bspace

low p8
pause bspace

next i
pause longBspace
ENDIF

pause seqSpace
endif

if potLED >= 8 then '40 mins
High p1
high p2
high p3
HIGH p4
HIGH p5
HIGH p6
HIGH p7
HIGH p8

If potMod > 0 THEN
for i=1 to potMod

high p9
pause bspace

low p9
pause bspace

next i
pause longBspace
ENDIF


pause seqSpace
endif

if potLED >= 9 then '45 mins
High p1
high p2
high p3
HIGH p4
HIGH p5
HIGH p6
HIGH p7
HIGH p8
HIGH p9

If potMod > 0 THEN
for i=1 to potMod

high p10
pause bspace

low p10
pause bspace

next i
pause longBspace
ENDIF

pause seqSpace
endif

if potLED >= 10 then '50 mins
High p1
high p2
high p3
HIGH p4
HIGH p5
HIGH p6
HIGH p7
HIGH p8
HIGH p9
HIGH p10

If potMod > 0 THEN
for i=1 to potMod

high p11
pause bspace

low p11
pause bspace

next i
pause longBspace
ENDIF

pause seqSpace
endif

if potLED >= 11 then '55 mins
High p1
high p2
high p3
HIGH p4
HIGH p5
HIGH p6
HIGH p7
HIGH p8
HIGH p9
HIGH p10
HIGH p11

If potMod > 0 THEN
for i=1 to potMod

high p12
pause bspace

low p12
pause bspace

next i
pause longBspace
ENDIF

pause seqSpace
endif

if potLED == 12 then '60 mins 'does not exist AVANI!
High p1
high p2
high p3
HIGH p4
HIGH p5
HIGH p6
HIGH p7
HIGH p8
HIGH p9
HIGH p10
HIGH p11
HIGH p12
pause seqSpace
endif

'Pause 1000 'this needs to compensate for rest of minute
high portd.2
pause 400
low portd.2
SEROUT2 portc.6, 16468, ["end sequence here", 13,10,13,10]

goSub turnLow

RETURN


turnLow: 'turns all LEDs off
PAUSE 1000
'LOW p1
LOW p2
LOW p3
LOW p4
LOW p5
LOW p6

LOW p7
LOW p8
LOW p9
LOW p10
LOW p11
LOW p12

RETURN

setClock:
'Write command
RTCSec=$00 ' Seconds
RTCMin=$08 ' Minutes
RTCHour= $01 ' Hours
RTCWDay=$01 ' Weekday
RTCDay=$19 ' Day
RTCMonth=$05 ' Months
RTCYear=$05 ' Year
RTCCtrl=$10 ' Control preset to output 1 second 'Tick' on SQWpin
I2CWrite SDA,SCL,$D0,$00,[RTCSec,RTCMin,RTCHour,RTCWDay,RTCDay,RTCMonth,RTCYear,RTCCtrl]
Pause 1000

return


Thursday, November 17, 2005

FlowerINProgress

Parts List
  • 2 colors of fabric: inside petals, outside petals
  • 12 servos: 6 small, 6 regular size. Need servos with a bit more torque
  • 12 servo arms
  • servo mounting tape
  • 12 super bright LEDs: 6 blue, 6 white
  • 2 circular wooden bases to mount servos on



This is what the top view of the piece will look like



Code so far...




Based on some servo testing fun, I determined the angel to open and close a petal.

Then a coded functions to control this. Finally I added a switch so I can bloom and close petals as I wish.








DEFINE OSC 4 'ADC DEFINITIONS
DEFINE ADC_BITS 10 'CHANGE ADCON1 IF 10 BIT OR 8
DEFINE ADC_CLOCK 4
DEFINE ADC_SAMPLEuS 50


OUTPUT portd.2 ' LED debug
OUTPUT portd.1

OUTPUT portb.7 ' servo is on this port
OUTPUT portb.6 ' servo is on this port
OUTPUT portb.5 ' servo is on this port
OUTPUT portb.4 ' servo is on this port

INPUT portc.4 ' openFlower switch
INPUT portc.6 ' closeFlower switch

HIGH portd.1
PAUSE 200
LOW portd.1
PAUSE 200

start:
LotOpening VAR BYTE

pulseWidth VAR BYTE
' set up constants with the minimum and maximum pulsewidths
' minPulse CON 140
' maxPulse CON 220

openPetal CON 140 ' minPulse
closePetal CON 220 'maxPulse

'write method for opening and closing

' set up a constant with the time between pulses:
refreshPeriod CON 20

' set an initial pulsewidth:
pulseWidth = closePetal 'start with closed petal stata

LotOpening = 1 ' it's opening

main:
' change the angle for the next time around:
if (portc.4=1) then
high portd.1 ' light at end of petal is on this port
PAUSE 500
LOW portd.1
GOSUB bloom ' petals open
ENDIF

IF (portc.6=1) THEN
LOw portd.1
PAUSE 500
GOSUB encase 'petals close
ENDIF

GOTO main

move:

' pulse the pin
PULSOUT PORTb.7, pulseWidth
PULSOUT PORTb.6, pulseWidth
PULSOUT PORTb.5, pulseWidth
PULSOUT PORTb.4, pulseWidth
' pause for as long as needed:
PAUSE refreshPeriod
RETURN

bloom:
IF (pulseWidth > openPetal) AND (LotOpening=1) THEN 'if the pulse is greater than 50
pulseWidth = pulseWidth-1 ' knock it down
GOSUB move

ENDIF

IF (pulseWidth = openPetal) THEN 'when pulseWidth reaches totally open state
LotOpening=0
pulseWidth = pulseWidth+1

ENDIF
RETURN

encase:
IF (pulseWidth < lotopening="0)" pulsewidth =" pulseWidth+1" pulsewidth =" closePetal)" lotopening="1" pulsewidth =" pulseWidth-1">

Thursday, November 10, 2005

PROJECTObservation

The real life inspiration:



I went to the New York Botanical Garden and apparently lotuses are not around this time of year. Nevertheless I found ample inspiration among the rainforest flora.

Here are some flowers that may work for the hours






Here are some stems that may work for the minutes:


InitialPROTOTYPE

My first prototype of the timepiece. The small stems in the middle represent the minutes, the inner petals the hours from 1-6, the outer petals the hours from 7-12.

Thursday, November 03, 2005

FinalPROJECT: Lotus of Time

For my final project I had the idea of making a clock [something that I needed in my room anyway]. My goal is to designing a clock of subtle beauty, not harsh and mechanical; a reinterpretation of nature, something that I miss dearly living in the concrete jungle.

The organic design and reverence for nature in India has always been a constant source of inspiration for me.





This past June I went Udaipur in the state of Rajasthan. We toured its famous palace, which in my mind is the Indian counterpart of the Palace of Versailles. The marble carvings found embedded in niches, doorways, floors were exquisite. I was most struck by the simple flower carvings.



The flower pattern inspired an ID project, namely repeating flowers cut out of leather, to be worn as a necklace. I liked the design so much that I realized the petals would be perfect for my clock interpretation.

Ideally, my clock will have the following features:

  • Tell time, via the petals of the flower and its tendrils

  • possibly differentiate between AM/PM

  • Show seasons, via the change in light color

  • Display date, again via the petals of the flower, altho I have to work out how to diffential the time and the date

  • Be able to toggle between different time zones. My family is spread all over the world and having this function would be very handy when I need to make phone calls

The remaining questions are:
  • scale, I like building in large scale, but I may built a small prototype to work out the kinks with

  • materials. Right now I envision using plexiglass & blue and white wire. The color of the wire is extremely important as I want the wiring to be a part of the design. Plexi is quite expensive, so I may have to substitute another material.

  • finding the correct LEDs

  • figuring out how it can be mounted onto a wall, or should it be standalone?

Saturday, October 29, 2005

The.USER.Illusion

The art I have made in the past could be defined as high resolution (3d animation) or low resolution (drawings). In my time at ITP, my purpose is to create art that responds to a user, not something that simply exists to be viewed. It is tempting to throw a lot out to the user at once, but "The User Illusion" illustrates that all these things are filtered differently by all, depending on a number of variables. The variable that interests me the most is increasing conscious bandwidth by tapping into a user's emotions. I saw Daniel Rozin's "Wooden Mirror" at SIGGRAPH years ago. But I only recalled it once I heard of physical computing. The secondary spark in me came years after I interacted with the mirror. When that happened it changed the course of how I see things.

Obs Proj TWO, the Final Stretch [um, Prototype]

Although the drum trigger was working, it was not giving us reliable results. As suggested in class we decided to work in parallel. We ultimately wanted two working paddles, so we decided to have one hooked up to a midi synth box and the other one using the Sonia sound library in Processing.

I am not taking ICM so I had never used Processing before. Dan Shiffman's book draft was invaluable in getting me up to speed, but soon realized that sound was not Processing's forte. At the end of the day I got Daniel to come by and take a look at my code and even he couldn't figure out why it wasn't working!

So I ditched Sonia for the time being and got the midi synth box from the ER. I got some simple tones to play with the paddle. Going back to my days of playing flute I got the paddles to play Salt 'n Peppa's "Push It".




DEFINE OSC 20
DEFINE HSER_RCSTA 90h ' enable the receive register
DEFINE HSER_TXSTA 20h ' enable the transmit register
DEFINE HSER_BAUD 31250 ' set the baud rate

TRISD = %00000000 'Set all of PORTD pins to output mode

paddleVar VAR word 'Create variable to store result
pitch var byte(12)

i var byte
i=0

' ranges for reference
pitch(0) = 60' mid c
pitch(1) = 61' c#
pitch(2) = 62' d
pitch(3) = 63' d#
pitch(4) = 64' e
pitch(5) = 65' f
pitch(6) = 66' f#
pitch(7) = 67' g
pitch(8) = 68' g#
pitch(9) = 69' a
pitch(10) = 70' a#
pitch(11) = 71' b


' a,e,d,c,b,g,g,b,c,b,g - salt n peppa push it!
'69,64,62,60,71,67,67,71,60,71,67
song var byte(11)
song(0)=69
song(1)=64
song(2)=62
song(3)=60
song(4)=71
song(5)=67
song(6)=67
song(7)=71
song(8)=60
song(9)=71
song(10)=67

'light debug sequence
high PORTD.0
pause 200
low PORTD.0

high PORTD.1
PAUSE 200
low PORTD.1

main:
ADCIN 3, paddleVar 'coming in at analog port 3

if paddleVar > 100 THEN 'set to 100 since slight vibrations give off readings
hserout [$90, pitch(i),$40]
if(i>11) then 'loop thru song once its at end reset to 0 o
i=0
ELSE
i=i+1
ENDIF
ENDIF

PAUSE 100

goto main




*One thing to remember, when working with the midi box, you need a 20 hz clock and when you program the chip you have to change the oscillator from XT to HS.

ConstructionWOES
On the sensor/paddle side, Steve ran into Danny Tsang [who had done a similiar project for a class] and he told us a better way to rig the paddles. Steve stripped a piezo speaker and took out the piezo film inside, carefully soldered the connections.



We hollowed out the paddle handle, ran wires through it and glued the pieces back on.





Steve used Gorilla Glue, which takes about 3 hours to dry. BUT the glue expands which fixes the sensor into place. [pic here]

We got some code that handled the sensor peak readings and luckily got Sonia to work at the last minute.



' 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
PingPong VAR WORD

PingPong = 420

' 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 3, sensorValue

' check to see that it'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
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, ["peak reading", DEC peakValue, 13,10]
'serout2 tx, n9600, [DEC peakValue]
serout2 tx, n9600, [DEC pingPong]
endif

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

' store the current sensor value for the next loop:
lastSensorValue = sensorValue
Goto main





//PROCESSING CODE FOR SOUNDS

import pitaru.sonia_v2_9.*;
import processing.serial.*;

/*avani added, put sounds in array, sounds should reside in same folder as .pde file */
String[] wavArray = {"first.wav", "second.wav","third.wav"};// new String[3];

//end avani additions
int bgcolor; // background color
int fgcolor; // fill color
Serial port; // the serial port
int[] serialInArray = new int[3]; // where we'll put what we receive
int serialPong = 0;
int serialCount = 0; // a count of how many bytes we receive

boolean firstContact = false; // whether we've heard from the microcontroller
int j=0; //wavs index
Sample bounce;

void setup() {
size(256, 256); // stage size
noStroke(); // no border on the next thing drawn

// 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
Sonia.start(this); // Start Sonia engine.

}

void draw() {
background(bgcolor);
fill(fgcolor);
// get any new serial data:
while (port.available() > 0) {
serialEvent();
// note that we heard from the microntroller:
firstContact = true;
}
}

void serialEvent() {
processByte((char)port.read());
}

void processByte(char inByte) {
// add the latest byte from the serial port to array:
serialInArray[serialCount] = inByte;
serialCount++;

// if we have 3 bytes:
if (serialCount > 2 ) {
bounce = new Sample(wavArray[j]);
serialPong = (int)serialInArray[0];
println(serialPong);

if (serialPong == 52) {
bounce.play();
j++;
if (j>2) { j=0;}
} serialCount = 0;
}
}

// Safely close the sound engine upon Browser shutdown.
public void stop(){
Sonia.stop();
super.stop();
}

[processing code here]

We constructed two Radio Shack project boxes in order to keep the components in place when the user swings the paddle.





So without further ado....see the project in action! That's right! Click here

Lots of fun was had.

Saturday, October 22, 2005

Observation Project TWO, it's Analog, it's digital....it ANALOG!

Steven decided to strip the drum trigger to see what was inside. He found piezo film which basically senses vibration. We rigged the paddle so that the film was placed inside a groove cut for it near the bottom of the paddle. It picked up the vibration and so we figured out YES the drum trigger is analog. Oh and when the vibration was sensed, the LED in Santa's mouth lit up! "Ping Pong, Santa's ON."