Piezo Summer mit Unterbrechungsintervall

Hallo,

ich möchte gerne einen Piezo Summer ansteuern, aber kein dauerhafter piepsen, sondern mit Unterbrechungen. Versuche das mit der INTERVAL-Funktion.

      INTERVAL(100)
      {
                    // Regelung Buzzer
                    if (led1_buzzer == true or led2_buzzer == true)
                    {
                      analogWrite(buzzer, 50);   // Buzzer an
                    }
      
                    else
                    {
                      analogWrite(buzzer, LOW);   // Buzzer aus
                    }
      
      }

Ziel ist es immer wenn die if-Bedingung erfüllt ist, soll er genau das gegenteil machen. Also wenn Buzzer an ist, soll er ihn aus machen und umgekehrt. Ist die Bedingung nicht erfüllt, geht er in die else und macht den Buzzer aus. Bei LEDs ging das ja mit dem ! vor dem Befehl, aber da gibts ja nur 2 Zustände (HIGH,LOW). Wie geht das bei nem Buzzer?

Was für einen Summer verwendest du?
Aktiv oder passiv?

Warum verwendest du “analogWrite” und nicht “tone”?
Ich kann mir nicht vorstellen, das es so richtig funktioniert.

amanera:
Wie geht das bei nem Buzzer?

Das hängt konkret vom verwendeten Buzzer ab. Da gibt es ganz verschiedene!

Im wesentlichen unterscheidet man diese zwei Arten von Piezo-Buzzern:

  1. Active Buzzer mit eingebauter Tonerzeugung, diese brauchen nur Betriebsspannung und piepsen dann
  2. Passive Buzzer, die mit einer Tonfreqquenz angesteuert werden müssen, diese können in verschiedenen Frequenzen piepsen und dadurch beispielsweise (mit geigneter Ansteuerung) auch ganze Melodien abspielen.

Man

Ist ein “Piezo Buzzer - PS1240”, ob der aktiv oder passiv ist, steht leider nicht dabei.

          INTERVAL(300)
          
          {
          
                        // Regelung Buzzer
                        if (led1_buzzer == true or led2_buzzer == true)
                        {
                          tone(buzzer,500,150);
                        }
          
          
                        else
                        {
                            digitalWrite(buzzer, LOW);
                        }
          
          }

Habs jetzt mal mit tone() probiert. Habe die Duration auf 150 gesetzt, also genau die Hälfte vom Intervall. Leider ist die Dauer des Tons nicht 100% gleichmäßig wie die Unterbrechungen.

Es gibt doch bestimmt eine elegantere Lösung als die obige oder?

amanera:
Ist ein "Piezo Buzzer - PS1240", ob der aktiv oder passiv ist, steht leider nicht dabei.

Aber es steht dabei:

Drive it with 3-30V peak-to-peak square wave.

Ofensichtlich ein passiver B uzzer, der mit einer Tonfrequenz angesteuert werden muss.

D.h. anschließen an GND und einen Arduino-Pin und dann mit der tone() Funktion eine Frequuenz draufgeben.

amanera:
Es gibt doch bestimmt eine elegantere Lösung als die obige oder?

Eine Lösung kannst Du formulieren, NACHDEM Du die Aufgabe formulierst hast.
Was möchtest Du?

Der Buzzer soll einen Stakkato-Ton mit einer Frequenz von 500Hzertz erzeugen, pro 300ms Intervall immer 150ms an und 150ms aus?
Das ginge z.B. so:

void loop
{
 tone(buzzer,500,150);
delay(150);
noTone(buzzer);
delay(150);

}

Wenn Du was anderes möchtest, dann formuliere, was genau Du möchtest!

Ein schlauer Mensch hat mal diesen sehr trick- und lehrreichen Code gepostet:

if(millis()%(500+2000)<500)
  {
  analogWrite(9, 80);
  }
  else
  {
    analogWrite(9, 0);
  }

Hab ich geklaut für meine akustische Rückmeldung und das funktioniert einfach sehr geschmeidig und natürlich ohne ein Delay.
Über die Parameter lassen sich (fast) beliebige an/aus Intervalle basteln.

amanera:

          INTERVAL(300)

{
         
                        // Regelung Buzzer
                        if (led1_buzzer == true or led2_buzzer == true)
                        {
                          tone(buzzer,500,150);
                        }
         
         
                        else
                        {
                            digitalWrite(buzzer, LOW);
                        }
         
          }

Kompiliert das?

Ich finde das "or" etwas merkwürdig, ich würde dir da || ans Herz legen.

nimm doch eine bool Variable und !, dann ist das ähnlich wie !digitalRead

Ich finde das "or" etwas merkwürdig, ich würde dir da || ans Herz legen.

Erstaunlicherweise geht das sogar. Das stammt aus C Urzeiten wo es nicht sicher war dass Zeichen wie & oder | auf der Tastatur waren. Später wurde dass dann in C++ übernommen

Ähnlich wie dem Spanier war mir das auch neu. Danke Serenifly.

The ISO C specification makes allowance for these keywords as preprocessor macros in the header file iso646.h. For compatibility with C, C++ provides the header ciso646, the inclusion of which has no effect.

Allerdings verstehe ich das so, dass es in C++ dazuerfunden wurde und wahlweise in C nach

#include <iso646.h>

auch verwendet werden kann.

Man sollte also eine Variable möglichst nicht bitand nennen :wink:

Und die && vs. & Problematik wird durch and vs. bitand nur unwesentlich verbessert, weil man in Zweifelsfall gar nicht merkt, dass man gerade Mist macht.

In C gab es das glaube ich schon vorher. Allerdings nicht als Teil des Standards und als Makros. Das wurde dann in C++ als übernommen (als “alternative tokens” die ähnlich wie Makros vor dem Compileren geändert werden. Anders als keywords). Außer wohl in MS Visual C++, welches den Header mit Makros benötigt.

Und wie gesagt dient es nicht immer der Lesbarkeit, sondern damit man es überhaupt schreiben kann. Wie Trigraphen, wo sich IBM jahrelang gegen deren Abschaffung gewehrt hat.