Anfänger: Ultraschallsensor + 8x8 Led-Matrix macht Probleme

Hallo zusammen.
Ich gehöre zu den blutigen einsteigern und versuche mir mit kleinen Projekten diese Wissenschaft anzueignen.

Ich versuche gerade mit einem Ultraschallsensor HC-SR04 einen Abstand zu messen, und je nach Entfernung auf einer 8x8 LED-Matrix MAX7219 verschiedene Sachen anzeigen zu lassen.

Nun habe ich aber gemerkt das irgendetwas das ganze System ins stocken bringt. Sprich die Anzahl der Abstandsmessungen geht zum Teil sehr in die Knie und ich weiß leider nicht woran das liegt.
Ich habe mir schon extra den Umgang mit den Millis angeeignet damit das ganze System keine Pause macht. Abgesehen von zwei delay-Zeiten beim ein uns ausschalten des Sensors, 5 und 10 Millisekunden, habe ich überall nur die millis benutzt.

Ich hoffe einer von euch findet die Zeit und kann mir sagen woran das evtl liegt, oder was man besser machen könnte.

Ich gehe davon aus dass wenn ich den Sensor mit einem eigennen Arduino-Nano betreiben würde und die Werte an den Uno übetragem, dass dann das Problem gelöst ist da der Sensor dann nicht von anderen Aufgaben unterbrochen wird.

Aber vielleicht liegts ja auch nur am Code.

Vielen Dank für eure Aufmerksamkeit.

LG
Basti

#include "LedControl.h"
LedControl lc=LedControl(12,10,11,1);  // Pins: DIN,CLK,CS, # Anzahl der Bildschirme

unsigned long startzeit; //Variable Startpunkt der Millis
unsigned long vergangene_zeit; // Variable um die vergangene Zeit zu speichern
int delay_zeit_1 = 100; // Variable der Zeit die zwischen den einzelnen LED Bildern vergehen soll um kleine Animationen zu machen
int delay_zeit_2 = 200; // Variable der Zeit die zwischen den einzelnen LED Bildern vergehen soll um kleine Animationen zu machen
int delay_zeit_3 = 300; // Variable der Zeit die zwischen den einzelnen LED Bildern vergehen soll um kleine Animationen zu machen
int delayTimeMessung = 100; // ALTE Variable der Zeit die zwischen den einzelnen LED Bildern vergehen soll um kleine Animationen zu machen

// AB HIER KOMMEN DIE BILDER DIE IN DER LED MATRIX ANGEZEIGT WERDEN SOLL
byte smiley1[] = {B00111100,B01000010,B10001001,B10110101,B10000101,B10110101,B01000010,B00111100};
byte smiley2[] = {B00111100,B01000010,B10110101,B10000101,B10110101,B10001001,B01000010,B00111100};

byte richtung1[] = {B11000000,B01100000,B01100000,B00110000,B00110000,B01100000,B01100000,B11000000};
byte richtung2[] = {B00110000,B00011000,B00011000,B00001100,B00001100,B00011000,B00011000,B00110000};
byte richtung3[] = {B00001100,B00000110,B00000110,B00000011,B00000011,B00000110,B00000110,B00001100};

byte test[] = 
{
  B10000111,
  B10111011,
  B10111011,
  B10000111,
  B10111111,
  B10111111,
  B10111111,
  B11111111
};

byte testt[] = 
{
  B11000011,
  B11011101,
  B11011101,
  B11000011,
  B11011111,
  B11011111,
  B11011111,
  B11111111
};

int trigger=7; // Trigger-Pin des Ultraschallsensors an Pin7
int echo=6; // Echo-Pim des Ultraschallsensors an Pin6
long dauer=0; // Variable, unter der die Zeit gespeichert wird, die eine Schallwelle bis zur Reflektion und zurück benötigt. Startwert ist hier 0.
long entfernung=0; // Variable in der die berechnete Entfernung gespeichert wird
int Pieps=5; // Pieps-Modul an Pin5

void setup()
{
  Serial.begin (9600);
  
lc.shutdown(0,false);  // Wake up displays LED Matrix
  lc.setIntensity(0,10);  // Set intensity levels LED Matrix
  lc.clearDisplay(0);  // Clear Displays  LED Matrix
  pinMode(trigger, OUTPUT); 
  pinMode(echo, INPUT); 
  pinMode(Pieps, OUTPUT); 
}



