Jason and I joint forces with the talented Steve, and brainy Inshan for the midterm assignment.
The task is to create a piece of furniture that joins and sends messages to a chat server. Each group in the class was required to do the same, so eventually all our furniture will IM each other.
after long brainstorming we decided to build a lamp that incorporates an IR sensor that will be triggered by the distance of a person from the lamp. In other words, the closer the person get to the lamp, the more intense the messages it sends to the server will become. Since it is a lamp, the IR will trigger interesting light combinations.
This was the first Pcomp-type project that I didn't do that much programming, and more designing. We were 4 group members and we naturally divided the job by strengths. Inshan and Jason did most of the programming, and Steve and me did most of the design and construction work. Nevertheless, we got a taste of everything every once in a while, when, for example a piece of code wouldn't work, we combined brain power.
The main idea of the light distribution of our lamp is by using bright-light LEDs that will shine through the edge of a frosted plexiglas, which will create a nice glow to the plexi. We wanted to use more than one source of light within the lamp to create the flexibility of manipulation by the different values of the IR sensor. Here are some of the preliminary sketches by Steve and myself:
 |
 |
Our basic concept was about the idea of translucency. We planned to create different layout of holes at each layer of plexiglas. When the light is off, only the first layer's layout of holes will be visible, when the light turns on and make the circles glow, a pattern (created by the combination of glowing circles from behind) would appear if standing right in front of the lamp. We later realized that the distance we had to create between the layers wouldn't allow for this effect.
We realized we will need a bunch of bright-lights to be powered at the same time. We were worried that sending a line of LEDs only 5v from a pin at the pic chip wouldn't supply enough power to the LEDs for sufficient glow. At first we thought of using Pulse Width Modulation, that way, we can light up all the LEDs at the same time by sending pulses of even 12v power so they'll blink very fast, and we won't worry about burning them. When this got too complicated code-wise, we decided to give it a try and light up the LEDs through the pic with only 5v. It wasn't as bright as we expected it, and we also realized that the blue bright-lights are the brightest ones.
Bottom line, that's how it works:
A person appears at a certain distance from the lamp, front Plexiglas lights up and the message: "Someone approaching me" is sent.
A person gets closer, middle Plexiglas lights up and the message: "Someone draws closer" is sent to server.
A person gets closest, back Plexiglas is also lighting up and the message: "Someone wants a kiss" is sent.
Getting to the technical level, Top wrote a java code to create a chat protocol on the furniture server (beyond me..). We wrote a code (well, we used Tom's example and modified it) to so the pic will receive the IR values and send out strings to the cobox which will send these strings to the furniture server. Sounds simple, but took us many many hours...
' Furniture Client 0001
' By Tom Igoe, 2004
' Serial out is on pin RC6
' serial in is on pin RC7
' an analog sensor is on pin RA0
DEFINE OSC 4
' 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
DEFINE CCP1_REG PORTC 'Hpwm 1 pin port
DEFINE CCP1_BIT 2 'Hpwm 1 pin bit
DEFINE CCP2_REG PORTC 'Hpwm 2 pin port
DEFINE CCP2_BIT 1 'Hpwm 2 pin bit
' variables and constants for the serial port:
tx var portc.6 ' transmit pin
rx var portc.7 ' receive pin
exitpin var portb.7
ledset1 var portc.1
ledset2 var portc.2
ledset3 var portc.3
debugr var portc.5
debugt var portc.4
input debugr
INPUT exitpin
output ledset1
output ledset2
output ledset3
exitpin = 0
non9600 con 16468 ' baudmode for serin2 and serout2: 9600 8-N-1 non-inverted
inputMaxLength con 96 ' max. input string
nameMaxLength con 20 ' max name string
cmdMaxLength con 10 ' max command string
asciiSpace con 32 ' constant for ascii SPACE character
lf con 10 ' constant for ascii linefeed character
cr con 13 ' constant for ascii carriage return character
i var byte ' counter
flag1 var bit
flag2 var bit
flag3 var bit
inputArray var byte(inputMaxLength) ' input strung from cobox
nameArray var byte(nameMaxLength) ' name of person who sent to us
cmdArray var byte(cmdMaxLength) ' command string they sent us
nameLength var byte ' length of their name
cmdLength var byte ' length of the command
chunkCursorPos var byte ' array pointer
currentChar var byte ' array pointer
dataByte var byte ' used when we just want one byte
distance var word
speed var word
dutyCycle var byte ' Duty cycle for PWM
Clear ' clear all variables
'variables for ADC:
ADCvar var word ' Create variable to store result
TRISA = %11111111 ' Set PORTA to all input
ADCON1 = %10000010 ' Set PORTA analog and right justify result
pause 1000 ' Wait a second at startup
login:
serout2 debugt, non9600, ["doing login", lf]
' wait for an ascii C, signifying a connection.
' this assumes you're in autoconnect mode (ConnectMode D5)
While dataByte <> 67
serin2 rx, non9600, [dataByte]
serout2 debugt, non9600, ["waiting for connect", lf,cr]
Wend
pause 100
' wait until the intro text is past. It ends with a > and a linefeed:
serin2 rx, non9600, [WAIT(">"), dataByte]
pause 100
' send your login
serout2 tx, non9600, ["login lampy", lf]
serout2 debugt, non9600, ["Logged in", lf,cr]
main:
GoSub check
GoTo main
check:
GoSub exit_server
GoSub ir_mode
Return
Return
ir_mode:
adcin 0, adcvar
If adcvar > 24 Then
serout2 debugt, non9600, ["In range",dec4 ADCvar, lf,cr]
If flag1 = 0 Then
serout2 tx, non9600, ["send all someone approaching me",lf,cr]
flag1 = 1
End If
high ledset1
adcin 0, adcvar 'get it again
If adcvar > 125 Then
high ledset2
If flag2 = 0 Then
serout2 tx, non9600, ["send all someone draws closer",lf,cr]
flag2 = 1
End If
If adcvar > 400 Then
If flag3 = 0 Then
serout2 tx, non9600, ["send all someone wants a kiss!!",lf,cr]
flag3 = 1
End If
high ledset3
Else
low ledset3
End If 'end set 3 conditional
Else
low ledset2
End If
Else
low ledset1
flag1 = 0
low ledset2
flag2 = 0
low ledset2
flag3 = 0
serout2 debugt, non9600, ["Out of range", lf,cr]
End If 'end range conditional
Return
exit_server:
If exitpin = 1 Then
serout2 debugt, non9600, ["send all exit ", lf]
serout2 tx, non9600, ["send all exit ", lf]
serout2 tx, non9600, ["exit ", lf]
End If
exitpin = 0
Return
|
A picture is better than 1,000 bytes (wait, it is bytes)...
 |  |
base of lamp in construction. By mounting boards on two parallel pieces of wood, we can hide breadboard underneath the lamp
| Open base view |
 |  |
Further away from the IR lights up 2 of the plexiglas
| Closer, lights up all plexiglas |
 |  |
Trying all colors only to realize that blue is our color.
|
...It would have been nice. Damn bright-lights! |
 |  |
And the magic begins...
| Completed Lampy, chatting away. |
Back to Top
|
Final Project /// Story Deconstruction
|
|
My final project is related somewhat to my future thesis project, although my thesis project intended users will be adults, and with this project the focus is on much younger users. Here it goes: The main purpose is to enhance collaboration between kids, as well as to test levels of attention and comprehension of familiar stories. Kids are at around ages 5 to 8.
Metaphorically, one cannot understand darkness without knowing light; or understand high without knowing low. The same idea I am applying to my testing of the young minds. My argument is that by showing a child a familiar story (i.e. Hanzle and Gratel) at a different point of view, their comprehension, and memory of the story's details may sharpen. I am creating a collaboration game that will allow 2 kids to create, deconstruct and reconstruct a story they are familiar with.
Well, since I'm combining 3 classes within one project, it has 2 aspects: Physical and Virtual. The Physical is related to the device each kid interacts with, and the Virtual is what they effect by using the physical devices. I will divide my notes to those two elements and see how it goes.
-- Physical
Each kid will have a tray with a number of plexiglas pieces arranged in a certain visual sequence. each piece will correspond to a scene of the story that will be represented through a flash interface. The flash interface will reside on the web so that the kids can be at different locations while they play.
Through the game, each kid, on his/her turn, will put a piece on the tray anywhere they like. This way the kids are rebuilding the story by changing the location of scenes. After they place all pieces on the tray, they'll be able to play the movie they both created by replacing the scenes.
At the Flash side, I will make sure that each scene's ending and beginning can match any scene that will be adjacent according to the kids' decision. I always find it easier to understand relationships through diagrams:
|
|
|
As I began testing my understanding of the Cobox-Flash relationship, I realize something - no project is ever complete without a stupid mistake at one point or another. I spent half a day frustrated about a program that was quite simple just to find out that my hex-inverter was turned the opposite way.
After figuring that out, I was pleased with how smooth the flash reaction was to physical buttons. There was not delay when flash received information and not delay when it sent. Luckily, my Flash teacher, Veronique, had given us a lecture and code examples for this type of communication.
Here is the code for the Pic:
Here is the Flash code:
Problem: The above Flash program worked perfectly fine when I opened the Flash SWF from our lab's computer, but when I uploaded the SWF, embedded in an HTML, to my web site, it didn't connect to my Cobox. When I read in the Flash Help files about the XML socket class (which is needed in order to open XML socket into the SWF), I found that for the XML socket to work it needs to connect to a server which is on the same domain as the SWF. If it is not on the same domain, a "cross-domain policy file" (a special XML file) needs to be used. I'm not sure if I am indeed communicating with the Cobox from a different domain, but I will find out next.
Solution: Yup, the above was my problem. The security restrictions have changes for flash 7 players, and now in order to communicate, elements have to reside on the same exact domain. If they are not, a cross domain XML file is needed as a connecting variable. More info about this and other security related changes, can be found here.
Well, I'm back with an actual solution to the above security problem - WEB2COB is the answer!
With much appreciated help from Tom Igoe and Veronique Brossier, I found a pretty simple answer. Tom had informed me about the possibility of adding files to the Cobox, limited to 64K in size. Since the necessary XML policy file has only a couple lines of code, there is no problem loading it to the Cobox.
I contacted technical assistance at Lantronix and they emailed me a folder that included everything I needed in order to install files into my Cobox. The application that does the job is called Web2cob. A not-too-complicated process is well described, step-by-step in the documentation I received from Lantronix.
Web2cob Starter Kit (zip file)
After extracting the file, open the Word document "web2cob example", which explains it all. If you follow this path: "cobox_app" -> "web (limor's)" -> "SOURCE" you can find my XML policy file. You will notice that in the XML file code, I am allowing access to all websites (marking it with an asterisk instead of a website address). I placed the XML on WEB1 spot on the Cobox, but it can be in either of the 6 available spots.
(Note: For some reason whenever I entered the address of my server, with the required absolute path, into the XML code, it didn't work and my SWF never communicated with the Cobox. It took quite a chunk of the day with Tom and Vero to later realize that all I needed to do is put an asterisk instead of an address. Arrrg)
It works like a charm!
Now, a person in Japan can open my Flash SWF on my server and light up some LEDs here in America. I love the Cobox!!
-- Virtual
At this stage, I needed to find the logic of my story telling which is the core of my project. I started by searching for a story. I was looking for a fairytale online. It didn't really matter which fairytale, since essentially, this project should produce the same results for any story told. I ended up selecting the Princess and the Pea by Hans Christian Andersen. Each fairy tale can usually be found in more than one style. I chose to use the style I found on this website.
The first step was to break the story into scenes. I decided to divide it to 8 scenes. Now, I knew that there will be lots of testing required for me to realize the final solution and arrangement of scenes. The application required needed to be flexible enough for me to quickly change scenes positions; just like it would be with index cards. I found the "Stickies" application (Mac) to be just right.
In Stickies, at the beginning, I created 8 notes - one for each scene. Then I started forming the game's logical arrangement for the scenes (which kept changing through the process). I needed to create somewhat of a restriction so the fairy tale will not be changed completely. Hence, Scene 1 and 8 are to remain static, so that only the remaining interim scenes can be rearranged. As I tested different scenarios, I realized that in order to always go back to the same ending of the story, I have to use a blank spot before the ending, where the sub scenes selected for that spot (I call them - special subs) will be a bit different from the other sub scenes in the game. These special sub scenes will have their ending modified rather than their beginning. I decided to merge the 7th and 8th scenes, and designate the 7th spot for these special subs.
During the game, each player can select a scene in the order they choose. It means that each of the scenes they select needs to match the adjacent scenes that comes before and after it. So the challenge I was facing was how to get each scene to match the previous and preceding one without changing the whole story. My solution was to create new notes to the possible scenes to be selected after the original scenes - we'll call them sub scenes. Each sub scene had to remain in the same family of the original scene which it is preceding. It meant that only one side of the scene can change, so that the original scene and its sub scenes will have some common denominator. As a result, I modified the beginning of each sub scene to match the ending of its original scene, and left their ending intact. So for example wherever scene 3 is placed, it'll always have the same ending.
The possibilities of creating large number of notes and modify their colors in Stickies, provided great visual assistance. The image below is the screen capture of my stickies arrangement. The static scenes are blue; the original scenes are purple; All the sub scenes behind the original are of different colors. On each of the sub scenes, the modified/added text at the beginning of the scene is a lighter blue to separate it from the original text. You can click the image for a larger/legible view.
To further clarify what all the possible combinations of scenes would be I'll draw a table:
Original
scenes | >> |
Scene
1 |
Scene
2 |
Scene
3 |
Scene
4 |
Scene
5 |
Scene
6 |
Scene
7 |
Scene
8 |
| Function |
>> |
Static |
Dynamic |
Dynamic |
Dynamic |
Dynamic |
Dynamic |
Open |
Static |
Logical scene
to follow |
>> |
Scene
2 |
Scene
3 |
Scene
4 |
Scene
5 |
Scene
6 |
Scene
8 |
Scene |
|
Sub scene
to follow |
>> |
Sub
1-3 |
Sub
2-4 |
Sub
3-2 |
Sub
4-2 |
Sub
5-2 |
Sub
6-2 |
Special sub
3--7 |
Sub
1-4 |
Sub
2-5 |
Sub
3-5 |
Sub
4-3 |
Sub
5-3 |
Sub
6-3 |
Special sub
4--7 |
Sub
1-5 |
Sub
2-6 |
Sub
3-6 |
Sub
4-6 |
Sub
5-4 |
Sub
6-4 |
Special sub
5--7 |
Sub
1-6 |
|
|
|
|
Sub
6-5 |
Special sub
6--7 |
The unique numerical values of all the scenes and sub scenes will be valuable in the programming phase. When writing Action-Script I will be able to concatenate groups of possible following scenes in "for" loops.
As I'm sitting here, trying to figure out the code I need to type, I'm realizing that another table can't be a bad thing. This one's only for the Sub scenes:
| |
Scene
1 |
Scene
2 |
Scene
3 |
Scene
4 |
Scene
5 |
Scene
6 |
| Sub scene 2 |
(1)-2 |
|
(3)-2 |
(4)-2 |
(5)-2 |
(6)-2 |
| Sub scene 3 |
(1)-3 |
(2)-3 |
|
(4)-3 |
(5)-3 |
(6)-3 |
| Sub scene 4 |
(1)-4 |
(2)-4 |
(3)-4 |
|
(5)-4 |
(6)-4 |
| Sub scene 5 |
(1)-5 |
(2)-5 |
(3)-5 |
(4)-5 |
|
(6)-5 |
| Sub scene 6 |
(1)-6 |
(2)-6 |
(3)-6 |
(4)-6 |
(5)-6 |
|
This time I enclosed the main scene numbers, within the sub scenes names, in parentheses because the sub scene (second) number is the actual scene - but modified - that is playing.
So, there are 8 spots in the main timeline. The first and the last are static, and the 7th is automatically selected, so the remaining 5 spots in between can be filled with any of the sub scene depending on the pervious spot's selection. Now I'm ready to write the general pseudo code:
- Spot 1 -
- Spot 2 -
If player chooses scene 2 then 1-2 will play
If player chooses scene 3 then 1-3 will play
If player chooses scene 4 then 1-4 will play
If player chooses scene 5 then 1-5 will play
If player chooses scene 6 then 1-6 will play
- Spots 3 -
If spot 2 ends with 2 and player chooses either scene 3, 4, 5, 6
then 2-3, 2-4, 2-5, 2-6 will play
If spot 2 ends with 3 and player chooses either scene 2, 4, 5, 6
then 3-2, 3-4, 3-5, 3-6 will play
If spot 2 ends with 4 and player chooses either scene 2, 3, 5, 6
then 4-2, 4-3, 4-5, 4-6 will play
If spot 2 ends with 5 and player chooses either scene 2, 3, 4, 6
then 5-2, 5-3, 5-4, 5-6 will play
If spot 2 ends with 6 and player chooses either scene 2, 3, 4, 5
then 6-2, 6-3, 6-4, 6-5 will play
- Spot 4 -
If spot 3 ends with 2 and player chooses either scene 3, 4, 5, 6
then 2-3, 2-4, 2-5, 2-6 will play
If spot 3 ends with 3 and player chooses either scene 2, 4, 5, 6
then 3-2, 3-4, 3-5, 3-6 will play
If spot 3 ends with 4 and player chooses either scene 2, 3, 5, 6
then 4-2, 4-3, 4-5, 4-6 will play
If spot 3 ends with 5 and player chooses either scene 2, 3, 4, 6
then 5-2, 5-3, 5-4, 5-6 will play
If spot 3 ends with 6 and player chooses either scene 2, 3, 4, 5
then 6-2, 6-3, 6-4, 6-5 will play
- Spot 5 -
If spot 4 ends with 2 and player chooses either scene 3, 4, 5, 6
then 2-3, 2-4, 2-5, 2-6 will play
If spot 4 ends with 3 and player chooses either scene 2, 4, 5, 6
then 3-2, 3-4, 3-5, 3-6 will play
If spot 4 ends with 4 and player chooses either scene 2, 3, 5, 6
then 4-2, 4-3, 4-5, 4-6 will play
If spot 4 ends with 5 and player chooses either scene 2, 3, 4, 6
then 5-2, 5-3, 5-4, 5-6 will play
If spot 4 ends with 6 and player chooses either scene 2, 3, 4, 5
then 6-2, 6-3, 6-4, 6-5 will play
- Spot 6 -
If spot 5 ends with 2 and player chooses either scene 3, 4, 5, 6
then 2-3, 2-4, 2-5, 2-6 will play
If spot 5 ends with 3 and player chooses either scene 2, 4, 5, 6
then 3-2, 3-4, 3-5, 3-6 will play
If spot 5 ends with 4 and player chooses either scene 2, 3, 5, 6
then 4-2, 4-3, 4-5, 4-6 will play
If spot 5 ends with 5 and player chooses either scene 2, 3, 4, 6
then 5-2, 5-3, 5-4, 5-6 will play
If spot 5 ends with 6 and player chooses either scene 2, 3, 4, 5
then 6-2, 6-3, 6-4, 6-5 will play
- Spot 7 -
If spot 6 ends with 2 then 7--3 will play
If spot 6 ends with 3 then 7--4 will play
If spot 6 ends with 4 then 7--5 will play
If spot 6 ends with 5 then 7--6 will play
- Spot 8 -
To try and make it clearer Here's a sample scenario of a game:
Yellow indicates lit LEDs = moveable pieces.
Scene 1 is playing in UI.
|
| Player A |
Flash UI |
Player B |
|
|
|
|
|
Player A chooses scene 3.
Sub scene 1-3 is playing.
|
|
Player B chooses scene 6.
Sub scene 3-6 is playing.
|
| |
|
|
|
|
scn 1
sbscn 1-3
sbscn 3-6
|
|
|
|
Player A chooses scene 2.
Sub scene 6-2 is playing.
|
| |
|
|
|
|
scn 1
sbscn 1-3
sbscn 3-6
sbscn 6-2
|
|
|
|
Player B chooses scene 4
Sub scene 2-4 is playing.
|
| |
|
|
|
|
scn 1
sbscn 1-3
sbscn 3-6
sbscn 6-2
sbscn 2-4
|
|
|
|
Player A chooses scene 5.
Sub scene 4-5 is playing.
|
| |
|
|
|
|
scn 1
sbscn 1-3
sbscn 3-6
sbscn 6-2
sbscn 2-4
sbscn 4-5
|
|
|
|
| Special scene 7--5 is playing.
|
| |
|
|
|
|
scn 1
sbscn 1-3
sbscn 3-6
sbscn 6-2
sbscn 2-4
sbscn 4-5
spcscn 7--5
|
|
|
|
| Scene 8 is playing
|
| |
|
|
|
|
scn 1
sbscn 1-3
sbscn 3-6
sbscn 6-2
sbscn 2-4
sbscn 4-5
spcscn 7--5
scn 8
|
|
|
|
|
|
Back to Top
|
|