SImpleSPS.ino 8.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518
  1. /*
  2. Simple SPS System mit dem Arduino.
  3. */
  4. // defining different hardware platforms
  5. #ifdef __AVR_ATmega328P__
  6. //#define SPS_USE_DISPLAY
  7. //#define SPS_RECEIVER
  8. //#define SPS_ENHANCEMENT
  9. //#define SPS_SERIAL_PRG
  10. //#define SPS_SERVO
  11. //#define SPS_TONE
  12. #endif
  13. // libraries
  14. #include <makros.h>
  15. #include <EEPROM.h>
  16. #include <avr/eeprom.h>
  17. #include "hardware.h"
  18. // Commands
  19. const byte PORT = 0x10;
  20. const byte DELAY = 0x20;
  21. const byte JUMP_BACK = 0x30;
  22. const byte SET_A = 0x40;
  23. const byte IS_A = 0x50;
  24. const byte A_IS = 0x60;
  25. const byte CALC = 0x70;
  26. const byte PAGE = 0x80;
  27. const byte JUMP = 0x90;
  28. const byte C_COUNT = 0xA0;
  29. const byte D_COUNT = 0xB0;
  30. const byte SKIP_IF = 0xC0;
  31. const byte CALL = 0xD0;
  32. const byte CALL_SUB = 0xE0;
  33. const byte CMD_BYTE = 0xF0;
  34. // debouncing with 100ms
  35. const byte DEBOUNCE = 100;
  36. // sub routines
  37. const byte subCnt = 7;
  38. word subs[subCnt];
  39. // the actual address of the program
  40. word addr;
  41. // page register
  42. word page;
  43. // defining register
  44. byte a, b, c, d;
  45. const byte SAVE_CNT = 1;
  46. word saveaddr[SAVE_CNT];
  47. byte saveCnt;
  48. unsigned long tmpValue;
  49. byte prog = 0;
  50. byte data = 0;
  51. byte com = 0;
  52. void setup() {
  53. pinMode(Dout_0, OUTPUT);
  54. pinMode(Dout_1, OUTPUT);
  55. pinMode(Dout_2, OUTPUT);
  56. pinMode(Dout_3, OUTPUT);
  57. pinMode(PWM_1, OUTPUT);
  58. pinMode(PWM_2, OUTPUT);
  59. pinMode(Din_0, INPUT_PULLUP);
  60. pinMode(Din_1, INPUT_PULLUP);
  61. pinMode(Din_2, INPUT_PULLUP);
  62. pinMode(Din_3, INPUT_PULLUP);
  63. pinMode(SW_PRG, INPUT_PULLUP);
  64. pinMode(SW_SEL, INPUT_PULLUP);
  65. digitalWrite(Dout_0, 1);
  66. delay(1000);
  67. digitalWrite(Dout_0, 0);
  68. prgDemoPrg();
  69. doReset();
  70. if (digitalRead(SW_PRG) == 0) {
  71. programMode();
  72. }
  73. }
  74. void doReset() {
  75. for (int i = 0; i < subCnt; i++) {
  76. subs[i] = 0;
  77. }
  78. readProgram();
  79. addr = 0;
  80. page = 0;
  81. saveCnt = 0;
  82. a = 0;
  83. b = 0;
  84. c = 0;
  85. d = 0;
  86. }
  87. /*
  88. getting all addresses of sub programms
  89. */
  90. void readProgram() {
  91. word addr = 0;
  92. for ( addr = 0; addr <= E2END; addr++) {
  93. byte value = EEPROM.read(addr);
  94. if (value == 0xFF) {
  95. // ende des Programms
  96. break;
  97. }
  98. byte cmd = (value & 0xF0);
  99. byte data = (value & 0x0F);
  100. if (cmd == CALL_SUB) {
  101. if (data >= 8) {
  102. data = data - 8;
  103. subs[data] = addr + 1;
  104. }
  105. }
  106. }
  107. }
  108. /*
  109. main loop
  110. */
  111. void loop() {
  112. byte value = EEPROM.read(addr);
  113. byte cmd = (value & 0xF0);
  114. byte data = (value & 0x0F);
  115. addr = addr + 1;
  116. switch (cmd) {
  117. case PORT:
  118. doPort(data);
  119. break;
  120. case DELAY:
  121. doDelay(data);
  122. break;
  123. case JUMP_BACK:
  124. doJumpBack(data);
  125. break;
  126. case SET_A:
  127. doSetA(data);
  128. break;
  129. case A_IS:
  130. doAIs(data);
  131. break;
  132. case IS_A:
  133. doIsA(data);
  134. break;
  135. case CALC:
  136. doCalc(data);
  137. break;
  138. case PAGE:
  139. doPage(data);
  140. break;
  141. case JUMP:
  142. doJump(data);
  143. break;
  144. case C_COUNT:
  145. doCCount(data);
  146. break;
  147. case D_COUNT:
  148. doDCount(data);
  149. break;
  150. case SKIP_IF:
  151. doSkipIf(data);
  152. break;
  153. case CALL:
  154. doCall(data);
  155. break;
  156. case CALL_SUB:
  157. doCallSub(data);
  158. break;
  159. default:
  160. ;
  161. }
  162. if (addr > E2END) {
  163. doReset();
  164. }
  165. }
  166. /*
  167. output to port
  168. */
  169. void doPort(byte data) {
  170. digitalWrite(Dout_0, (data & 0x01) > 0);
  171. digitalWrite(Dout_1, (data & 0x02) > 0);
  172. digitalWrite(Dout_2, (data & 0x04) > 0);
  173. digitalWrite(Dout_3, (data & 0x08) > 0);
  174. }
  175. /*
  176. delay in ms
  177. */
  178. void doDelay(byte data) {
  179. switch (data) {
  180. case 0:
  181. delay(1);
  182. break;
  183. case 1:
  184. delay(2);
  185. break;
  186. case 2:
  187. delay(5);
  188. break;
  189. case 3:
  190. delay(10);
  191. break;
  192. case 4:
  193. delay(20);
  194. break;
  195. case 5:
  196. delay(50);
  197. break;
  198. case 6:
  199. delay(100);
  200. break;
  201. case 7:
  202. delay(200);
  203. break;
  204. case 8:
  205. delay(500);
  206. break;
  207. case 9:
  208. delay(1000);
  209. break;
  210. case 10:
  211. delay(2000);
  212. break;
  213. case 11:
  214. delay(5000);
  215. break;
  216. case 12:
  217. delay(10000);
  218. break;
  219. case 13:
  220. delay(20000);
  221. break;
  222. case 14:
  223. delay(30000);
  224. break;
  225. case 15:
  226. delay(60000);
  227. break;
  228. default:
  229. break;
  230. }
  231. }
  232. /*
  233. jump relative back
  234. */
  235. void doJumpBack(byte data) {
  236. addr = addr - data - 1;
  237. }
  238. /*
  239. a = data
  240. */
  241. void doSetA(byte data) {
  242. a = data;
  243. }
  244. /*
  245. a = somthing;
  246. */
  247. void doAIs(byte data) {
  248. switch (data) {
  249. case 1:
  250. a = b;
  251. break;
  252. case 2:
  253. a = c;
  254. break;
  255. case 3:
  256. a = d;
  257. break;
  258. case 4:
  259. a = digitalRead(Din_0) + (digitalRead(Din_1) << 1) + (digitalRead(Din_2) << 2) + (digitalRead(Din_3) << 3);
  260. break;
  261. case 5:
  262. a = digitalRead(Din_0);
  263. break;
  264. case 6:
  265. a = digitalRead(Din_1);
  266. break;
  267. case 7:
  268. a = digitalRead(Din_2);
  269. break;
  270. case 8:
  271. a = digitalRead(Din_3);
  272. break;
  273. case 9:
  274. tmpValue = analogRead(ADC_0);
  275. a = tmpValue / 64; //(Umrechnen auf 4 bit)
  276. break;
  277. case 10:
  278. tmpValue = analogRead(ADC_1);
  279. a = tmpValue / 64; //(Umrechnen auf 4 bit)
  280. break;
  281. default:
  282. break;
  283. }
  284. }
  285. /*
  286. somthing = a;
  287. */
  288. void doIsA(byte data) {
  289. switch (data) {
  290. case 1:
  291. b = a;
  292. break;
  293. case 2:
  294. c = a;
  295. break;
  296. case 3:
  297. d = a;
  298. break;
  299. case 4:
  300. doPort(a);
  301. break;
  302. case 5:
  303. digitalWrite(Dout_0, (a & 0x01) > 0);
  304. break;
  305. case 6:
  306. digitalWrite(Dout_1, (a & 0x01) > 0);
  307. break;
  308. case 7:
  309. digitalWrite(Dout_2, (a & 0x01) > 0);
  310. break;
  311. case 8:
  312. digitalWrite(Dout_3, (a & 0x01) > 0);
  313. break;
  314. case 9:
  315. tmpValue = a * 16;
  316. analogWrite(PWM_1, tmpValue);
  317. break;
  318. case 10:
  319. tmpValue = a * 16;
  320. analogWrite(PWM_2, tmpValue);
  321. break;
  322. default:
  323. break;
  324. }
  325. }
  326. /*
  327. calculations
  328. */
  329. void doCalc(byte data) {
  330. switch (data) {
  331. case 1:
  332. a = a + 1;
  333. break;
  334. case 2:
  335. a = a - 1;
  336. break;
  337. case 3:
  338. a = a + b;
  339. break;
  340. case 4:
  341. a = a - b;
  342. break;
  343. case 5:
  344. a = a * b;
  345. break;
  346. case 6:
  347. a = a / b;
  348. break;
  349. case 7:
  350. a = a & b;
  351. break;
  352. case 8:
  353. a = a | b;
  354. break;
  355. case 9:
  356. a = a ^ b;
  357. break;
  358. case 10:
  359. a = ~a;
  360. break;
  361. default:
  362. break;
  363. }
  364. a = a & 15;
  365. }
  366. /*
  367. setting page
  368. */
  369. void doPage(byte data) {
  370. page = data * 16;
  371. }
  372. /*
  373. jump absolute
  374. */
  375. void doJump(byte data) {
  376. addr = page + data;
  377. }
  378. /*
  379. counting with c register
  380. */
  381. void doCCount(byte data) {
  382. if (c > 0) {
  383. c -= 1;
  384. c = c & 0x0F;
  385. doJump(data);
  386. }
  387. }
  388. /*
  389. counting with d register
  390. */
  391. void doDCount(byte data) {
  392. if (d > 0) {
  393. d -= 1;
  394. d = d & 0x0F;
  395. doJump(data);
  396. }
  397. }
  398. /*
  399. simple condition = true, skip next command
  400. */
  401. void doSkipIf(byte data) {
  402. bool skip = false;
  403. switch (data) {
  404. case 1:
  405. skip = (a > b);
  406. break;
  407. case 2:
  408. skip = (a < b);
  409. break;
  410. case 3:
  411. skip = (a == b);
  412. break;
  413. case 4:
  414. skip = digitalRead(Din_0);
  415. break;
  416. case 5:
  417. skip = digitalRead(Din_1);
  418. break;
  419. case 6:
  420. skip = digitalRead(Din_2);
  421. break;
  422. case 7:
  423. skip = digitalRead(Din_3);
  424. break;
  425. case 8:
  426. skip = !digitalRead(Din_0);
  427. break;
  428. case 9:
  429. skip = !digitalRead(Din_1);
  430. break;
  431. case 10:
  432. skip = !digitalRead(Din_2);
  433. break;
  434. case 11:
  435. skip = !digitalRead(Din_3);
  436. break;
  437. case 12:
  438. skip = !digitalRead(SW_PRG);
  439. break;
  440. case 13:
  441. skip = !digitalRead(SW_SEL);
  442. break;
  443. case 14:
  444. skip = digitalRead(SW_PRG);
  445. break;
  446. case 15:
  447. skip = digitalRead(SW_SEL);
  448. break;
  449. default:
  450. break;
  451. }
  452. if (skip) {
  453. addr += 1;
  454. }
  455. }
  456. /*
  457. calling a subroutine
  458. */
  459. void doCall(byte data) {
  460. saveaddr[saveCnt] = addr;
  461. saveCnt++;
  462. addr = page + data;
  463. }
  464. /*
  465. calling a subroutine, calling return and restart
  466. */
  467. void doCallSub(byte data) {
  468. if (data == 0) {
  469. if (saveCnt < 0) {
  470. doReset();
  471. return;
  472. }
  473. saveCnt -= 1;
  474. addr = saveaddr[saveCnt];
  475. return;
  476. }
  477. }