Arduino byte BufferOverflow bzw. reboot - warum?

Hallo zusammen!

Ich freue dabei zu sein und habe schon viel wissenswertes aus dem Forum mitnehmen können! Früher als gedacht, habe ich tatsächlich eine Frage!

Ich habe ein Projekt wo ich ein LED Stripe mit FastLED ansteuere. Nix besonderes. Funktioniert auch super. Solange ich nicht versuche die Laufrichtung zu ändern.

herzschlag4() läuft wunderbar, herzschlag5() lässt den kleinen immer wieder rebooten.

Der Unterschied ist, die byte Variable herzschlaege subtrahiert wird, anstatt addiert. Das gleiche Phänomen hatte ich auch schon mit der pos Variable, was ich aber i r g e n d w i e gefixt hatte.

Ich bin der Meinung gewesen, dass wenn eine Variable überläuft kein Fehler auftritt, sondern die Variable wieder vom anderen Ende anfängt. Habe ich mich hier getäuscht?

Hat jemand eine Idee?

beste Grüße
Paul

#include <FastLED.h>
#include <avr/interrupt.h>
#include <avr/wdt.h>
#include <util/atomic.h>
#include <math.h>


// The following addresses a problem in version 1.0.5 and earlier of the Arduino IDE 
// that prevents randomSeed from working properly.
//        https://github.com/arduino/Arduino/issues/575
#define randomSeed(s) srandom(s)
 
volatile uint32_t seed;  // These two variables can be reused in your program after the
volatile int8_t nrot;    // function CreateTrulyRandomSeed()executes in the setup() 
                         // function.
 
#define LED_PIN     6

// Information about the LED strip itself
#define NUM_LEDS    16
#define CHIPSET     WS2812B
#define COLOR_ORDER GRB
CRGB leds[NUM_LEDS];

#define TEMPERATURE Tungsten100W
#define FRAMES_PER_SECOND  30

byte alleFarben = 255;
byte maxByte = 255;
byte maxHerzVariation = 32;

byte buntheit;
byte herzFarbe;
byte herzVariation;

float goldenerSchnitt = 0.618;
float goldenerSchnittKlein = 0.382;

byte herzschlaege = NUM_LEDS;
byte pos = NUM_LEDS;
byte temp;

bool debug = true;

void ausgabe(String text, byte nummer){
  if (debug){
    Serial.print(text);
    Serial.println(nummer);
  }
}

void ausgabe(String text, byte nummer, bool booli){
  if (booli){
    Serial.print(text);
    Serial.println(nummer);
  }
}

void herzschlag4() {
  fadeToBlackBy( leds, NUM_LEDS, 17);
  ausgabe("pos: ",pos);

  if (pos >= NUM_LEDS){
    if(herzschlaege>=NUM_LEDS){
      herzschlaege=0;
    }else{
      herzschlaege++;
    }
  }
  
  if (pos >= 16){
    pos=0;
  }

  byte helligkeit;
  byte grosserBereich = NUM_LEDS*goldenerSchnitt;
  byte radLed;
  float faktor = 1.2;

  if (herzschlaege+pos > NUM_LEDS){
    radLed = herzschlaege + pos - NUM_LEDS;
  }else{
    radLed = herzschlaege + pos;
  }
  ausgabe("radLed: ",radLed);
  
  if (radLed <= grosserBereich){
    byte hGrosserBereich = grosserBereich/2;
    ausgabe("hGrosserBereich: ",hGrosserBereich);
    if (radLed <=hGrosserBereich){
      byte exponent = hGrosserBereich-radLed;
      helligkeit = maxByte*pow(goldenerSchnitt*faktor,exponent);
      ausgabe("exponent: ",exponent);
      ausgabe("helligkeit: ",helligkeit);
    }else{
      byte exponent = radLed-hGrosserBereich;
      helligkeit = maxByte*pow(goldenerSchnitt*faktor,exponent);
      ausgabe("exponent: ",exponent);
      ausgabe("helligkeit: ",helligkeit);
    }
  }else{
    byte kleinerBereich = NUM_LEDS * (1-goldenerSchnitt)/2+grosserBereich;
    ausgabe("kleinerBereich: ",kleinerBereich);
    if(radLed <= kleinerBereich){
      byte exponent = kleinerBereich-radLed;
      helligkeit = maxByte*pow(goldenerSchnitt*faktor,exponent);
      ausgabe("exponent: ",exponent);
      ausgabe("helligkeit: ",helligkeit);
    }else{
      byte exponent = radLed-kleinerBereich;
      helligkeit = maxByte*pow(goldenerSchnitt*faktor,exponent);
      ausgabe("exponent: ",exponent);
      ausgabe("helligkeit: ",helligkeit);
    }
  }
  ausgabe("helligkeit: ",helligkeit);

  temp = herzFarbe + NextGaussian()*herzVariation;
  leds[pos] += CHSV( temp, buntheit, helligkeit);
  
  pos++;
}

