SPS.ino 19 KB

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