Problem mit Pointer

Hallo,

habe mal wieder Probleme mit, na was schon, Pointern ^^
Ich versuche mich an einem Sequencer für LED-Effekte im Rythmus der Musik.
Der Takt wird bestimmt durch SeqBpmSet bzw. SeqBpm welcher aber innerhalb einer Sequenz auch verdoppelt etc. oder auch mal halbiert werden kann.
Diese Unterfunktionen werden von dem “Fernbedienungscontroller”. welcher sowieso schon per TWI dem “LED-Controller”, beides süsse, kleine A-Star 32u4, dekodierte Tastencodes und auch komplette Befehle sendet ausgeführt und soll dem LED-Controller sagen was er machen soll.
Im LED-Controller habe ich bereits passende “Empfangsroutinen” geschrieben aber irgend wie bringe ich das mit dem Sequencepointer “SeqPtr” mal wieder nicht ans laufen (keine Ahnung wo der hin pointet ^^).
Hier der Codes:

#define uint unsigned int
#define ulong unsigned long

byte *SeqPtr;
volatile byte TSeq;

uint SeqBeats, SeqReg[11], SeqBpmSet, SeqBpm;

#define ssc 242
#define ssl 241
#define ssw 240
#define ssbpm 239
#define sEnd 238
#define srep 237
#define sbpmdouble 236
#define sbpmquad 235
#define sbpmhalf 234
#define sbpmquarter 233
#define sbpmnormal 232

const PROGMEM byte Seq1 []= {
  ssbpm,480>>8,480&255,
  ssc,0,200,255, ssl,0,0,0,79,
  ssc,0,0,255,   ssl,0,80,0,159,
  ssc,0,200,255, ssl,0,160,0,239,
  ssc,0,0,255,   ssl,0,240,320>>8,320&255,
  ssw,
  ssc,0,200,255, ssl,0,0,0,19,
  ssc,0,0,255,   ssl,0,20,0,99,
  ssc,0,200,255, ssl,0,100,0,179,
  ssc,0,0,255,   ssl,0,180,259>>8,259&255,
  ssc,0,200,255, ssl,260>>8,260&255,339>>8,339&255,
  ssw,
  ssc,0,200,255, ssl,0,0,0,39,
  ssc,0,0,255,   ssl,0,40,0,119,
  ssc,0,200,255, ssl,0,120,0,199,
  ssc,0,0,255,   ssl,0,200,279>>8,279&255,
  ssw,
  ssc,0,200,255, ssl,0,0,0,59,
  ssc,0,0,255,   ssl,0,60,0,139,
  ssc,0,200,255, ssl,0,140,0,219,
  ssc,0,0,255,   ssl,0,220,299>>8,299&255,
  ssw,
  srep
};

void sequencerStart(){
  SeqPtr=Seq1;
  SeqReg[0]=1;
  SeqReg[1]=65535;
  SeqReg[2]=SeqPtr;
}
void sequencer(){
  byte a=pgm_read_byte(*SeqPtr);
  if(a==ssw){
    byte Timer=TSeq;
    cli();
    TSeq-=Timer;
    sei();
    SeqBeats+=SeqBpm*Timer;
    if(SeqBeats>=60000){
      SeqBeats-=60000;
      sendSeqSwitch(25);
      SeqPtr++;
    }
  }
  if(a==ssbpm){SeqBpmSet=*(++SeqPtr)<<8+*(++SeqPtr);SeqBpm=SeqBpmSet;SeqPtr++;}
  if(a==sbpmnormal){SeqBpm=SeqBpmSet;SeqPtr++;}
  if(a==sbpmdouble){SeqBpm=SeqBpmSet<<1;SeqPtr++;}
  if(a==sbpmquad){SeqBpm=SeqBpmSet<<2;SeqPtr++;}
  if(a==sbpmhalf){SeqBpm=SeqBpmSet>>1;SeqPtr++;}
  if(a==sbpmquarter){SeqBpm=SeqBpmSet>>2;SeqPtr++;}

  if(a==ssc){
    sendCom(ssc,4,*(++SeqPtr)<<16+*(++SeqPtr)<<8+*(++SeqPtr),1);
    SeqPtr++;
  }
  if(a==ssl){
    sendCom(ssl,4,*(++SeqPtr)<<24+*(++SeqPtr)<<16+*(++SeqPtr)<<8+*(++SeqPtr),1);
    SeqPtr++;
  }

  if(a==srep){
    uint b=SeqReg[0];
    if(SeqReg[b]==65535){
      SeqPtr=SeqReg[b+1];
    }else{
      if(SeqReg[b]>0){
        SeqReg[b]--;
        SeqPtr=SeqReg[b+1];
      }else{
        if(b>1){
          b-=2;
          SeqPtr=SeqReg[b+1];
          SeqReg[0]=b;
        }
      }
    }
  }
}

Vielleicht kann jemand drüber gucken und mir mitteilen wie ich wo den (Dr…)Pointer setzen und steuern muss.

Vielen Dank im Voraus

MfG
Andi

Ohhh, man.
Ich, ähm, verdammt. Muss ja im Flash auch für die Parameter mit read_pgm_byte vorgehen, oh jemine.
OK, alles klar. Passt schon und danke ^^

MfG
Andi

Dein sequencer wäre als switch case besser zu lesen und würde nicht immer alle Möglichkeiten durchtesten.

Da du ja die pgm_read_… Funktionen benutzen musst/willst, kannst du dir auch eine Menge an Shift/Combines sparen,
es gibt da ja auch Varianten die mehr als ein Byte lesen.

