SPS.ino 21 KB

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