1
0

SPS.ino 18 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024
  1. /*
  2. SPS System mit dem Arduino.
  3. Version 0.10
  4. 18.11.2018 WKLA
  5. - new standard programming mode
  6. i added a new programming mode for the default programming, because i thing the old one was a little bit clumsy.
  7. the new one has a nicer interface, as you now always know where you are.
  8. Starting with PRG pushed after Reset.
  9. as a result, all LEDs will shortly blink
  10. now you are in programming mode.
  11. * the D1 LED will blink
  12. * the higher nibble of the address will be shown
  13. * the D2 LED will blink
  14. * the lower nibble of the address will be shown
  15. * the D3 LED will blink
  16. * the command part (high nibble) will be shown
  17. * with SEL you can step thru all commands
  18. * PRG will save the command
  19. * the D4 LED will blink
  20. * the data part (low nibble) will be shown
  21. * with SEL you can step thru all datas
  22. * PRG will save the data
  23. * if the new value has been changed, all LEDs will flash as the byte will be written to the EEPROM
  24. * address will be increased and now it will start with blinking of the D1 LED
  25. *
  26. * To leave the programming simply push reset.
  27. Version 0.9
  28. 18.11.2018 WKLA
  29. - BUGs entfernt. Release.
  30. 10.11.2018 WKLA
  31. - Implementierung Tone Befehl
  32. Version 0.8
  33. 06.11.2018 WKLA
  34. - Umstellung auf dbgOut
  35. - Display TM1637 Anbindung
  36. Version 0.7
  37. 24.09.2012 WKLA
  38. - neue Berechnung A = B - A und Swap A,B...
  39. - Stack auf 16 Bytes berschränkt, wird zu oft gepusht, werden die alten Werte rausgeschoben.
  40. Basierd auf dem TPS System vom elektronik-labor.
  41. Erweiterungen:
  42. - es können bis zu 6 Unterroutinen definiert werden und diese direkt angesprungen werden.
  43. - neben return gibt's auch einen restart
  44. - 2 Servoausgänge für übliche RC Servos. (10° Auflösung in Nibble Modus, <1° Auflösung im Bytemodus)
  45. ACHTUNG: Servo und PWM Ausgänge sind nicht mischbar und können auch nicht gleichzeitig benutzt werden.
  46. - 2 RC Eingänge (16 Schritte auflösung im nibble Modus, Mitte 8, 255 Schritte im Byte Modus)
  47. - fkt. auch mit einem ATTiny84 (44 ist leider auf GRund der Programmgröße nicht mehr für den erweiterten Befehlssatz möglich)
  48. - call stack von bis zu 16 Unterfunktionen
  49. - neue Register e,f
  50. */
  51. // Program im Debugmodus kompilieren, dann werden zus. Ausgaben auf die serielle Schnittstelle geschrieben.
  52. #ifdef __AVR_ATtiny4313__
  53. #define SPS_RCRECEIVER
  54. #endif
  55. #ifdef __AVR_ATmega328P__
  56. #define debug
  57. #define SPS_USE_DISPLAY
  58. #define SPS_RECEIVER
  59. #define SPS_ENHANCEMENT
  60. #define SPS_SERVO
  61. #define SPS_TONE
  62. #endif
  63. #ifdef __AVR_ATinyx4__
  64. #define SPS_ENHANCEMENT
  65. #define SPS_SERVO
  66. #endif
  67. #include <debug.h>
  68. #include <makros.h>
  69. #include <EEPROM.h>
  70. #include <avr/eeprom.h>
  71. #ifdef SPS_SERVO
  72. #include <Servo.h>
  73. #endif
  74. #ifdef SPS_ENHANCEMENT
  75. #include <avdweb_Switch.h>
  76. #endif
  77. #ifdef SPS_TONE
  78. #include "notes.h"
  79. #endif
  80. // Hardwareanbindung
  81. #ifdef __AVR_ATmega328P__
  82. // Arduino Hardware
  83. const byte Din_0 = 0;
  84. const byte Din_1 = 1;
  85. const byte Din_2 = 2;
  86. const byte Din_3 = 3;
  87. const byte Dout_0 = 4;
  88. const byte Dout_1 = 5;
  89. const byte Dout_2 = 6;
  90. const byte Dout_3 = 7;
  91. const byte ADC_0 = 0; //(15)
  92. const byte ADC_1 = 1; //(16)
  93. const byte PWM_1 = 9;
  94. const byte PWM_2 = 10;
  95. #ifdef SPS_RCRECEIVER
  96. const byte RC_0 = 18;
  97. const byte RC_1 = 19;
  98. #endif
  99. #ifdef SPS_SERVO
  100. const byte SERVO_1 = 9;
  101. const byte SERVO_2 = 10;
  102. #endif
  103. const byte SW_PRG = 8;
  104. const byte SW_SEL = 11;
  105. #ifdef SPS_USE_DISPLAY
  106. const byte DIGIT_DATA_IO = 12;
  107. const byte DIGIT_CLOCK = 13;
  108. #endif
  109. #endif
  110. #ifdef __AVR_ATtinyX4__
  111. // ATTiny84 Hardware
  112. const byte Dout_0 = 6;
  113. const byte Dout_1 = 5;
  114. const byte Dout_2 = 4;
  115. const byte Dout_3 = 1;
  116. const byte Din_0 = 10;
  117. const byte Din_1 = 9;
  118. const byte Din_2 = 8;
  119. const byte Din_3 = 7;
  120. const byte ADC_0 = 0;
  121. const byte ADC_1 = 1;
  122. const byte PWM_1 = 2;
  123. const byte PWM_2 = 3;
  124. #ifdef SPS_RCRECEIVER
  125. const byte RC_0 = 10;
  126. const byte RC_1 = 9;
  127. #endif
  128. #ifdef SPS_SERVO
  129. const byte SERVO_1 = 2;
  130. const byte SERVO_2 = 3;
  131. #endif
  132. const byte SW_PRG = 0;
  133. const byte SW_SEL = 8;
  134. #ifdef SPS_USE_DISPLAY
  135. const byte DIGIT_DATA_IO = 4;
  136. const byte DIGIT_CLOCK = 5;
  137. #endif
  138. #endif
  139. #ifdef __AVR_ATtiny4313__
  140. // ATTiny4313 Hardware
  141. const byte Dout_0 = 0;
  142. const byte Dout_1 = 1;
  143. const byte Dout_2 = 2;
  144. const byte Dout_3 = 3;
  145. const byte Din_0 = 4;
  146. const byte Din_1 = 5;
  147. const byte Din_2 = 6;
  148. const byte Din_3 = 7;
  149. const byte ADC_0 = 13;
  150. const byte ADC_1 = 14;
  151. const byte PWM_1 = 11;
  152. const byte PWM_2 = 12;
  153. #ifdef SPS_RCRECEIVER
  154. const byte RC_0 = 15;
  155. const byte RC_1 = 16;
  156. #endif
  157. #ifdef SPS_SERVO
  158. const byte SERVO_1 = 11;
  159. const byte SERVO_2 = 12;
  160. #endif
  161. const byte SW_PRG = 9;
  162. const byte SW_SEL = 8;
  163. #endif
  164. // Befehle
  165. const byte PORT = 0x10;
  166. const byte DELAY = 0x20;
  167. const byte JUMP_BACK = 0x30;
  168. const byte SET_A = 0x40;
  169. const byte IS_A = 0x50;
  170. const byte A_IS = 0x60;
  171. const byte CALC = 0x70;
  172. const byte PAGE = 0x80;
  173. const byte JUMP = 0x90;
  174. const byte C_COUNT = 0xA0;
  175. const byte D_COUNT = 0xB0;
  176. const byte SKIP_IF = 0xC0;
  177. const byte CALL = 0xD0;
  178. const byte CALL_SUB = 0xE0;
  179. const byte CMD_BYTE = 0xF0;
  180. // debouncing with 100ms
  181. const byte DEBOUNCE = 100;
  182. // sub routines
  183. const byte subCnt = 7;
  184. word subs[subCnt];
  185. word addr;
  186. word page;
  187. #ifdef SPS_ENHANCEMENT
  188. const byte SAVE_CNT = 16;
  189. #else
  190. const byte SAVE_CNT = 1;
  191. #endif
  192. word saveaddr[SAVE_CNT];
  193. byte saveCnt;
  194. #ifdef SPS_ENHANCEMENT
  195. byte stack[SAVE_CNT];
  196. byte stackCnt;
  197. #endif
  198. unsigned long tmpValue;
  199. byte a, b, c, d;
  200. #ifdef SPS_ENHANCEMENT
  201. byte e, f;
  202. #endif
  203. #ifdef SPS_SERVO
  204. Servo servo1;
  205. Servo servo2;
  206. #endif
  207. byte prog = 0;
  208. byte data = 0;
  209. byte com = 0;
  210. void setup() {
  211. pinMode(Dout_0, OUTPUT);
  212. pinMode(Dout_1, OUTPUT);
  213. pinMode(Dout_2, OUTPUT);
  214. pinMode(Dout_3, OUTPUT);
  215. pinMode(PWM_1, OUTPUT);
  216. pinMode(PWM_2, OUTPUT);
  217. pinMode(Din_0, INPUT_PULLUP);
  218. pinMode(Din_1, INPUT_PULLUP);
  219. pinMode(Din_2, INPUT_PULLUP);
  220. pinMode(Din_3, INPUT_PULLUP);
  221. pinMode(SW_PRG, INPUT_PULLUP);
  222. pinMode(SW_SEL, INPUT_PULLUP);
  223. #ifdef SPS_USE_DISPLAY
  224. initDisplay();
  225. #endif
  226. // Serielle Schnittstelle einstellen
  227. #ifndef __AVR_ATtinyX4__
  228. initDebug();
  229. #endif
  230. // writeProgram();
  231. doReset();
  232. if (digitalRead(SW_PRG) == 0) {
  233. programMode();
  234. }
  235. }
  236. void doReset() {
  237. dbgOutLn("Reset");
  238. #ifdef SPS_SERVO
  239. servo1.detach();
  240. servo2.detach();
  241. #endif
  242. for (int i = 0; i < subCnt; i++) {
  243. subs[i] = 0;
  244. }
  245. readProgram();
  246. addr = 0;
  247. page = 0;
  248. saveCnt = 0;
  249. a = 0;
  250. b = 0;
  251. c = 0;
  252. d = 0;
  253. #ifdef SPS_ENHANCEMENT
  254. e = 0;
  255. f = 0;
  256. #endif
  257. }
  258. /*
  259. getting all addresses of sub programms
  260. */
  261. void readProgram() {
  262. dbgOutLn("Read program");
  263. word addr = 0;
  264. for ( addr = 0; addr <= E2END; addr++) {
  265. byte value = EEPROM.read(addr);
  266. #ifdef debug
  267. dbgOut2(value, HEX);
  268. if (((addr + 1) % 16) == 0) {
  269. dbgOutLn();
  270. }
  271. else {
  272. dbgOut(",");
  273. }
  274. #endif
  275. if (value == 0xFF) {
  276. // ende des Programms
  277. break;
  278. }
  279. byte cmd = (value & 0xF0);
  280. byte data = (value & 0x0F);
  281. dbgOut("(");
  282. dbgOut2(cmd, HEX);
  283. dbgOut2(data, HEX);
  284. dbgOut(")");
  285. if (cmd == CALL_SUB) {
  286. if (data >= 8) {
  287. data = data - 8;
  288. subs[data] = addr + 1;
  289. }
  290. }
  291. #ifdef SPS_SERVO
  292. if ((cmd == IS_A) && (data == 0x0B)) {
  293. if (!servo1.attached()) {
  294. dbgOutLn("attach Srv1");
  295. servo1.attach(SERVO_1);
  296. }
  297. } else if ((cmd == CMD_BYTE) && (data == 0x06)) {
  298. if (!servo1.attached()) {
  299. dbgOutLn("attach Srv1");
  300. servo1.attach(SERVO_1);
  301. }
  302. } else if ((cmd == IS_A) && (data == 0x0C)) {
  303. if (!servo2.attached()) {
  304. dbgOutLn("attach Srv2");
  305. servo2.attach(SERVO_2);
  306. }
  307. } else if ((cmd == CMD_BYTE) && (data == 0x07)) {
  308. if (!servo2.attached()) {
  309. dbgOutLn("attach Srv2");
  310. servo2.attach(SERVO_2);
  311. }
  312. }
  313. #endif
  314. }
  315. dbgOutLn();
  316. }
  317. /*
  318. main loop
  319. */
  320. void loop() {
  321. byte value = EEPROM.read(addr);
  322. byte cmd = (value & 0xF0);
  323. byte data = (value & 0x0F);
  324. dbgOut2(addr, HEX);
  325. dbgOut(":");
  326. dbgOut2(value, HEX);
  327. dbgOut(",");
  328. dbgOut2(cmd, HEX);
  329. dbgOut(",");
  330. dbgOut2(data, HEX);
  331. dbgOut(",a:");
  332. dbgOut2(a, HEX);
  333. dbgOut(",");
  334. dbgOut2(b, HEX);
  335. dbgOut(",");
  336. dbgOut2(c, HEX);
  337. dbgOut(",");
  338. dbgOut2(d, HEX);
  339. dbgOut(",");
  340. dbgOut2(e, HEX);
  341. dbgOut(",");
  342. dbgOut2(f, HEX);
  343. dbgOutLn();
  344. addr = addr + 1;
  345. switch (cmd) {
  346. case PORT:
  347. doPort(data);
  348. break;
  349. case DELAY:
  350. doDelay(data);
  351. break;
  352. case JUMP_BACK:
  353. doJumpBack(data);
  354. break;
  355. case SET_A:
  356. doSetA(data);
  357. break;
  358. case A_IS:
  359. doAIs(data);
  360. break;
  361. case IS_A:
  362. doIsA(data);
  363. break;
  364. case CALC:
  365. doCalc(data);
  366. break;
  367. case PAGE:
  368. doPage(data);
  369. break;
  370. case JUMP:
  371. doJump(data);
  372. break;
  373. case C_COUNT:
  374. doCCount(data);
  375. break;
  376. case D_COUNT:
  377. doDCount(data);
  378. break;
  379. case SKIP_IF:
  380. doSkipIf(data);
  381. break;
  382. case CALL:
  383. doCall(data);
  384. break;
  385. case CALL_SUB:
  386. doCallSub(data);
  387. break;
  388. case CMD_BYTE:
  389. doByte(data);
  390. break;
  391. default:
  392. ;
  393. }
  394. if (addr > E2END) {
  395. doReset();
  396. }
  397. }
  398. /*
  399. output to port
  400. */
  401. void doPort(byte data) {
  402. digitalWrite(Dout_0, (data & 0x01) > 0);
  403. digitalWrite(Dout_1, (data & 0x02) > 0);
  404. digitalWrite(Dout_2, (data & 0x04) > 0);
  405. digitalWrite(Dout_3, (data & 0x08) > 0);
  406. }
  407. /*
  408. delay in ms
  409. */
  410. void doDelay(byte data) {
  411. dbgOut("dly: ");
  412. dbgOutLn2(data, HEX);
  413. switch (data) {
  414. case 0:
  415. delay(1);
  416. break;
  417. case 1:
  418. delay(2);
  419. break;
  420. case 2:
  421. delay(5);
  422. break;
  423. case 3:
  424. delay(10);
  425. break;
  426. case 4:
  427. delay(20);
  428. break;
  429. case 5:
  430. delay(50);
  431. break;
  432. case 6:
  433. delay(100);
  434. break;
  435. case 7:
  436. delay(200);
  437. break;
  438. case 8:
  439. delay(500);
  440. break;
  441. case 9:
  442. delay(1000);
  443. break;
  444. case 10:
  445. delay(2000);
  446. break;
  447. case 11:
  448. delay(5000);
  449. break;
  450. case 12:
  451. delay(10000);
  452. break;
  453. case 13:
  454. delay(20000);
  455. break;
  456. case 14:
  457. delay(30000);
  458. break;
  459. case 15:
  460. delay(60000);
  461. break;
  462. default:
  463. break;
  464. }
  465. }
  466. /*
  467. jump relative back
  468. */
  469. void doJumpBack(byte data) {
  470. addr = addr - data - 1;
  471. }
  472. /*
  473. a = data
  474. */
  475. void doSetA(byte data) {
  476. a = data;
  477. }
  478. /*
  479. a = somthing;
  480. */
  481. void doAIs(byte data) {
  482. switch (data) {
  483. case 1:
  484. a = b;
  485. break;
  486. case 2:
  487. a = c;
  488. break;
  489. case 3:
  490. a = d;
  491. break;
  492. case 4:
  493. a = digitalRead(Din_0) + (digitalRead(Din_1) << 1) + (digitalRead(Din_2) << 2) + (digitalRead(Din_3) << 3);
  494. break;
  495. case 5:
  496. a = digitalRead(Din_0);
  497. break;
  498. case 6:
  499. a = digitalRead(Din_1);
  500. break;
  501. case 7:
  502. a = digitalRead(Din_2);
  503. break;
  504. case 8:
  505. a = digitalRead(Din_3);
  506. break;
  507. #ifndef __AVR_ATtiny4313__
  508. case 9:
  509. tmpValue = analogRead(ADC_0);
  510. a = tmpValue / 64; //(Umrechnen auf 4 bit)
  511. break;
  512. case 10:
  513. tmpValue = analogRead(ADC_1);
  514. a = tmpValue / 64; //(Umrechnen auf 4 bit)
  515. break;
  516. #else
  517. case 9:
  518. a = digitalRead(ADC_0);
  519. break;
  520. case 10:
  521. a = digitalRead(ADC_1);
  522. break;
  523. #endif
  524. #ifdef SPS_RCRECEIVER
  525. case 11:
  526. tmpValue = pulseIn(RC_0, HIGH, 100000);
  527. if (tmpValue < 1000) {
  528. tmpValue = 1000;
  529. }
  530. if (tmpValue > 2000) {
  531. tmpValue = 2000;
  532. }
  533. a = (tmpValue - 1000) / 64; //(Umrechnen auf 4 bit)
  534. dbgOut("RC1:");
  535. dbgOut(tmpValue);
  536. dbgOut("=");
  537. dbgOutLn(a);
  538. break;
  539. case 12:
  540. tmpValue = pulseIn(RC_1, HIGH, 100000);
  541. if (tmpValue < 1000) {
  542. tmpValue = 1000;
  543. }
  544. if (tmpValue > 2000) {
  545. tmpValue = 2000;
  546. }
  547. a = (tmpValue - 1000) / 64; //(Umrechnen auf 4 bit)
  548. dbgOut("RC2:");
  549. dbgOut(tmpValue);
  550. dbgOut("=");
  551. dbgOutLn(a);
  552. break;
  553. #endif
  554. #ifdef SPS_ENHANCMENT
  555. case 13:
  556. a = e;
  557. break;
  558. case 14:
  559. a = f;
  560. break;
  561. case 15:
  562. if (stackCnt > 0) {
  563. stackCnt -= 1;
  564. a = stack[stackCnt];
  565. } else {
  566. a = 0;
  567. }
  568. break;
  569. #endif
  570. default:
  571. break;
  572. }
  573. }
  574. /*
  575. somthing = a;
  576. */
  577. void doIsA(byte data) {
  578. switch (data) {
  579. #ifdef SPS_ENHANCEMENT
  580. case 0:
  581. swap(a, b, byte);
  582. break;
  583. #endif
  584. case 1:
  585. b = a;
  586. break;
  587. case 2:
  588. c = a;
  589. break;
  590. case 3:
  591. d = a;
  592. break;
  593. case 4:
  594. doPort(a);
  595. break;
  596. case 5:
  597. digitalWrite(Dout_0, (a & 0x01) > 0);
  598. break;
  599. case 6:
  600. digitalWrite(Dout_1, (a & 0x01) > 0);
  601. break;
  602. case 7:
  603. digitalWrite(Dout_2, (a & 0x01) > 0);
  604. break;
  605. case 8:
  606. digitalWrite(Dout_3, (a & 0x01) > 0);
  607. break;
  608. case 9:
  609. tmpValue = a * 16;
  610. dbgOut("PWM1:");
  611. dbgOutLn(tmpValue);
  612. analogWrite(PWM_1, tmpValue);
  613. break;
  614. case 10:
  615. tmpValue = a * 16;
  616. dbgOut("PWM2:");
  617. dbgOutLn(tmpValue);
  618. analogWrite(PWM_2, tmpValue);
  619. break;
  620. #ifdef SPS_SERVO
  621. case 11:
  622. if (servo1.attached()) {
  623. tmpValue = (a * 10) + 10;
  624. dbgOut("Srv1:");
  625. dbgOutLn(tmpValue);
  626. servo1.write(tmpValue);
  627. }
  628. break;
  629. case 12:
  630. if (servo2.attached()) {
  631. tmpValue = (a * 10) + 10;
  632. dbgOut("Srv2:");
  633. dbgOutLn(tmpValue);
  634. servo2.write(tmpValue);
  635. }
  636. break;
  637. #endif
  638. #ifdef SPS_ENHANCEMENT
  639. case 13:
  640. e = a;
  641. break;
  642. case 14:
  643. f = a;
  644. break;
  645. case 15:
  646. if (stackCnt < SAVE_CNT) {
  647. stack[stackCnt] = a;
  648. stackCnt += 1;
  649. }
  650. else {
  651. for (int i = 1; i <= SAVE_CNT; i++) {
  652. stack[i - 1] = stack[i];
  653. }
  654. stack[stackCnt] = a;
  655. }
  656. break;
  657. #endif
  658. default:
  659. break;
  660. }
  661. }
  662. /*
  663. calculations
  664. */
  665. void doCalc(byte data) {
  666. switch (data) {
  667. case 1:
  668. a = a + 1;
  669. break;
  670. case 2:
  671. a = a - 1;
  672. break;
  673. case 3:
  674. a = a + b;
  675. break;
  676. case 4:
  677. a = a - b;
  678. break;
  679. case 5:
  680. a = a * b;
  681. break;
  682. case 6:
  683. a = a / b;
  684. break;
  685. case 7:
  686. a = a & b;
  687. break;
  688. case 8:
  689. a = a | b;
  690. break;
  691. case 9:
  692. a = a ^ b;
  693. break;
  694. case 10:
  695. a = !a;
  696. break;
  697. #ifdef SPS_ENHANCEMENT
  698. case 11:
  699. a = a % b;
  700. break;
  701. case 12:
  702. a = a + 16 * b;
  703. break;
  704. case 13:
  705. a = b - a;
  706. break;
  707. #endif
  708. default:
  709. break;
  710. }
  711. #ifndef SPS_ENHANCEMENT
  712. a = a & 15;
  713. #endif
  714. }
  715. /*
  716. setting page
  717. */
  718. void doPage(byte data) {
  719. page = data * 16;
  720. }
  721. /*
  722. jump absolute
  723. */
  724. void doJump(byte data) {
  725. #ifdef debug
  726. dbgOut("J");
  727. dbgOut2(page, HEX);
  728. dbgOutLn2(data, HEX);
  729. #endif
  730. addr = page + data;
  731. }
  732. /*
  733. counting with c register
  734. */
  735. void doCCount(byte data) {
  736. if (c > 0) {
  737. c -= 1;
  738. c = c & 0x0F;
  739. doJump(data);
  740. }
  741. }
  742. /*
  743. counting with d register
  744. */
  745. void doDCount(byte data) {
  746. if (d > 0) {
  747. d -= 1;
  748. d = d & 0x0F;
  749. doJump(data);
  750. }
  751. }
  752. /*
  753. simple comdition = true skip next command
  754. */
  755. void doSkipIf(byte data) {
  756. bool skip = false;
  757. switch (data) {
  758. #ifdef SPS_ENHANCEMENT
  759. case 0:
  760. skip = (a == 0);
  761. break;
  762. #endif
  763. case 1:
  764. skip = (a > b);
  765. break;
  766. case 2:
  767. skip = (a < b);
  768. break;
  769. case 3:
  770. skip = (a == b);
  771. break;
  772. case 4:
  773. skip = digitalRead(Din_0);
  774. break;
  775. case 5:
  776. skip = digitalRead(Din_1);
  777. break;
  778. case 6:
  779. skip = digitalRead(Din_2);
  780. break;
  781. case 7:
  782. skip = digitalRead(Din_3);
  783. break;
  784. case 8:
  785. skip = !digitalRead(Din_0);
  786. break;
  787. case 9:
  788. skip = !digitalRead(Din_1);
  789. break;
  790. case 10:
  791. skip = !digitalRead(Din_2);
  792. break;
  793. case 11:
  794. skip = !digitalRead(Din_3);
  795. break;
  796. case 12:
  797. skip = !digitalRead(SW_PRG);
  798. break;
  799. case 13:
  800. skip = !digitalRead(SW_SEL);
  801. break;
  802. case 14:
  803. skip = digitalRead(SW_PRG);
  804. break;
  805. case 15:
  806. skip = digitalRead(SW_SEL);
  807. break;
  808. default:
  809. break;
  810. }
  811. if (skip) {
  812. addr += 1;
  813. }
  814. }
  815. /*
  816. calling a subroutine
  817. */
  818. void doCall(byte data) {
  819. saveaddr[saveCnt] = addr;
  820. saveCnt++;
  821. addr = page + data;
  822. }
  823. /*
  824. calling a subroutine, calling return and restart
  825. */
  826. void doCallSub(byte data) {
  827. if (data == 0) {
  828. if (saveCnt < 0) {
  829. doReset();
  830. return;
  831. }
  832. saveCnt -= 1;
  833. addr = saveaddr[saveCnt];
  834. dbgOut("r:");
  835. dbgOutLn(addr);
  836. return;
  837. }
  838. #ifdef SPS_ENHANCEMENT
  839. if (data <= 7) {
  840. // call subroutine number
  841. doCall(addr);
  842. addr = subs[data - 1];
  843. dbgOut("c:");
  844. dbgOutLn(addr);
  845. return;
  846. }
  847. if (data == 0x0f) {
  848. doReset();
  849. }
  850. #endif
  851. }
  852. /*
  853. calling a byte methods
  854. */
  855. void doByte(byte data) {
  856. #ifdef SPS_ENHANCEMENT
  857. dbgOut("B ");
  858. switch (data) {
  859. case 0:
  860. tmpValue = analogRead(ADC_0);
  861. a = tmpValue >> 2; //(Umrechnen auf 8 bit)
  862. break;
  863. case 1:
  864. tmpValue = analogRead(ADC_1);
  865. a = tmpValue >> 2; //(Umrechnen auf 8 bit)
  866. break;
  867. #ifdef SPS_RCRECEIVER
  868. case 2:
  869. tmpValue = pulseIn(RC_0, HIGH, 100000);
  870. if (tmpValue < 1000) {
  871. tmpValue = 1000;
  872. }
  873. if (tmpValue > 2000) {
  874. tmpValue = 2000;
  875. }
  876. a = (tmpValue - 1000) / 4; //(Umrechnen auf 4 bit)
  877. dbgOut("RC1:");
  878. dbgOut(tmpValue);
  879. dbgOut("=");
  880. dbgOutLn(a);
  881. break;
  882. case 3:
  883. tmpValue = pulseIn(RC_1, HIGH, 100000);
  884. if (tmpValue < 1000) {
  885. tmpValue = 1000;
  886. }
  887. if (tmpValue > 2000) {
  888. tmpValue = 2000;
  889. }
  890. a = (tmpValue - 1000) / 4; //(Umrechnen auf 4 bit)
  891. dbgOut("RC2:");
  892. dbgOut(tmpValue);
  893. dbgOut("=");
  894. dbgOutLn(a);
  895. break;
  896. #endif
  897. case 4:
  898. tmpValue = a;
  899. dbgOut("PWM1:");
  900. dbgOutLn(a);
  901. analogWrite(PWM_1, a);
  902. break;
  903. case 5:
  904. tmpValue = a;
  905. dbgOut("PWM2:");
  906. dbgOutLn(a);
  907. analogWrite(PWM_2, a);
  908. break;
  909. #ifdef SPS_SERVO
  910. case 6:
  911. if (servo1.attached()) {
  912. dbgOut("Srv1:");
  913. tmpValue = map(a,0, 255,0,180);
  914. dbgOutLn(tmpValue);
  915. servo1.write(tmpValue);
  916. }
  917. break;
  918. case 7:
  919. if (servo2.attached()) {
  920. dbgOut("Srv2:");
  921. tmpValue = map(a,0, 255,0,180);
  922. dbgOutLn(tmpValue);
  923. servo2.write(tmpValue);
  924. }
  925. break;
  926. #endif
  927. #ifdef SPS_TONE
  928. case 8:
  929. if (a == 0) {
  930. dbgOutLn("Tone off");
  931. noTone(PWM_2);
  932. } else {
  933. if (between(a, MIDI_START, MIDI_START + MIDI_NOTES)) {
  934. word frequenz = pgm_read_word(a - MIDI_START + midiNoteToFreq);
  935. dbgOut("Tone on: midi ");
  936. dbgOut2(a, DEC);
  937. dbgOut(", ");
  938. dbgOut2(frequenz, DEC);
  939. dbgOutLn("Hz");
  940. tone(PWM_2, frequenz);
  941. }
  942. }
  943. break;
  944. #endif
  945. }
  946. #endif
  947. }