sendCom(ssl,4,*(++SeqPtr)<<24+*(++SeqPtr)<<16+*(++SeqPtr)<<8+*(++SeqPtr),1);

sendCom(ssl, 4, pgm_read_dword(SeqPtr)); SeqPtr +=4;

Macro pgm_read_byte_near
Macro pgm_read_word_near
Macro pgm_read_dword_near
Macro pgm_read_float_near
Macro pgm_read_ptr_near

Aus AVRLibcReferenceManual

Hi,

schön das du da bist ^^
Das mit dem Pointer krieg ich doch nicht einfach so hin.
Ich weis nicht, ob ich ihn in sequencerStart falsch setze oder ich ihn falsch bewege oder beides.
Hier noch mal die letzten Änderungen:

#define uint unsigned int
#define ulong unsigned long

byte *SeqPtr;
volatile byte TSeq;

uint SeqBeats, SeqReg[11], SeqBpmSet, SeqBpm;

#define ssc 242
#define ssl 241
#define ssw 240
#define ssbpm 239
#define sEnd 238
#define srep 237
#define sbpmdouble 236
#define sbpmquad 235
#define sbpmhalf 234
#define sbpmquarter 233
#define sbpmnormal 232

const PROGMEM byte Seq1 []= {
  ssbpm,480>>8,480&255,
  ssc,0,200,255, ssl,0,0,0,79,
  ssc,0,0,255,   ssl,0,80,0,159,
  ssc,0,200,255, ssl,0,160,0,239,
  ssc,0,0,255,   ssl,0,240,320>>8,320&255,
  ssw,
  ssc,0,200,255, ssl,0,0,0,19,
  ssc,0,0,255,   ssl,0,20,0,99,
  ssc,0,200,255, ssl,0,100,0,179,
  ssc,0,0,255,   ssl,0,180,259>>8,259&255,
  ssc,0,200,255, ssl,260>>8,260&255,339>>8,339&255,
  ssw,
  ssc,0,200,255, ssl,0,0,0,39,
  ssc,0,0,255,   ssl,0,40,0,119,
  ssc,0,200,255, ssl,0,120,0,199,
  ssc,0,0,255,   ssl,0,200,279>>8,279&255,
  ssw,
  ssc,0,200,255, ssl,0,0,0,59,
  ssc,0,0,255,   ssl,0,60,0,139,
  ssc,0,200,255, ssl,0,140,0,219,
  ssc,0,0,255,   ssl,0,220,299>>8,299&255,
  ssw,
  srep
};

void sequencerStart(){
  *SeqPtr=&Seq1;
  SeqReg[0]=1;
  SeqReg[1]=65535;
  SeqReg[2]=SeqPtr;
}
byte SeqRead(byte *Ptr){
  return pgm_read_byte(Ptr);
}
void sequencer(){
  byte a=SeqRead(SeqPtr);
  if(a==ssw){
    byte Timer=TSeq;
    cli();
    TSeq-=Timer;
    sei();
    SeqBeats+=SeqBpm*Timer;
    if(SeqBeats>=60000){
      SeqBeats-=60000;
      sendCom(ssw,0,0,25);
      SeqPtr++;
    }
  }
  if(a==ssbpm){SeqBpmSet=SeqRead(++SeqPtr)<<8+SeqRead(++SeqPtr);SeqBpm=SeqBpmSet;SeqPtr++;}
  if(a==sbpmnormal){SeqBpm=SeqBpmSet;SeqPtr++;}
  if(a==sbpmdouble){SeqBpm=SeqBpmSet<<1;SeqPtr++;}
  if(a==sbpmquad){SeqBpm=SeqBpmSet<<2;SeqPtr++;}
  if(a==sbpmhalf){SeqBpm=SeqBpmSet>>1;SeqPtr++;}
  if(a==sbpmquarter){SeqBpm=SeqBpmSet>>2;SeqPtr++;}

  if(a==ssc){sendCom(ssc,4,SeqRead(++SeqPtr)<<16+SeqRead(++SeqPtr)<<8+SeqRead(++SeqPtr),1);SeqPtr++;}
  if(a==ssl){sendCom(ssl,4,SeqRead(++SeqPtr)<<8+SeqRead(++SeqPtr)+SeqRead(++SeqPtr)<<24+SeqRead(++SeqPtr)<<16,1);SeqPtr++;}

  if(a==srep){
    uint b=SeqReg[0];
    if(SeqReg[b]==65535){
      SeqPtr=SeqReg[b+1];
    }else{
      if(SeqReg[b]>0){
        SeqReg[b]--;
        SeqPtr=SeqReg[b+1];
      }else{
        if(b>1){
          b-=2;
          SeqPtr=SeqReg[b+1];
          SeqReg[0]=b;
        }
      }
    }
  }
}

Das mit dem Switch->Case ist schon klar, aber erst mal muss das laufen.
Das ist ja auch erst mal der Anfang, mir schweben sämtliche Features im Kopf rum aber der Compiler mag mich nicht ^^

MfG
Andi

Siehst Du, wir haben Dir geholfen ( auch wenn wir nur zugehört haben). :wink: :wink: :smiley: :smiley:
siehe auch Rubber duck debugging - Wikipedia

Grüße Uwe

uwefed:
Siehst Du, wir haben Dir geholfen ( auch wenn wir nur zugehört haben). :wink: :wink: :smiley: :smiley:
siehe auch Rubber duck debugging - Wikipedia

Grüße Uwe

Ähm, nö.
Ich schnall das mit dem Pointer nicht richtig.
Bitte schau mal drüber, bin am verzweifeln.

