Browse Source

FEATURE: adding simple ArduinoSPS, a basic variant without any enhancments

Klaas, Wilfried 4 years ago
parent
commit
52284e2f23
4 changed files with 698 additions and 16 deletions
  1. 16 16
      SPS/SPS.ino
  2. 518 0
      SimpleSPS/SImpleSPS/SImpleSPS.ino
  3. 20 0
      SimpleSPS/SImpleSPS/hardware.h
  4. 144 0
      SimpleSPS/SImpleSPS/prgmode.ino

+ 16 - 16
SPS/SPS.ino

@@ -82,32 +82,32 @@
 //#define debug
 
 // defining different hardware platforms
-#ifdef __AVR_ATtiny861__
-#define SPS_RCRECEIVER
-#define SPS_ENHANCEMENT
-#define SPS_SERIAL_PRG
+#ifdef __AVR_ATmega328P__
+//#define SPS_USE_DISPLAY
+//#define SPS_RECEIVER
+//#define SPS_ENHANCEMENT
+//#define SPS_SERIAL_PRG
 //#define SPS_SERVO
-#define SPS_TONE
-#endif
-
-#ifdef __AVR_ATtiny4313__
-#define SPS_RCRECEIVER
+//#define SPS_TONE
 #endif
 
-#ifdef __AVR_ATmega328P__
-#define SPS_USE_DISPLAY
-#define SPS_RECEIVER
+#ifdef __AVR_ATtiny84__
 #define SPS_ENHANCEMENT
 #define SPS_SERIAL_PRG
 #define SPS_SERVO
-#define SPS_TONE
+//#define SPS_TONE
 #endif
 
-#ifdef __AVR_ATtiny84__
+#ifdef __AVR_ATtiny861__
+#define SPS_RCRECEIVER
 #define SPS_ENHANCEMENT
 #define SPS_SERIAL_PRG
-#define SPS_SERVO
-//#define SPS_TONE
+//#define SPS_SERVO
+#define SPS_TONE
+#endif
+
+#ifdef __AVR_ATtiny4313__
+#define SPS_RCRECEIVER
 #endif
 
 // libraries

+ 518 - 0
SimpleSPS/SImpleSPS/SImpleSPS.ino

@@ -0,0 +1,518 @@
+/*
+  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;
+  }
+}

+ 20 - 0
SimpleSPS/SImpleSPS/hardware.h

@@ -0,0 +1,20 @@
+// defining the hardware connections
+
+// Arduino Hardware
+const byte Din_0 = 0;
+const byte Din_1 = 1;
+const byte Din_2 = 2;
+const byte Din_3 = 3;
+
+const byte Dout_0 = 4;
+const byte Dout_1 = 5;
+const byte Dout_2 = 6;
+const byte Dout_3 = 7;
+
+const byte ADC_0 = 0; //(15)
+const byte ADC_1 = 1; //(16)
+const byte PWM_1 = 9;
+const byte PWM_2 = 10;
+
+const byte SW_PRG = 8;
+const byte SW_SEL = 11;

+ 144 - 0
SimpleSPS/SImpleSPS/prgmode.ino

@@ -0,0 +1,144 @@
+/*
+  entering the programming mode
+*/
+
+#define BLINK_DELAY 500
+#define SHOW_DELAY 1000
+#define KEY_DELAY 250
+#define ADDR_LOOP 50
+
+const byte demoPrg[] = { 0x4F, 0x59, 0x1F, 0x29, 0x10, 0x29, 0x5A, 0x40,
+                         0x59, 0x64, 0x54, 0x29, 0x4F, 0x59, 0x10, 0xCD,
+                         0x11, 0x28, 0xCC, 0x18, 0x28, 0x4F, 0x59, 0x5A,
+                         0x72, 0x26, 0xC0, 0x35, 0x80, 0x90, 0xFF
+                       };
+
+
+enum PROGRAMMING_MODE {ADDRESS, COMMAND, DATA};
+
+PROGRAMMING_MODE prgMode;
+
+void prgDemoPrg() {
+  byte value = EEPROM.read(0);
+  if (value == 0xFF) {
+    value = EEPROM.read(1);
+    if (value == 0xFF) {
+      for (byte i = 0; i < sizeof(demoPrg); i++) {
+        EEPROM.write(i, demoPrg[i]);
+      }
+    }
+  }
+}
+
+void programMode() {
+  // checking if advance programmer board connected?
+  doPort(0x08);
+  while (digitalRead(SW_PRG) == 0) {
+    // waiting for PRG to release
+  }
+  blinkAll();
+  prgMode = ADDRESS;
+  addr = 0;
+  do {
+    blinkD1();
+    // LoNibble Adresse anzeigen
+    doAddr(addr);
+    //delay(SHOW_DELAY);
+
+    blinkD2();
+    // HiNibble Adresse anzeigen
+    data = (addr & 0xf0) >> 4;                                  //Adresse anzeigen
+    doAddr(data);
+    //delay(SHOW_DELAY);
+
+    byte Eebyte = EEPROM.read(addr);
+    data = Eebyte & 15;
+    com = Eebyte >> 4;
+
+    blinkD3();
+    prgMode = COMMAND;
+    doPort(com); //show command
+
+    do {
+      if (digitalRead(SW_SEL) == 0) {
+        delay(KEY_DELAY);
+        com += 1;
+        com = com & 0x0F;
+        doPort(com);
+      }
+    }
+    while (digitalRead(SW_PRG) == 1);
+    delay(DEBOUNCE);
+
+    blinkD4();
+    prgMode = DATA;
+    doPort(data); //show data
+
+    do {
+      if (digitalRead(SW_SEL) == 0) {
+        delay(KEY_DELAY);
+        data += 1;
+        data = data & 0x0F;
+        doPort(data);
+      }
+    }
+    while (digitalRead(SW_PRG) == 1); // S2 = 1
+    delay(DEBOUNCE);
+
+    byte newValue = (com << 4) + data;
+    if (newValue != Eebyte) {
+      EEPROM.write(addr, newValue); //           Writeeeprom Eebyte , Addr
+      blinkAll();
+    }
+    addr += 1;
+  }
+  while (true);
+}
+
+void blinkAll() {
+  blinkNull();
+  doPort(0x0F);
+  delay(BLINK_DELAY);
+}
+
+void blinkD1() {
+  blinkNull();
+  doPort(0x01);
+  delay(BLINK_DELAY);
+  blinkNull();
+}
+
+void blinkD2() {
+  blinkNull();
+  doPort(0x02);
+  delay(BLINK_DELAY);
+  blinkNull();
+}
+
+void blinkD3() {
+  blinkNull();
+  doPort(0x04);
+  delay(BLINK_DELAY);
+  blinkNull();
+}
+
+void blinkD4() {
+  blinkNull();
+  doPort(0x08);
+  delay(BLINK_DELAY);
+  blinkNull();
+}
+
+void blinkNull() {
+  doPort(0x00);
+  delay(BLINK_DELAY);
+}
+
+void doAddr(byte value) {
+  for (byte i = ADDR_LOOP; i > 0; i--) {
+    doPort(value);
+    delay(19);
+    doPort(0x0F);
+    delay(1);
+  }
+}