Bei hinzufügen eines Serial.prints kommt eine Endlosschleife zustande

Hallo,

das Ziel von meinem Projekt ist es ein Objekt in einem Raum zu erkennen mit hilfe von einem "Radar". Also Ultraschallsensor an einem Schrittmotor befestigt.

Was ich bisher programmiert habe ist: Es werden 4 Scanns des Raumes durchgeführt und jeweils in ein Array geschrieben. Dann nehme ich mir diese 4 Arrays und vergleiche an der Stelle i die Werte, filter den größten und kleinsten raus und aus den anderen 2 bilde ich den Mittelwert. Diesen schreibe ich in das Array "a_ref[ii]". Diese Werte sollen später als Referenz dienen.
Im Moment möchte ich mir alle Werte ausgeben, um diese kontrollieren zu können. Jetzt kommt mein Problem: Sobald ich in der letzten for-Schleife das kommentierte entkommentiere kommt es zu einer endlos-Schleife bei der for-Schleife, wo das a[ii] Array gesetzt wird.. Es wird nur noch von 0 bis 6 gezählt und dann wieder von vorne und es werden keine Werte in das Array geschrieben.
Woran kann das liegen?? Wie kann ein Serial.print so auswirkungen haben?

Danke für eure Antworten.

#include <CheapStepper.h>

CheapStepper myStepper(2,3,4,5);

const int grad=120;
int a_ref[grad];    //120 bedeutet 120 Elemente, Indizes von 0 bis 119
int a_ver[grad];
int a_v[grad];

int end_one=6, tasterstatus_one;

int trigger=8; 
int echo=9; 
long dauer=0; 
long entfernung=0;

void setup() {
  pinMode(trigger, OUTPUT); 
  pinMode(echo, INPUT);
  myStepper.setRpm(5);
  Serial.begin(9600);

  int a[grad], b[grad], c[grad], d[grad], f=0;

  for (int n=0; n<grad+1; n++)
  {
    a_ref[n]=f;
    a_ver[n]=f;
    a[n]=f;
    b[n]=f;
    c[n]=f;
    d[n]=f;
  } 

  for (int i=0; i<grad; i++)
  {
    myStepper.moveDegreesCW (1);
    digitalWrite(trigger, LOW); 
    delay(5); 
    digitalWrite(trigger, HIGH); 
    delay(10);
    digitalWrite(trigger, LOW);
    dauer = pulseIn(echo, HIGH,24000); 
    a[i]= (dauer/2) * 0.03432;

    Serial.print("A:   ");
    Serial.print(i);
    Serial.print("-");
    Serial.print(a[i]);
    Serial.print("  ####  ");
    
  }
  
  Serial.println("");

  for (int i=grad-1; i> -1; i--)
  {
    digitalWrite(trigger, LOW); 
    delay(5); 
    digitalWrite(trigger, HIGH); 
    delay(10);
    digitalWrite(trigger, LOW);
    dauer = pulseIn(echo, HIGH,24000); 
    b[i]= (dauer/2) * 0.03432;

    Serial.print("B:   ");
    Serial.print(i);
    Serial.print("-");
    Serial.print(b[i]);
    Serial.print("  ####  ");
    
    
    myStepper.moveDegreesCCW (1);
    
  }
  
  Serial.println("");

  for (int i=0; i<grad; i++)
  {
    myStepper.moveDegreesCW (1);
    digitalWrite(trigger, LOW); 
    delay(5); 
    digitalWrite(trigger, HIGH); 
    delay(10);
    digitalWrite(trigger, LOW);
    dauer = pulseIn(echo, HIGH,24000); 
    c[i]= (dauer/2) * 0.03432;

    Serial.print("C:   ");
    Serial.print(i);
    Serial.print("-");
    Serial.print(c[i]);
    Serial.print("  ####  ");
  }

  Serial.println("");

  for (int i=grad-1; i> -1; i--)
  {
    digitalWrite(trigger, LOW); 
    delay(5); 
    digitalWrite(trigger, HIGH); 
    delay(10);
    digitalWrite(trigger, LOW);
    dauer = pulseIn(echo, HIGH,24000); 
    d[i]= (dauer/2) * 0.03432;

    Serial.print("D:   ");
    Serial.print(i);
    Serial.print("-");
    Serial.print(d[i]);
    Serial.print("  ####  ");
    
    myStepper.moveDegreesCCW (1);
  }

  Serial.println("");
  Serial.println("");

  for (int i=0; i<grad; i++)
  {
    int maximal=0, minimal=9999;
    
    if (a[i]>maximal) {maximal=a[i];}
    if (b[i]>maximal) {maximal=b[i];}
    if (c[i]>maximal) {maximal=c[i];}
    if (d[i]>maximal) {maximal=d[i];}

    if (a[i]<minimal) {minimal=a[i];}
    if (b[i]<minimal) {minimal=b[i];}
    if (c[i]<minimal) {minimal=c[i];}
    if (d[i]<minimal) {minimal=d[i];}
    
    a_ref[i]=(a[i]+b[i]+c[i]+d[i]-maximal-minimal)/2;   
  } 
  
  for (int i=0; i<grad; i++)
  {
    Serial.print(i);
    Serial.print("-");
    Serial.print(a[i]);
    Serial.print(" | ");
    Serial.print(b[i]);
    Serial.print(" | ");
    Serial.print(c[i]);
    Serial.print(" | ");
    Serial.print(d[i]);
    Serial.print(" ### ");
  }
  
  Serial.println("");
  Serial.println("");
   
  for (int i=0; i<grad; i++)
  {
    Serial.print(i);
    Serial.print("-");
//  Serial.print(a_ref[i]);
    Serial.print(" ### ");
  }
  
}