MfG
Andi

Es scheint ein Problem mit deinem rep zu geben, dein Pointer verlässt dabei den Array.

Ich habe mal etwas Kode ergänzt um es kompilieren zu können, der Timer ist natürlich nur gefakt.

Die Endianness der Parameter habe ich auf verarbeitungsfreudige little-endian geändert,
bei den Doppelparametern ist das zu berücksichtigen.

#define uint unsigned int
#define ulong unsigned long

const byte *SeqPtr;
volatile byte TSeq;

uint SeqBeats, SeqReg[11], SeqBpmSet, SeqBpm;

#define ssc 242
#define ssl 241
#define ssw 240
#define ssbpm 239
#define sEnd 238
#define srep 237
#define sbpmdouble 236
#define sbpmquad 235
#define sbpmhalf 234
#define sbpmquarter 233
#define sbpmnormal 232

const PROGMEM byte Seq1 [] = {
  ssbpm, 480 & 255, 480 >> 8,
  ssc, 255, 200, 0, ssl, 79, 0, 0, 0,
  ssc, 255, 0, 0,   ssl, 159, 0, 80, 0,
  ssc, 255, 200, 0, ssl, 239, 0, 160, 0,
  ssc, 255, 0, 0,   ssl, 320 & 0xFF, 320 >> 8, 240, 0,
  ssw,
  ssc, 255, 200, 0, ssl, 19, 0, 0, 0,
  ssc, 255, 0, 0,   ssl, 99, 0, 20, 0,
  ssc, 255, 200, 0, ssl, 179, 0, 100, 0,
  ssc, 255, 0, 0,   ssl, 259 & 0xFF, 259 >> 8, 180, 0,
  ssc, 255, 200, 0, ssl, 339 & 0xFF, 339 >> 8, 260 & 255, 260 >> 8,
  ssw,
  ssc, 255, 200, 0, ssl, 39, 0, 0, 0,
  ssc, 255, 0, 0,   ssl, 119, 0, 40, 0,
  ssc, 255, 200, 0, ssl, 199, 0, 120, 0,
  ssc, 255, 0, 0,   ssl, 279 & 0xFF, 279 >> 8, 200, 0,
  ssw,
  ssc, 255, 200, 0, ssl, 0, 0, 0, 59,
  ssc, 255, 0, 0,   ssl, 0, 60, 0, 139,
  ssc, 255, 200, 0, ssl, 0, 140, 0, 219,
  ssc, 255, 0, 0,   ssl, 299 & 0xFF, 299 >> 8, 220, 0,
  ssw,
  srep
};

void sequencerStart() {
  SeqPtr = Seq1;  // oder &Seq[0]
  SeqReg[0] = 1;
  SeqReg[1] = 65535;
  SeqReg[2] = (uint)SeqPtr;
}

byte SeqRead(const byte *Ptr) {
  return pgm_read_byte(Ptr);
}

void sequencer() {
  byte Timer = TSeq;
  uint b = SeqReg[0];
  switch (pgm_read_byte_near(SeqPtr++)) {  // Kommando Byte lesen und Zeiger auf eventuelle Parameter setzen
    case ssw: // keine Parameter
      showEntry(SeqPtr, 1);
      cli();
      TSeq -= Timer;
      sei();
      SeqBeats += SeqBpm * Timer;
      if (SeqBeats >= 60000) {
        SeqBeats -= 60000;
        sendCom(ssw, 0, 0, 25);
      }
      break;
    case ssbpm: // ein unsigned
      showEntry(SeqPtr, 3);
      SeqBpm = SeqBpmSet = pgm_read_word_near(SeqPtr);;
      SeqPtr += 2;
      break;
    case sbpmnormal:  // keine Parameter
      showEntry(SeqPtr, 1);
      SeqBpm = SeqBpmSet;
      break;
    case sbpmdouble:  // keine Parameter
      showEntry(SeqPtr, 1);
      SeqBpm = SeqBpmSet << 1;
      break;
    case sbpmquad:  // keine Parameter
      showEntry(SeqPtr, 1);
      SeqBpm = SeqBpmSet << 2;
      break;
    case sbpmhalf:  // keine Parameter
      showEntry(SeqPtr, 1);
      SeqBpm = SeqBpmSet >> 1;
      break;
    case sbpmquarter: // keine Parameter
      showEntry(SeqPtr, 1);
      SeqBpm = SeqBpmSet >> 2;
      break;
    case ssc: // 3 Byte
      showEntry(SeqPtr, 4);
      sendCom(ssc, 4, pgm_read_word_near(SeqPtr) | (((unsigned long)pgm_read_byte_near(SeqPtr + 2)) << 16), 1);
      SeqPtr += 3;
      break;
    case ssl: // 4 Byte
      showEntry(SeqPtr, 5);
      sendCom(ssl, 4, pgm_read_dword_near(SeqPtr), 1);
      SeqPtr += 4;
      break;
    case srep:  // keine Parameter
      showEntry(SeqPtr, 1);
      b = SeqReg[0];
      if (SeqReg[b] == 0xFFFF) {
        SeqPtr = (const byte*)SeqReg[b + 1];
      } else {
        if (SeqReg[b] > 0) {
          SeqReg[b]--;
          SeqPtr = (const byte*)SeqReg[b + 1];
        } else {
          if (b > 1) {
            b -= 2;
            SeqPtr = (const byte*)SeqReg[b + 1];
            SeqReg[0] = b;
          }
        }
      }
      break;
    default:
      Serial.print(F("unknown "));
      showEntry(SeqPtr, 1);
      break;
  }
}

