1
0

SPS.ino 20 KB

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