void bildzeit1()  // Delay-Ersatz um zwischen den einzelnen LED-Bildern eine Pause zu haben
{
  startzeit = millis();
    vergangene_zeit = millis() - startzeit;
    while (vergangene_zeit < delay_zeit_1)
    {
      vergangene_zeit = millis() - startzeit;
    }
}
void bildzeit2() // Delay-Ersatz um zwischen den einzelnen LED-Bildern eine Pause zu haben
{
  startzeit = millis();
    vergangene_zeit = millis() - startzeit;
    while (vergangene_zeit < delay_zeit_2)
    {
      vergangene_zeit = millis() - startzeit;
    }
}
void bildzeit3() // Delay-Ersatz um zwischen den einzelnen LED-Bildern eine Pause zu haben
{
  startzeit = millis();
    vergangene_zeit = millis() - startzeit;
    while (vergangene_zeit < delay_zeit_3)
    {
      vergangene_zeit = millis() - startzeit;
    }
}

void messung() // ALTER Delay-Ersatz um zwischen den einzelnen LED-Bildern eine Pause zu haben
{
  startzeit = millis();
    vergangene_zeit = millis() - startzeit;
    while (vergangene_zeit < delayTimeMessung)
    {
      vergangene_zeit = millis() - startzeit;
    }
}
void ssmiley1() // Code um ein Bild auf der LED Matrix anzuzeigen
{
  for (int i = 0; i < 8; i++)  
  {
    lc.setRow(0,i,smiley1[i]);
  }
}
void ssmiley2() // Code um ein Bild auf der LED Matrix anzuzeigen
{
  for (int i = 0; i < 8; i++)
  {
    lc.setRow(0,i,smiley2[i]);
  }
}
void srichtung1() // Code um ein Bild auf der LED Matrix anzuzeigen
{
  for (int i = 0; i < 8; i++)
  {
    lc.setRow(0,i,richtung1[i]);
  }
}
void srichtung2() // Code um ein Bild auf der LED Matrix anzuzeigen
{
  for (int i = 0; i < 8; i++)
  {
    lc.setRow(0,i,richtung2[i]);
  }
}
void srichtung3() // Code um ein Bild auf der LED Matrix anzuzeigen
{
  for (int i = 0; i < 8; i++)
  {
    lc.setRow(0,i,richtung3[i]);
  }
}





void stest() // Code um ein Bild auf der LED Matrix anzuzeigen
{
  for (int i = 0; i < 8; i++)
  {
    lc.setRow(0,i,test[i]);
  }
}
void stestt() // Code um ein Bild auf der LED Matrix anzuzeigen
{
  for (int i = 0; i < 8; i++)
  {
    lc.setRow(0,i,testt[i]);
  }
}


void loop()
{
digitalWrite(trigger, LOW); // Spannung für kurze Zeit vom Trigger-Pin nehmen, damit man später beim senden des Trigger-Signals ein rauschfreies Signal hat.
delay(5); 
digitalWrite(trigger, HIGH); // Sendet Ultraschallwelle
delay(10); 
digitalWrite(trigger, LOW); // Senden unterbrechen
dauer = pulseIn(echo, HIGH); // Zeit die der Schall gebraucht hat in Variable speichern
entfernung = (dauer/2) * 0.03432; // Berechnung der Entfernung in cm
Serial.println(entfernung);

if (entfernung > 51) // Schleife die eine Bildabfolge auf die LED-MAtrix übertragen soll je nach Entfernung
{
    srichtung1();
    bildzeit2();
    srichtung2();
    bildzeit2();
    srichtung3();
    bildzeit2();
}

if (entfernung < 50 && entfernung > 21) // Schleife die eine Bildabfolge auf die LED-MAtrix übertragen soll je nach Entfernung
{
    ssmiley1();
    bildzeit3();
    ssmiley2();
    bildzeit3();
}

if ( entfernung < 20) // Schleife die eine Bildabfolge auf die LED-MAtrix übertragen soll je nach Entfernung
{
    stest();
    digitalWrite(Pieps,HIGH);
    messung();
    stestt();
    digitalWrite(Pieps,LOW);

    messung();
}
}

Schön, dass du uns deinen Sketch zeigst.

Nur verstehen kann man den nicht. Da fehlt komplett die Kommentare.
Und was sollen die while-Schleife ? Die werden das wohl blockieren.