void setup() {
  Serial.begin(250000);
  sequencerStart();
  for (int tests = 0; tests < 300; tests++) {
    TSeq = 20;
    sequencer();
  }
}

void loop() {}

void sendCom(byte p1, byte p2, unsigned long value, byte p3) {
  Serial.print(F("sendCom(0x"));
  Serial.print(p1, HEX);
  Serial.print(F(", 0x"));
  Serial.print(p2, HEX);
  Serial.print(F(", 0x"));
  Serial.print(value, HEX);
  Serial.print(F(", 0x"));
  Serial.print(p3, HEX);
  Serial.println(F(");"));
}


void showEntry(const byte* pMem, byte total) {
  if (pMem < Seq1) {
    Serial.print(F("vor dem Array "));
  } else if (((unsigned int)(pMem - Seq1)) >= sizeof(Seq1)) {
    Serial.print(F("hinter dem Array "));
  }
  aWord((unsigned int)pMem);
  Serial.write(':');
  while (total--) {
    Serial.write(' ');
    aByte(pgm_read_byte_near(pMem++));
  }
  Serial.println();
}

void aNibble(byte val) {
  val &= 0xF;
  Serial.write(val < 10 ? '0' + val : 'A' + val - 10);
}

void aByte(byte val) {
  aNibble(val >> 4);
  aNibble(val);
}

void aWord(unsigned int val) {
  aByte(val >> 8);
  aByte(val);
}
0139: E0 01 F2
013C: FF C8 00 F1
sendCom(0xF2, 0x4, 0xC8FF, 0x1);
0140: 4F 00 00 00 F2
sendCom(0xF1, 0x4, 0x4F, 0x1);
0145: FF 00 00 F1
sendCom(0xF2, 0x4, 0xFF, 0x1);
0149: 9F 00 50 00 F2
sendCom(0xF1, 0x4, 0x50009F, 0x1);
014E: FF C8 00 F1
sendCom(0xF2, 0x4, 0xC8FF, 0x1);
0152: EF 00 A0 00 F2
sendCom(0xF1, 0x4, 0xA000EF, 0x1);
0157: FF 00 00 F1
sendCom(0xF2, 0x4, 0xFF, 0x1);
015B: 40 01 F0 00 F0
sendCom(0xF1, 0x4, 0xF00140, 0x1);
0160: F2
0161: FF C8 00 F1
sendCom(0xF2, 0x4, 0xC8FF, 0x1);
0165: 13 00 00 00 F2
sendCom(0xF1, 0x4, 0x13, 0x1);
016A: FF 00 00 F1
sendCom(0xF2, 0x4, 0xFF, 0x1);
016E: 63 00 14 00 F2
sendCom(0xF1, 0x4, 0x140063, 0x1);
0173: FF C8 00 F1
sendCom(0xF2, 0x4, 0xC8FF, 0x1);
0177: B3 00 64 00 F2
...
01CF: FF 00 00 F1
sendCom(0xF2, 0x4, 0xFF, 0x1);
01D3: 2B 01 DC 00 F0
sendCom(0xF1, 0x4, 0xDC012B, 0x1);
01D8: ED
hinter dem Array 01D9: 75
0139: E0 01 F2
013C: FF C8 00 F1
sendCom(0xF2, 0x4, 0xC8FF, 0x1);
0140: 4F 00 00 00 F2
sendCom(0xF1, 0x4, 0x4F, 0x1);
...

Das hatte hauptsächlich Quatsch gedruckt und auch einen falschen Alarm ausgelöst.

Neuer Versuch:

#define uint unsigned int
#define ulong unsigned long

const byte *SeqPtr;
volatile byte TSeq;

uint SeqBeats, SeqReg[11], SeqBpmSet, SeqBpm;

#define ssc 242
#define ssl 241
#define ssw 240
#define ssbpm 239
#define sEnd 238
#define srep 237
#define sbpmdouble 236
#define sbpmquad 235
#define sbpmhalf 234
#define sbpmquarter 233
#define sbpmnormal 232

const PROGMEM byte Seq1 [] = {
  ssbpm, 480 & 255, 480 >> 8,
  ssc, 255, 200, 0, ssl, 79, 0, 0, 0,
  ssc, 255, 0, 0,   ssl, 159, 0, 80, 0,
  ssc, 255, 200, 0, ssl, 239, 0, 160, 0,
  ssc, 255, 0, 0,   ssl, 320 & 0xFF, 320 >> 8, 240, 0,
  ssw,
  ssc, 255, 200, 0, ssl, 19, 0, 0, 0,
  ssc, 255, 0, 0,   ssl, 99, 0, 20, 0,
  ssc, 255, 200, 0, ssl, 179, 0, 100, 0,
  ssc, 255, 0, 0,   ssl, 259 & 0xFF, 259 >> 8, 180, 0,
  ssc, 255, 200, 0, ssl, 339 & 0xFF, 339 >> 8, 260 & 255, 260 >> 8,
  ssw,
  ssc, 255, 200, 0, ssl, 39, 0, 0, 0,
  ssc, 255, 0, 0,   ssl, 119, 0, 40, 0,
  ssc, 255, 200, 0, ssl, 199, 0, 120, 0,
  ssc, 255, 0, 0,   ssl, 279 & 0xFF, 279 >> 8, 200, 0,
  ssw,
  ssc, 255, 200, 0, ssl, 0, 0, 0, 59,
  ssc, 255, 0, 0,   ssl, 0, 60, 0, 139,
  ssc, 255, 200, 0, ssl, 0, 140, 0, 219,
  ssc, 255, 0, 0,   ssl, 299 & 0xFF, 299 >> 8, 220, 0,
  ssw,
  srep
};

