subDesTagesMitExtraKaese 5 years ago
commit
e3b882a385
1 changed files with 303 additions and 0 deletions
  1. 303 0
      cube_control.ino

+ 303 - 0
cube_control.ino

@@ -0,0 +1,303 @@
+//Arduino\hardware\arduino\avr\cores\arduino
+#define SERIAL_RX_BUFFER_SIZE = 256
+
+#include <dataflash.h>
+#include <EEPROM.h>
+#include <TimerOne.h>
+
+int animationId = 0;
+unsigned long animationStart = 0;
+unsigned long animationLength = 0;
+unsigned long frameIndex = 0;
+bool animate = 0;
+Dataflash dflash; 
+
+unsigned char buf[32];
+
+byte zpin[4]={6,5,9,10}; // z axis on pwmable pins
+byte sw[3]={A4,A5,2}; // 3 switches
+unsigned long led[4][2];//led[plane] [regNo] = brightness + (ledNo(8) << 16)
+unsigned int brightness[16] = {0, 1, 257, 2113, 4369, 9361, 35476, 21833, 43690, 21931, 30422, 61142, 30583, 65518, 63479, 65535}; 
+
+void setup() {
+  Serial.begin(115200);
+ 
+  pinMode(A0, OUTPUT);//data
+  pinMode(A1, OUTPUT);//sck
+  pinMode(A2, OUTPUT);//rck
+  pinMode(A3, OUTPUT);//sclr
+
+  for(byte i=0; i<4; i++) {
+    pinMode(zpin[i], OUTPUT);
+  }
+  for(byte i=0; i<3; i++) {
+    pinMode(sw[i], INPUT_PULLUP);
+  }
+  attachInterrupt(0, ta3, FALLING );
+  //attachInterrupt(1, suspend, CHANGE );
+
+  digitalWrite(A3, 0);
+  digitalWrite(A3, 1);
+
+  Timer1.initialize(16667);
+  Timer1.attachInterrupt( timerIsr );
+
+  dflash.init();
+  Serial.println("AtMega168PA");
+}
+
+void loop() {
+  while(Serial.available()>=1) {
+    char com = Serial.read();
+    if(com == '~') {
+      if(waitForSerial(1)) return;
+      exec(Serial.read());
+    } else {
+      error("no cmd",com);
+    }
+  }
+  show();
+}
+void exec(byte com) {
+  if(com < 48) { //data
+    return;
+  }
+  else if(com == '`') { //set 1 led
+    if(waitForSerial(2)) return;
+    byte get[2]={Serial.read()-32,Serial.read()-32};
+    if(get[0]<64 && get[1]<16) {
+      set(get[0], get[1]);
+    }
+  } 
+  else if(com == 'a') {//set all leds
+    byte i = 0;
+    for(byte k=16; k<=64; k+=16) {
+      if(waitForSerial(16)) return;
+      while(i < k) {
+        set(i++, Serial.read()-32);
+      }
+    }
+  } 
+  else if(com == 'b') {//set eeprom 
+    if(waitForSerial(9)) return;//0:id, 1-4:start, 5-8:length
+    int i = Serial.read() * 8; //64 Id's
+    if(i>=512) {
+      error("EEPROM index", i);
+      return;
+    }
+    for(byte n=0;n<8;n++) {
+      EEPROM.write(i+n, Serial.read());
+    }
+  } 
+  else if(com == 'B') {//get eeprom 
+    //0-3:start, 4-7:length
+    //64 Id's
+    for(int i=0; i<64; i++) {
+      Serial.print(i);
+      Serial.print(',');
+      Serial.print(eepromReadLong(i*8));
+      Serial.print(',');
+      Serial.println(eepromReadLong(i*8+4));
+    }
+  } 
+  else if(com == 'c') {//set all leds to a value
+    if(waitForSerial(1)) return;
+    byte x = Serial.read()-32;
+    memset(led,x+(x<<4),sizeof(led));
+  } 
+  else if(com == 'd') {//dump buffer
+    for(byte i=0;i<16;i++)
+      debug(String(dflash.Buffer_Read_Byte(1,i*32)), i); 
+  } 
+  else if(com == 'g') {//get frame count
+    Serial.println(frameIndex); 
+  }
+  else if(com == 'h') {//set frame count
+    if(waitForSerial(4)) return;
+    frameIndex = readLong();
+    if(frameIndex >= 65536)
+      frameIndex = 0;
+    dflash.Page_To_Buffer(frameIndex/16, 2);
+    dflash.Buffer_Read_Str(2, (frameIndex % 16)*32, 32, buf);
+    for(byte i=0;i<8;i++) {
+      led[i>>1][i&1] = buf2Long(i*4);
+    }
+    
+  }
+  else
+  if(com == 's') {
+    animate = 1;
+    
+    if(waitForSerial(1)) return;
+     int i = Serial.read(); //64 Id's
+    if(i>=64) {
+      error("EEPROM index", i);
+      return;
+    }
+    animationId = i;
+    readAnim();
+  }
+  else if(com == 't') {
+    if(frameIndex<animationStart+animationLength)
+      animate = !animate;
+  }  
+  else if(com == 'u') {
+    animate = 0;
+    //readAnim();
+  }  
+  return;
+  if(com == 'x') {//load page to buffer 1
+    //4196 pages
+    if(waitForSerial(2)) return;
+    int i = readInt();
+    if(i>=4196) {
+      error("read page index", i);
+      return;
+    }
+    dflash.Page_To_Buffer(i, 1);
+  } 
+  else if(com == 'y') {//set pattern in buffer 1
+    if(waitForSerial(1)) return;
+    int i = Serial.read() * 32;//16
+    if(i>=512) {
+      error("buffer index", i);
+      return;
+    }
+    for(byte i=0;i<8;i++) {
+      buf[i*4]   = (led[i>>1][i&1]>>24)&0xff;
+      buf[i*4+1] = (led[i>>1][i&1]>>16)&0xff;
+      buf[i*4+2] = (led[i>>1][i&1]>>8)&0xff;
+      buf[i*4+3] = (led[i>>1][i&1])&0xff;
+    }
+    dflash.Buffer_Write_Str(1,i,32,buf);
+  } 
+  else if(com == 'z') {//write buffer 1 to page
+    /* 4bit/led * 64 = 32 byte
+       2097152 byte / 32 = 65536
+       18m12@60p/s
+       528/32=16.5
+     * 4196 pages
+     */
+    if(waitForSerial(2)) return;
+    int i = readInt();
+    if(i>=4196) {
+      error("write page index", i);
+      return;
+    }
+    dflash.Buffer_To_Page(1, i);
+    debug("buffer to page", i);
+  } 
+  else {
+    error("no cmd", com);
+  }
+}
+
+bool waitForSerial(byte n) {
+  unsigned long t = millis();
+  while(Serial.available()<n) { 
+    if(millis() - t > n * 2) {
+      error("timeout at byte", Serial.available());
+      return true;      
+    }
+    show();
+  }
+  return false;
+}
+unsigned int readInt() {
+  return (Serial.read()<<8)+(Serial.read());
+}
+unsigned long readLong() {
+  return (Serial.read()<<24)+(Serial.read()<<16)+(Serial.read()<<8)+(Serial.read());
+}
+unsigned long eepromReadLong(int addr) {
+  return ((unsigned long)EEPROM.read(addr)<<24)+
+          ((unsigned long)EEPROM.read(addr+1)<<16)+
+          ((unsigned long)EEPROM.read(addr+2)<<8)+
+          ((unsigned long)EEPROM.read(addr+3));
+}
+unsigned long buf2Long(byte addr) {
+  return ((unsigned long)buf[addr]<<24)+
+          ((unsigned long)buf[addr+1]<<16)+
+          ((unsigned long)buf[addr+2]<<8)+
+          ((unsigned long)buf[addr+3]);
+}
+void set(byte i, unsigned long b) {
+  led[i>>4][(i&B100)>>2] &= ~((unsigned long)0xf << (((i&B11) << 3) + ((i&B1000)>>1)));
+  led[i>>4][(i&B100)>>2] |= (b&B1111) << (((i&B11) << 3) + ((i&B1000)>>1));
+}
+void add(byte x, byte y, byte z, unsigned long b) {
+  led[z][y%2] += b << (x*8+y*2);
+}
+void show() {
+  byte hOld = 3;
+   for(byte i=0;i<16;i++) { //brightnesses
+    for(byte h=0;h<4;h++) { //z axis
+      for(byte k=0;k<8; k++) {
+        PORTC |= (brightness[(led[h][0] >> (k<<2)) & 0xf] >> i) & 1;
+        PORTC |= B00000010;
+        PORTC &= B11111100;
+        PORTC |= (brightness[(led[h][1] >> (k<<2)) & 0xf] >> i) & 1;
+        PORTC |= B00000010;
+        PORTC &= B11111100;
+      }
+      
+      digitalWrite(zpin[hOld],0);
+      PORTC |= B00000100;
+      PORTC &= B11111011;
+      digitalWrite(zpin[h],1);
+      hOld = h;
+      delayMicroseconds(5);
+    }
+  }
+}
+
+void suspend() {
+  Serial.println("ISR: suspend");
+}
+void ta3() {
+  readAnim();
+  if(++animationId==64 || animationLength == 0) animationId = 0;
+  if(animationLength == 0) {
+    animate=0;
+    memset(led,0,sizeof(led));
+  } else {
+    animate=1;    
+  }
+}
+void readAnim() {
+  animationStart = eepromReadLong(animationId*8);
+  animationLength = eepromReadLong(animationId*8+4);
+  debug("Animation Id:", animationId);
+  debug("Start:", animationStart);
+  debug("length:", animationLength);
+  frameIndex=animationStart;
+}
+
+void timerIsr() {
+  if(animate) {
+    if(frameIndex >= 65536) frameIndex = 0;
+    if(frameIndex % 4 == 0) dflash.Page_To_Buffer(frameIndex/4, 2);
+    dflash.Buffer_Read_Str(2, (frameIndex % 4)*32, 32, buf);
+    for(byte i=0;i<8;i++) {
+      led[i>>1][i&1] = buf2Long(i*4);
+    }
+    frameIndex++;
+    if(frameIndex>=animationStart+animationLength) {
+      animate = 0;
+      memset(led,0,sizeof(led));
+      debug("animation stopped", frameIndex);
+    }
+  }
+}
+void error(const String& txt, const uint32_t& val) {
+   Serial.print("ERR: ");
+   Serial.print(txt);
+   Serial.print(" ");
+   Serial.println(val);
+}
+void debug(const String& txt, const uint32_t& val) {
+   Serial.print("DEBUG: ");
+   Serial.print(txt);
+   Serial.print(" ");
+   Serial.println(val);
+}