1
0

SPS.ino 21 KB

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