void sequencerStart() {
  SeqPtr = Seq1;  // oder &Seq[0]
  SeqReg[0] = 1;
  SeqReg[1] = 65535;
  SeqReg[2] = (uint)SeqPtr;
}

void sequencer() {
  byte Timer = TSeq;
  uint b;
  switch (pgm_read_byte_near(SeqPtr++)) {  // Kommando Byte lesen und Zeiger auf eventuelle Parameter setzen
    case ssw: // keine Parameter
      showEntry(SeqPtr-1, 1);
      cli();
      TSeq -= Timer;
      sei();
      SeqBeats += SeqBpm * Timer;
      if (SeqBeats >= 60000) {
        SeqBeats -= 60000;
        sendCom(ssw, 0, 0, 25);
      }
      break;
    case ssbpm: // ein unsigned
      showEntry(SeqPtr-1, 3);
      SeqBpm = SeqBpmSet = pgm_read_word_near(SeqPtr);;
      SeqPtr += 2;
      break;
    case sbpmnormal:  // keine Parameter
      showEntry(SeqPtr-1, 1);
      SeqBpm = SeqBpmSet;
      break;
    case sbpmdouble:  // keine Parameter
      showEntry(SeqPtr-1, 1);
      SeqBpm = SeqBpmSet << 1;
      break;
    case sbpmquad:  // keine Parameter
      showEntry(SeqPtr-1, 1);
      SeqBpm = SeqBpmSet << 2;
      break;
    case sbpmhalf:  // keine Parameter
      showEntry(SeqPtr-1, 1);
      SeqBpm = SeqBpmSet >> 1;
      break;
    case sbpmquarter: // keine Parameter
      showEntry(SeqPtr-1, 1);
      SeqBpm = SeqBpmSet >> 2;
      break;
    case ssc: // 3 Byte
      showEntry(SeqPtr-1, 4);
      sendCom(ssc, 4, pgm_read_word_near(SeqPtr) | (((unsigned long)pgm_read_byte_near(SeqPtr + 2)) << 16), 1);
      SeqPtr += 3;
      break;
    case ssl: // 4 Byte
      showEntry(SeqPtr-1, 5);
      sendCom(ssl, 4, pgm_read_dword_near(SeqPtr), 1);
      SeqPtr += 4;
      break;
    case srep:  // keine Parameter
      showEntry(SeqPtr-1, 1);
      b = SeqReg[0];
      if (SeqReg[b] == 0xFFFF) {
        SeqPtr = (const byte*)SeqReg[b + 1];
      } else {
        if (SeqReg[b] > 0) {
          SeqReg[b]--;
          SeqPtr = (const byte*)SeqReg[b + 1];
        } else {
          if (b > 1) {
            b -= 2;
            SeqPtr = (const byte*)SeqReg[b + 1];
            SeqReg[0] = b;
          }
        }
      }
      break;
    default:
      Serial.print(F("unknown "));
      showEntry(SeqPtr-1, 1);
      break;
  }
}

void setup() {
  Serial.begin(250000);
  sequencerStart();
  for (int tests = 0; tests < 300; tests++) {
    TSeq = 20;
    sequencer();
  }
}

void loop() {}

void sendCom(byte p1, byte p2, unsigned long value, byte p3) {
  Serial.print(F("sendCom(0x"));
  Serial.print(p1, HEX);
  Serial.print(F(", 0x"));
  Serial.print(p2, HEX);
  Serial.print(F(", 0x"));
  Serial.print(value, HEX);
  Serial.print(F(", 0x"));
  Serial.print(p3, HEX);
  Serial.println(F(");"));
}

void showEntry(const byte* pMem, byte total) {
  if (pMem < Seq1) {
    Serial.print(F("vor dem Array "));
  } else if (((unsigned int)(pMem - Seq1)) >= sizeof(Seq1)) {
    Serial.print(F("hinter dem Array "));
  }
  aWord((unsigned int)pMem);
  Serial.write(':');
  while (total--) {
    Serial.write(' ');
    aByte(pgm_read_byte_near(pMem++));
  }
  Serial.println();
}

void aNibble(byte val) {
  val &= 0xF;
  Serial.write(val < 10 ? '0' + val : 'A' + val - 10);
}

void aByte(byte val) {
  aNibble(val >> 4);
  aNibble(val);
}

void aWord(unsigned int val) {
  aByte(val >> 8);
  aByte(val);
}
0138: EF E0 01
013B: F2 FF C8 00
sendCom(0xF2, 0x4, 0xC8FF, 0x1);
013F: F1 4F 00 00 00
sendCom(0xF1, 0x4, 0x4F, 0x1);
0144: F2 FF 00 00
sendCom(0xF2, 0x4, 0xFF, 0x1);
0148: F1 9F 00 50 00
sendCom(0xF1, 0x4, 0x50009F, 0x1);
014D: F2 FF C8 00
sendCom(0xF2, 0x4, 0xC8FF, 0x1);
0151: F1 EF 00 A0 00
sendCom(0xF1, 0x4, 0xA000EF, 0x1);
0156: F2 FF 00 00
sendCom(0xF2, 0x4, 0xFF, 0x1);
015A: F1 40 01 F0 00
sendCom(0xF1, 0x4, 0xF00140, 0x1);
015F: F0
0160: F2 FF C8 00
sendCom(0xF2, 0x4, 0xC8FF, 0x1);
0164: F1 13 00 00 00
sendCom(0xF1, 0x4, 0x13, 0x1);
0169: F2 FF 00 00
sendCom(0xF2, 0x4, 0xFF, 0x1);
016D: F1 63 00 14 00
sendCom(0xF1, 0x4, 0x140063, 0x1);
0172: F2 FF C8 00
sendCom(0xF2, 0x4, 0xC8FF, 0x1);
0176: F1 B3 00 64 00
sendCom(0xF1, 0x4, 0x6400B3, 0x1);
017B: F2 FF 00 00
sendCom(0xF2, 0x4, 0xFF, 0x1);
017F: F1 03 01 B4 00
sendCom(0xF1, 0x4, 0xB40103, 0x1);
0184: F2 FF C8 00
sendCom(0xF2, 0x4, 0xC8FF, 0x1);
0188: F1 53 01 04 01
sendCom(0xF1, 0x4, 0x1040153, 0x1);