void herzschlag5() {
  fadeToBlackBy( leds, NUM_LEDS, 17);
  ausgabe("pos: ",pos);
  
  if(herzschlaege == 0){
    herzschlaege=NUM_LEDS;
  }
  ausgabe("herzschlaege: ", herzschlaege, true);
  
  if (pos == 0){
    pos=NUM_LEDS;
    herzschlaege--;
  }

  byte helligkeit;
  byte grosserBereich = NUM_LEDS*goldenerSchnitt;
  byte radLed;
  float faktor = 1.2;

  if (herzschlaege+pos > NUM_LEDS){
    radLed = herzschlaege + pos - NUM_LEDS;
  }else{
    radLed = herzschlaege + pos;
  }
  ausgabe("radLed: ",radLed);
  
  if (radLed <= grosserBereich){
    byte hGrosserBereich = grosserBereich/2;
    ausgabe("hGrosserBereich: ",hGrosserBereich);
    if (radLed <=hGrosserBereich){
      byte exponent = hGrosserBereich-radLed;
      helligkeit = maxByte*pow(goldenerSchnitt*faktor,exponent);
      ausgabe("exponent: ",exponent);
      ausgabe("helligkeit: ",helligkeit);
    }else{
      byte exponent = radLed-hGrosserBereich;
      helligkeit = maxByte*pow(goldenerSchnitt*faktor,exponent);
      ausgabe("exponent: ",exponent);
      ausgabe("helligkeit: ",helligkeit);
    }
  }else{
    byte kleinerBereich = NUM_LEDS * (1-goldenerSchnitt)/2+grosserBereich;
    ausgabe("kleinerBereich: ",kleinerBereich);
    if(radLed <= kleinerBereich){
      byte exponent = kleinerBereich-radLed;
      helligkeit = maxByte*pow(goldenerSchnitt*faktor,exponent);
      ausgabe("exponent: ",exponent);
      ausgabe("helligkeit: ",helligkeit);
    }else{
      byte exponent = radLed-kleinerBereich;
      helligkeit = maxByte*pow(goldenerSchnitt*faktor,exponent);
      ausgabe("exponent: ",exponent);
      ausgabe("helligkeit: ",helligkeit);
    }
  }
  ausgabe("helligkeit: ",helligkeit);

  temp = herzFarbe + NextGaussian()*herzVariation;
  leds[pos] += CHSV( temp, buntheit, helligkeit);
  
  pos--;
}

// List of patterns to cycle through.  Each is defined as a separate function below.
//typedef void (*SimplePatternList[])();
//SimplePatternList gPatterns = { herzschlag1, herzschlag2,herzschlag3,herzschlag4 };
uint8_t gCurrentPatternNumber = 0; // Index number of which pattern is current
uint8_t gHue = 0; // rotating "base color" used by many of the patterns

void loop()
{
  // send the 'leds' array out to the actual LED strip
  FastLED.show();  
  // insert a delay to keep the framerate modest
  FastLED.delay(1000/FRAMES_PER_SECOND); 
  herzschlag5();
}

void setupZufall(){
  CreateTrulyRandomSeed();
  randomSeed(seed);
}

void setupFarben(){
  herzFarbe = random(alleFarben);
  buntheit = NextGaussian(random(RAND_MAX),random(RAND_MAX))*alleFarben*-1;
  herzVariation = NextGaussian(random(RAND_MAX),random(RAND_MAX))*maxHerzVariation*-1;
  Serial.print("herzFarbe: ");
  Serial.println(herzFarbe);
  Serial.print("buntheit: ");
  Serial.println(buntheit);
  Serial.print("herzVariation: ");
  Serial.println(herzVariation);
}

