SPS.ino 21 KB

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