void loop() {
  

}

a_ref[ii]

Kein a_ref[ii] zu sehen.

Alle Warnungen aktivieren, Warnung beheben

sketch_jul31a\sketch_jul31a.ino:30:9: warning: iteration 120 invokes undefined behavior [-Waggressive-loop-optimizations]

   30 |     a[n]=f;

      |         ^

k\sketch_jul31a\sketch_jul31a.ino:26:18: note: within this loop

   26 |   for (int n=0; n<grad+1; n++)

      |                  ^

1.) Um Arrays auf 0 zu setzen gibt es memset()

2.) Globale Variablen sind automatisch mit 0 initialisiert. Nur lokale nicht-statische Variablen müssen initialisiert werden

3.) Das verursacht einen Puffer-Überlauf:
for (int n=0; n<grad+1; n++)
Array gehen von N bis N - 1

  1. verbrauchst Du für die Arrays alleine schon 1680 byte RAM
  2. for (int n=0; n<grad+1; n++) ist ein Indexüberlauf
  3. Serial.print("text") verbraucht auch RAM

Mit einem Arduino UNO hast Du schon viel zu viel RAM verbraucht und überschreibst den Stack.

Grüße Uwe

Danke für eure Antworten!

"Kein a_ref[ii] zu sehen." Ich habe das hier a_ref[ii] genannt, weil sonst der Text kursiv geschrieben wird.

Das die Arrays am Anfang 0 sind habe ich mir gedacht, wollte nur erstmal sicher gehen. Mit dem Überlauf habt ihr da natürlich recht.

Die 4 Arrays sind ja nur lokal und von den 3 globalen werde ich später nur eins verwenden. Aber um im Moment die Daten zu speichern würde ich die gerne noch lassen.

Ich habe jetzt int a_ver[grad]; und int a_v[grad]; auskommentiert und den Überlauf behoben. Jetzt funktioniert es.

Also kann der Fehler davon kommen das nicht genügend RAM vorhanden ist?
Die Serial.prints kommen später eh alle weg, das ist im Moment nur zur Kontrolle aber wenn die zu viel RAM benötigen, dann werde ich immer Step-by-Step kontrollieren.

Die 4 Arrays sind ja nur lokal

Dass die lokal sind ändert nichts am Speicherverbrauch! Du kannst nicht nur danach gehen was dir die IDE anzeigt

Also kann der Fehler davon kommen das nicht genügend RAM vorhanden ist?

Ja

Bei den seriellen Text Ausgaben kannst du einfach etwas RAM sparen:

Serial.println(F("Text"));

Das ist überflüssig, da println() auch ohne Parameter geht

  Serial.println("");

Und das belegt auch etwas weniger Speicher, auch wenn es nur ein Byte ist:

Serial.print('-');

Okay vielen Dank.

Dann werde ich jetzt erstmal bei den Serial.prints sparen - und später verschwinden die dann eh komplett.
Die 4 Arrays brauche ich allerdings, da dort die Daten gespeichert werden, die ich dann auswerte.

Nachdem die void setup durchlaufen wurde, wird der Speicher für die 4 Arrays doch wieder freigegeben oder?

Damm kauf Dir schon mal einen Arduino MEGA. Der hat mehr RAM
Grüße Uwe

Hi

Hatte ich schon erwähnt, daß ich die Forensoftware hasse?? Schon wieder ALLES weg ... könnte kotzen ...

Ok, dann als Kurzgeschichte:
Was const ist, nenne auch so - mindestens die Pin-Nummern trigger und echo werden sich wohl NIE ändern (zumindest nicht zur Laufzeit).
Warum hat bei Dir ALLES den Datentyp INT? Muss Das so? (bei Den, Die eh const werden, ist Das wurscht - bei dem Rest könnte man erkennen, daß Du Dir Gedanken gemacht hast)

Sprechende Namen: In drei Wochen weiß kein Schwein mehr, was Du Da treibst - auch Du wirst Dich dann in DEINEN Sketch einfuchsen müssen - die Zeit kann man sinnvoller verbringen und Das bekommt man 'frei Haus', wenn man beim Programmieren z.B. sprechende Variablen benutzt.
Also nicht a[],b[],a2[],c_irgendwas[].

ALLES, was Du mehrfach machst, auslagern.
Du machst:

  • pingen links rum
  • pingen rechts rum
  • pingen links rum
  • pingen rechts rum

