123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518 |
- /*
- Simple SPS System mit dem Arduino.
- */
- // defining different hardware platforms
- #ifdef __AVR_ATmega328P__
- //#define SPS_USE_DISPLAY
- //#define SPS_RECEIVER
- //#define SPS_ENHANCEMENT
- //#define SPS_SERIAL_PRG
- //#define SPS_SERVO
- //#define SPS_TONE
- #endif
- // libraries
- #include <makros.h>
- #include <EEPROM.h>
- #include <avr/eeprom.h>
- #include "hardware.h"
- // Commands
- const byte PORT = 0x10;
- const byte DELAY = 0x20;
- const byte JUMP_BACK = 0x30;
- const byte SET_A = 0x40;
- const byte IS_A = 0x50;
- const byte A_IS = 0x60;
- const byte CALC = 0x70;
- const byte PAGE = 0x80;
- const byte JUMP = 0x90;
- const byte C_COUNT = 0xA0;
- const byte D_COUNT = 0xB0;
- const byte SKIP_IF = 0xC0;
- const byte CALL = 0xD0;
- const byte CALL_SUB = 0xE0;
- const byte CMD_BYTE = 0xF0;
- // debouncing with 100ms
- const byte DEBOUNCE = 100;
- // sub routines
- const byte subCnt = 7;
- word subs[subCnt];
- // the actual address of the program
- word addr;
- // page register
- word page;
- // defining register
- byte a, b, c, d;
- const byte SAVE_CNT = 1;
- word saveaddr[SAVE_CNT];
- byte saveCnt;
- unsigned long tmpValue;
- byte prog = 0;
- byte data = 0;
- byte com = 0;
- void setup() {
- pinMode(Dout_0, OUTPUT);
- pinMode(Dout_1, OUTPUT);
- pinMode(Dout_2, OUTPUT);
- pinMode(Dout_3, OUTPUT);
- pinMode(PWM_1, OUTPUT);
- pinMode(PWM_2, OUTPUT);
- pinMode(Din_0, INPUT_PULLUP);
- pinMode(Din_1, INPUT_PULLUP);
- pinMode(Din_2, INPUT_PULLUP);
- pinMode(Din_3, INPUT_PULLUP);
- pinMode(SW_PRG, INPUT_PULLUP);
- pinMode(SW_SEL, INPUT_PULLUP);
- digitalWrite(Dout_0, 1);
- delay(1000);
- digitalWrite(Dout_0, 0);
- prgDemoPrg();
- doReset();
- if (digitalRead(SW_PRG) == 0) {
- programMode();
- }
- }
- void doReset() {
- for (int i = 0; i < subCnt; i++) {
- subs[i] = 0;
- }
- readProgram();
- addr = 0;
- page = 0;
- saveCnt = 0;
- a = 0;
- b = 0;
- c = 0;
- d = 0;
- }
- /*
- getting all addresses of sub programms
- */
- void readProgram() {
- word addr = 0;
- for ( addr = 0; addr <= E2END; addr++) {
- byte value = EEPROM.read(addr);
- if (value == 0xFF) {
- // ende des Programms
- break;
- }
- byte cmd = (value & 0xF0);
- byte data = (value & 0x0F);
- if (cmd == CALL_SUB) {
- if (data >= 8) {
- data = data - 8;
- subs[data] = addr + 1;
- }
- }
- }
- }
- /*
- main loop
- */
- void loop() {
- byte value = EEPROM.read(addr);
- byte cmd = (value & 0xF0);
- byte data = (value & 0x0F);
- addr = addr + 1;
- switch (cmd) {
- case PORT:
- doPort(data);
- break;
- case DELAY:
- doDelay(data);
- break;
- case JUMP_BACK:
- doJumpBack(data);
- break;
- case SET_A:
- doSetA(data);
- break;
- case A_IS:
- doAIs(data);
- break;
- case IS_A:
- doIsA(data);
- break;
- case CALC:
- doCalc(data);
- break;
- case PAGE:
- doPage(data);
- break;
- case JUMP:
- doJump(data);
- break;
- case C_COUNT:
- doCCount(data);
- break;
- case D_COUNT:
- doDCount(data);
- break;
- case SKIP_IF:
- doSkipIf(data);
- break;
- case CALL:
- doCall(data);
- break;
- case CALL_SUB:
- doCallSub(data);
- break;
- default:
- ;
- }
- if (addr > E2END) {
- doReset();
- }
- }
- /*
- output to port
- */
- void doPort(byte data) {
- digitalWrite(Dout_0, (data & 0x01) > 0);
- digitalWrite(Dout_1, (data & 0x02) > 0);
- digitalWrite(Dout_2, (data & 0x04) > 0);
- digitalWrite(Dout_3, (data & 0x08) > 0);
- }
- /*
- delay in ms
- */
- void doDelay(byte data) {
- switch (data) {
- case 0:
- delay(1);
- break;
- case 1:
- delay(2);
- break;
- case 2:
- delay(5);
- break;
- case 3:
- delay(10);
- break;
- case 4:
- delay(20);
- break;
- case 5:
- delay(50);
- break;
- case 6:
- delay(100);
- break;
- case 7:
- delay(200);
- break;
- case 8:
- delay(500);
- break;
- case 9:
- delay(1000);
- break;
- case 10:
- delay(2000);
- break;
- case 11:
- delay(5000);
- break;
- case 12:
- delay(10000);
- break;
- case 13:
- delay(20000);
- break;
- case 14:
- delay(30000);
- break;
- case 15:
- delay(60000);
- break;
- default:
- break;
- }
- }
- /*
- jump relative back
- */
- void doJumpBack(byte data) {
- addr = addr - data - 1;
- }
- /*
- a = data
- */
- void doSetA(byte data) {
- a = data;
- }
- /*
- a = somthing;
- */
- void doAIs(byte data) {
- switch (data) {
- case 1:
- a = b;
- break;
- case 2:
- a = c;
- break;
- case 3:
- a = d;
- break;
- case 4:
- a = digitalRead(Din_0) + (digitalRead(Din_1) << 1) + (digitalRead(Din_2) << 2) + (digitalRead(Din_3) << 3);
- break;
- case 5:
- a = digitalRead(Din_0);
- break;
- case 6:
- a = digitalRead(Din_1);
- break;
- case 7:
- a = digitalRead(Din_2);
- break;
- case 8:
- a = digitalRead(Din_3);
- break;
- case 9:
- tmpValue = analogRead(ADC_0);
- a = tmpValue / 64; //(Umrechnen auf 4 bit)
- break;
- case 10:
- tmpValue = analogRead(ADC_1);
- a = tmpValue / 64; //(Umrechnen auf 4 bit)
- break;
- default:
- break;
- }
- }
- /*
- somthing = a;
- */
- void doIsA(byte data) {
- switch (data) {
- case 1:
- b = a;
- break;
- case 2:
- c = a;
- break;
- case 3:
- d = a;
- break;
- case 4:
- doPort(a);
- break;
- case 5:
- digitalWrite(Dout_0, (a & 0x01) > 0);
- break;
- case 6:
- digitalWrite(Dout_1, (a & 0x01) > 0);
- break;
- case 7:
- digitalWrite(Dout_2, (a & 0x01) > 0);
- break;
- case 8:
- digitalWrite(Dout_3, (a & 0x01) > 0);
- break;
- case 9:
- tmpValue = a * 16;
- analogWrite(PWM_1, tmpValue);
- break;
- case 10:
- tmpValue = a * 16;
- analogWrite(PWM_2, tmpValue);
- break;
- default:
- break;
- }
- }
- /*
- calculations
- */
- void doCalc(byte data) {
- switch (data) {
- case 1:
- a = a + 1;
- break;
- case 2:
- a = a - 1;
- break;
- case 3:
- a = a + b;
- break;
- case 4:
- a = a - b;
- break;
- case 5:
- a = a * b;
- break;
- case 6:
- a = a / b;
- break;
- case 7:
- a = a & b;
- break;
- case 8:
- a = a | b;
- break;
- case 9:
- a = a ^ b;
- break;
- case 10:
- a = ~a;
- break;
- default:
- break;
- }
- a = a & 15;
- }
- /*
- setting page
- */
- void doPage(byte data) {
- page = data * 16;
- }
- /*
- jump absolute
- */
- void doJump(byte data) {
- addr = page + data;
- }
- /*
- counting with c register
- */
- void doCCount(byte data) {
- if (c > 0) {
- c -= 1;
- c = c & 0x0F;
- doJump(data);
- }
- }
- /*
- counting with d register
- */
- void doDCount(byte data) {
- if (d > 0) {
- d -= 1;
- d = d & 0x0F;
- doJump(data);
- }
- }
- /*
- simple condition = true, skip next command
- */
- void doSkipIf(byte data) {
- bool skip = false;
- switch (data) {
- case 1:
- skip = (a > b);
- break;
- case 2:
- skip = (a < b);
- break;
- case 3:
- skip = (a == b);
- break;
- case 4:
- skip = digitalRead(Din_0);
- break;
- case 5:
- skip = digitalRead(Din_1);
- break;
- case 6:
- skip = digitalRead(Din_2);
- break;
- case 7:
- skip = digitalRead(Din_3);
- break;
- case 8:
- skip = !digitalRead(Din_0);
- break;
- case 9:
- skip = !digitalRead(Din_1);
- break;
- case 10:
- skip = !digitalRead(Din_2);
- break;
- case 11:
- skip = !digitalRead(Din_3);
- break;
- case 12:
- skip = !digitalRead(SW_PRG);
- break;
- case 13:
- skip = !digitalRead(SW_SEL);
- break;
- case 14:
- skip = digitalRead(SW_PRG);
- break;
- case 15:
- skip = digitalRead(SW_SEL);
- break;
- default:
- break;
- }
- if (skip) {
- addr += 1;
- }
- }
- /*
- calling a subroutine
- */
- void doCall(byte data) {
- saveaddr[saveCnt] = addr;
- saveCnt++;
- addr = page + data;
- }
- /*
- calling a subroutine, calling return and restart
- */
- void doCallSub(byte data) {
- if (data == 0) {
- if (saveCnt < 0) {
- doReset();
- return;
- }
- saveCnt -= 1;
- addr = saveaddr[saveCnt];
- return;
- }
- }
|