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