INFO: Dieses Forum nutzt Cookies...
Cookies sind für den Betrieb des Forums unverzichtbar. Mit der Nutzung des Forums erklärst Du dich damit einverstanden, dass wir Cookies verwenden.

Es wird in jedem Fall ein Cookie gesetzt um diesen Hinweis nicht mehr zu erhalten. Desweiteren setzen wir Google Adsense und Google Analytics ein.

Antwort schreiben 
 
Themabewertung:
  • 0 Bewertungen - 0 im Durchschnitt
  • 1
  • 2
  • 3
  • 4
  • 5
Probleme mit dem Erzeugen von Tönen
03.01.2020, 13:58
Beitrag #1
Probleme mit dem Erzeugen von Tönen
Bisher habe ich wirklich alle Probleme meines Projektes mit der Hilfe von euch lösen können. Dafür zunächst mal herzlichen Dank!

Nun komme ich an den wahrscheinlich letzten Punkt meines Projektes. Entweder verstehe ich die Funktionsweise des Befehls falsch (ist recht wahrscheinlich so) oder der ESP32 Devkit V1 ist einfach nicht das geeignete Bauteil um dieses Problem zu lösen.

Problembeschreibung:
Ich möchte aus dem Steigwert eines Segelflugzeugs ein akustisches Signal machen. Die Tonfrequenz ist abhängig vom Steigwert. Wenn der Steigwert negativ ist, soll der Ton anhaltend sein. Ist der Steigwert positiv, soll der Ton einige ms anhalten und dann für 10ms unterbrochen werden.
Hier ein Beispiel:
https://www.youtube.com/watch?v=uwpnXf916gM

