Gleicher Code, andere Variablen, keine Funktion

Guten Tag, ich habe diesen Parksensor im Projecthub gefunden und dieser funktioniert tadellos:

/**************************************************************
 *  PARKING SENSOR WITH HC-SR04                               *
 *                                                            *
  *  This code receives data from the HC-SR04 proximity        *
 *  sensor, analyses  them, sends them to the serial monitor   *
 *  and produces intermittent sounds  to warn of an obstacle.  *
 **************************************************************/

//  Definition of trigger, echo, beep pins and other constants
#define trigger      2
#define  echo         3
#define beep        11
#define beep_start 100
#define min_distance  5

// Definition of sound speed (centimetres / microsecond)
#define c 0.0343

//  Definition of the variables
long tempo;
float space;

void setup() {
  // Definition of input and output
  pinMode(trigger, OUTPUT);
  pinMode(echo,  INPUT);
  pinMode(beep, OUTPUT);

  // Serial communication initialisation  (optional)
  Serial.begin(9600);
}

void loop() {
  // Before measurement,  the trigger is set to low level
  digitalWrite(trigger, LOW);
  delayMicroseconds(5);

  // Send one pulse (trigger goes high level for 10 microseconds)
  digitalWrite(trigger,  HIGH);
  delayMicroseconds(10);
  digitalWrite(trigger, LOW);

  //  Reading echo, via pulseIn, which returns the duration of the impuse (in microseconds)
  // The acquired data is then divided by 2 (forward and backward)
  tempo =  pulseIn(echo, HIGH) / 2;
  // Computation of distance in centimetres
  space  = tempo * c;

  // space is displayed in the serial monitor ([Ctrl] + [Shift]  + M)
  // approximated to the first decimal place
  Serial.println("Distanza  = " + String(space, 1) + " cm");

  // If the distance is less than one  metre
  if (space < beep_start) { 
    // Emits sounds at intervals proportional  to distance (1 m = 400 ms)
    tone(beep, 1000); 
    delay(40);
    //  Below min_distance cm it emits a continuous sound
    if (space > min_distance)  {
      noTone(beep); 
      delay(space * 4);
    }
  } 
  // Waits  50 milliseconds before another measurement
  delay(50);
}

Nun habe ich mir gedacht, ein Auto hat nicht nur hinten einen Sensor, sondern auch vorne. Also habe ich den Code mehr oder weniger copy pasted:

/**************************************************************
 *  PARKING SENSOR WITH HC-SR04                               *
 *                                                            *
  *  This code receives data from the HC-SR04 proximity        *
 *  sensor, analyses  them, sends them to the serial monitor   *
 *  and produces intermittent sounds  to warn of an obstacle.  *
 **************************************************************/

//  Definition of trigger, echo, beep pins and other constants
#define trigger      2
#define  echo         3
#define beep        4
#define beep_start 20
#define min_distance  5

#define trigger2      5
#define  echo2         6
#define beep2        7
#define beep_start2 200
#define min_distance2  5

// Definition of sound speed (centimetres / microsecond)
#define c 0.0343
#define c2 0.0343

//  Definition of the variables
long tempo;
float space;
long tempo2;
float space2;

void setup() {
  // Definition of input and output
  pinMode(trigger, OUTPUT);
  pinMode(echo,  INPUT);
  pinMode(beep, OUTPUT);

  // Serial communication initialisation  (optional)
  Serial.begin(9600);
}

