1
0

SPS.ino 20 KB

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