SPS.ino 17 KB

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