Das geht auch in EINER Funktion, Der Du sagst, wie rum gerade 'gepingt' wird.
Das Abspeichern der Werte in den verschiedenen Array's - da wäre wohl ein 2-dimensionales Array meine Wahl.
Wenn ich Das unbedingt zwölf Mal abklappern will - man könnte auch die x Messungen 'am Stück' machen und per Median/Mittelwert den gültigen Wert bestimmen - bräuchte um Längen weniger RAM.

Denke, die Berechnunga[i]= (dauer/2) * 0.03432;wird 'anders herum' schneller und wohl auch genauer.
Wenn Du dauer * (0.3432/2) schreibst, kann der Kompiler die Klammer auflösen und im Programm steht dort nur noch eine Multiplikation mit einer Konstanten - Das kann der Kompiler direkt im Code fest verbauen - kein RAM!
Bei Dauer/2*irgendwas muß der µC Dauer nach rechts shiften (entspricht :2) und dann Multiplizieren - ok, nicht wirklich viel gespart, bei 2er-Potenzen (:2, :4, ... :256, ...) hat der Kompiler leichtes Spiel - bei jeder anderen Zahl (nicht 2er-Potenz), muß hier wirklich richtig gerechnet werden.

Denke, habe wieder Alles soweit zusammen ...

MfG

postmaster-ino:
Hi

Hatte ich schon erwähnt, daß ich die Forensoftware hasse?? Schon wieder ALLES weg ... könnte kotzen ...

Hi, schalte mal die automatische Entwurfspeicherung an. https://forum.arduino.cc/index.php?action=profile;area=theme Option Enable automatic saving of drafts, rettet vielleicht nicht immer alles, aber kann hilfreich sein. :wink:

Edit: Deine Entwürfe findest du dann unter https://forum.arduino.cc/index.php?action=profile;area=showdrafts.

Hi

Danke - Da hatte ich schon ein Kreuz - aber kein 'draft'.
Hatte mir eigentlich angewöhnt, VOR dem Absenden STRG+A, STRG+C V zu drücken - man merkt aber schnell, wenn man Das 'Mal wieder' vergessen hat - zumindest, wenn das Forum Einen 'Mal so' abgemeldet hat.

MfG

PS: klar - STRG+C (wie Copy) ... wird Zeit für's Bett ...

Du meinst sicher STRG+A, STRG+C (Kopieren).

STRG+V wäre einfügen gewesen.

Gruß Tommy

postmaster-ino:
Hi

Danke - Da hatte ich schon ein Kreuz - aber kein 'draft'.
Hatte mir eigentlich angewöhnt, VOR dem Absenden STRG+A, STRG+V zu drücken - man merkt aber schnell, wenn man Das 'Mal wieder' vergessen hat - zumindest, wenn das Forum Einen 'Mal so' abgemeldet hat.

MfG

Bei manchen Foren hast du noch mit Browser-Zurück Glück, aber nur selten... Mit dem Smartphone ist es mir hier auch schon mal passiert, weil die Anhänge zu groß waren - Posting war verloren...

Was mich aber wundert ist, dass du so oft ausgeloggt wirst, ich muss mich so ca. alle 24-48 Stunden neu einloggen, aber bisher noch nie während ich einen Post senden wollte, aber ich schreibe nicht so oft wie du.

Tommy56:
Du meinst sicher STRG+A, STRG+C (Kopieren).

STRG+V wäre einfügen gewesen.

Gruß Tommy

Ich tippe auf Vertipper, sonst wäre die Lösung zu einfach... :wink:

Hi

Kann sein, daß Das der erste Post in 'dieser Session' war - kA, habe nicht drauf geachtet - soll aber hier erst Mal 'wurscht' sein - Ausnahme: die Serial.print() haben was damit zu tun :wink:

MfG

postmaster-ino:
Hi

Kann sein, daß Das der erste Post in 'dieser Session' war - kA, habe nicht drauf geachtet - soll aber hier erst Mal 'wurscht' sein - Ausnahme: die Serial.print() haben was damit zu tun :wink:

MfG

okay, OT-Ende :wink:

dauer * (0.3432/2)

Wäre es nicht noch besser schon vorher auszurechnen und
dauer * 0.1716 zu schreiben. Da bleibt nur ein Rechenschritt über.

Grüße Uwe

uwefed:
Wäre es nicht noch besser schon vorher auszurechnen und
dauer * 0.1716 zu schreiben. Da bleibt nur ein Rechenschritt über.

Die beiden Literale werden schon beim Kompilieren berechnet.

Hi

Das wird der Kompiler schon für uns tun - Das, was Der optimieren kann, wird Er wohl wegoptimieren.
Wie oben schon angesprochen: Die 'durch 2' spielt hier voll in die Rechnung, bei jeder anderen Zahl (nicht 2er-Potenz) müsste mit der Variable erst richtig gerechnet werden, bevor mit einem festen Wert multipliziert wird.

Soll im Grunde heißen: Um die Klammer kümmert sich der Kompiler, wenn Er denn kann - nur bei (x/irgendwas)*wasanderes MUSS Er Das zur Laufzeit rechnen.

MfG