Ich habe versucht dies mit ledcWrite zu lösen:
Code:
if ((E > 0) && (E <= 8) && (E != Ealt)) {
            float d = (-0.8921 * pow(E, 3) + 16.068 * pow(E, 2) - 94.772 * E + 256.27);
            float f = (-0.3308 * pow(E, 4) + 7.8042 * pow(E, 3) - 64.994 * pow(E, 2) + 321.8 * E + 744.54 - 200);
            ledcWrite(channel, dutyCycle);
            ledcWriteTone(channel, f);
            delay(d);
            Serial.print("Vario Modus, Steigen: ");
            //Serial.println(E);
            ledcWrite(channel, 0);
            delay(10);

Die delays sind dazu gedacht, den Ton bei positiven Steigwerten zu unterbrechen, führen aber dazu, dass das Programm extrem hinterher hinkt. Das ist also keine gute Lösung. Ohne delay bekomme ich aber gar keinen Ton, weil das Programm wahrscheinlich kontinuierlich einen neuen Ton erzeugen möchte, und es dadurch zu Überlagerungen kommt. Also habe ich statt in der if-Anweisung ein delay nach der Abfrage des Wertes E eingefügt, der dann für alle Bereiche der Tonerzeugung gilt:
Code:
if (DataString.startsWith("$POV")) {
      pos = DataString.indexOf(',');
      DataString.remove(0, pos + 1);
      //
      //Analyse des Steigwertes
      //
      if (DataString[0] == 'E') {
        pos = DataString.indexOf(',');
        DataString.remove(0, pos + 1);
        pos = DataString.indexOf('*');
        for (i = 0; i < pos; i++) {
          Vario += DataString[i];
        }
        E = Vario.toFloat();
        Vario = "";
        delay(100);
      }

Logisch, dass dann alle Töne 100ms lang sind, und dann eine Unterbrechung kommt.
Also entweder eignet sich dieser Weg absolut gar nicht für mein Vorhaben, oder ich muss es anders lösen.

Wenn es z.B. die Möglichkeit gäbe, den Ton bspw. 10s lang ausgeben zu lassen, ihn aber abzubrechen, wenn es erforderlich ist. Dann wären die andauernden Töne bei negativen Steigwerten nicht unterbrochen, soll aber ein anderer Ton erzeugt werden, würde er vorzeitig abgebrochen, und das Programm würde nicht so langsam werden wie mit delay.

Hat jemand eine Idee, in welche Richtung ich da gehen sollte? Oder gibt es eine andere Hardware, die vielleicht besser geeignet ist?
Alle Beiträge dieses Benutzers finden
Diese Nachricht in einer Antwort zitieren
03.01.2020, 15:14
Beitrag #2
RE: Probleme mit dem Erzeugen von Tönen
(03.01.2020 13:58)Gerdchen03 schrieb:  Hat jemand eine Idee, in welche Richtung ich da gehen sollte?

Mach es ohne "delay()".

Hilfreich zur Umsetzung ist die Nachtwächtererklärung!

Gruß Fips

Meine Esp8266 & ESP32 Projekte
Webseite des Benutzers besuchen Alle Beiträge dieses Benutzers finden
Diese Nachricht in einer Antwort zitieren
03.01.2020, 18:57
Beitrag #3
RE: Probleme mit dem Erzeugen von Tönen
Danke!!
Für die gepulsten Töne funktioniert das mega.

Nun bleiben noch die anhaltenden, die aber kontinuierlich die Frequenz ändern sollen, ohne dass der Ton dabei unterbrochen wird. Big Grin
Alle Beiträge dieses Benutzers finden
Diese Nachricht in einer Antwort zitieren
03.01.2020, 19:04
Beitrag #4
RE: Probleme mit dem Erzeugen von Tönen
Dann zeige doch mal Deinen aktuellen Sketch.
Was verstehst Du unter "kontinuierlich ändern"? Eine gewisse Zeit lang muss der Ton schon gleich bleiben.

Gruß Tommy

"Wer den schnellen Erfolg sucht, sollte nicht programmieren, sondern Holz hacken." (Quelle unbekannt)
Alle Beiträge dieses Benutzers finden
Diese Nachricht in einer Antwort zitieren
03.01.2020, 19:57
Beitrag #5
RE: Probleme mit dem Erzeugen von Tönen
Code:
//    VarioSound is a programm to generate the vario sound using NMEA Output of OpenVario.
//    Copyright (C) 2019  Dirk Jung Blaubart@gmx.de
//
//    This program is free software: you can redistribute it and/or modify
//    it under the terms of the GNU General Public License as published by
//    the Free Software Foundation, either version 3 of the License, or
//    (at your option) any later version.
//
//    This program is distributed in the hope that it will be useful,
//    but WITHOUT ANY WARRANTY; without even the implied warranty of
//    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
//    GNU General Public License for more details.
//
//    You should have received a copy of the GNU General Public License
//    along with this program.  If not, see <https://www.gnu.org/licenses/>.

// Erzeugen des Variotons durch das e-Vario anstatt durch das OpenVario
// In den NMEA-Datenstrom müssen noch Werte für S, C, X, und ggf. a und c
// der Polaren eingebaut werden

#define RXD1 32
#define TXD1 33
#define RXD2 16
#define TXD2 -1 // -1 means it not used beacause of trouble with Dispolay-ESP32. Set TXD2 to 17 if you like to use

unsigned long Sound_timestore;

int SoundStatus = LOW;
int freq = 100;
int dutyCycle = 127;
int channel = 0;
int resolution = 16;
int SoundPIN = 26;
const int Varioschalter = 15;        //Taster an GND anschließen, 10 kOhm Pullup-Widerstand zw. 3,3V und Pin anschließen
const int STF_schalter = 5;          //Taster an GND anschließen, 10 kOhm Pullup-Widerstand zw. 3,3V und Pin anschließen

//Polar of H205 Club Libelle
float a = 0.000164875045587;
float c = 1.149709854615560;

double SF;           //Speedfaktor zur Berechnung des STF-Tons

float E;            //Variowert
float S;            //True Airspeed
float C;            // MacCready-Wert
float Ealt;
float SFalt;
float f;            //Frequenz Varioton
float f1;           //Frequenz STF-Ton
float d;            //Delay Varioton
float d1;           //Delay STF-Ton
float b;

String Climb = String("FLIGHTMODE_CLIMB");
String Cruise = String("FLIGHTMODE_CRUISE");
//String X;                                    //Aktivieren, wenn Übertragung von X umgesetzt ist
String X = String("FLIGHTMODE_CLIMB");         //Löschen, wenn Übertragung von X umgesetzt ist

void setup() {

  Serial.begin(115200, SERIAL_8N1);
  Serial1.begin(115200, SERIAL_8N1, RXD1, TXD1);
  Serial2.begin(115200, SERIAL_8N1, RXD2, TXD2);
  if (Serial2.available() > 0) {
    Serial.println("VarioSound is ready!!");
  }
  ledcSetup(channel, freq, resolution);
  ledcAttachPin(SoundPIN, channel);
  pinMode(SoundPIN, OUTPUT);
}

void loop() {
  char Data;
  String DataString, DataString_STF, Vario, STF, MCC, AS;
  int pos, pos1, pos2, pos3, i, i1, i2, i3;
  if (Serial2.available() > 0) {
    Data = Serial2.read();
    if (Data == '$') {
      while (Data != 10) {
        DataString += Data;
        Data = Serial2.read();
      }
    }

    if (DataString.startsWith("$POV")) {
      pos = DataString.indexOf(',');
      DataString.remove(0, pos + 1);
      //
      //Analyse des Steigwertes
      //
      if (DataString[0] == 'E') {
        pos = DataString.indexOf(',');
        DataString.remove(0, pos + 1);
        pos = DataString.indexOf('*');
        for (i = 0; i < pos; i++) {
          Vario += DataString[i];
        }
        E = Vario.toFloat();
        Vario = "";
      }
      //
      //Analyse der automatischen Sollfahrtumstellung
      //
      if (DataString[0] == 'X') {
        pos1 = DataString.indexOf(',');
        DataString.remove(0, pos1 + 1);
        pos1 = DataString.indexOf('*');
        for (i1 = 0; i1 < pos1; i1++) {
          STF += DataString[i1];
        }
        X = STF;
        STF = "";
      }
      //
      //Analyse des McCready-Wertes
      //
      if (DataString[0] == 'C') {
        pos2 = DataString.indexOf(',');
        DataString.remove(0, pos2 + 1);
        pos2 = DataString.indexOf('*');
        for (i2 = 0; i2 < pos2; i2++) {
          MCC += DataString[i2];
        }
        C = MCC.toFloat();
        MCC = "";
      }
      //
      //Analyse der true Airspeed
      //
      if (DataString[0] == 'S') {
        pos3 = DataString.indexOf(',');
        DataString.remove(0, pos3 + 1);
        pos3 = DataString.indexOf('*');
        for (i3 = 0; i3 < pos3; i3++) {
          AS += DataString[i3];
        }
        S = AS.toFloat();
        AS = "";
      }
      DataString = "";
    }
  }

  int Varioschalter_state = digitalRead(Varioschalter);
  int STF_schalter_state = digitalRead(STF_schalter);

  //
  //Varioton erzeugen
  //

  if (((Varioschalter_state == 1) && (STF_schalter_state == 0)) || ((Varioschalter_state == 1) && (STF_schalter_state == 1) && (X == Climb))) {
    if ((E >= -8) && (E <= -2) && (E != Ealt)) {
      float f = (17.33 * E + 483.67);
      if (millis() - Sound_timestore > 300 ) {
        ledcWrite(channel, dutyCycle);
        ledcWriteTone(channel, f);
        Sound_timestore = millis();
        SoundStatus = HIGH;
        //Serial.print("Vario Modus, sehr starkes Saufen: ");
        //Serial.println(E);
      }
    }

    else {
      if ((E > -2) && (E < -0.7) && (E != Ealt)) {
        float f = (74.615 * E + 598.23);
        if (millis() - Sound_timestore > 300 ) {
          ledcWrite(channel, dutyCycle);
          ledcWriteTone(channel, f);
          Sound_timestore = millis();
          SoundStatus = HIGH;
          //Serial.print("Vario Modus, starkes Saufen: ");
          //Serial.println(E);
        }
      }

      else {
        if ((E >= -0.7) && (E <= 0) && (E != Ealt)) {
          float f = (287.14 * E + 747);
          if (millis() - Sound_timestore > 300 ) {
            ledcWrite(channel, dutyCycle);
            ledcWriteTone(channel, f);
            Sound_timestore = millis();
            SoundStatus = HIGH;
            //Serial.print("Vario Modus, leichtes Saufen: ");
            //Serial.println(E);
          }
        }

        else {
          if ((E > 0) && (E <= 8) && (E != Ealt)) {
            float d = (-0.8921 * pow(E, 3) + 16.068 * pow(E, 2) - 94.772 * E + 256.27);
            float f = (-0.3308 * pow(E, 4) + 7.8042 * pow(E, 3) - 64.994 * pow(E, 2) + 321.8 * E + 744.54 - 200);
            if (millis() - Sound_timestore > d + 10 ) {
              ledcWrite(channel, dutyCycle);
              ledcWriteTone(channel, f);
              Sound_timestore = millis();
              SoundStatus = HIGH;
              //Serial.print("Vario Modus, Steigen: ");
              //Serial.println(E);
            }
            else {
              if (millis() - Sound_timestore > d) {
                digitalWrite(SoundPIN, LOW);
                SoundStatus = LOW;
              }
            }
          }
          else {
            if ((E < -8) && (E != Ealt)) {
              float f = 340;
              if (millis() - Sound_timestore > 100000 ) {
                ledcWrite(channel, dutyCycle);
                ledcWriteTone(channel, f);
                Sound_timestore = millis();
                SoundStatus = HIGH;
                //Serial.print("Vario Modus, extremes Saufen: ");
                //Serial.println(E);
              }
            }
            else {
              if ((E > 8) && (E != Ealt)) {
                float f = 1850 - 200;
                if (millis() - Sound_timestore > 85 ) {
                  ledcWrite(channel, dutyCycle);
                  ledcWriteTone(channel, f);
                  Sound_timestore = millis();
                  SoundStatus = HIGH;
                  //Serial.print("Vario Modus, extremes Steigen: ");
                  //Serial.println(E);
                }
                else {
                  if (millis() - Sound_timestore > 65) {
                    digitalWrite(SoundPIN, LOW);
                    SoundStatus = LOW;
                  }
                }
              }
            }
          }
        }
      }
    }
  }
  float Ealt = E;

  //
  //Sollfahrtton erzeugen
  //

  if (((Varioschalter_state == 0) && (STF_schalter_state == 1)) || ((Varioschalter_state == 1) && (STF_schalter_state == 1) && (X == Cruise))) {
    SF = (S - sqrt(abs((c - E + C) / a))) / 10;
    if ((SF >= -8) && (SF <= -2) && (SF != SFalt)) {
      float f1 = (17.33 * E + 483.67);
      //Serial.println("STF Modus, sehr schnell fliegen:");
      ledcWrite(channel, dutyCycle);
      ledcWriteTone(channel, f1);
    }

    else {
      if ((SF > -2) && (SF < -0.5) && (SF != SFalt)) {
        float f1 = (74.615 * E + 598.23);
        //Serial.println("STF Modus, schnell fliegen:");
        ledcWrite(channel, dutyCycle);
        ledcWriteTone(channel, f1);
      }

      else {
        if ((SF >= -0.5) && (SF <= 0.5) && (SF != SFalt)) {
          float f1 = 0;
          //Serial.println("STF Modus, langsam fliegen:");
          ledcWrite(channel, dutyCycle);
          ledcWriteTone(channel, f1);
        }

        else {
          if ((SF > 0.5) && (SF <= 8) && (SF != SFalt)) {
            float d1 = (-0.8921 * pow(SF, 3) + 16.068 * pow(SF, 2) - 94.772 * SF + 256.27);
            float f1 = (-0.3308 * pow(SF, 4) + 7.8042 * pow(SF, 3) - 64.994 * pow(SF, 2) + 321.8 * SF + 744.54 - 200);
            //Serial.println("STF Modus, sehr langsam fliegen:");
            ledcWrite(channel, dutyCycle);
            ledcWriteTone(channel, f1);
            delay(d1);
          }
          else {
            if ((SF < -8) && (SF != SFalt)) {
              float f1 = 340;
              //Serial.println("STF Modus, extrem schnell fliegen:");
              ledcWrite(channel, dutyCycle);
              ledcWriteTone(channel, f1);
            }
            else {
              if ((SF > 8) && (SF != SFalt)) {
                float f1 = 1850 - 200;
                //Serial.println("STF Modus, extrem langsam fliegen:");
                ledcWrite(channel, dutyCycle);
                ledcWriteTone(channel, f1);
                delay(65);
              }
            }
          }
        }
      }
    }
    float SFalt = SF;
  }

  //
  //Störungsanzeige, falls Schalter beschädigt
  //

  if ((Varioschalter_state == 0) && (STF_schalter_state == 0)) {
    Serial.println("Störung: Vario und STF Mode gleichzeitig aktiv. Überprüfe des Scahlter am Vario!");
    float f = 2000;
    if (millis() - Sound_timestore > 1000 ) {
      ledcWrite(channel, dutyCycle);
      ledcWriteTone(channel, f);
      Sound_timestore = millis();
      SoundStatus = HIGH;
    }
    else {
      if (millis() - Sound_timestore > 500) {
        digitalWrite(SoundPIN, LOW);
        SoundStatus = LOW;
      }
    }
  }
}

Es geht speziell um diesen Bereich.
Code:
if ((E >= -8) && (E <= -2) && (E != Ealt)) {
      float f = (17.33 * E + 483.67);
      if (millis() - Sound_timestore > 300 ) {
        ledcWrite(channel, dutyCycle);
        ledcWriteTone(channel, f);
        Sound_timestore = millis();
        SoundStatus = HIGH;
        //Serial.print("Vario Modus, sehr starkes Saufen: ");
        //Serial.println(E);
      }
    }

Ich meine sowas wie eine Tonleiter. Am Besten du schaust dir das mal in dem Video ab der 7. Sekunde an. Da zeigt das Vario kurz sinken an, und da ist der nicht gepulste Ton, dessen Frequenz sich aber mit zunehmendem Sinken verändert.
Alle Beiträge dieses Benutzers finden
Diese Nachricht in einer Antwort zitieren
03.01.2020, 20:01
Beitrag #6
RE: Probleme mit dem Erzeugen von Tönen
Da musst Du schauen, wie weit Du die 300 verringern kannst, bis nichts Sinnvolles mehr zu hören ist.
Etwas anderes dürfte wohl kaum möglich sein.

Gruß Tommy

"Wer den schnellen Erfolg sucht, sollte nicht programmieren, sondern Holz hacken." (Quelle unbekannt)
Alle Beiträge dieses Benutzers finden
Diese Nachricht in einer Antwort zitieren
03.01.2020, 20:06 (Dieser Beitrag wurde zuletzt bearbeitet: 03.01.2020 20:07 von Tommy56.)
Beitrag #7
RE: Probleme mit dem Erzeugen von Tönen
Ergänzung: Videos interessieren mich nicht.

Gruß Tommy

"Wer den schnellen Erfolg sucht, sollte nicht programmieren, sondern Holz hacken." (Quelle unbekannt)
Alle Beiträge dieses Benutzers finden
Diese Nachricht in einer Antwort zitieren
03.01.2020, 20:11
Beitrag #8
RE: Probleme mit dem Erzeugen von Tönen
Zitat:Da musst Du schauen, wie weit Du die 300 verringern kannst, bis nichts Sinnvolles mehr zu hören ist.
Etwas anderes dürfte wohl kaum möglich sein.

Hab ich schon mit rumgespielt, wird aber dann eben sehr abgehackt.
Alle Beiträge dieses Benutzers finden
Diese Nachricht in einer Antwort zitieren
Antwort schreiben 


Möglicherweise verwandte Themen...
Thema: Verfasser Antworten: Ansichten: Letzter Beitrag
  Probleme nach Bord und Bibliothek Update TT-Tom 9 1.432 16.11.2019 19:48
Letzter Beitrag: Fips
  Probleme bei Auslesen des seriellen Ports Gerdchen03 26 1.943 17.10.2019 09:03
Letzter Beitrag: Gerdchen03
  Probleme mit TTGO-Modul scritch 6 1.182 27.08.2019 22:22
Letzter Beitrag: Bitklopfer
  Probleme mit dem kompilieren ErzGabriel 29 6.795 26.01.2019 14:59
Letzter Beitrag: ErzGabriel
  ESP32 Deepsleep und FRITZ!Box 7590 WiFi probleme. MeisterQ 42 12.496 08.01.2019 09:33
Letzter Beitrag: Hoffmakl
  Probleme mit Nodemcu, Blynk und Oled MasterOfPuppets 3 2.223 10.03.2018 21:52
Letzter Beitrag: Fips
  Probleme mit ESP8266 BennIY 6 3.672 20.11.2016 14:49
Letzter Beitrag: BennIY
  ESP8266 EEPROM Probleme Pf@nne 5 9.292 09.10.2015 18:00
Letzter Beitrag: Pf@nne
  Probleme mit ESP8266 giessbee 1 4.545 09.06.2015 22:47
Letzter Beitrag: Scherheinz

Gehe zu:


Benutzer, die gerade dieses Thema anschauen: 1 Gast/Gäste