Setze weinigsten ein paar Kommentare rein, damit wir sehen können, was da abgeht. Und wir müssen nicht alles erraten.

Ich hoffe der Code ist jetzt verständlicher. Habe Kommentare gesetzt.

BastiBpunkt:
Ich hoffe der Code ist jetzt verständlicher. Habe Kommentare gesetzt.

Ja, ein wenig schon.

Nur wozu brauchst du den "delay-Ersatz" ?
Die while-Schleifen blockieren deinen Sketch.

ich dachte wenn ich millis anstelle von delays benutze wird der Scetch nicht blockiert und der Ultraschallsensort führ weiterhin seine Messungen durch.
Nach meinem Verständnis würde bei einer Abfolge von mehreren Bildern die auf der Matrix angezeigt werden sollen, der Sensor solange keine Messungen durchführen bis die Abfolge der Bilder beendet ist.
Das habe ich versucht damit zu verhindern. Leider vergeblich.

Nein, dalay kannst du nicht einfach durch millis ersetzen.
Du musst deinen Sketch nach dem Beispiel "BlinkWithoutDelay" aufbauen.
Da läuft der normale Sketch immer ohne eine Pause weiter und springt erst nach Ablauf der Zeit in die gewünschte Funktion.
Eine While-Schleife darfst du an der Stelle nicht verwenden.

Delay() bremst den sketch aus, gleich wie pulseIn()
Mit Deine while - millis() Konstruktion verkpempert der Controller Zeit.

Zeitinterwalle bestimmt man mit millis() indem man immer wieder nachschaut ob die zeit vergangen ind nach der etwas gemacht werden muß.

loop
   if (currentMillis - previousMillis >= interval) 
        mach irgendwas

Grüße Uwe

Für mein Verständnis...
Wenn ich für jeden Abstandsbereich nur ein Bild über die Matrix ausgeben will klappt das. Möchte ich aber für einen bestimmten Abstandsbereich mehrere Bilder nacheinander Anzeigen lassen, müsste ich gleichzeit noch eine Abfrage einsetzen die überprüft welches Bild gerade angezeigt wird, und jenachdem welches Bild gerade angezeigt wird, dies durch das nachfolgende ersetzen?!

Wie in dem Beispiel "BlinkWithoutDelay" der Status der LED abgefragt wird.

Mein plumper Versuch die while-Schleife durch folgendes zu ersetzen hat nämlicht nicht funktioniert.

if (entfernung > 51)
{
    if (millis() - previousMillis > interval) {
    previousMillis = millis();   // aktuelle Zeit abspeichern
    srichtung1();
    }
    
    if (millis() - previousMillis > interval) {
    previousMillis = millis();   // aktuelle Zeit abspeichern
    srichtung2();
    }
    
    if (millis() - previousMillis > interval) {
    previousMillis = millis();   // aktuelle Zeit abspeichern
    srichtung3();
    }

Hi

Bei Deinem Versuch kann immer nur die erste IF gültig werden - und wenn, wird previousMIllis (bei mir heißt Das lastmillis - Da ist die Rechtschreibung auch nicht so ...) auf millis() gesetzt und die folgenden Abfragen KÖNNEN gar nicht wahr werden - die bisher vergangene Zeit ist ja jetzt wieder Null.

Versuche Mal Das:

if (entfernung > 51)
{
  static byte letzteanzeige=0;
  if (millis() - previousMillis > interval) {
    previousMillis = millis();   // aktuelle Zeit abspeichern
    switch case (letzteanzeige){
        case 0:    srichtung1();break;
        case 1:    srichtung2();break;
        case 2:    srichtung3();break;
        default:letzteanzeige=255; //Nullsetzen, etwas tricky, 255+1=0
    }
    letzteanzeige++;  //so kann ich hier hoch zählen und komme trotzdem auch auf Null
  }
}

MfG
Edit
Tatsächlich ist Da eine Klammer verschwunden ... wurde wieder 'montiert'
Welcher Case-Ausdruck nicht passt - sehe ich aber immer noch nicht :confused:

Hi,

vielen Dank. Das hat geklappt. :smiley:

Musste zwar noch dein Rätsel der fehlenden }-Klammer und des unpassenden Case-Ausdrucks lösen, aber das hab ich voller Zufriedenheit geschafft. Und dabei noch was gelernt.

Vielen Dank nochmal.

LG
Basti