Simple single-color 8x8x8 LED Cube with AVRs
Vous ne pouvez pas sélectionner plus de 25 sujets Les noms de sujets doivent commencer par une lettre ou un nombre, peuvent contenir des tirets ('-') et peuvent comporter jusqu'à 35 caractères.

cubeWorker.java 11KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476
  1. /*
  2. * cubeWorker.java
  3. *
  4. * Copyright 2011 Thomas Buck <xythobuz@me.com>
  5. * Copyright 2011 Max Nuding <max.nuding@gmail.com>
  6. * Copyright 2011 Felix Bäder <baeder.felix@gmail.com>
  7. *
  8. * This file is part of LED-Cube.
  9. *
  10. * LED-Cube is free software: you can redistribute it and/or modify
  11. * it under the terms of the GNU General Public License as published by
  12. * the Free Software Foundation, either version 3 of the License, or
  13. * (at your option) any later version.
  14. *
  15. * LED-Cube is distributed in the hope that it will be useful,
  16. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  17. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  18. * GNU General Public License for more details.
  19. *
  20. * You should have received a copy of the GNU General Public License
  21. * along with LED-Cube. If not, see <http://www.gnu.org/licenses/>.
  22. */
  23. /*
  24. * This class handles one animation file. This file can contain
  25. * many animations, but has to be only 1Mbit in size (128*1024 Byte).
  26. */
  27. import java.util.ArrayList;
  28. import java.util.List;
  29. import java.util.StringTokenizer;
  30. import java.util.Collections;
  31. /**
  32. * This class holds all Data of the Application. Additionally it performs the
  33. * transmission of animation data to/from the cube and saves/loads animations
  34. * in/from a file.
  35. *
  36. * @author Thomas Buck
  37. * @author Felix Bäder
  38. * @author Max Nuding
  39. * @version 1.0
  40. */
  41. public class cubeWorker {
  42. private final int framesRemaining = 2016; // (128 * 1024) / 65 = 2016,...
  43. private boolean changedState = false;
  44. private Frame parentFrame;
  45. private Animation[] animations = new Animation[1];
  46. /**
  47. * Creates a worker with one animation, containing an empty frame.
  48. */
  49. public cubeWorker(Frame parent) {
  50. animations[0] = new Animation();
  51. parentFrame = parent;
  52. }
  53. public cubeWorker(Animation[] anims, Frame parent) {
  54. animations = anims;
  55. parentFrame = parent;
  56. }
  57. /**
  58. * Returns number of frames in this cubeWorker.
  59. *
  60. * @return number of frames.
  61. */
  62. public int completeNumOfFrames() {
  63. int c = 0;
  64. for (int i = 0; i < size(); i++) {
  65. c += getAnimation(i).size();
  66. }
  67. return c;
  68. }
  69. // --------------------
  70. // Misc. Methods
  71. // --------------------
  72. /**
  73. * Get the number of animations in this worker.
  74. *
  75. * @return number of animations
  76. */
  77. public int size() {
  78. return animations.length;
  79. }
  80. /**
  81. * Get the number of frames you can add until the Cubes memory is full.
  82. *
  83. * @return number of frames remaining
  84. */
  85. public int memoryRemaining() {
  86. return framesRemaining - completeNumOfFrames();
  87. }
  88. /**
  89. * Add an animation. It has an initial empty frame
  90. *
  91. * @return Index of new animation, or -1 if not enough space remaining.
  92. */
  93. public int addAnimation() {
  94. changedState = true;
  95. if (memoryRemaining() <= 0) {
  96. return -1;
  97. } else {
  98. extendArray();
  99. animations[animations.length - 1] = new Animation();
  100. return animations.length - 1;
  101. }
  102. }
  103. /**
  104. * Remove an animation.
  105. *
  106. * @param i the animation you want to delete
  107. */
  108. public void removeAnimation(int i) {
  109. changedState = true;
  110. shiftOver(i);
  111. shrinkArray();
  112. }
  113. /**
  114. * Move an animation up.
  115. * @param i the animation you want to move
  116. */
  117. public void moveAnimationUp(int i) {
  118. if (i > 0) {
  119. Animation tmp = animations[i];
  120. animations[i] = animations[i - 1];
  121. animations[i - 1] = tmp;
  122. }
  123. }
  124. /**
  125. * Move an animation down.
  126. * @param i the animation you want to move
  127. */
  128. public void moveAnimationDown(int i) {
  129. if (i < (animations.length - 1)) {
  130. Animation tmp = animations[i];
  131. animations[i] = animations[i + 1];
  132. animations[i + 1] = tmp;
  133. }
  134. }
  135. public Animation getAnimation(int i) {
  136. if (i < animations.length) {
  137. return animations[i];
  138. } else {
  139. return null;
  140. }
  141. }
  142. public void setAnimation(Animation a, int i) {
  143. changedState = true;
  144. if (i < animations.length) {
  145. animations[i] = a;
  146. }
  147. }
  148. /**
  149. * Loads an animation file into this worker.
  150. *
  151. * @param path Path of file to load
  152. * @return 0 on success, -1 on error.
  153. */
  154. public int loadState(String path) {
  155. changedState = false;
  156. try {
  157. animations = AnimationUtility.readFile(path);
  158. } catch (Exception e) {
  159. System.out.println("Did not load!");
  160. e.printStackTrace(System.out);
  161. return -1;
  162. }
  163. int size = 0;
  164. for (int i = 0; i < animations.length; i++) {
  165. size += animations[i].size();
  166. }
  167. if (size > framesRemaining) {
  168. return -1;
  169. }
  170. return 0;
  171. }
  172. /**
  173. * Save the state of this object into a file.
  174. *
  175. * @param path Path to save file in
  176. * @return 0 on success, -1 on error
  177. */
  178. public int saveState(String path) {
  179. changedState = false;
  180. AnimationUtility.writeFile(path, animations);
  181. if (AnimationUtility.getLastError() != null) {
  182. System.out.println(AnimationUtility.getLastError());
  183. return -1;
  184. }
  185. return 0;
  186. }
  187. /**
  188. * Check if something changed after loading/saving.
  189. *
  190. * @return TRUE if something changed, FALSE otherwise
  191. */
  192. public boolean changedStateSinceSave() {
  193. return changedState;
  194. }
  195. /**
  196. * Get the array of animations in this worker.
  197. * @return animation array
  198. */
  199. public Animation[] getAnimationArray() {
  200. return animations;
  201. }
  202. /**
  203. * Send all animations to the cube.
  204. *
  205. * @param port Name of serial port to use
  206. * @return 0 on success, -1 on error
  207. */
  208. public int cubeSendState(String port) {
  209. int a, f;
  210. short[] d;
  211. if (HelperUtility.openPort(port) == false) {
  212. error("Could not open Port!");
  213. return -1;
  214. }
  215. // Send command
  216. d = new short[1];
  217. d[0] = 's';
  218. if (HelperUtility.writeData(d, 1) == false) {
  219. error("Could not write to port!");
  220. HelperUtility.closePort();
  221. return -1;
  222. }
  223. // Recieve ack
  224. d = HelperUtility.readData(1);
  225. if (d.length == 0) {
  226. error("Could not read from port!");
  227. HelperUtility.closePort();
  228. return -1;
  229. }
  230. if (d[0] != 0x42) {
  231. error("Cube not OK!");
  232. HelperUtility.closePort();
  233. return -1;
  234. }
  235. System.out.println("Command sent!");
  236. // Send animation count
  237. d = new short[1];
  238. if (animations.length >= 255) {
  239. error("Too many animations");
  240. return -1;
  241. }
  242. d[0] = (short)animations.length;
  243. if (HelperUtility.writeData(d, 1) == false) {
  244. error("Could not write to port!");
  245. HelperUtility.closePort();
  246. return -1;
  247. }
  248. // Recieve ack
  249. d = HelperUtility.readData(1);
  250. if (d.length == 0) {
  251. error("Could not read from port!");
  252. HelperUtility.closePort();
  253. return -1;
  254. }
  255. if (d[0] != 0x42) {
  256. error("Cube not OK!");
  257. HelperUtility.closePort();
  258. return -1;
  259. }
  260. System.out.println("Animation count sent (" + animations.length + ")!");
  261. for (a = 0; a < animations.length; a++) {
  262. // Send frame count
  263. d = new short[1];
  264. if (animations[a].size() >= 255) {
  265. error("Too many frames!");
  266. HelperUtility.closePort();
  267. return -1;
  268. }
  269. d[0] = (short)animations[a].size();
  270. if (HelperUtility.writeData(d, 1) == false) {
  271. error("Could not write to port!");
  272. HelperUtility.closePort();
  273. return -1;
  274. }
  275. // Recieve ack
  276. d = HelperUtility.readData(1);
  277. if (d.length == 0) {
  278. error("Could not read from port!");
  279. HelperUtility.closePort();
  280. return -1;
  281. }
  282. if (d[0] != 0x42) {
  283. error("Cube not OK!");
  284. HelperUtility.closePort();
  285. return -1;
  286. }
  287. System.out.println("Frame count sent (" + animations[a].size() + ")!");
  288. for (f = 0; f < animations[a].size(); f++) {
  289. // Send duration
  290. d = new short[1];
  291. d[0] = animations[a].getFrame(f).getTime();
  292. if (HelperUtility.writeData(d, 1) == false) {
  293. error("Could not write to port!");
  294. HelperUtility.closePort();
  295. return -1;
  296. }
  297. // Recieve ack
  298. d = HelperUtility.readData(1);
  299. if (d.length == 0) {
  300. error("Could not read from port!");
  301. HelperUtility.closePort();
  302. return -1;
  303. }
  304. if (d[0] != 0x42) {
  305. error("Cube not OK!");
  306. HelperUtility.closePort();
  307. return -1;
  308. }
  309. System.out.println("Duration sent (" + animations[a].getFrame(f).getTime() + ")!");
  310. // Send data
  311. d = animations[a].getFrame(f).getData();
  312. if (HelperUtility.writeData(d, 64) == false) {
  313. error("Could not write to port!");
  314. HelperUtility.closePort();
  315. return -1;
  316. }
  317. // Recieve ack
  318. d = HelperUtility.readData(1);
  319. if (d.length == 0) {
  320. error("Could not read from port!");
  321. HelperUtility.closePort();
  322. return -1;
  323. }
  324. if (d[0] != 0x42) {
  325. error("Cube not OK!");
  326. HelperUtility.closePort();
  327. return -1;
  328. }
  329. System.out.println("Data sent");
  330. }
  331. }
  332. // Send finish sequence
  333. d = new short[4];
  334. d[0] = 0x42;
  335. d[1] = 0x42;
  336. d[2] = 0x42;
  337. d[3] = 0x42;
  338. if (HelperUtility.writeData(d, 4) == false) {
  339. error("Could not write to port!");
  340. HelperUtility.closePort();
  341. return -1;
  342. }
  343. // Recieve ack
  344. d = HelperUtility.readData(1);
  345. if (d.length == 0) {
  346. error("Could not read from port!");
  347. HelperUtility.closePort();
  348. return -1;
  349. }
  350. if (d[0] != 0x42) {
  351. error("Cube not OK!");
  352. HelperUtility.closePort();
  353. return -1;
  354. }
  355. System.out.println("Uploaded animations!");
  356. return 0;
  357. }
  358. /**
  359. * Get all animations from the cube, place it in this object
  360. *
  361. * @param port Name of serial port to use
  362. * @return 0 on success, -1 on error
  363. */
  364. // We generate error messages in here
  365. public int cubeGetState(String port) {
  366. return -1;
  367. }
  368. /**
  369. * Try to speak with the cube.
  370. *
  371. * @return TRUE if cube responds
  372. * @param port Name of serial port
  373. */
  374. public boolean cubeProbeConnected(String port) {
  375. if (HelperUtility.openPort(port) == false) {
  376. error("Could not open Port!");
  377. return false;
  378. }
  379. short[] d = new short[1];
  380. d[0] = 0x42;
  381. if (HelperUtility.writeData(d, 1) == false) {
  382. error("Could not write to port!");
  383. HelperUtility.closePort();
  384. return false;
  385. }
  386. d = HelperUtility.readData(1);
  387. if (d.length == 0) {
  388. error("Could not read from port!");
  389. HelperUtility.closePort();
  390. return false;
  391. }
  392. HelperUtility.closePort();
  393. if (d[0] != 0x42) {
  394. error("Answer was not OK");
  395. return false;
  396. } else {
  397. System.out.println("Got probe response!");
  398. return true;
  399. }
  400. }
  401. private void error(String s) {
  402. System.out.println(s);
  403. parentFrame.errorMessage("Serial Error", s);
  404. }
  405. private void extendArray() {
  406. Animation newArray[] = new Animation[animations.length + 1];
  407. for (int i = 0; i < animations.length; i++) {
  408. newArray[i] = animations[i];
  409. }
  410. animations = newArray;
  411. }
  412. private void shrinkArray() {
  413. Animation newArray[] = new Animation[animations.length - 1];
  414. for (int i = 0; i < newArray.length; i++) {
  415. newArray[i] = animations[i];
  416. }
  417. animations = newArray;
  418. }
  419. private void shiftOver(int toForget) {
  420. for (int i = (toForget + 1); i < animations.length; i++) {
  421. animations[i - 1] = animations[i];
  422. }
  423. }
  424. }