/*******************************************************************************
|
|
*
|
|
* CapTouch_BoosterPack_UserExperience_GUI.pde
|
|
* - PC demo application for establishing a serial connection
|
|
* with the LaunchPad CapTouch BoosterPack.
|
|
*
|
|
* Copyright (C) 2011 Texas Instruments Incorporated - http://www.ti.com/
|
|
*
|
|
* Redistribution and use in source and binary forms, with or without
|
|
* modification, are permitted provided that the following conditions
|
|
* are met:
|
|
*
|
|
* Redistributions of source code must retain the above copyright
|
|
* notice, this list of conditions and the following disclaimer.
|
|
*
|
|
* Redistributions in binary form must reproduce the above copyright
|
|
* notice, this list of conditions and the following disclaimer in the
|
|
* documentation and/or other materials provided with the
|
|
* distribution.
|
|
*
|
|
* Neither the name of Texas Instruments Incorporated nor the names of
|
|
* its contributors may be used to endorse or promote products derived
|
|
* from this software without specific prior written permission.
|
|
*
|
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
|
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
|
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
|
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
|
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
|
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
|
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
|
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
|
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
|
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
*
|
|
*
|
|
******************************************************************************/
|
|
|
|
/******************************************************************************
|
|
* MSP430G2-LaunchPad CapTouch BoosterPack User Experience GUI
|
|
* Desc:
|
|
* This PC GUI application communicates with the LaunchPad specifically to
|
|
* receive capacitive touch data from the LaunchPad CapTouch BoosterPack and
|
|
* provides the visualization of said information in the GUI.
|
|
*
|
|
* The GUI uses a small .NET utility (FindAppUART.exe) to automatically detect
|
|
* a proper LaunchPad/430Emulator device connected to the PC USB port. Upon
|
|
* correct USB COM port discovery, the application initiates a 9600baud UART
|
|
* connection and starts receiving data.
|
|
*
|
|
* Upon each LaunchPad event, data is transmitted [always] via a simple '2-byte'
|
|
* protocol as described below.
|
|
* [LaunchPad] Wake up : 0xBE 0xEF
|
|
* [LaunchPad] Sleep : 0xDE 0xAD
|
|
* [CapTouch] Center Button : 0x80 0x80
|
|
* [CapTouch] Wheel Tap : WT WT = pos. on wheel [0-0x0F] + 0x30
|
|
* [CapTouch] Gesture Start : 0xFC POS = pos. on wheel [0-0x0F] + 0x20
|
|
* [CapTouch] Gesture Stop : 0xFB POS = pos. on wheel [0-0x0F] + 0x20
|
|
* [CapTouch] Gesture Update: GES POS
|
|
* Gesture = [0-0x0F] --> Clockwise gesture
|
|
* = 0x10+ [0-0x0F] --> Counter-clockwise gesture
|
|
*
|
|
* The GUI grays out during sleep mode and returns to active mode upon wake up.
|
|
* The 'Center Button' press data toggles the center circle color, mimicking the
|
|
* behavior of the center LED on the BoosterPack.
|
|
* The 'Wheel Tap' is represented by lighting up a single slice on the wheel.
|
|
* The gesture tracking [Start, Stop, Update] is visualized on the wheel with
|
|
* the coloration of the wheel slices. Gesture can be tracked for several
|
|
* revolutions of the wheel, in both clockwise and counter-clockwise directions.
|
|
*
|
|
* A hidden code/lock is embedded in the wheel. Correct sequence [similar to a
|
|
* rotational combination lock] reveals a secret address.
|
|
*
|
|
* D. Dang
|
|
* Texas Instruments, Inc.
|
|
* Ver 0.90 Feb 2011
|
|
******************************************************************************/
|
|
|
|
import pitaru.sonia_v2_9.*;
|
|
import processing.serial.*;
|
|
import java.io.BufferedReader;
|
|
import java.io.IOException;
|
|
import java.io.InputStreamReader;
|
|
|
|
final int TIME_OUT = 140;
|
|
|
|
/*--------Dimensions & coordinates------------*/
|
|
final int CANVAS_SIZE_X = 900;
|
|
final int CANVAS_SIZE_Y = 580;
|
|
final int OUT_CIRCLE_RADIUS = 248;
|
|
final int IN_CIRCLE_RADIUS = 101;
|
|
final int CENTER_CIRCLE_RADIUS = 37;
|
|
final int CIRCLE_CENTER_X = 450;
|
|
final int CIRCLE_CENTER_Y = 285;
|
|
|
|
final int SOUND_ICON_X = 820;
|
|
final int SOUND_ICON_Y = 20;
|
|
|
|
/*--------Drawing definitions------------*/
|
|
final int NUMBER_OF_SLICES = 16;
|
|
final int BACKGROUND_COLOR = 170;
|
|
final int TAP_SLICE_COLOR = -100;
|
|
final int SLICE_TRANSPARENCY = 30;
|
|
final int SLICE_TRANSPARENCY_OFFSET = 80;
|
|
|
|
/*--------UART protocol definitions------------*/
|
|
final int WAKE_UP_UART_CODE = 0xBE;
|
|
final int WAKE_UP_UART_CODE2 = 0xEF;
|
|
final int SLEEP_MODE_UART_CODE = 0xDE;
|
|
final int SLEEP_MODE_UART_CODE2 = 0xAD;
|
|
final int CENTER_BUTTON_CODE = 0x80;
|
|
final int INVALID_WHEEL_POSITION = 0xFE;
|
|
final int INVALID_GESTURE = 0xFD;
|
|
final int GESTURE_START = 0xFC;
|
|
final int GESTURE_STOP = 0xFB;
|
|
final int GESTURE_POSITION_OFFSET = 0x20;
|
|
final int WHEEL_POSITION_OFFSET = 0x30;
|
|
final int NUMBER_OF_WHEEL_POSITIONS = 16;
|
|
//final int INVALID_WHEEL_POSITION = -100;
|
|
final int INVALID_GESTURE_DIRECTION = -100;
|
|
final int GESTURE_CLOCKWISE = 1;
|
|
final int GESTURE_COUNTERCLOCKWISE = -1;
|
|
|
|
|
|
|
|
|
|
/*----------CapTouch-related variables----------------*/
|
|
int gestureStartingPosition = INVALID_WHEEL_POSITION, gestureStoppingPosition = INVALID_WHEEL_POSITION;
|
|
int[] gestureCoverPositions = new int[16];
|
|
int gestureDirection = INVALID_GESTURE_DIRECTION;
|
|
int gestureImmediateDirection = INVALID_GESTURE_DIRECTION;
|
|
|
|
int allLit = 0;
|
|
int inactivityCounter=0, sleeping=0, tapping=0, centerButton=0;
|
|
int CenterButtonToggle=0;
|
|
|
|
/*------Serial communication----------------*/
|
|
int LaunchPadComPortFound = 0, numberOfLookingDots=0;
|
|
Serial LaunchPad;
|
|
|
|
/*--------- Visual & audio elements-----------*/
|
|
PImage backgroundImage, innerCircleImage,innerCircleSelectedImage, innerCircleUnlockedImage ;
|
|
int drawNumberEnabled = 0;
|
|
|
|
Sample click,clickFound, clickOpen;
|
|
int soundEnabled = 0;
|
|
|
|
|
|
void drawSlice(int sliceIndex, int sliceLevel)
|
|
{
|
|
int sliceAfter, sliceLabel;
|
|
sliceLabel = sliceIndex;
|
|
if (sliceIndex < 3)
|
|
sliceIndex = sliceIndex + 16 - 4;
|
|
else
|
|
sliceIndex = sliceIndex - 4;
|
|
sliceAfter = sliceIndex + 1;
|
|
if (sliceAfter == NUMBER_OF_SLICES)
|
|
sliceAfter = 0;
|
|
noStroke();
|
|
stroke(255);
|
|
strokeWeight(4);
|
|
if (sliceLevel == TAP_SLICE_COLOR)
|
|
fill(160,160,160, 225);
|
|
else
|
|
fill(252,236,54, sliceLevel * SLICE_TRANSPARENCY + SLICE_TRANSPARENCY_OFFSET);
|
|
arc(CIRCLE_CENTER_X, CIRCLE_CENTER_Y, OUT_CIRCLE_RADIUS*2, OUT_CIRCLE_RADIUS*2, (((float)sliceIndex)-0.5) * 2 * PI /16, (((float)sliceIndex)+0.5) * 2 * PI /16);
|
|
line( CIRCLE_CENTER_X + cos( (((float)sliceIndex)-0.5) * 2 * PI /16 ) * OUT_CIRCLE_RADIUS, CIRCLE_CENTER_Y + sin((((float)sliceIndex)-0.5) * 2 * PI /16 ) * OUT_CIRCLE_RADIUS,
|
|
CIRCLE_CENTER_X + cos( (((float)sliceIndex)-0.5) * 2 * PI /16 ) * IN_CIRCLE_RADIUS, CIRCLE_CENTER_Y + sin((((float)sliceIndex)-0.5) * 2 * PI /16 ) * IN_CIRCLE_RADIUS);
|
|
line( CIRCLE_CENTER_X + cos( (((float)sliceIndex)+0.5) * 2 * PI /16 ) * OUT_CIRCLE_RADIUS, CIRCLE_CENTER_Y + sin((((float)sliceIndex)+0.5) * 2 * PI /16 ) * OUT_CIRCLE_RADIUS,
|
|
CIRCLE_CENTER_X + cos( (((float)sliceIndex)+0.5) * 2 * PI /16 ) * IN_CIRCLE_RADIUS, CIRCLE_CENTER_Y + sin((((float)sliceIndex)+0.5) * 2 * PI /16 ) * IN_CIRCLE_RADIUS);
|
|
if (drawNumberEnabled == 1)
|
|
{
|
|
fill(0);
|
|
text( sliceLabel,
|
|
CIRCLE_CENTER_X + cos( (((float)sliceIndex)) * 2 * PI /16 ) * (OUT_CIRCLE_RADIUS-40)-7,
|
|
CIRCLE_CENTER_Y + sin( (((float)sliceIndex)) * 2 * PI /16 ) * (OUT_CIRCLE_RADIUS-40));
|
|
}
|
|
}
|
|
void drawCanvas()
|
|
{
|
|
int i;
|
|
background(BACKGROUND_COLOR);
|
|
image(backgroundImage, 0 ,0);
|
|
fill(0,0,0,255);
|
|
if (unlocked == 1)
|
|
{
|
|
fill(0);
|
|
text("BoosterPack Unlocked",300,30);
|
|
|
|
for (i=0;i<4;i++)
|
|
drawSlice(code[i],4);
|
|
fill(255);
|
|
ellipse(CIRCLE_CENTER_X, CIRCLE_CENTER_Y, IN_CIRCLE_RADIUS*2 , IN_CIRCLE_RADIUS*2);
|
|
image(innerCircleUnlockedImage, 0, 0);
|
|
}
|
|
|
|
}
|
|
|
|
void goToSleep()
|
|
{
|
|
tint(120,120,120,180);
|
|
drawCanvas();
|
|
tint(120,120,120,180);
|
|
fill(255);
|
|
textSize(20);
|
|
text(".",20,30);
|
|
text(".",28,30);
|
|
text(".",35,30);
|
|
textSize(25);
|
|
text("z",47,30);
|
|
textSize(30);
|
|
text("z",65,30);
|
|
textSize(35);
|
|
text("z",85,30);
|
|
textSize(40);
|
|
text("z",108,30);
|
|
textSize(30);
|
|
noTint();
|
|
sleeping = 1;
|
|
inactivityCounter = TIME_OUT;
|
|
}
|
|
|
|
void findLaunchPad()
|
|
{
|
|
String ComPortName ="";
|
|
try
|
|
{
|
|
Process proc = Runtime.getRuntime().exec("FindAppUART.exe");
|
|
proc.waitFor();
|
|
int exitVal = proc.exitValue();
|
|
// Get the first line from the process' STDOUT
|
|
BufferedReader buf = new BufferedReader(new InputStreamReader(proc.getInputStream()));
|
|
ComPortName = buf.readLine();
|
|
if (ComPortName.substring(0,3).equals("COM") != true)
|
|
ComPortName = "";
|
|
else
|
|
{
|
|
LaunchPadComPortFound = 1;
|
|
LaunchPad = new Serial(this, ComPortName, 9600);
|
|
}
|
|
}
|
|
catch(Exception e)
|
|
{
|
|
println(e);
|
|
}
|
|
}
|
|
|
|
void promptLookingForLaunchPad()
|
|
{
|
|
fill(255,0,0);
|
|
noStroke();
|
|
rect(100,CANVAS_SIZE_Y/2-100,CANVAS_SIZE_X-120,200);
|
|
fill(255);
|
|
textSize(50);
|
|
numberOfLookingDots++;
|
|
if (numberOfLookingDots==5)
|
|
numberOfLookingDots = 1;
|
|
switch(numberOfLookingDots)
|
|
{
|
|
case 1: text("Looking for LaunchPad ", 175,CANVAS_SIZE_Y/2 ); break;
|
|
case 2: text("Looking for LaunchPad . ", 175,CANVAS_SIZE_Y/2 ); break;
|
|
case 3: text("Looking for LaunchPad .. ", 175,CANVAS_SIZE_Y/2 ); break;
|
|
case 4: text("Looking for LaunchPad ...", 175,CANVAS_SIZE_Y/2 ); break;
|
|
}
|
|
|
|
}
|
|
void setup()
|
|
{
|
|
size(CANVAS_SIZE_X, CANVAS_SIZE_Y);
|
|
background(255,0,0);
|
|
Sonia.start(this);
|
|
click = new Sample("click1.aiff");
|
|
clickOpen = new Sample("open.aiff");
|
|
clickFound = new Sample("unlock.aiff");
|
|
click.setVolume(3);
|
|
clickFound.setVolume(3);
|
|
frameRate(3);
|
|
|
|
backgroundImage = loadImage("background.png");
|
|
innerCircleImage = loadImage("innerCircle.png");
|
|
innerCircleSelectedImage = loadImage("innerCircleSelected.png");
|
|
innerCircleUnlockedImage = loadImage("innerCircleUnlocked.png");
|
|
|
|
|
|
|
|
findLaunchPad();
|
|
if (LaunchPadComPortFound == 0)
|
|
{
|
|
fill(255);
|
|
textSize(40);
|
|
text("LaunchPad Capacitive Touch BoosterPack", 70,50);
|
|
textSize(55);
|
|
fill(0);
|
|
text("User Experience Demo", 150,100);
|
|
|
|
fill(0);
|
|
textSize(25);
|
|
text("1. Plug your Capacitive Touch BoosterPack into the LaunchPad", 150,CANVAS_SIZE_Y - 70);
|
|
text("2. Connect your LaunchPad to the PC via USB", 150,CANVAS_SIZE_Y - 45);
|
|
promptLookingForLaunchPad();
|
|
}
|
|
else
|
|
{
|
|
frameRate(30);
|
|
goToSleep();
|
|
}
|
|
}
|
|
|
|
|
|
|
|
void draw()
|
|
{
|
|
int i;
|
|
if (LaunchPadComPortFound==0)
|
|
{
|
|
findLaunchPad();
|
|
if (LaunchPadComPortFound==1)
|
|
{
|
|
goToSleep();
|
|
frameRate(30);
|
|
}
|
|
else
|
|
promptLookingForLaunchPad();
|
|
|
|
}
|
|
else
|
|
|
|
if(LaunchPad.available() >= 0)
|
|
{
|
|
int buf, buf1;
|
|
buf = LaunchPad.read();
|
|
buf1 = -1;
|
|
|
|
if (buf>=0)
|
|
{
|
|
drawCanvas();
|
|
textSize(30);
|
|
|
|
sleeping = 0;
|
|
inactivityCounter=0;
|
|
tapping = 0 ;
|
|
centerButton = 0;
|
|
switch(buf)
|
|
{
|
|
case WAKE_UP_UART_CODE:
|
|
|
|
while (buf1 <0)
|
|
buf1 = LaunchPad.read();
|
|
if (buf1==WAKE_UP_UART_CODE2)
|
|
text("Proximity Sensor Wake Up",20,30);
|
|
else
|
|
{
|
|
print("Error: invalid UART Wake up == ");
|
|
println(buf1);
|
|
}
|
|
break;
|
|
|
|
case SLEEP_MODE_UART_CODE:
|
|
while (buf1 <0)
|
|
buf1 = LaunchPad.read();
|
|
if (buf1==SLEEP_MODE_UART_CODE2)
|
|
{
|
|
//tint(120,0,0,180);
|
|
CenterButtonToggle = 0;
|
|
backgroundImage = loadImage("background.png");
|
|
innerCircleImage = loadImage("innerCircle.png");
|
|
tint(120,120,120,180);
|
|
drawCanvas();
|
|
text("Good night!",20,30);
|
|
sleeping = 1;
|
|
noTint();
|
|
}
|
|
else
|
|
{
|
|
print("Error: invalid UART Sleep == ");
|
|
println(buf1);
|
|
}
|
|
break;
|
|
|
|
case CENTER_BUTTON_CODE:
|
|
while (buf1 <0)
|
|
buf1 = LaunchPad.read();
|
|
if (buf==buf1)
|
|
{
|
|
if (unlocked==1)
|
|
{
|
|
unlocked = 0;
|
|
link(secretURL);
|
|
}
|
|
CenterButtonToggle = 1 - CenterButtonToggle;
|
|
if (CenterButtonToggle == 1)
|
|
{
|
|
innerCircleImage= loadImage("innerCircleSelected.png");
|
|
backgroundImage = loadImage("backgroundSelected.png");
|
|
}
|
|
else
|
|
{
|
|
innerCircleImage= loadImage("innerCircle.png");
|
|
backgroundImage = loadImage("background.png");
|
|
}
|
|
drawCanvas();
|
|
centerButton = 1;
|
|
}
|
|
else
|
|
{
|
|
print("Error: invalid CENTER BUTTON code == ");
|
|
println(buf1);
|
|
}
|
|
break;
|
|
|
|
|
|
case GESTURE_STOP:
|
|
while (buf1 <0)
|
|
buf1 = LaunchPad.read();
|
|
|
|
if (buf==buf1)
|
|
{
|
|
text("Gesture Released",20,30);
|
|
gestureStartingPosition = INVALID_WHEEL_POSITION;
|
|
gestureStoppingPosition = INVALID_WHEEL_POSITION;
|
|
gestureDirection = INVALID_GESTURE_DIRECTION;
|
|
allLit = 0;
|
|
codeCheck = 0;
|
|
codeLevel = 0;
|
|
//unlocked = 0;
|
|
}
|
|
else
|
|
{
|
|
print("Error: invalid GESTURE_STOP code == ");
|
|
println(buf1);
|
|
}
|
|
break;
|
|
|
|
case GESTURE_START:
|
|
|
|
while (buf1 <0)
|
|
buf1 = LaunchPad.read();
|
|
|
|
if ( (buf1 < GESTURE_POSITION_OFFSET ) || (buf1 > GESTURE_POSITION_OFFSET + NUMBER_OF_WHEEL_POSITIONS))
|
|
{
|
|
print("Error: invalid gesture start position == ");
|
|
println(buf1);
|
|
}
|
|
else
|
|
{
|
|
text("Gesture Detected",20,30);
|
|
buf1 = buf1 - GESTURE_POSITION_OFFSET;
|
|
if (buf1<0)
|
|
println(buf);
|
|
gestureStartingPosition = buf1;
|
|
gestureStoppingPosition = buf1;
|
|
if (buf1 == code[0])
|
|
codeCheck = 1;
|
|
else
|
|
codeCheck = -1;
|
|
|
|
codeLevel = 0;
|
|
changeDirection = 0;
|
|
drawSlice(buf1, 1);
|
|
fill(255);
|
|
ellipse(CIRCLE_CENTER_X, CIRCLE_CENTER_Y, IN_CIRCLE_RADIUS*2 , IN_CIRCLE_RADIUS*2);
|
|
image(innerCircleImage,0,0);
|
|
}
|
|
break;
|
|
|
|
|
|
default: // data from LaunchPad is not code, but value
|
|
|
|
if (buf > WHEEL_POSITION_OFFSET + NUMBER_OF_WHEEL_POSITIONS ) // Invalid Code
|
|
{
|
|
print("Error: invalid UART code == ");
|
|
println(buf);
|
|
}
|
|
else
|
|
/*---------------------WHEEL POSITION-----------------------*/
|
|
if ((buf <= WHEEL_POSITION_OFFSET + NUMBER_OF_WHEEL_POSITIONS) && (buf >= WHEEL_POSITION_OFFSET )) // Tapping
|
|
{
|
|
|
|
while (buf1 <0)
|
|
buf1 = LaunchPad.read();
|
|
if (buf==buf1)
|
|
{
|
|
buf = buf - WHEEL_POSITION_OFFSET;
|
|
text("Press @ ",10,30);
|
|
text(buf,125,30);
|
|
tapping = 1;
|
|
drawSlice(buf, TAP_SLICE_COLOR);
|
|
fill(255);
|
|
ellipse(CIRCLE_CENTER_X, CIRCLE_CENTER_Y, IN_CIRCLE_RADIUS*2 , IN_CIRCLE_RADIUS*2);
|
|
image(innerCircleImage, 0,0);
|
|
}
|
|
else
|
|
{
|
|
print("Error: invalid WHEEL POSITION code == ");
|
|
println(buf);
|
|
}
|
|
}
|
|
else
|
|
/*---------------------GESTURE DATA-----------------------*/
|
|
if (buf < GESTURE_POSITION_OFFSET ) // Gesturing
|
|
if (gestureStartingPosition != INVALID_WHEEL_POSITION)
|
|
{
|
|
if (buf>=NUMBER_OF_WHEEL_POSITIONS) // Determine orientation: binary value 00000xxx = CW, 00001xxx = CC
|
|
{
|
|
buf -= NUMBER_OF_WHEEL_POSITIONS;
|
|
text(buf, 20,30);
|
|
text("Counter-Clockwise",55,30);
|
|
gestureImmediateDirection = GESTURE_COUNTERCLOCKWISE;
|
|
}
|
|
else
|
|
{
|
|
text(buf, 20,30);
|
|
text("Clockwise",55,30);
|
|
gestureImmediateDirection = GESTURE_CLOCKWISE;
|
|
}
|
|
|
|
while (buf1 <0)
|
|
buf1 = LaunchPad.read();
|
|
if ( (buf1 >= GESTURE_POSITION_OFFSET ) && (buf1 < GESTURE_POSITION_OFFSET + NUMBER_OF_WHEEL_POSITIONS))
|
|
{
|
|
buf1 = buf1 - GESTURE_POSITION_OFFSET;
|
|
if (gestureDirection == INVALID_GESTURE_DIRECTION)
|
|
gestureDirection = gestureImmediateDirection;
|
|
|
|
// if (gestureImmediateDirection != gestureDirection)
|
|
// gestureCoverPositions[gestureStoppingPosition] = 0;
|
|
//
|
|
while (buf-->0)
|
|
{
|
|
if (gestureStoppingPosition == gestureStartingPosition) //If moving from the starting position
|
|
if (gestureDirection != gestureImmediateDirection) //If moving against the current direction
|
|
{
|
|
if (allLit == 0) //Starting at zero? Change direction
|
|
gestureDirection = gestureImmediateDirection;
|
|
else //Back to a previous revolution?
|
|
allLit--;
|
|
}
|
|
gestureStoppingPosition += gestureImmediateDirection;
|
|
if (gestureStoppingPosition == NUMBER_OF_WHEEL_POSITIONS)
|
|
gestureStoppingPosition = 0;
|
|
if (gestureStoppingPosition < 0)
|
|
gestureStoppingPosition = NUMBER_OF_WHEEL_POSITIONS-1;
|
|
|
|
if (gestureStoppingPosition == gestureStartingPosition) //If moving to the starting position
|
|
{
|
|
if (gestureImmediateDirection == gestureDirection) //complete a revolution?
|
|
allLit += 1;
|
|
else
|
|
if (allLit == 0) //Back to zero
|
|
gestureDirection = INVALID_GESTURE_DIRECTION;
|
|
//Undo
|
|
}
|
|
}
|
|
|
|
for ( i = 0; i < NUMBER_OF_WHEEL_POSITIONS; i++)
|
|
gestureCoverPositions[i] = allLit;
|
|
|
|
i = gestureStartingPosition;
|
|
while (i != gestureStoppingPosition)
|
|
{
|
|
gestureCoverPositions[i]= allLit + 1;
|
|
i += gestureDirection;
|
|
if (i<0)
|
|
i = NUMBER_OF_WHEEL_POSITIONS-1;
|
|
if (i == NUMBER_OF_WHEEL_POSITIONS)
|
|
i = 0;
|
|
}
|
|
gestureCoverPositions[i]= allLit + 1;
|
|
|
|
for ( i = 0; i < NUMBER_OF_WHEEL_POSITIONS; i++)
|
|
if (gestureCoverPositions[i] > 0)
|
|
drawSlice(i, gestureCoverPositions[i]);
|
|
fill(255);
|
|
ellipse(CIRCLE_CENTER_X, CIRCLE_CENTER_Y, IN_CIRCLE_RADIUS*2 , IN_CIRCLE_RADIUS*2);
|
|
image(innerCircleImage,0,0);
|
|
|
|
if (changeDirection !=0)
|
|
{
|
|
if (gestureImmediateDirection != changeDirection)
|
|
codeCheck = -1;
|
|
|
|
changeDirection = 0;
|
|
}
|
|
if (soundEnabled == 1)
|
|
click.play();
|
|
if (codeModeEnabled == 1)
|
|
{
|
|
if (codeCheck==1)
|
|
{
|
|
codeValid = 1;
|
|
for ( i = 0; i < NUMBER_OF_WHEEL_POSITIONS; i++)
|
|
if (gestureCoverPositions[i] != codeValues[codeLevel][i])
|
|
codeValid = 0;
|
|
if (codeRotate[codeLevel] != gestureImmediateDirection)
|
|
codeValid = 0;
|
|
if (codeValid == 1)
|
|
{
|
|
if (codeLevel++ < 2)
|
|
{
|
|
changeDirection = -gestureImmediateDirection;
|
|
if (soundEnabled == 1)
|
|
clickFound.play();
|
|
}
|
|
else
|
|
{
|
|
fill(0);
|
|
text("Unlocked!!",400,30);
|
|
text("Press Center",500,90);
|
|
unlocked = 1;
|
|
codeLevel = 0;
|
|
codeCheck = -1;
|
|
if (soundEnabled == 1)
|
|
clickOpen.play();
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
// invalid gesture data
|
|
else
|
|
{
|
|
print("Error: invalid gesture position data == ");
|
|
println(buf1);
|
|
}
|
|
}
|
|
else
|
|
{ // Should not happen
|
|
buf = buf - GESTURE_POSITION_OFFSET;
|
|
println("Invalid UART Data, not expecting such data");
|
|
}
|
|
|
|
|
|
|
|
break;
|
|
}
|
|
|
|
}
|
|
|
|
|
|
else
|
|
{
|
|
if (++inactivityCounter==TIME_OUT)
|
|
{
|
|
if (sleeping==1)
|
|
{
|
|
goToSleep();
|
|
}
|
|
else
|
|
|
|
drawCanvas();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
void mouseReleased()
|
|
{
|
|
if ( (mouseX-CANVAS_SIZE_X/2)*(mouseX-CANVAS_SIZE_X/2) + (mouseY-CANVAS_SIZE_Y/2)*(mouseY-CANVAS_SIZE_Y/2) < IN_CIRCLE_RADIUS * IN_CIRCLE_RADIUS )
|
|
if (LaunchPadComPortFound ==1)
|
|
{
|
|
soundEnabled = 1 - soundEnabled;
|
|
codeModeEnabled = 1 - codeModeEnabled;
|
|
drawNumberEnabled = 1 - drawNumberEnabled;
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/*---------Embedded code validation------------------*/
|
|
// Ideally nobody should ever bother scrolling down here
|
|
// But good job, you've found it the easy way!
|
|
// Anyways, don't spoil the fun for others would ya?
|
|
int[] code = { 0, 4, 3, 0};
|
|
int[] codeRotate = {1, -1, 1};
|
|
int[][] codeValues = { {1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
|
|
{1, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1},
|
|
{1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}};
|
|
String secretURL = "http://ti.com/msp430rr";
|
|
int codeCheck, codeLevel, codeValid, changeDirection, unlocked=0, codeModeEnabled = 0;
|
|
|
|
|
|
|