void loop() {
    // Before measurement,  the trigger is set to low level
  digitalWrite(trigger, LOW);
  delayMicroseconds(5);

  // Send one pulse (trigger goes high level for 10 microseconds)
  digitalWrite(trigger,  HIGH);
  delayMicroseconds(10);
  digitalWrite(trigger, LOW);

  //  Reading echo, via pulseIn, which returns the duration of the impuse (in microseconds)
  // The acquired data is then divided by 2 (forward and backward)
  tempo =  pulseIn(echo, HIGH) / 2;
  // Computation of distance in centimetres
  space  = tempo * c;

  // space is displayed in the serial monitor ([Ctrl] + [Shift]  + M)
  // approximated to the first decimal place
  Serial.println("Distanza  = " + String(space, 1) + " cm");

  // If the distance is less than one  metre
  if (space < beep_start) { 
    // Emits sounds at intervals proportional  to distance (1 m = 400 ms)
    tone(beep, 1000); 
    delay(40);
    //  Below min_distance cm it emits a continuous sound
    if (space > min_distance)  {
      noTone(beep); 
      delay(space * 4);
    }
  } 
  // Waits  50 milliseconds before another measurement
  delay(50);
      // Before measurement,  the trigger is set to low level
  digitalWrite(trigger2, LOW);
  delayMicroseconds(5);

  // Send one pulse (trigger goes high level for 10 microseconds)
  digitalWrite(trigger2,  HIGH);
  delayMicroseconds(10);
  digitalWrite(trigger2, LOW);

  //  Reading echo, via pulseIn, which returns the duration of the impuse (in microseconds)
  // The acquired data is then divided by 2 (forward and backward)
  tempo2 =  pulseIn(echo2, HIGH) / 2;
  // Computation of distance in centimetres
  space2  = tempo2 * c;

  // space is displayed in the serial monitor ([Ctrl] + [Shift]  + M)
  // approximated to the first decimal place
  Serial.println("Distanza2  = " + String(space, 1) + " cm");

  // If the distance is less than one  metre
  if (space2 < beep_start2) { 
    // Emits sounds at intervals proportional  to distance (1 m = 400 ms)
    tone(beep2, 1001); 
    delay(40);
    //  Below min_distance cm it emits a continuous sound
    if (space2 > min_distance2)  {
      noTone(beep2); 
      delay(space2 * 4);
    }
  } 
  // Waits  50 milliseconds before another measurement
  delay(50);
}

Aber aus irgendeinem Grund funktioniert es einfach nicht, obwohl ich doch einfach nur hinter jede Variable eine 2 gesetzt habe, ist alles identisch, aber in TinkerCAD piept der zweite Piezo durchgehend, und nichts Weiteres läuft.
Ich habe auch schon einfach zwei void loops genommen einmal halt void sensor1 und void sensor2, die beide im void loop drinne waren, also auch liefen.

Dann mach das doch konsequent so weiter und initialisiere auch die neuen Pins im Setup.

Herzlichen Glückwunsch.
Du hast in einer frühen Phase des Lernens erkannt, warum man das genau nicht macht.

Was hat Dir an der Antwort

nicht gepasst, dass Du auch hier einen neuen Thread aufmachst?

1 Like

Hi @my_xy_projekt ,

vielleicht werden ja auch drei, vier oder noch mehr Sensoren benötigt? :wink:

Die Aufgabe hat mich mal gereizt:

/*
  Forum: https://forum.arduino.cc/t/gleicher-code-andere-variablen-keine-funktion/1381736
  Wokwi: https://wokwi.com/projects/431030224650716161

  Handles several sensors (here four).
  The minimum distance of all sensors is used to control the buzzer.
  Each sensor has its own frequency.
  Buzzer control is non-blocking.

  ec2021
  2025/05/15

*/

constexpr float microsecond2CM {0.0343};

struct dataS {
  byte trigger;
  byte echo;
  long frequency;
};

//  Definition of trigger, echo, frequency for each sensor
constexpr dataS sensorData[] = {
  { 3, 2,  400},
  {10, 9,  600},
  { 8, 7,  800},
  { 6, 5, 1000}
};
constexpr int noOfSensors = sizeof(sensorData) / sizeof(sensorData[0]);

constexpr byte beepPin    {11};
constexpr long beep_start {100};
constexpr long min_distance  {5};


class sensorClass {
  private:
    byte trigger;
    byte echo;
  public:
    long frequency;
    void init(dataS s) {
      trigger = s.trigger;
      echo    = s.echo;
      frequency = s.frequency;
      pinMode(trigger, OUTPUT);
      pinMode(echo,  INPUT);
    }
    float getDistance() {
      digitalWrite(trigger, LOW);
      delayMicroseconds(5);
      digitalWrite(trigger,  HIGH);
      delayMicroseconds(10);
      digitalWrite(trigger, LOW);
      long returnTime =  pulseIn(echo, HIGH) / 2;
      return  (returnTime * microsecond2CM);
    }
};

sensorClass sensor[noOfSensors];

void setup() {
  for (int i = 0; i < noOfSensors; i++) {
    sensor[i].init(sensorData[i]);
  }

  pinMode(beepPin, OUTPUT);
  Serial.begin(115200);
}

void loop() {
  float space = 9999;
  long frequency = 2000;
  for (auto s : sensor) {
    float sp = s.getDistance();
    if (sp < space) {
      space = sp;
      frequency = s.frequency;
    }
  }
  handleDistance(space, frequency);
}