OK, läuft.

Von wegen Problem mit Pointer, eher mit den Augen ^^
Hatte beim Empfänger die Abfrage für die Ausgabe auf die LEDs in die Abfrage zum Linie ziehen mit drin.
Eine Zeile zu weit oben vor die Klammer statt danach :frowning:
Da kommt dann nix ^^
Natürlich geht man erst mal auf das los was man noch nicht wirklich gut kann :slight_smile:

Jedenfalls, vielen Dank für die Mühe

MfG
Andi

Hallo mal wieder ^^

der Sequencer kommt zwar voran aber ich stolper doch schon wieder über den Umgang mit Pointern.
Z. B. hier (siehe scall):

const PROGMEM byte Seq1_2 []= {
  sspos,0,0, sucr,0, ssl,40,0, sloop,3,0, sucr,1, ssl,40,0, sucr,0, ssl,40,0, srep, ssw, sEnd
};

const PROGMEM byte Seq1_3 []= {
  sloop,3,0, sucr,0, ssl,40,0, sucr,1, ssl,40,0, srep, sucr,0, ssl,40,0, ssw, sEnd
};

const PROGMEM byte Seq1_1 []= {
  ssbpm,480,480>>8,
  sscr,0,0,200,255,
  sscr,1,255,0,55,
  sbpmdouble,

  scall,*Seq1_2,(*Seq1_2)>>8,
  sspos,0,0, sucr,1, ssl,10,0, scall,*Seq1_3,(*Seq1_3)>>8,
  sspos,0,0, sucr,1, ssl,20,0, scall,*Seq1_3,(*Seq1_3)>>8,
  sspos,0,0, sucr,1, ssl,30,0, scall,*Seq1_3,(*Seq1_3)>>8,
  sscr,1,0,200,255,
  sscr,0,255,0,55,
  scall,*Seq1_2,(*Seq1_2)>>8,
  sspos,0,0, sucr,1, ssl,10,0, scall,*Seq1_3,(*Seq1_3)>>8,
  sspos,0,0, sucr,1, ssl,20,0, scall,*Seq1_3,(*Seq1_3)>>8,
  sspos,0,0, sucr,1, ssl,30,0, scall,*Seq1_3,(*Seq1_3)>>8,
  srep
};

Ist es möglich in einem Block const PROGMEM byte, in diesem Fall für Sequencen, die low- und high-Bytes der Adressen von anderen Sequenceblöcken im Flash einzutragen?
Weis nicht wie ich das dem Compiler erklären soll, das die Parameter nach einem "scall" die Startadresse von anderen Konstanten im Flash sind.

Vielen Dank schon mal

MfG
Andi

Haribo68:
Ist es möglich in einem Block const PROGMEM byte, in diesem Fall für Sequencen, die low- und high-Bytes der Adressen von anderen Sequenceblöcken im Flash einzutragen?
Weis nicht wie ich das dem Compiler erklären soll, das die Parameter nach einem "scall" die Startadresse von anderen Konstanten im Flash sind.

Da sind wir schon zwei.

Nimm statt der Adressen den Index von einer Adresstabelle,
macht dein Kommando ein Byte kürzer und sollte funktionieren.

Schön ist anders... aber es würde gehen.

const byte mess1[] PROGMEM = "eins";
const byte mess2[] PROGMEM = "zwei";

const byte * const hTabelle[] PROGMEM = {
  mess1,
  mess2,
};

const byte table[] PROGMEM = {
  'e', 0, // cmd, index
  'z', 1,
};

void setup() {
  Serial.begin(250000);
  Serial.println((__FlashStringHelper*)pgm_read_word(hTabelle + pgm_read_byte(table + 1)));
  Serial.println((__FlashStringHelper*)pgm_read_word(hTabelle + pgm_read_byte(table + 3)));
}
void loop() {}

Super, danke, hat geklapt.
Dachte mir auch schon, dass das nur über eine weitere Tabelle geht.
Es war ja geplant das man aus einer Sequenz in eine andere Sequenz “springt” und aus dieser zurückkehrt.
Habe das nun so gelöst das alle nötigen Sequenzen in der Adresstabelle stehen. Die Verzweigung wird dann über einen relativen Index in der Adresstabelle durchgeführt und Untersequenzen welche andere Sequenzen aufrufen bleiben dann zusammen.

Hier der neue Code:

#define uint unsigned int
#define ulong unsigned long

byte SeqBeatCount, SeqNextBeatCount, SeqPause, SeqLevel, SRIndex, *SeqPtr, *SeqPtrArray, SRLoop[20], SRColor[16*3];
uint SRPtr[20], SeqBpm, SRCtrl[16];
ulong SeqBeats;