void setup() {
  delay( 3000 ); // power-up safety delay
  // It's important to set the color correction for your LED strip here,
  // so that colors can be more accurately rendered through the 'temperature' profiles
  Serial.begin(9600);
  Serial.println("Ich lebe!");
  setupZufall();
  setupFarben();
  FastLED.addLeds<CHIPSET, LED_PIN, COLOR_ORDER>(leds, NUM_LEDS).setCorrection( TypicalSMD5050 );
  FastLED.setTemperature( TEMPERATURE );
}


void CreateTrulyRandomSeed()
{
  seed = 0;
  nrot = 32; // Must be at least 4, but more increased the uniformity of the produced 
             // seeds entropy.
  
  // The following five lines of code turn on the watch dog timer interrupt to create
  // the seed value
  cli();                                             
  MCUSR = 0;                                         
  _WD_CONTROL_REG |= (1<<_WD_CHANGE_BIT) | (1<<WDE); 
  _WD_CONTROL_REG = (1<<WDIE);                       
  sei();                                             
 
  while (nrot > 0);  // wait here until seed is created
 
  // The following five lines turn off the watch dog timer interrupt
  cli();                                             
  MCUSR = 0;                                         
  _WD_CONTROL_REG |= (1<<_WD_CHANGE_BIT) | (0<<WDE); 
  _WD_CONTROL_REG = (0<< WDIE);                      
  sei();                                             
}
 
ISR(WDT_vect)
{
  nrot--;
  seed = seed << 8;
  seed = seed ^ TCNT1L;
}

float NextGaussian() {

    float v1, v2, s;
    do {
    v1  = 2.0*(float)rand()/(float)RAND_MAX-1.0; 
    v2  = 2.0*(float)rand()/(float)RAND_MAX-1.0; 
        s = v1 * v1 + v2 * v2;
    } while (s >= 1.0 || s == 0.0);

    s = sqrt((-2.0 * log(s)) / s);
    return v1 * s;
}

herzschlag_breakdown.ino (7.98 KB)

Da wir Deinen Sketch nicht kennen, kann ich nur vermuten: Du überschreibst die Grenzen eines Arrays.
Da fängt nichts von vorn an, das überschreibt andere Speicherbereiche. Je nachdem, was da drin steht ist die Wirkung mehr oder weniger katastrophal aber meist unerwünscht.

Gruß Tommy

Hey Tommy,

ich hab den Sketch mit angehangen, kann man den nicht sehen?

Bitte setze Deinen Sketch in Codetags (oben links </> im Foreneditor oder [code] davor und [/code] dahinter - ohne die *).
Das kannst Du auch noch nachträglich durch Editieren tun. Bitte mach das, der Sketch ist besser zu lesen, besonders auf mobilen Geräten.

Als Anhang liest ihn keiner.

Gruß´Tommy

Alles klar,

Sorry ich dachte man läd die direkt runter, ich musste eine nextGaussian funtion raus nehmen weil sonst der beitrag zu lang wurde. :wink:

Du beachtest an einigen Stellen die Arraygrenzen nicht.

Du erzeugst ein LED-Array mit 16 Elementen (NUM_LEDS). Das har die Positionen 0 bis 15 du setzt sie aber auf NUM_LEDS, also 16.

  if (pos == 0){
    pos=NUM_LEDS;
    herzschlaege--;
  }

// auch das passt nicht ganz:
  if (pos >= NUM_LEDS){
...
// oder das
  if (pos >= 16){
    pos=0;
  }

Gruß Tommy

Ahh, das habe ich übersehen. Besten Dank :slight_smile:
Ich dachte schon es wäre was schwerwiegenderes :wink:

ArduinoGuy255:
Ich dachte schon es wäre was schwerwiegenderes :wink:

Der Fehler ist extrem schwerwiegend, da er unvorhersehbares Verhalten nach sich zieht,
dazu zählt auch das anscheinende Funktionieren.
So ein Fehler kann sich sehr lange verstecken und im unpassendsten Moment zuschlagen.