void handleDistance(float distance, long freq) {
  static unsigned long lastChangeTime = 0;
  static byte lastMode = 0;
  static boolean buzzOff = true;
  byte mode = 0;
  if (distance < beep_start) {
    mode = 1;
    if (distance > min_distance)  {
      mode = 2;
    }
  }
  switch (mode) {
    case 0:
      if (lastMode == 0) return;
      noTone(beepPin);
      break;
    case 1:
      if (lastMode == 1) return;
      lastChangeTime = millis();
      tone(beepPin, freq);
      break;
    case 2:
      unsigned long interval = distance * 4 + 50;
      if (!buzzOff) interval = 40;
      if (millis() - lastChangeTime > interval) {
        lastChangeTime = millis();
        if (buzzOff) {
          tone(beepPin, freq);
        } else {
          noTone(beepPin);
        }
        buzzOff = !buzzOff;
      }
      break;
  }
  lastMode = mode;
}

Siehe https://wokwi.com/projects/431030224650716161

  • Nicht blockierendes Buzzern ...
  • Frequenz des Buzzers je Sensor wählbar
  • Einfach erweiterbar über das Array sensorData vom Typ dataS:
//  Definition of trigger, echo, frequency for each sensor
constexpr dataS sensorData[] = {
  { 3, 2,  400},
  {10, 9,  600},
  { 8, 7,  800},
  { 6, 5, 1000}
};

Da kommt copy/paste mit Anhängen von Ziffern nicht dran ... :wink:

Gruß
ec2021

2 Likes

Geil, das die Sensoren ohne Strom gehen :slight_smile:

Genau, das ist klimaschonend ... :slight_smile:

Die Beschaltung mit GND/Vcc kann man bei Wokwi i.d.R. weglassen. Nicht realistisch, aber spart Zeit und macht die übrige Verkabelung halt etwas übersichtlicher ...

(Könnte natürlich auch behaupten, dass die Sensoren von der Rückseite mit Spannung versorgt werden. Bin aber kein Politiker in führender Position :wink: )

Und irgendwas ist ja immer ...

Gruß
ec2021

P.S.: Und der Arduino funktioniert sogar ohne USB-Kabel ...

das wäre morgen der neue Thread geworden...

Vorauseilende Programmierung :wink:

#define ersetzt ja nur den Text vor dem Leerzeichen mit dem nach dem Leerzeichen.

Berücksichtigt das Ersetzen Leerzeichen im Suchtext oder ersetzt es auch Zeichenfolgen die Teil einer anderen Zeichenfolge (Word) ist?

oder anders gefragt wird durch

#define trigger      2

aus

#define trigger2      5

gleich

#define 22      5

?

Grüße Uwe

nein.

Erster Absatz unter Hinweise.

Gut, da merkt man, dass ich noch nicht so viel Plan davon habe, ich bin beim alten Programm geblieben und an sich funktioniert es auch, sowohl physisch als auch in TinkerCAD, ABER die Piezos piepen bei sinkender Distanz nicht zunehmend schneller. UND wenn der eine Piezo bei der min_distance durchgehend piept, geht der andere aus...

#define PsHiEc A5
#define PsTrig A4
#define PsHiBe 3
#define PsHiWE 4
#define PsHiME 5
#define PsHiKE 6
#define PsVoEc A3
#define PsVoBe 2
#define PsVoWE 9
#define PsVoME 8
#define PsVoKE 7
#define MoRuEr A2
#define MoVoEr A1
#define BliHeb A0
#define LeBlLi 10
#define LeBlRe 11
#define LeLeHi 12
#define LeLeVo 13
#define BeStHi 30
#define BeStVo 30

#define min_distanceHi  10
#define min_distanceVo  10
#define cHi 0.0343
#define cVo 0.0343

long tempoVo;
long tempoHi;
float spaceVo;
float spaceHi;
int potiPin = A0;
int BliHebVal = 0;

bool blinkModus = false;

void setup() {
  pinMode(PsHiEc,INPUT);
  pinMode(PsTrig,OUTPUT);
  pinMode(PsHiBe,OUTPUT);
  pinMode(PsHiWE,OUTPUT);
  pinMode(PsHiME,OUTPUT);
  pinMode(PsHiKE,OUTPUT);
  pinMode(PsVoEc,INPUT);
  pinMode(PsVoBe,OUTPUT);
  pinMode(PsVoWE,OUTPUT);
  pinMode(PsVoME,OUTPUT);
  pinMode(PsVoKE,OUTPUT);
  pinMode(MoRuEr,INPUT);
  pinMode(MoVoEr,INPUT);
  pinMode(BliHeb,INPUT);
  pinMode(LeBlLi,OUTPUT);
  pinMode(LeBlRe,OUTPUT);
  pinMode(LeLeVo,OUTPUT);
  pinMode(LeLeHi,OUTPUT);
  
  Serial.begin(9600);
}