#define ssetCol 242       //Sequencer Set Color (R,G,B)
#define ssetPos 241       //Sequencer Set Position (X(low,high))
#define saddPos 240       //Sequencer Add Position (X)
#define ssetL 239         //Sequencer Set Line with (lenght(low,high))
#define ssetLA 238        //Sequencer Set Line Absolute (Start(low,high), End(low,high)
#define ssetLR 237        //Sequencer Set two Repeated Lines (lenght(low,high),Colorregister)
#define sDim 236          //Sequencer Dim all Pixel (Transparence)
#define ssw 235           //Sequencer Switch to LEDs
#define sPause 234        //Sequencer Pause n Beats (Pause)
#define ssetBPM 233       //Sequencer Set Beats per Minute (BpM (low,high)
#define sBPMhalf 232      //Sequencer half of Beats per Minute
#define sBPMquarter 231   //Sequencer quarter of Beats per Minute
#define sBPMnormal 230    //Sequencer normal Beats per Minute there are set with ssbpm
#define ssetColR 229      //Sequencer Set Color Register (Register,R,G,B)
#define suseColR 228      //Sequencer Use Color Register (Register)
#define sLoop 227         //Sequencer Loop (Loopings)
#define sRep 226          //Sequencer Repeat to Loop
#define sCall 225         //Sequencer Call to Sequence (Sequencenumber relative)
#define sEnd 224          //Sequencer End Sequence
#define ssetCR 223        //Sequencer Set Control Register X (Register,Value(low,high))
#define saddCR 222        //Sequencer Add Control Register X imediate (Register,Addition)
#define saddCRCR 221      //Sequencer Add Control Register X indirect (Register,Register with Addition)
#define ssetLRCR 220      //Sequencer Set two Repeated Lines with Control Register (X(CR),lenght(CR),Colorregister)

#define StartSequence BlueMonday

const PROGMEM byte Seq1_0 []= {
  ssetBPM,480*40,480*40>>8,
  ssetColR,0,255,0,55, ssetColR,1,0,200,255,
  ssetCR,0,0,0, ssetCR,1,24,0,
  ssetCR,2,3,0, ssetCR,3,0,0,
  sLoop,2, sLoop,32, sCall,1, sRep, ssetCR,2,-3,0, ssetCR,3,0,0, sRep,
  sLoop,2, ssetCR,2,3,0, ssetCR,3,0,0, sLoop,2, sLoop,16, sCall,1, sRep, ssetCR,2,-3,0, ssetCR,3,0,0, sRep,
  sRep,
  sEnd
};
const PROGMEM byte Seq1_1 []= {
  suseColR,0,
  ssetLRCR,0,1,1,
  ssw,
  saddCRCR,0,2,
  saddCRCR,1,3,
  sEnd //*/
};

const byte* const PROGMEM Seq1 []= {
  Seq1_0, Seq1_1
};

const PROGMEM byte Flash32 []= {
  suseColR,0, sDim,0, ssw,
  suseColR,1, sLoop,30, sDim,230, ssw, sRep,
  sDim,0, ssw,
  sEnd
};
const PROGMEM byte Flash16 []= {
  suseColR,0, sDim,0, ssw,
  suseColR,1, sLoop,14, sDim,220, ssw, sRep,
  sDim,0, ssw,
  sEnd
};
const PROGMEM byte Flash8 []= {
  suseColR,0, sDim,0, ssw,
  suseColR,1, sLoop,6, sDim,190, ssw, sRep,
  sDim,0, ssw,
  sEnd
};
const PROGMEM byte Flash4 []= {
  suseColR,0, sDim,0, ssw,
  suseColR,1, sLoop,2, sDim,128, ssw, sRep,
  sDim,0, ssw,
  sEnd
};

const PROGMEM byte BlueMonday_0 []= {
  ssetBPM,20899,20899>>8,
//  sBPMhalf,

  sPause,35,
  sLoop,-1,


  sLoop,8, sCall,1, sRep,
  sCall,2,  //*/
  ssetColR,0,255,255,255,
  ssetColR,1,100,0,0,
  sLoop,64, sCall,4, sRep,
//  sCall,3,
  sRep,
  sEnd
};
const PROGMEM byte BlueMonday_1 []= {
  ssetColR,0,255,255,255,
  ssetColR,1,100,0,0,
  sLoop,2, sCall,3, sRep,
  sLoop,8, sCall,5, sRep,
  sLoop,4, sCall,3, sRep,
  sEnd
};
const PROGMEM byte BlueMonday_2 []= {
  ssetColR,0,255,200,0,
  ssetColR,1,0,0,55,
  sLoop,2, sLoop,4, sCall,3,sPause,4,sRep, sPause,16,sRep,
  sEnd
};
const PROGMEM byte BlueMonday_3 []= {
  ssetColR,0,255,0,200,
  ssetColR,1,0,0,0,
  sLoop,2,
  sLoop,5, sCall,3, sRep,
  sPause,4,
  sCall,3,
  sRep,
  sEnd
};

const byte* const PROGMEM BlueMonday []= {
  BlueMonday_0,
  BlueMonday_1,
  BlueMonday_2,
  BlueMonday_3,
  Flash16,
  Flash8,
  Flash4
};

#define pgmB pgm_read_byte_near
#define pgmW pgm_read_word_near
#define pgmL pgm_read_dword_near

void sequencerStart(){
  SeqPtrArray=(byte*)StartSequence;
  SeqPtr=pgmW(SeqPtrArray);
  SRIndex=SeqLevel=SeqBeatCount=SeqBeats=SeqPause=0;
  SeqNextBeatCount=1;
  SRLoop[0]=255;
  SRPtr[0]=SeqPtr;
}

