Testing out the PPD42 Air Quality Sensor, with an MSP430 Launchpad and graphing the data with GNUplot.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

725 lines
24 KiB

5 years ago
  1. /*******************************************************************************
  2. *
  3. * CapTouch_BoosterPack_UserExperience_GUI.pde
  4. * - PC demo application for establishing a serial connection
  5. * with the LaunchPad CapTouch BoosterPack.
  6. *
  7. * Copyright (C) 2011 Texas Instruments Incorporated - http://www.ti.com/
  8. *
  9. * Redistribution and use in source and binary forms, with or without
  10. * modification, are permitted provided that the following conditions
  11. * are met:
  12. *
  13. * Redistributions of source code must retain the above copyright
  14. * notice, this list of conditions and the following disclaimer.
  15. *
  16. * Redistributions in binary form must reproduce the above copyright
  17. * notice, this list of conditions and the following disclaimer in the
  18. * documentation and/or other materials provided with the
  19. * distribution.
  20. *
  21. * Neither the name of Texas Instruments Incorporated nor the names of
  22. * its contributors may be used to endorse or promote products derived
  23. * from this software without specific prior written permission.
  24. *
  25. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  26. * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  27. * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  28. * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
  29. * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  30. * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
  31. * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  32. * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  33. * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  34. * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  35. * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  36. *
  37. *
  38. ******************************************************************************/
  39. /******************************************************************************
  40. * MSP430G2-LaunchPad CapTouch BoosterPack User Experience GUI
  41. * Desc:
  42. * This PC GUI application communicates with the LaunchPad specifically to
  43. * receive capacitive touch data from the LaunchPad CapTouch BoosterPack and
  44. * provides the visualization of said information in the GUI.
  45. *
  46. * The GUI uses a small .NET utility (FindAppUART.exe) to automatically detect
  47. * a proper LaunchPad/430Emulator device connected to the PC USB port. Upon
  48. * correct USB COM port discovery, the application initiates a 9600baud UART
  49. * connection and starts receiving data.
  50. *
  51. * Upon each LaunchPad event, data is transmitted [always] via a simple '2-byte'
  52. * protocol as described below.
  53. * [LaunchPad] Wake up : 0xBE 0xEF
  54. * [LaunchPad] Sleep : 0xDE 0xAD
  55. * [CapTouch] Center Button : 0x80 0x80
  56. * [CapTouch] Wheel Tap : WT WT = pos. on wheel [0-0x0F] + 0x30
  57. * [CapTouch] Gesture Start : 0xFC POS = pos. on wheel [0-0x0F] + 0x20
  58. * [CapTouch] Gesture Stop : 0xFB POS = pos. on wheel [0-0x0F] + 0x20
  59. * [CapTouch] Gesture Update: GES POS
  60. * Gesture = [0-0x0F] --> Clockwise gesture
  61. * = 0x10+ [0-0x0F] --> Counter-clockwise gesture
  62. *
  63. * The GUI grays out during sleep mode and returns to active mode upon wake up.
  64. * The 'Center Button' press data toggles the center circle color, mimicking the
  65. * behavior of the center LED on the BoosterPack.
  66. * The 'Wheel Tap' is represented by lighting up a single slice on the wheel.
  67. * The gesture tracking [Start, Stop, Update] is visualized on the wheel with
  68. * the coloration of the wheel slices. Gesture can be tracked for several
  69. * revolutions of the wheel, in both clockwise and counter-clockwise directions.
  70. *
  71. * A hidden code/lock is embedded in the wheel. Correct sequence [similar to a
  72. * rotational combination lock] reveals a secret address.
  73. *
  74. * D. Dang
  75. * Texas Instruments, Inc.
  76. * Ver 0.90 Feb 2011
  77. ******************************************************************************/
  78. import pitaru.sonia_v2_9.*;
  79. import processing.serial.*;
  80. import java.io.BufferedReader;
  81. import java.io.IOException;
  82. import java.io.InputStreamReader;
  83. final int TIME_OUT = 140;
  84. /*--------Dimensions & coordinates------------*/
  85. final int CANVAS_SIZE_X = 900;
  86. final int CANVAS_SIZE_Y = 580;
  87. final int OUT_CIRCLE_RADIUS = 248;
  88. final int IN_CIRCLE_RADIUS = 101;
  89. final int CENTER_CIRCLE_RADIUS = 37;
  90. final int CIRCLE_CENTER_X = 450;
  91. final int CIRCLE_CENTER_Y = 285;
  92. final int SOUND_ICON_X = 820;
  93. final int SOUND_ICON_Y = 20;
  94. /*--------Drawing definitions------------*/
  95. final int NUMBER_OF_SLICES = 16;
  96. final int BACKGROUND_COLOR = 170;
  97. final int TAP_SLICE_COLOR = -100;
  98. final int SLICE_TRANSPARENCY = 30;
  99. final int SLICE_TRANSPARENCY_OFFSET = 80;
  100. /*--------UART protocol definitions------------*/
  101. final int WAKE_UP_UART_CODE = 0xBE;
  102. final int WAKE_UP_UART_CODE2 = 0xEF;
  103. final int SLEEP_MODE_UART_CODE = 0xDE;
  104. final int SLEEP_MODE_UART_CODE2 = 0xAD;
  105. final int CENTER_BUTTON_CODE = 0x80;
  106. final int INVALID_WHEEL_POSITION = 0xFE;
  107. final int INVALID_GESTURE = 0xFD;
  108. final int GESTURE_START = 0xFC;
  109. final int GESTURE_STOP = 0xFB;
  110. final int GESTURE_POSITION_OFFSET = 0x20;
  111. final int WHEEL_POSITION_OFFSET = 0x30;
  112. final int NUMBER_OF_WHEEL_POSITIONS = 16;
  113. //final int INVALID_WHEEL_POSITION = -100;
  114. final int INVALID_GESTURE_DIRECTION = -100;
  115. final int GESTURE_CLOCKWISE = 1;
  116. final int GESTURE_COUNTERCLOCKWISE = -1;
  117. /*----------CapTouch-related variables----------------*/
  118. int gestureStartingPosition = INVALID_WHEEL_POSITION, gestureStoppingPosition = INVALID_WHEEL_POSITION;
  119. int[] gestureCoverPositions = new int[16];
  120. int gestureDirection = INVALID_GESTURE_DIRECTION;
  121. int gestureImmediateDirection = INVALID_GESTURE_DIRECTION;
  122. int allLit = 0;
  123. int inactivityCounter=0, sleeping=0, tapping=0, centerButton=0;
  124. int CenterButtonToggle=0;
  125. /*------Serial communication----------------*/
  126. int LaunchPadComPortFound = 0, numberOfLookingDots=0;
  127. Serial LaunchPad;
  128. /*--------- Visual & audio elements-----------*/
  129. PImage backgroundImage, innerCircleImage,innerCircleSelectedImage, innerCircleUnlockedImage ;
  130. int drawNumberEnabled = 0;
  131. Sample click,clickFound, clickOpen;
  132. int soundEnabled = 0;
  133. void drawSlice(int sliceIndex, int sliceLevel)
  134. {
  135. int sliceAfter, sliceLabel;
  136. sliceLabel = sliceIndex;
  137. if (sliceIndex < 3)
  138. sliceIndex = sliceIndex + 16 - 4;
  139. else
  140. sliceIndex = sliceIndex - 4;
  141. sliceAfter = sliceIndex + 1;
  142. if (sliceAfter == NUMBER_OF_SLICES)
  143. sliceAfter = 0;
  144. noStroke();
  145. stroke(255);
  146. strokeWeight(4);
  147. if (sliceLevel == TAP_SLICE_COLOR)
  148. fill(160,160,160, 225);
  149. else
  150. fill(252,236,54, sliceLevel * SLICE_TRANSPARENCY + SLICE_TRANSPARENCY_OFFSET);
  151. 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);
  152. 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,
  153. 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);
  154. 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,
  155. 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);
  156. if (drawNumberEnabled == 1)
  157. {
  158. fill(0);
  159. text( sliceLabel,
  160. CIRCLE_CENTER_X + cos( (((float)sliceIndex)) * 2 * PI /16 ) * (OUT_CIRCLE_RADIUS-40)-7,
  161. CIRCLE_CENTER_Y + sin( (((float)sliceIndex)) * 2 * PI /16 ) * (OUT_CIRCLE_RADIUS-40));
  162. }
  163. }
  164. void drawCanvas()
  165. {
  166. int i;
  167. background(BACKGROUND_COLOR);
  168. image(backgroundImage, 0 ,0);
  169. fill(0,0,0,255);
  170. if (unlocked == 1)
  171. {
  172. fill(0);
  173. text("BoosterPack Unlocked",300,30);
  174. for (i=0;i<4;i++)
  175. drawSlice(code[i],4);
  176. fill(255);
  177. ellipse(CIRCLE_CENTER_X, CIRCLE_CENTER_Y, IN_CIRCLE_RADIUS*2 , IN_CIRCLE_RADIUS*2);
  178. image(innerCircleUnlockedImage, 0, 0);
  179. }
  180. }
  181. void goToSleep()
  182. {
  183. tint(120,120,120,180);
  184. drawCanvas();
  185. tint(120,120,120,180);
  186. fill(255);
  187. textSize(20);
  188. text(".",20,30);
  189. text(".",28,30);
  190. text(".",35,30);
  191. textSize(25);
  192. text("z",47,30);
  193. textSize(30);
  194. text("z",65,30);
  195. textSize(35);
  196. text("z",85,30);
  197. textSize(40);
  198. text("z",108,30);
  199. textSize(30);
  200. noTint();
  201. sleeping = 1;
  202. inactivityCounter = TIME_OUT;
  203. }
  204. void findLaunchPad()
  205. {
  206. String ComPortName ="";
  207. try
  208. {
  209. Process proc = Runtime.getRuntime().exec("FindAppUART.exe");
  210. proc.waitFor();
  211. int exitVal = proc.exitValue();
  212. // Get the first line from the process' STDOUT
  213. BufferedReader buf = new BufferedReader(new InputStreamReader(proc.getInputStream()));
  214. ComPortName = buf.readLine();
  215. if (ComPortName.substring(0,3).equals("COM") != true)
  216. ComPortName = "";
  217. else
  218. {
  219. LaunchPadComPortFound = 1;
  220. LaunchPad = new Serial(this, ComPortName, 9600);
  221. }
  222. }
  223. catch(Exception e)
  224. {
  225. println(e);
  226. }
  227. }
  228. void promptLookingForLaunchPad()
  229. {
  230. fill(255,0,0);
  231. noStroke();
  232. rect(100,CANVAS_SIZE_Y/2-100,CANVAS_SIZE_X-120,200);
  233. fill(255);
  234. textSize(50);
  235. numberOfLookingDots++;
  236. if (numberOfLookingDots==5)
  237. numberOfLookingDots = 1;
  238. switch(numberOfLookingDots)
  239. {
  240. case 1: text("Looking for LaunchPad ", 175,CANVAS_SIZE_Y/2 ); break;
  241. case 2: text("Looking for LaunchPad . ", 175,CANVAS_SIZE_Y/2 ); break;
  242. case 3: text("Looking for LaunchPad .. ", 175,CANVAS_SIZE_Y/2 ); break;
  243. case 4: text("Looking for LaunchPad ...", 175,CANVAS_SIZE_Y/2 ); break;
  244. }
  245. }
  246. void setup()
  247. {
  248. size(CANVAS_SIZE_X, CANVAS_SIZE_Y);
  249. background(255,0,0);
  250. Sonia.start(this);
  251. click = new Sample("click1.aiff");
  252. clickOpen = new Sample("open.aiff");
  253. clickFound = new Sample("unlock.aiff");
  254. click.setVolume(3);
  255. clickFound.setVolume(3);
  256. frameRate(3);
  257. backgroundImage = loadImage("background.png");
  258. innerCircleImage = loadImage("innerCircle.png");
  259. innerCircleSelectedImage = loadImage("innerCircleSelected.png");
  260. innerCircleUnlockedImage = loadImage("innerCircleUnlocked.png");
  261. findLaunchPad();
  262. if (LaunchPadComPortFound == 0)
  263. {
  264. fill(255);
  265. textSize(40);
  266. text("LaunchPad Capacitive Touch BoosterPack", 70,50);
  267. textSize(55);
  268. fill(0);
  269. text("User Experience Demo", 150,100);
  270. fill(0);
  271. textSize(25);
  272. text("1. Plug your Capacitive Touch BoosterPack into the LaunchPad", 150,CANVAS_SIZE_Y - 70);
  273. text("2. Connect your LaunchPad to the PC via USB", 150,CANVAS_SIZE_Y - 45);
  274. promptLookingForLaunchPad();
  275. }
  276. else
  277. {
  278. frameRate(30);
  279. goToSleep();
  280. }
  281. }
  282. void draw()
  283. {
  284. int i;
  285. if (LaunchPadComPortFound==0)
  286. {
  287. findLaunchPad();
  288. if (LaunchPadComPortFound==1)
  289. {
  290. goToSleep();
  291. frameRate(30);
  292. }
  293. else
  294. promptLookingForLaunchPad();
  295. }
  296. else
  297. if(LaunchPad.available() >= 0)
  298. {
  299. int buf, buf1;
  300. buf = LaunchPad.read();
  301. buf1 = -1;
  302. if (buf>=0)
  303. {
  304. drawCanvas();
  305. textSize(30);
  306. sleeping = 0;
  307. inactivityCounter=0;
  308. tapping = 0 ;
  309. centerButton = 0;
  310. switch(buf)
  311. {
  312. case WAKE_UP_UART_CODE:
  313. while (buf1 <0)
  314. buf1 = LaunchPad.read();
  315. if (buf1==WAKE_UP_UART_CODE2)
  316. text("Proximity Sensor Wake Up",20,30);
  317. else
  318. {
  319. print("Error: invalid UART Wake up == ");
  320. println(buf1);
  321. }
  322. break;
  323. case SLEEP_MODE_UART_CODE:
  324. while (buf1 <0)
  325. buf1 = LaunchPad.read();
  326. if (buf1==SLEEP_MODE_UART_CODE2)
  327. {
  328. //tint(120,0,0,180);
  329. CenterButtonToggle = 0;
  330. backgroundImage = loadImage("background.png");
  331. innerCircleImage = loadImage("innerCircle.png");
  332. tint(120,120,120,180);
  333. drawCanvas();
  334. text("Good night!",20,30);
  335. sleeping = 1;
  336. noTint();
  337. }
  338. else
  339. {
  340. print("Error: invalid UART Sleep == ");
  341. println(buf1);
  342. }
  343. break;
  344. case CENTER_BUTTON_CODE:
  345. while (buf1 <0)
  346. buf1 = LaunchPad.read();
  347. if (buf==buf1)
  348. {
  349. if (unlocked==1)
  350. {
  351. unlocked = 0;
  352. link(secretURL);
  353. }
  354. CenterButtonToggle = 1 - CenterButtonToggle;
  355. if (CenterButtonToggle == 1)
  356. {
  357. innerCircleImage= loadImage("innerCircleSelected.png");
  358. backgroundImage = loadImage("backgroundSelected.png");
  359. }
  360. else
  361. {
  362. innerCircleImage= loadImage("innerCircle.png");
  363. backgroundImage = loadImage("background.png");
  364. }
  365. drawCanvas();
  366. centerButton = 1;
  367. }
  368. else
  369. {
  370. print("Error: invalid CENTER BUTTON code == ");
  371. println(buf1);
  372. }
  373. break;
  374. case GESTURE_STOP:
  375. while (buf1 <0)
  376. buf1 = LaunchPad.read();
  377. if (buf==buf1)
  378. {
  379. text("Gesture Released",20,30);
  380. gestureStartingPosition = INVALID_WHEEL_POSITION;
  381. gestureStoppingPosition = INVALID_WHEEL_POSITION;
  382. gestureDirection = INVALID_GESTURE_DIRECTION;
  383. allLit = 0;
  384. codeCheck = 0;
  385. codeLevel = 0;
  386. //unlocked = 0;
  387. }
  388. else
  389. {
  390. print("Error: invalid GESTURE_STOP code == ");
  391. println(buf1);
  392. }
  393. break;
  394. case GESTURE_START:
  395. while (buf1 <0)
  396. buf1 = LaunchPad.read();
  397. if ( (buf1 < GESTURE_POSITION_OFFSET ) || (buf1 > GESTURE_POSITION_OFFSET + NUMBER_OF_WHEEL_POSITIONS))
  398. {
  399. print("Error: invalid gesture start position == ");
  400. println(buf1);
  401. }
  402. else
  403. {
  404. text("Gesture Detected",20,30);
  405. buf1 = buf1 - GESTURE_POSITION_OFFSET;
  406. if (buf1<0)
  407. println(buf);
  408. gestureStartingPosition = buf1;
  409. gestureStoppingPosition = buf1;
  410. if (buf1 == code[0])
  411. codeCheck = 1;
  412. else
  413. codeCheck = -1;
  414. codeLevel = 0;
  415. changeDirection = 0;
  416. drawSlice(buf1, 1);
  417. fill(255);
  418. ellipse(CIRCLE_CENTER_X, CIRCLE_CENTER_Y, IN_CIRCLE_RADIUS*2 , IN_CIRCLE_RADIUS*2);
  419. image(innerCircleImage,0,0);
  420. }
  421. break;
  422. default: // data from LaunchPad is not code, but value
  423. if (buf > WHEEL_POSITION_OFFSET + NUMBER_OF_WHEEL_POSITIONS ) // Invalid Code
  424. {
  425. print("Error: invalid UART code == ");
  426. println(buf);
  427. }
  428. else
  429. /*---------------------WHEEL POSITION-----------------------*/
  430. if ((buf <= WHEEL_POSITION_OFFSET + NUMBER_OF_WHEEL_POSITIONS) && (buf >= WHEEL_POSITION_OFFSET )) // Tapping
  431. {
  432. while (buf1 <0)
  433. buf1 = LaunchPad.read();
  434. if (buf==buf1)
  435. {
  436. buf = buf - WHEEL_POSITION_OFFSET;
  437. text("Press @ ",10,30);
  438. text(buf,125,30);
  439. tapping = 1;
  440. drawSlice(buf, TAP_SLICE_COLOR);
  441. fill(255);
  442. ellipse(CIRCLE_CENTER_X, CIRCLE_CENTER_Y, IN_CIRCLE_RADIUS*2 , IN_CIRCLE_RADIUS*2);
  443. image(innerCircleImage, 0,0);
  444. }
  445. else
  446. {
  447. print("Error: invalid WHEEL POSITION code == ");
  448. println(buf);
  449. }
  450. }
  451. else
  452. /*---------------------GESTURE DATA-----------------------*/
  453. if (buf < GESTURE_POSITION_OFFSET ) // Gesturing
  454. if (gestureStartingPosition != INVALID_WHEEL_POSITION)
  455. {
  456. if (buf>=NUMBER_OF_WHEEL_POSITIONS) // Determine orientation: binary value 00000xxx = CW, 00001xxx = CC
  457. {
  458. buf -= NUMBER_OF_WHEEL_POSITIONS;
  459. text(buf, 20,30);
  460. text("Counter-Clockwise",55,30);
  461. gestureImmediateDirection = GESTURE_COUNTERCLOCKWISE;
  462. }
  463. else
  464. {
  465. text(buf, 20,30);
  466. text("Clockwise",55,30);
  467. gestureImmediateDirection = GESTURE_CLOCKWISE;
  468. }
  469. while (buf1 <0)
  470. buf1 = LaunchPad.read();
  471. if ( (buf1 >= GESTURE_POSITION_OFFSET ) && (buf1 < GESTURE_POSITION_OFFSET + NUMBER_OF_WHEEL_POSITIONS))
  472. {
  473. buf1 = buf1 - GESTURE_POSITION_OFFSET;
  474. if (gestureDirection == INVALID_GESTURE_DIRECTION)
  475. gestureDirection = gestureImmediateDirection;
  476. // if (gestureImmediateDirection != gestureDirection)
  477. // gestureCoverPositions[gestureStoppingPosition] = 0;
  478. //
  479. while (buf-->0)
  480. {
  481. if (gestureStoppingPosition == gestureStartingPosition) //If moving from the starting position
  482. if (gestureDirection != gestureImmediateDirection) //If moving against the current direction
  483. {
  484. if (allLit == 0) //Starting at zero? Change direction
  485. gestureDirection = gestureImmediateDirection;
  486. else //Back to a previous revolution?
  487. allLit--;
  488. }
  489. gestureStoppingPosition += gestureImmediateDirection;
  490. if (gestureStoppingPosition == NUMBER_OF_WHEEL_POSITIONS)
  491. gestureStoppingPosition = 0;
  492. if (gestureStoppingPosition < 0)
  493. gestureStoppingPosition = NUMBER_OF_WHEEL_POSITIONS-1;
  494. if (gestureStoppingPosition == gestureStartingPosition) //If moving to the starting position
  495. {
  496. if (gestureImmediateDirection == gestureDirection) //complete a revolution?
  497. allLit += 1;
  498. else
  499. if (allLit == 0) //Back to zero
  500. gestureDirection = INVALID_GESTURE_DIRECTION;
  501. //Undo
  502. }
  503. }
  504. for ( i = 0; i < NUMBER_OF_WHEEL_POSITIONS; i++)
  505. gestureCoverPositions[i] = allLit;
  506. i = gestureStartingPosition;
  507. while (i != gestureStoppingPosition)
  508. {
  509. gestureCoverPositions[i]= allLit + 1;
  510. i += gestureDirection;
  511. if (i<0)
  512. i = NUMBER_OF_WHEEL_POSITIONS-1;
  513. if (i == NUMBER_OF_WHEEL_POSITIONS)
  514. i = 0;
  515. }
  516. gestureCoverPositions[i]= allLit + 1;
  517. for ( i = 0; i < NUMBER_OF_WHEEL_POSITIONS; i++)
  518. if (gestureCoverPositions[i] > 0)
  519. drawSlice(i, gestureCoverPositions[i]);
  520. fill(255);
  521. ellipse(CIRCLE_CENTER_X, CIRCLE_CENTER_Y, IN_CIRCLE_RADIUS*2 , IN_CIRCLE_RADIUS*2);
  522. image(innerCircleImage,0,0);
  523. if (changeDirection !=0)
  524. {
  525. if (gestureImmediateDirection != changeDirection)
  526. codeCheck = -1;
  527. changeDirection = 0;
  528. }
  529. if (soundEnabled == 1)
  530. click.play();
  531. if (codeModeEnabled == 1)
  532. {
  533. if (codeCheck==1)
  534. {
  535. codeValid = 1;
  536. for ( i = 0; i < NUMBER_OF_WHEEL_POSITIONS; i++)
  537. if (gestureCoverPositions[i] != codeValues[codeLevel][i])
  538. codeValid = 0;
  539. if (codeRotate[codeLevel] != gestureImmediateDirection)
  540. codeValid = 0;
  541. if (codeValid == 1)
  542. {
  543. if (codeLevel++ < 2)
  544. {
  545. changeDirection = -gestureImmediateDirection;
  546. if (soundEnabled == 1)
  547. clickFound.play();
  548. }
  549. else
  550. {
  551. fill(0);
  552. text("Unlocked!!",400,30);
  553. text("Press Center",500,90);
  554. unlocked = 1;
  555. codeLevel = 0;
  556. codeCheck = -1;
  557. if (soundEnabled == 1)
  558. clickOpen.play();
  559. }
  560. }
  561. }
  562. }
  563. }
  564. // invalid gesture data
  565. else
  566. {
  567. print("Error: invalid gesture position data == ");
  568. println(buf1);
  569. }
  570. }
  571. else
  572. { // Should not happen
  573. buf = buf - GESTURE_POSITION_OFFSET;
  574. println("Invalid UART Data, not expecting such data");
  575. }
  576. break;
  577. }
  578. }
  579. else
  580. {
  581. if (++inactivityCounter==TIME_OUT)
  582. {
  583. if (sleeping==1)
  584. {
  585. goToSleep();
  586. }
  587. else
  588. drawCanvas();
  589. }
  590. }
  591. }
  592. }
  593. void mouseReleased()
  594. {
  595. 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 )
  596. if (LaunchPadComPortFound ==1)
  597. {
  598. soundEnabled = 1 - soundEnabled;
  599. codeModeEnabled = 1 - codeModeEnabled;
  600. drawNumberEnabled = 1 - drawNumberEnabled;
  601. }
  602. }
  603. /*---------Embedded code validation------------------*/
  604. // Ideally nobody should ever bother scrolling down here
  605. // But good job, you've found it the easy way!
  606. // Anyways, don't spoil the fun for others would ya?
  607. int[] code = { 0, 4, 3, 0};
  608. int[] codeRotate = {1, -1, 1};
  609. int[][] codeValues = { {1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
  610. {1, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1},
  611. {1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}};
  612. String secretURL = "http://ti.com/msp430rr";
  613. int codeCheck, codeLevel, codeValid, changeDirection, unlocked=0, codeModeEnabled = 0;