void loop() {
  blinkerSteuerung();
  parkSensorik();
  BliHebVal = analogRead(potiPin);
  Serial.println(BliHebVal);
}
void blinkerSteuerung() {
//Auswertung, auf welcher Stelle der Blinker steht
  if (BliHebVal < 400) {
    blinkModus = true;
    digitalWrite(LeBlLi, HIGH);
    delay(1000);
    digitalWrite(LeBlLi, LOW);
  }
  else if (BliHebVal > 600) {
    blinkModus = true;
    digitalWrite(LeBlRe, HIGH);
    delay(1000);
    digitalWrite(LeBlRe, LOW);
  }
  else {
    blinkModus = false;
    digitalWrite(LeBlLi, LOW);
    digitalWrite(LeBlRe, LOW);
  }
}
void parkSensorik() {
  if (blinkModus) {
//Parksensorik Vorne
  digitalWrite(PsTrig, LOW);
  delayMicroseconds(5);

  digitalWrite(PsTrig,  HIGH);
  delayMicroseconds(10);
  digitalWrite(PsTrig, LOW);

  tempoVo =  pulseIn(PsVoEc, HIGH) / 2;
  spaceVo  = tempoVo * cVo;

  Serial.println("Distanz Vorne = " + String(spaceVo, 1) + " cm");

  if (spaceVo < BeStVo) { 
    tone(PsVoBe, 1000); 
    delay(40);
    if (spaceVo > min_distanceVo)  {
      noTone(PsVoBe); 
      delay(spaceVo * 4);
    }
  } 
  delay(50);
    //Parksensorik Hinten
      digitalWrite(PsTrig, LOW);
  delayMicroseconds(5);

  digitalWrite(PsTrig,  HIGH);
  delayMicroseconds(10);
  digitalWrite(PsTrig, LOW);

  tempoHi =  pulseIn(PsHiEc, HIGH) / 2;
  spaceHi  = tempoHi * cHi;

  Serial.println("Distanz Hinten = " + String(spaceHi, 1) + " cm");

  if (spaceHi < BeStHi) { 
    tone(PsHiBe, 1000); 
    delay(40);
    if (spaceHi > min_distanceHi)  {
      noTone(PsHiBe); 
      delay(spaceHi * 4);
    }
  } 
  delay(50);
  }
}

Scheinbar ja nicht.

Hast du dir mal Post #4 angesehen? Da ist eine elegante Lösung drin.

Nur mal als Tipp: Solange du mit delay() arbeitest, wirst du nicht glücklich werden.

1 Like

Und warum nimmst Du dann Hilfe nicht an?

Du hast doch gemerkt, dass das nicht funktioniert.
Und nu sollen wieder alle von vorne anfangen?

Viele Beispiele der Arduino-Welt sind so abgefasst, dass sie nur genau die spezielle (begrenzte) Konfiguration abdecken.

Das ist nicht zwingend falsch, sondern erleichtert in der Regel den Einstieg und das Erlernen der grundsätzlichen Handhabung eines bestimmten Sensors, Aktuators oder Verfahrens.

Wer mehr will, ist leider gezwungen, sich aus der Welt der stark vereinfachten Basisrezepte herauszuarbeiten und zu lernen, die grundsätzlichen Einschränkungen zu erkennen und zu vermeiden. Eine häufige davon ist die Einschränkung durch blockierende Funktionen, seien es delays oder längere Schleifen.

Die meisten Mikrokontroller können nur eine Sache zur Zeit abarbeiten, das aber extrem schnell. Nutzt man die Schnelligkeit aus, erscheint es uns dem gegenüber extrem langsamen Menschen so, als passiere es gleichzeitig.

Vergleiche mal die Abläufe in meinen Sketch mit Deinem daraufhin...

Gruß
ec2021

Der Code ist echt cool, sehr komplex und alles, aber in Wokwi funktioniert alles (auch geringfügig von mir für mein kleines Projekt modifiziert), aber seltsamer weise bricht alles im Arduino IDE zusammen... wenn ich den Code compile und hochlade piepst es einfach durchgehend am physischen Modell. Ich habe auch in Wokwi einen serial.println für die Distanz eingefügt, das funktioniert, aber im Arduino IDE sind nur so Fragezeichen-Emojis (�). Gibt es da bessere Programme zum Hochladen oder so?

Stelle den Seriellen Monitor so ein, wie Du ihn im Code eingestellt hast, dann siehst Du auch was.

Baudrate

Noch eine Frage:

Der Wokwi Sketch unterstützt vier Sensoren.

Hast Du

a) vier Sensoren angeschlossen und
b) an den im Sketch angegebenen Pins?

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.