void sequencer(){
  uint tempW;
  byte tempB;
  ulong Val;
Start:
  tempB=pgmB(SeqPtr++);
  switch(tempB){
    case ssw:
      cli();
      if(SeqBeats>=600000){
        SeqBeats-=600000;
        sei();
        SeqBeatCount--;
        if(char(SeqBeatCount)<=0){
          SeqBeatCount=SeqNextBeatCount;
          if(char(SeqPause)>=0){
            SeqPause--;
            SeqPtr--;
            return;
          }
          sendCom(ssw,0,0,numLEDs*31>>10);
          goto Start;
        }
      }else sei();
      SeqPtr--;
      return;
      break;
    case sPause:
      SeqPause=pgmB(SeqPtr++);
      break;
    case ssetBPM:
      SeqBpm=pgmW(SeqPtr);
      SeqPtr+=2;
      break;
    case sBPMnormal:
      SeqNextBeatCount=1;
      break;
    case sBPMhalf:
      SeqNextBeatCount=2;
      break;
    case sBPMquarter:
      SeqNextBeatCount=4;
      break;

    case ssetCol:
      Val=pgmL(SeqPtr);
      sendCom(ssetCol,3,Val,0);
      SeqPtr+=3;
      break;

    case ssetPos:
      tempW=pgmW(SeqPtr);
      sendCom(ssetPos,2,tempW,0);
      SeqPtr+=2;
      break;

    case saddPos:
      tempB=pgmB(SeqPtr);
      sendCom(saddPos,1,tempB,0);
      SeqPtr++;
      break;

    case ssetCR:
      SRCtrl[pgmB(SeqPtr)]=pgmW(SeqPtr+1);
      SeqPtr+=3;
      break;

    case saddCR:
      SRCtrl[pgmB(SeqPtr)]+=(char)pgmB(SeqPtr+1);
      SeqPtr+=2;
      break;

    case saddCRCR:
      SRCtrl[pgmB(SeqPtr)]+=SRCtrl[pgmB(SeqPtr+1)];
      SeqPtr+=2;
      break;

    case ssetL:
      sendCom(ssetL,2,pgmW(SeqPtr),1);
      SeqPtr+=2;
      break;

    case ssetLA:
      sendCom(ssetLA,4,pgmL(SeqPtr),1);
      SeqPtr+=4;
      break;

    case ssetLR:
      sendCom(ssetLR,2,pgmW(SeqPtr),0);
      tempB=pgmB(SeqPtr+2)*3;
      sendCom(0,3,SRColor[tempB]|(uint)(SRColor[tempB+1])<<8|(ulong)(SRColor[tempB+2])<<16,0);
      SeqPtr+=2;
      break;

    case ssetLRCR:
      sendCom(ssetPos,2,SRCtrl[pgmB(SeqPtr)],0);
      sendCom(ssetLR,2,SRCtrl[pgmB(SeqPtr+1)],0);
      tempB=pgmB(SeqPtr+2)*3;
      sendCom(0,3,SRColor[tempB]|(uint)(SRColor[tempB+1])<<8|(ulong)(SRColor[tempB+2])<<16,0);
      SeqPtr+=3;
      break;

    case sDim:
      tempB=pgmB(SeqPtr++);
      sendCom(sDim,1,tempB,1);
      break;
      
    case ssetColR:
      tempB=(pgmB(SeqPtr)*3);
      SRColor[tempB]=pgmB(SeqPtr+1);
      SRColor[tempB+1]=pgmB(SeqPtr+2);
      SRColor[tempB+2]=pgmB(SeqPtr+3);
      SeqPtr+=4;
      break;

    case suseColR:
      tempB=(pgmB(SeqPtr)*3);
      Val=(SRColor[tempB])|((uint)(SRColor[tempB+1])<<8)|((ulong)(SRColor[tempB+2])<<16);
      sendCom(ssetCol,3,Val,0);
      SeqPtr++;
      break;

    case sLoop:
      SRLoop[++SRIndex]=pgmB(SeqPtr++);
      SRPtr[SRIndex]=SeqPtr;
      break;

    case sCall:
      tempB=pgmB(SeqPtr);
      if(tempB && SRIndex<18){
        SRLoop[++SRIndex]=SeqLevel;
        SRPtr[SRIndex]=SeqPtr+1;
        tempB+=SeqLevel;
        SeqLevel=tempB;
        SeqPtr=pgmW(SeqPtrArray+tempB*2);
      }else{
        SeqPtr--;
        return;
      }
      break;

    case sEnd:
      if(SRIndex){
        SeqLevel=SRLoop[SRIndex];
        SeqPtr=SRPtr[SRIndex--];
      }else{
        SeqPtr--;
        return;
      }
      break;

    case sRep:
      if(SRLoop[SRIndex]==255){
        SeqPtr=SRPtr[SRIndex];
      }else{
        SRLoop[SRIndex]--;
        if(SRLoop[SRIndex]){
          SeqPtr=SRPtr[SRIndex];
        }else{
          if(SRIndex){
            SRIndex--;
          }else{
            SeqPtr--;
            return;
          }
        }
      }
      break;
  }
  goto Start;
}

Überraschender weise bleibt das sehr schön im Takt wenn man die Beats mal gefunden hat. Auch nach 3 Minuten mit einem Song trifft es die Effekte auf den Punkt obwohl es als Sub-Funktion neben anderem Zeugs nebenher aufgerufen wird.

MfG
Andi

Super! :smiley: