1
0

SPS.ino 20 KB

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