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

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