SPS.ino 19 KB

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