Arduino OBD2 Soundgenrator

// Copyright (c) Simon2008
// This Sketch should funkction as an OBD2-Soundgenerator and driving-data-monitor


#include <CAN.h>

// Most cars support 11-bit adddress, others (like Honda),
// require 29-bit (extended) addressing, set the next line
// to true to use extended addressing
const bool useStandardAddressing = true;



////////////////////////////////////////////////////////////////////////////////////////////////////////////
//Setup/////////////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////////////////

void setup() {
  Serial.begin(9600);

  Serial.println("CAN OBD-II Soundgenerator");

  // start the CAN bus at 500 kbps
  if (!CAN.begin(500E3)) {
    Serial.println("Starting CAN failed!");
    while (1);
  }

  // add filter to only receive the CAN bus ID's we care about
  if (useStandardAddressing) {
    CAN.filter(0x7e8);
  } else {
    CAN.filterExtended(0x18daf110);
  }
}



////////////////////////////////////////////////////////////////////////////////////////////////////////////
//Loop//////////////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////////////////

void loop() {



////////////////////////////////////////////////////////////////////////////////////////////////////////////
//vehicle speed/////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////////////////

  if (useStandardAddressing) {
    CAN.beginPacket(0x7df, 8);
  } else {
    CAN.beginExtendedPacket(0x18db33f1, 8);
  }
  CAN.write(0x02); // number of additional bytes
  CAN.write(0x01); // show current data
  CAN.write(0x0d); // vehicle speed
  CAN.endPacket();

  // wait for response
  while (CAN.parsePacket() == 0 ||
         CAN.read() < 2 ||          // correct length
         CAN.read() != 0x41 ||      // correct mode
         CAN.read() != 0x0d);       // correct PID

  float kmh = ((CAN.read()));

  Serial.print("Speed = ");
  Serial.println(kmh);



////////////////////////////////////////////////////////////////////////////////////////////////////////////
//engine speed//////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////////////////

if (useStandardAddressing) {
    CAN.beginPacket(0x7df, 8);
  } else {
    CAN.beginExtendedPacket(0x18db33f1, 8);
  }
  CAN.write(0x02); // number of additional bytes
  CAN.write(0x01); // show current data
  CAN.write(0x0c); // engine RPM
  CAN.endPacket();

  // wait for response
  while (CAN.parsePacket() == 0 ||
         CAN.read() < 3 ||          // correct length
         CAN.read() != 0x41 ||      // correct mode
         CAN.read() != 0x0c);       // correct PID

  float rpm = (((CAN.read())*256)/4);

  Serial.print("Engine RPM = ");
  Serial.println(rpm);



////////////////////////////////////////////////////////////////////////////////////////////////////////////
//Engine Load///////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////////////////

if (useStandardAddressing) {
    CAN.beginPacket(0x7df, 8);
  } else {
    CAN.beginExtendedPacket(0x18db33f1, 8);
  }
  CAN.write(0x02); // number of additional bytes
  CAN.write(0x01); // show current data
  CAN.write(0x04); // engine load
  CAN.endPacket();

  // wait for response
  while (CAN.parsePacket() == 0 ||
         CAN.read() < 2 ||          // correct length
         CAN.read() != 0x41 ||      // correct mode
         CAN.read() != 0x04);       // correct PID

  float eload = ((CAN.read())/2.55);

  Serial.print("Engine Load = ");
  Serial.println(eload);



////////////////////////////////////////////////////////////////////////////////////////////////////////////
//geartranslation///////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////////////////

  float geartranslation = (rpm / (kmh / (2.001 * 60)));



////////////////////////////////////////////////////////////////////////////////////////////////////////////
//gear//////////////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////////////////

  //NEUTRAL
  if (kmh == 0.0)  {
    Serial.println("Gear = N");
  }
  else
  {
    Serial.print(F("Gearwert: "));
    Serial.println(geartranslation);
    switch (geartranslation)
    {
  //GEAR 1
      case 13 ... 14.5:
        Serial.println("Gear = 1");
        break;
  //GEAR 2
      case 7 ... 8.5:
        Serial.println("Gear = 2");
        break;
  //GEAR 3
      case 4.5 ... 6:
        Serial.println("Gear = 3");
        break;
  //GEAR 4
      case 3.5 ... 4.3:
        Serial.println("Gear = 4");
        break;
  //GEAR 5
      case 3 ... 3.3:
        Serial.println("Gear = 5");
        break;
  //GEAR 6
      case 2 ... 2.8:
        Serial.println("Gear = 6");
        break;
    }
  }
  delay(500);
}

Also ich habe deinen Code umgesetzt, nur leider lässt er mich das jetzt nicht anwenden, da ich beim Upload eine Fehlermeldung in Arduino IDE bekomme.

Das wird in der Konsole unten ausgegeben:

C:\Program Files (x86)\Arduino\arduino-builder -dump-prefs -logger=machine -hardware C:\Program Files (x86)\Arduino\hardware -hardware C:\Users\simon\AppData\Local\Arduino15\packages -tools C:\Program Files (x86)\Arduino\tools-builder -tools C:\Program Files (x86)\Arduino\hardware\tools\avr -tools C:\Users\simon\AppData\Local\Arduino15\packages -built-in-libraries C:\Program Files (x86)\Arduino\libraries -libraries C:\Users\Simon\Documents\Arduino\libraries -fqbn=arduino:avr:uno -vid-pid=2A03_0043 -ide-version=10813 -build-path C:\Users\simon\AppData\Local\Temp\arduino_build_731948 -warnings=none -build-cache C:\Users\simon\AppData\Local\Temp\arduino_cache_752181 -prefs=build.warn_data_percentage=75 -prefs=runtime.tools.avr-gcc.path=C:\Program Files (x86)\Arduino\hardware\tools\avr -prefs=runtime.tools.avr-gcc-7.3.0-atmel3.6.1-arduino7.path=C:\Program Files (x86)\Arduino\hardware\tools\avr -prefs=runtime.tools.avrdude.path=C:\Users\simon\AppData\Local\Arduino15\packages\arduino\tools\avrdude\6.3.0-arduino17 -prefs=runtime.tools.avrdude-6.3.0-arduino17.path=C:\Users\simon\AppData\Local\Arduino15\packages\arduino\tools\avrdude\6.3.0-arduino17 -prefs=runtime.tools.arduinoOTA.path=C:\Users\simon\AppData\Local\Arduino15\packages\arduino\tools\arduinoOTA\1.3.0 -prefs=runtime.tools.arduinoOTA-1.3.0.path=C:\Users\simon\AppData\Local\Arduino15\packages\arduino\tools\arduinoOTA\1.3.0 -verbose C:\Users\simon\Documents\Arduino\Soundgenerator_1.0_beta_1\Soundgenerator_1.0_beta_1.ino
C:\Program Files (x86)\Arduino\arduino-builder -compile -logger=machine -hardware C:\Program Files (x86)\Arduino\hardware -hardware C:\Users\simon\AppData\Local\Arduino15\packages -tools C:\Program Files (x86)\Arduino\tools-builder -tools C:\Program Files (x86)\Arduino\hardware\tools\avr -tools C:\Users\simon\AppData\Local\Arduino15\packages -built-in-libraries C:\Program Files (x86)\Arduino\libraries -libraries C:\Users\Simon\Documents\Arduino\libraries -fqbn=arduino:avr:uno -vid-pid=2A03_0043 -ide-version=10813 -build-path C:\Users\simon\AppData\Local\Temp\arduino_build_731948 -warnings=none -build-cache C:\Users\simon\AppData\Local\Temp\arduino_cache_752181 -prefs=build.warn_data_percentage=75 -prefs=runtime.tools.avr-gcc.path=C:\Program Files (x86)\Arduino\hardware\tools\avr -prefs=runtime.tools.avr-gcc-7.3.0-atmel3.6.1-arduino7.path=C:\Program Files (x86)\Arduino\hardware\tools\avr -prefs=runtime.tools.avrdude.path=C:\Users\simon\AppData\Local\Arduino15\packages\arduino\tools\avrdude\6.3.0-arduino17 -prefs=runtime.tools.avrdude-6.3.0-arduino17.path=C:\Users\simon\AppData\Local\Arduino15\packages\arduino\tools\avrdude\6.3.0-arduino17 -prefs=runtime.tools.arduinoOTA.path=C:\Users\simon\AppData\Local\Arduino15\packages\arduino\tools\arduinoOTA\1.3.0 -prefs=runtime.tools.arduinoOTA-1.3.0.path=C:\Users\simon\AppData\Local\Arduino15\packages\arduino\tools\arduinoOTA\1.3.0 -verbose C:\Users\simon\Documents\Arduino\Soundgenerator_1.0_beta_1\Soundgenerator_1.0_beta_1.ino
Using board 'uno' from platform in folder: C:\Program Files (x86)\Arduino\hardware\arduino\avr
Using core 'arduino' from platform in folder: C:\Program Files (x86)\Arduino\hardware\arduino\avr
Detecting libraries used...
"C:\Program Files (x86)\Arduino\hardware\tools\avr/bin/avr-g++" -c -g -Os -w -std=gnu++11 -fpermissive -fno-exceptions -ffunction-sections -fdata-sections -fno-threadsafe-statics -Wno-error=narrowing -flto -w -x c++ -E -CC -mmcu=atmega328p -DF_CPU=16000000L -DARDUINO=10813 -DARDUINO_AVR_UNO -DARDUINO_ARCH_AVR "-IC:\Program Files (x86)\Arduino\hardware\arduino\avr\cores\arduino" "-IC:\Program Files (x86)\Arduino\hardware\arduino\avr\variants\standard" "C:\Users\simon\AppData\Local\Temp\arduino_build_731948\sketch\Soundgenerator_1.0_beta_1.ino.cpp" -o nul -DARDUINO_LIB_DISCOVERY_PHASE
Alternatives for CAN.h: [CAN@0.3.1]
ResolveLibrary(CAN.h)
-> candidates: [CAN@0.3.1]
"C:\Program Files (x86)\Arduino\hardware\tools\avr/bin/avr-g++" -c -g -Os -w -std=gnu++11 -fpermissive -fno-exceptions -ffunction-sections -fdata-sections -fno-threadsafe-statics -Wno-error=narrowing -flto -w -x c++ -E -CC -mmcu=atmega328p -DF_CPU=16000000L -DARDUINO=10813 -DARDUINO_AVR_UNO -DARDUINO_ARCH_AVR "-IC:\Program Files (x86)\Arduino\hardware\arduino\avr\cores\arduino" "-IC:\Program Files (x86)\Arduino\hardware\arduino\avr\variants\standard" "-IC:\Users\Simon\Documents\Arduino\libraries\CAN\src" "C:\Users\simon\AppData\Local\Temp\arduino_build_731948\sketch\Soundgenerator_1.0_beta_1.ino.cpp" -o nul -DARDUINO_LIB_DISCOVERY_PHASE
Alternatives for SPI.h: [SPI@1.0]
ResolveLibrary(SPI.h)
-> candidates: [SPI@1.0]
"C:\Program Files (x86)\Arduino\hardware\tools\avr/bin/avr-g++" -c -g -Os -w -std=gnu++11 -fpermissive -fno-exceptions -ffunction-sections -fdata-sections -fno-threadsafe-statics -Wno-error=narrowing -flto -w -x c++ -E -CC -mmcu=atmega328p -DF_CPU=16000000L -DARDUINO=10813 -DARDUINO_AVR_UNO -DARDUINO_ARCH_AVR "-IC:\Program Files (x86)\Arduino\hardware\arduino\avr\cores\arduino" "-IC:\Program Files (x86)\Arduino\hardware\arduino\avr\variants\standard" "-IC:\Users\Simon\Documents\Arduino\libraries\CAN\src" "-IC:\Program Files (x86)\Arduino\hardware\arduino\avr\libraries\SPI\src" "C:\Users\simon\AppData\Local\Temp\arduino_build_731948\sketch\Soundgenerator_1.0_beta_1.ino.cpp" -o nul -DARDUINO_LIB_DISCOVERY_PHASE
"C:\Program Files (x86)\Arduino\hardware\tools\avr/bin/avr-g++" -c -g -Os -w -std=gnu++11 -fpermissive -fno-exceptions -ffunction-sections -fdata-sections -fno-threadsafe-statics -Wno-error=narrowing -flto -w -x c++ -E -CC -mmcu=atmega328p -DF_CPU=16000000L -DARDUINO=10813 -DARDUINO_AVR_UNO -DARDUINO_ARCH_AVR "-IC:\Program Files (x86)\Arduino\hardware\arduino\avr\cores\arduino" "-IC:\Program Files (x86)\Arduino\hardware\arduino\avr\variants\standard" "-IC:\Users\Simon\Documents\Arduino\libraries\CAN\src" "-IC:\Program Files (x86)\Arduino\hardware\arduino\avr\libraries\SPI\src" "C:\Users\Simon\Documents\Arduino\libraries\CAN\src\CANController.cpp" -o nul -DARDUINO_LIB_DISCOVERY_PHASE
"C:\Program Files (x86)\Arduino\hardware\tools\avr/bin/avr-g++" -c -g -Os -w -std=gnu++11 -fpermissive -fno-exceptions -ffunction-sections -fdata-sections -fno-threadsafe-statics -Wno-error=narrowing -flto -w -x c++ -E -CC -mmcu=atmega328p -DF_CPU=16000000L -DARDUINO=10813 -DARDUINO_AVR_UNO -DARDUINO_ARCH_AVR "-IC:\Program Files (x86)\Arduino\hardware\arduino\avr\cores\arduino" "-IC:\Program Files (x86)\Arduino\hardware\arduino\avr\variants\standard" "-IC:\Users\Simon\Documents\Arduino\libraries\CAN\src" "-IC:\Program Files (x86)\Arduino\hardware\arduino\avr\libraries\SPI\src" "C:\Users\Simon\Documents\Arduino\libraries\CAN\src\ESP32SJA1000.cpp" -o nul -DARDUINO_LIB_DISCOVERY_PHASE
"C:\Program Files (x86)\Arduino\hardware\tools\avr/bin/avr-g++" -c -g -Os -w -std=gnu++11 -fpermissive -fno-exceptions -ffunction-sections -fdata-sections -fno-threadsafe-statics -Wno-error=narrowing -flto -w -x c++ -E -CC -mmcu=atmega328p -DF_CPU=16000000L -DARDUINO=10813 -DARDUINO_AVR_UNO -DARDUINO_ARCH_AVR "-IC:\Program Files (x86)\Arduino\hardware\arduino\avr\cores\arduino" "-IC:\Program Files (x86)\Arduino\hardware\arduino\avr\variants\standard" "-IC:\Users\Simon\Documents\Arduino\libraries\CAN\src" "-IC:\Program Files (x86)\Arduino\hardware\arduino\avr\libraries\SPI\src" "C:\Users\Simon\Documents\Arduino\libraries\CAN\src\MCP2515.cpp" -o nul -DARDUINO_LIB_DISCOVERY_PHASE
"C:\Program Files (x86)\Arduino\hardware\tools\avr/bin/avr-g++" -c -g -Os -w -std=gnu++11 -fpermissive -fno-exceptions -ffunction-sections -fdata-sections -fno-threadsafe-statics -Wno-error=narrowing -flto -w -x c++ -E -CC -mmcu=atmega328p -DF_CPU=16000000L -DARDUINO=10813 -DARDUINO_AVR_UNO -DARDUINO_ARCH_AVR "-IC:\Program Files (x86)\Arduino\hardware\arduino\avr\cores\arduino" "-IC:\Program Files (x86)\Arduino\hardware\arduino\avr\variants\standard" "-IC:\Users\Simon\Documents\Arduino\libraries\CAN\src" "-IC:\Program Files (x86)\Arduino\hardware\arduino\avr\libraries\SPI\src" "C:\Program Files (x86)\Arduino\hardware\arduino\avr\libraries\SPI\src\SPI.cpp" -o nul -DARDUINO_LIB_DISCOVERY_PHASE
Generating function prototypes...
"C:\Program Files (x86)\Arduino\hardware\tools\avr/bin/avr-g++" -c -g -Os -w -std=gnu++11 -fpermissive -fno-exceptions -ffunction-sections -fdata-sections -fno-threadsafe-statics -Wno-error=narrowing -flto -w -x c++ -E -CC -mmcu=atmega328p -DF_CPU=16000000L -DARDUINO=10813 -DARDUINO_AVR_UNO -DARDUINO_ARCH_AVR "-IC:\Program Files (x86)\Arduino\hardware\arduino\avr\cores\arduino" "-IC:\Program Files (x86)\Arduino\hardware\arduino\avr\variants\standard" "-IC:\Users\Simon\Documents\Arduino\libraries\CAN\src" "-IC:\Program Files (x86)\Arduino\hardware\arduino\avr\libraries\SPI\src" "C:\Users\simon\AppData\Local\Temp\arduino_build_731948\sketch\Soundgenerator_1.0_beta_1.ino.cpp" -o "C:\Users\simon\AppData\Local\Temp\arduino_build_731948\preproc\ctags_target_for_gcc_minus_e.cpp" -DARDUINO_LIB_DISCOVERY_PHASE
"C:\Program Files (x86)\Arduino\tools-builder\ctags\5.8-arduino11/ctags" -u --language-force=c++ -f - --c++-kinds=svpf --fields=KSTtzns --line-directives "C:\Users\simon\AppData\Local\Temp\arduino_build_731948\preproc\ctags_target_for_gcc_minus_e.cpp"
Sketch wird kompiliert...
"C:\Program Files (x86)\Arduino\hardware\tools\avr/bin/avr-g++" -c -g -Os -w -std=gnu++11 -fpermissive -fno-exceptions -ffunction-sections -fdata-sections -fno-threadsafe-statics -Wno-error=narrowing -MMD -flto -mmcu=atmega328p -DF_CPU=16000000L -DARDUINO=10813 -DARDUINO_AVR_UNO -DARDUINO_ARCH_AVR "-IC:\Program Files (x86)\Arduino\hardware\arduino\avr\cores\arduino" "-IC:\Program Files (x86)\Arduino\hardware\arduino\avr\variants\standard" "-IC:\Users\Simon\Documents\Arduino\libraries\CAN\src" "-IC:\Program Files (x86)\Arduino\hardware\arduino\avr\libraries\SPI\src" "C:\Users\simon\AppData\Local\Temp\arduino_build_731948\sketch\Soundgenerator_1.0_beta_1.ino.cpp" -o "C:\Users\simon\AppData\Local\Temp\arduino_build_731948\sketch\Soundgenerator_1.0_beta_1.ino.cpp.o"
C:\Users\simon\Documents\Arduino\Soundgenerator_1.0_beta_1\Soundgenerator_1.0_beta_1.ino: In function 'void loop()':
Soundgenerator_1.0_beta_1:148:28: error: switch quantity not an integer
switch (geartranslation)
^
Soundgenerator_1.0_beta_1:151:19: error: could not convert '1.45e+1' from 'double' to ''
case 13 ... 14.5:
^~~~
Soundgenerator_1.0_beta_1:155:18: error: could not convert '8.5e+0' from 'double' to ''
case 7 ... 8.5:
^~~
Soundgenerator_1.0_beta_1:159:20: error: could not convert '4.5e+0' from 'double' to ''
case 4.5 ... 6:
^
Soundgenerator_1.0_beta_1:163:20: error: could not convert '3.5e+0' from 'double' to ''
case 3.5 ... 4.3:
^~~
Soundgenerator_1.0_beta_1:163:20: error: could not convert '4.30000019e+0' from 'double' to ''
Soundgenerator_1.0_beta_1:167:18: error: could not convert '3.29999995e+0' from 'double' to ''
case 3 ... 3.3:
^~~
Soundgenerator_1.0_beta_1:171:18: error: could not convert '2.79999995e+0' from 'double' to ''
case 2 ... 2.8:
^~~
Bibliothek CAN in Version 0.3.1 im Ordner: C:\Users\Simon\Documents\Arduino\libraries\CAN wird verwendet
Bibliothek SPI in Version 1.0 im Ordner: C:\Program Files (x86)\Arduino\hardware\arduino\avr\libraries\SPI wird verwendet
exit status 1
switch quantity not an integer

Kannst du oder jmd da helfen?:slight_smile:

MFG Simon2008

Ein falscher Datentyp, besser ganzzahlig:

    switch (uint16_t(10 * geartranslation))
    {
      //GEAR 1
      case 130 ... 145:
        Serial.println("Gear = 1");
        break;
      //GEAR 2
      case 70 ... 85:
        Serial.println("Gear = 2");
        break;
      //GEAR 3
      case 45 ... 60:
        Serial.println("Gear = 3");
        break;
      //GEAR 4
      case 35 ... 43:
        Serial.println("Gear = 4");
        break;
      //GEAR 5
      case 30 ... 33:
        Serial.println("Gear = 5");
        break;
      //GEAR 6
      case 20 ... 28:
        Serial.println("Gear = 6");
        break;
    }
// Copyright (c) Simon2008
// This Sketch should funkction as an OBD2-Soundgenerator and driving-data-monitor


#include <CAN.h>

// Most cars support 11-bit adddress, others (like Honda),
// require 29-bit (extended) addressing, set the next line
// to true to use extended addressing
const bool useStandardAddressing = true;



////////////////////////////////////////////////////////////////////////////////////////////////////////////
//Setup/////////////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////////////////

void setup() {
  Serial.begin(9600);

  Serial.println("CAN OBD-II Soundgenerator");

  // start the CAN bus at 500 kbps
  if (!CAN.begin(500E3)) {
    Serial.println("Starting CAN failed!");
    while (1);
  }

  // add filter to only receive the CAN bus ID's we care about
  if (useStandardAddressing) {
    CAN.filter(0x7e8);
  } else {
    CAN.filterExtended(0x18daf110);
  }
}



////////////////////////////////////////////////////////////////////////////////////////////////////////////
//Loop//////////////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////////////////

void loop() {



////////////////////////////////////////////////////////////////////////////////////////////////////////////
//vehicle speed/////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////////////////

  if (useStandardAddressing) {
    CAN.beginPacket(0x7df, 8);
  } else {
    CAN.beginExtendedPacket(0x18db33f1, 8);
  }
  CAN.write(0x02); // number of additional bytes
  CAN.write(0x01); // show current data
  CAN.write(0x0d); // vehicle speed
  CAN.endPacket();

  // wait for response
  while (CAN.parsePacket() == 0 ||
         CAN.read() < 2 ||          // correct length
         CAN.read() != 0x41 ||      // correct mode
         CAN.read() != 0x0d);       // correct PID

  float kmh = ((CAN.read()));

  Serial.print("Speed = ");
  Serial.println(kmh);



////////////////////////////////////////////////////////////////////////////////////////////////////////////
//engine speed//////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////////////////

if (useStandardAddressing) {
    CAN.beginPacket(0x7df, 8);
  } else {
    CAN.beginExtendedPacket(0x18db33f1, 8);
  }
  CAN.write(0x02); // number of additional bytes
  CAN.write(0x01); // show current data
  CAN.write(0x0c); // engine RPM
  CAN.endPacket();

  // wait for response
  while (CAN.parsePacket() == 0 ||
         CAN.read() < 3 ||          // correct length
         CAN.read() != 0x41 ||      // correct mode
         CAN.read() != 0x0c);       // correct PID

  float rpm = (((CAN.read())*256)/4);

  Serial.print("Engine RPM = ");
  Serial.println(rpm);



////////////////////////////////////////////////////////////////////////////////////////////////////////////
//Engine Load///////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////////////////

if (useStandardAddressing) {
    CAN.beginPacket(0x7df, 8);
  } else {
    CAN.beginExtendedPacket(0x18db33f1, 8);
  }
  CAN.write(0x02); // number of additional bytes
  CAN.write(0x01); // show current data
  CAN.write(0x04); // engine load
  CAN.endPacket();

  // wait for response
  while (CAN.parsePacket() == 0 ||
         CAN.read() < 2 ||          // correct length
         CAN.read() != 0x41 ||      // correct mode
         CAN.read() != 0x04);       // correct PID

  float eload = ((CAN.read())/2.55);

  Serial.print("Engine Load = ");
  Serial.println(eload);



////////////////////////////////////////////////////////////////////////////////////////////////////////////
//geartranslation///////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////////////////

  float geartranslation = (rpm / ((kmh*1000) / (2.001 * 60)));



////////////////////////////////////////////////////////////////////////////////////////////////////////////
//gear//////////////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////////////////

  //NEUTRAL
  if (kmh == 0.0)  {
    Serial.println("Gear = N");
  }
  else
  {
    Serial.print(F("Gearwert: "));
    Serial.println(geartranslation);
    switch (uint16_t(10*geartranslation))
    {
  //GEAR 1
      case 130 ... 150:
        Serial.println("Gear = 1");
        break;
  //GEAR 2
      case 70 ... 85:
        Serial.println("Gear = 2");
        break;
  //GEAR 3
      case 45 ... 60:
        Serial.println("Gear = 3");
        break;
  //GEAR 4
      case 35 ... 43:
        Serial.println("Gear = 4");
        break;
  //GEAR 5
      case 30 ... 33:
        Serial.println("Gear = 5");
        break;
  //GEAR 6
      case 20 ... 28:
        Serial.println("Gear = 6");
        break;
    }
  }
  delay(500);
}

Also, im Code war noch ein kleiner Fehler meinerseits, denn bei der Formel für die Geartranslation muss die Geschwindigkeit noch mit dem Faktor 1000 multipliziert werden. Aber jetzt funktioniert alles hinsichtlich Geschwindikeit, Gang, Motordrehzahl und Motorlast:)

Jetzt ist der nächste Schritt, die Ausgabe des Motorsounds über Lautsprecher. Hat da jmd Ideen? Die Lautsprecher hab ich schon sowie den DFPlayer Mini, die SD-Karte und das Digitale Poti X9C104.

Bitte um Ideen, Ratschläge etc:)

MFG Simon2008

Mein Tipp: Verwende den Pin BUSY für die Endeerkennung anstelle der Bibliotheksfunktion, denn die hat bei mir Störgeräusche erzeugt.

Da sich das Motorgeräusch kontinuierlich ändert, benötigst Du zur Nachbildung vermutlich sehr viele MP3-Dateien.

Für eine sprechende Uhr habe ich mit Sprachausgabe auch über DACs experimentiert, allerdings mit Teensy 3.2 (mehr Speicher und schneller) und ESP32 (wegen der Zeit aus dem Internet). Da geht dann beispielsweise sam->Say(out, " 12 59 o'clock!");. Ob I2S neben Sprache auch Motorgeräusche wiedergeben kann, hat mich nicht interessiert.

Also hast du den DFPlayer Mini auch verwendet? Mit dem Teensy 4.1 hab ichs schon versucht, aber der funktioniert mit den Bibliotheken nicht von OBD2

Na klar, wer nicht? Die gesprochenen Zahlen einer Uhr sind ja auch hinsichtlich der Anzahl übersichtlich und der Klang ist deutlich. Der ESP32 hat allerdings ein eigenes Dateisystem, wenn man möchte, kann man die mp3-Dateien auch dort speichern.

Mit einem Teensy 3.2 läuft der CAN-BUS, wie im Thema UNO - Mega - Teensy mittels CAN-Bus verbinden nachzulesen. Einen 4.1 hatte ich noch nicht in der Hand.

Aber wie verbinde ich den Teensy mit meinem shield? Hab das nämlich mal probiert und der Teensy ist daraufhin durchgebrannt, wie ich die OBD2 Spannung verbunden habe auf Vin

Wie schnell wechselt der DFPlayer Mini die Tracks?

Der Teensy hat CAN-BUS eingebaut, Du brauchst nur einen Interface-Baustein wie TJA1050. Das Shield hat auch nur MCP2515 und MCÜ2551 drauf.

Du kannst auch mit dem Mega2560 auf den CAN-BUS hören und mit dem Teensy Töne erzeugen, beide mit einer Schnittstelle wie UART verbunden.

Ich möchte Dich aber nicht zu irgendwas überreden, denn wie man ein Motorgeräusch macht, weiß ich auch nicht. Alles nur Ideen, danach hattest Du gefragt :slightly_smiling_face:

Ist fraglich ob das überhaupt funktioniert. Das "Motorgeräusch" soll sich ja mit der Drehzahl ändern. Normalerweise nimmt man da einen DSP und erzeugt den Sound direkt. Mit dem MP3 Player kann man ja die Geschwindigkeit nicht anpassen, oder doch? Wenn nein, müsste man ja z.B. für jede 20 Umdrehungen mehr eine eigene MP3 generieren und die dann je nach Drehzahl abspielen, abbrechen, nächste abspielen...
Ob die dann allerdings nahtlos abgespielt werden, ist eine andere Frage.

Gruß, Jürgen

Richtig, weshalb ich den Player auch für nicht optimal halte.

Das geht für eine Zeitansage hinreichend gut, aber nicht nahtlos.

Vom Videoschnitt weiß ich, daß der Ton gegenüber dem Bild kritischer wahrgenommen wird. Daher halte ich den Player für den nicht so guten oder gar falschen Ansatz.

// Copyright (c) Simon2008
// This Sketch should funkction as an OBD2-Soundgenerator and driving-data-monitor



/*
What´s new?

1.0 beta 1
o reading of the engine speed, vehicle speed, engine load and the gear

1.0 beta 2
o reading of the engine speed, vehicle speed, engine load and the gear
o Engine Startup Sound

1.0 beta 3
o reading of the engine speed, vehicle speed, engine load and the gear
o Engine Startup Sound
o Gear Changing Sound

1.0 beta 4
o reading of the engine speed, vehicle speed, engine load and the gear
o Engine Startup Sound
o Gear Changing Sound
o Launch-Control Sound with Engine-Load and Vehicle-Speed

1.0 beta 5
o reading of the engine speed, vehicle speed, engine load and the gear
o Engine Startup Sound
o Gear Changing Sound
o Launch-Control Sound with Engine-Load and Vehicle-Speed
o Thrust Cut-Off Sound


Coming Soon


1.0 beta 6
o reading of the engine speed, vehicle speed, engine load and the gear
o Engine Startup Sound
o Gear Changing Sound
o Launch-Control Sound with Engine-Load and Vehicle-Speed
o Thrust Cut-Off Sound
o Engine Sound with Engine-Speed and Engine-Load
*/



#include <SoftwareSerial.h>
#include <DFPlayer_Mini_Mp3.h>
SoftwareSerial mySerial(11, 10); //(RX, TX);
#include <CAN.h>

// Most cars support 11-bit adddress, others (like Honda),
// require 29-bit (extended) addressing, set the next line
// to true to use extended addressing
const bool useStandardAddressing = true;

float Umfang = 2.001;
int gear=1;
int gearold=1;
int eloadold=0;
int eloadint=0;

////////////////////////////////////////////////////////////////////////////////////////////////////////////
//Setup/////////////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////////////////

void setup() {
  Serial.begin(9600);

  Serial.println("CAN OBD-II Soundgenerator");

  // start the CAN bus at 500 kbps
  if (!CAN.begin(500E3)) {
    Serial.println("Starting CAN failed!");
    while (1);
  }

  // add filter to only receive the CAN bus ID's we care about
  if (useStandardAddressing) {
    CAN.filter(0x7e8);
  } else {
    CAN.filterExtended(0x18daf110);
  }
  mySerial.begin(9600);
  mp3_set_serial (mySerial);    
  delay(10);  
  mp3_set_volume (30);
////////////////////////////////////////////////////////////////////////////////////////////////////////////
//Startup-Sound/////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////////////////
  mp3_play(1);
////////////////////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////////////////
}



////////////////////////////////////////////////////////////////////////////////////////////////////////////
//Loop//////////////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////////////////

void loop() {



////////////////////////////////////////////////////////////////////////////////////////////////////////////
//vehicle speed/////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////////////////

  if (useStandardAddressing) {
    CAN.beginPacket(0x7df, 8);
  } else {
    CAN.beginExtendedPacket(0x18db33f1, 8);
  }
  CAN.write(0x02); // number of additional bytes
  CAN.write(0x01); // show current data
  CAN.write(0x0d); // vehicle speed
  CAN.endPacket();

  // wait for response
  while (CAN.parsePacket() == 0 ||
         CAN.read() < 2 ||          // correct length
         CAN.read() != 0x41 ||      // correct mode
         CAN.read() != 0x0d);       // correct PID

  float kmh = ((CAN.read()));

  Serial.print("Speed = ");
  Serial.println(kmh);



////////////////////////////////////////////////////////////////////////////////////////////////////////////
//engine speed//////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////////////////

if (useStandardAddressing) {
    CAN.beginPacket(0x7df, 8);
  } else {
    CAN.beginExtendedPacket(0x18db33f1, 8);
  }
  CAN.write(0x02); // number of additional bytes
  CAN.write(0x01); // show current data
  CAN.write(0x0c); // engine RPM
  CAN.endPacket();

  // wait for response
  while (CAN.parsePacket() == 0 ||
         CAN.read() < 3 ||          // correct length
         CAN.read() != 0x41 ||      // correct mode
         CAN.read() != 0x0c);       // correct PID

  float rpm = (((CAN.read())*256)/4);

  Serial.print("Engine RPM = ");
  Serial.println(rpm);



////////////////////////////////////////////////////////////////////////////////////////////////////////////
//Engine Load///////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////////////////
int eloadold = eloadint;
if (useStandardAddressing) {
    CAN.beginPacket(0x7df, 8);
  } else {
    CAN.beginExtendedPacket(0x18db33f1, 8);
  }
  CAN.write(0x02); // number of additional bytes
  CAN.write(0x01); // show current data
  CAN.write(0x04); // engine load
  CAN.endPacket();

  // wait for response
  while (CAN.parsePacket() == 0 ||
         CAN.read() < 2 ||          // correct length
         CAN.read() != 0x41 ||      // correct mode
         CAN.read() != 0x04);       // correct PID

  float eload = ((CAN.read())/2.55);
  int eloadint = (int)eload;
  Serial.print("Engine Load = ");
  Serial.println(eload);



////////////////////////////////////////////////////////////////////////////////////////////////////////////
//geartranslation///////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////////////////

  float geartranslation = (rpm / ((kmh*1000) / (Umfang * 60)));



////////////////////////////////////////////////////////////////////////////////////////////////////////////
//gear//////////////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////////////////

  gearold=gear;
  //NEUTRAL
  if (kmh == 0.0)  {
    Serial.println("Gear = N");
  }
  else
  {
    Serial.print(F("Gearwert: "));
    Serial.println(geartranslation);
    switch (uint16_t(10*geartranslation))
    {
  //GEAR 1
      case 130 ... 150:
        Serial.println("Gear = 1");
        gear=1;
        break;
  //GEAR 2
      case 70 ... 85:
        Serial.println("Gear = 2");
        gear=2;
        break;
  //GEAR 3
      case 45 ... 60:
        Serial.println("Gear = 3");
        gear=3;
        break;
  //GEAR 4
      case 35 ... 43:
        Serial.println("Gear = 4");
        gear=4;
        break;
  //GEAR 5
      case 30 ... 33:
        Serial.println("Gear = 5");
        gear=5;
        break;
  //GEAR 6
      case 20 ... 28:
        Serial.println("Gear = 6");
        gear=6;
        break;
    }
  }



////////////////////////////////////////////////////////////////////////////////////////////////////////////
//Gear-Changing Sound///////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////////////////

if((gearold != gear) && (kmh > 10))
{
  mp3_play(2);
}



////////////////////////////////////////////////////////////////////////////////////////////////////////////
//Launch-Control Sound//////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////////////////

if((eload >= 98.0) && (kmh == 0.0))
{
  mp3_play(3);
}



////////////////////////////////////////////////////////////////////////////////////////////////////////////
//Thrust-Cut-Off Sound//////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////////////////

if((eloadold > (eloadint + 5)) && (gearold == gear))
{
  mp3_play(4);
}
}

Hallo Leute,

Ich habe mich jetzt aus kostengründen für einen Versuch mit dem DFPlayer und einem Arduino Due entschieden, da ich diese schon bereits habe. Man kann ja zu einem späteren Zeitpunkt auch noch auf Teensy und DSP umsteigen:)

Jetzt habe ich den Code bereits zu einem Großteil geschrieben und wollte wissen ob es irgendwelche Anmerkungen und Verbesserungsvorschläge dafür gibt. Über ein Feedback würde ich mich freuen;)

Aktuell bei den Funktionen von beta 5 und ich werde bald den X9C104 miteinbinden für die Lautstärkeregelung.

Mit freundlichen Grüßen
Simon2008

Der Due hat Serial1, Serial2 und Serial3 in Hardware, die solltest Du nutzen.

Viele nutzlose Zeilen im Code machen ihn m. E. nicht lesbarer :crazy_face:

Wenn Du weißt, was Du brauchst, kannst Du die Bedingungen rauswerfen.

Strg-t in der IDE macht den Code lesbarer. So sieht das falsch aus.

Wie hört sich das denn an? Sehr gut, brauchbar oder gruselig?

// Copyright (c) Simon2008
// This Sketch should funkction as an OBD2-Soundgenerator and driving-data-monitor

/*
  What´s new?

  1.0 beta 1
  o reading of the engine speed, vehicle speed, engine load and the gear

  1.0 beta 2
  o reading of the engine speed, vehicle speed, engine load and the gear
  o Engine Startup Sound

  1.0 beta 3
  o reading of the engine speed, vehicle speed, engine load and the gear
  o Engine Startup Sound
  o Gear Changing Sound

  1.0 beta 4
  o reading of the engine speed, vehicle speed, engine load and the gear
  o Engine Startup Sound
  o Gear Changing Sound
  o Launch-Control Sound with Engine-Load and Vehicle-Speed

  1.0 beta 5
  o reading of the engine speed, vehicle speed, engine load and the gear
  o Engine Startup Sound
  o Gear Changing Sound
  o Launch-Control Sound with Engine-Load and Vehicle-Speed
  o Thrust Cut-Off Sound


  Coming Soon

  1.0 beta 6
  o reading of the engine speed, vehicle speed, engine load and the gear
  o Engine Startup Sound
  o Gear Changing Sound
  o Launch-Control Sound with Engine-Load and Vehicle-Speed
  o Thrust Cut-Off Sound
  o Engine Sound with Engine-Speed and Engine-Load
*/

#include <SoftwareSerial.h>
#include <DFPlayer_Mini_Mp3.h>
SoftwareSerial mySerial(11, 10); //(RX, TX);
#include <CAN.h>

// Most cars support 11-bit adddress, others (like Honda),require 29-bit (extended) addressing, set the next line to true to use extended addressing
const bool useStandardAddressing = true;
////////////////////////////////////////////////////////////////////////////////////////////////////////////
//Variablen/////////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////////////////
float Umfang = 2.001;
int gear = 1;
int gearold = 1;
int eloadold = 0;
int eloadint = 0;

////////////////////////////////////////////////////////////////////////////////////////////////////////////
//Setup/////////////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////////////////
void setup() {
  Serial.begin(9600);
  Serial.println("CAN OBD-II Soundgenerator");
  if (!CAN.begin(500E3)) {                    // start the CAN bus at 500 kbps
    Serial.println("Starting CAN failed!");
    while (1);
  }
  // add filter to only receive the CAN bus ID's we care about
  if (useStandardAddressing) {                // add filter to only receive the CAN bus ID's we care about
    CAN.filter(0x7e8);
  } else {
    CAN.filterExtended(0x18daf110);
  }
  mySerial.begin(9600);
  mp3_set_serial (mySerial);
  delay(10);
  mp3_set_volume (30);
  ////////////////////////////////////////////////////////////////////////////////////////////////////////////
  //Startup-Sound/////////////////////////////////////////////////////////////////////////////////////////////
  ////////////////////////////////////////////////////////////////////////////////////////////////////////////
  mp3_play(1);
}

////////////////////////////////////////////////////////////////////////////////////////////////////////////
//Loop//////////////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////////////////
void loop() {
  ////////////////////////////////////////////////////////////////////////////////////////////////////////////
  //vehicle speed/////////////////////////////////////////////////////////////////////////////////////////////
  ////////////////////////////////////////////////////////////////////////////////////////////////////////////
  if (useStandardAddressing) {
    CAN.beginPacket(0x7df, 8);
  } else {
    CAN.beginExtendedPacket(0x18db33f1, 8);
  }
  CAN.write(0x02); // number of additional bytes
  CAN.write(0x01); // show current data
  CAN.write(0x0d); // vehicle speed
  CAN.endPacket();
  while (CAN.parsePacket() == 0 ||  // wait for response
         CAN.read() < 2 ||          // correct length
         CAN.read() != 0x41 ||      // correct mode
         CAN.read() != 0x0d);       // correct PID
  float kmh = ((CAN.read()));
  Serial.print("Speed = ");
  Serial.println(kmh);
  ////////////////////////////////////////////////////////////////////////////////////////////////////////////
  //engine speed//////////////////////////////////////////////////////////////////////////////////////////////
  ////////////////////////////////////////////////////////////////////////////////////////////////////////////
  if (useStandardAddressing) {
    CAN.beginPacket(0x7df, 8);
  } else {
    CAN.beginExtendedPacket(0x18db33f1, 8);
  }
  CAN.write(0x02); // number of additional bytes
  CAN.write(0x01); // show current data
  CAN.write(0x0c); // engine RPM
  CAN.endPacket();
  while (CAN.parsePacket() == 0 ||  // wait for response
         CAN.read() < 3 ||          // correct length
         CAN.read() != 0x41 ||      // correct mode
         CAN.read() != 0x0c);       // correct PID
  float rpm = (((CAN.read()) * 256) / 4);
  Serial.print("Engine RPM = ");
  Serial.println(rpm);
  ////////////////////////////////////////////////////////////////////////////////////////////////////////////
  //Engine Load///////////////////////////////////////////////////////////////////////////////////////////////
  ////////////////////////////////////////////////////////////////////////////////////////////////////////////
  int eloadold = eloadint;
  if (useStandardAddressing) {
    CAN.beginPacket(0x7df, 8);
  } else {
    CAN.beginExtendedPacket(0x18db33f1, 8);
  }
  CAN.write(0x02); // number of additional bytes
  CAN.write(0x01); // show current data
  CAN.write(0x04); // engine load
  CAN.endPacket();
  while (CAN.parsePacket() == 0 ||  // wait for response
         CAN.read() < 2 ||          // correct length
         CAN.read() != 0x41 ||      // correct mode
         CAN.read() != 0x04);       // correct PID
  float eload = ((CAN.read()) / 2.55);
  int eloadint = (int)eload;
  Serial.print("Engine Load = ");
  Serial.println(eload);
  ////////////////////////////////////////////////////////////////////////////////////////////////////////////
  //geartranslation///////////////////////////////////////////////////////////////////////////////////////////
  ////////////////////////////////////////////////////////////////////////////////////////////////////////////
  float geartranslation = (rpm / ((kmh * 1000) / (Umfang * 60)));
  ////////////////////////////////////////////////////////////////////////////////////////////////////////////
  //gear//////////////////////////////////////////////////////////////////////////////////////////////////////
  ////////////////////////////////////////////////////////////////////////////////////////////////////////////
  gearold = gear;
  //NEUTRAL
  if (kmh == 0.0)  {
    Serial.println("Gear = N");
  }
  else
  {
    Serial.print(F("Gearwert: "));
    Serial.println(geartranslation);
    switch (uint16_t(10 * geartranslation))
    {
      //GEAR 1
      case 130 ... 150:
        Serial.println("Gear = 1");
        gear = 1;
        break;
      //GEAR 2
      case 70 ... 85:
        Serial.println("Gear = 2");
        gear = 2;
        break;
      //GEAR 3
      case 45 ... 60:
        Serial.println("Gear = 3");
        gear = 3;
        break;
      //GEAR 4
      case 35 ... 43:
        Serial.println("Gear = 4");
        gear = 4;
        break;
      //GEAR 5
      case 30 ... 33:
        Serial.println("Gear = 5");
        gear = 5;
        break;
      //GEAR 6
      case 20 ... 28:
        Serial.println("Gear = 6");
        gear = 6;
        break;
    }
  }
  ////////////////////////////////////////////////////////////////////////////////////////////////////////////
  //Gear-Changing Sound///////////////////////////////////////////////////////////////////////////////////////
  ////////////////////////////////////////////////////////////////////////////////////////////////////////////
  if ((gearold != gear) && (kmh > 10))
  {
    mp3_play(2);
  }
  ////////////////////////////////////////////////////////////////////////////////////////////////////////////
  //Launch-Control Sound//////////////////////////////////////////////////////////////////////////////////////
  ////////////////////////////////////////////////////////////////////////////////////////////////////////////
  if ((eload >= 98.0) && (kmh == 0.0))
  {
    mp3_play(3);
  }
  ////////////////////////////////////////////////////////////////////////////////////////////////////////////
  //Thrust-Cut-Off Sound//////////////////////////////////////////////////////////////////////////////////////
  ////////////////////////////////////////////////////////////////////////////////////////////////////////////
  if ((eloadold > (eloadint + 5)) && (gearold == gear))
  {
    mp3_play(4);
  }
}

Weil du von Hardware Serial redest, wie steuer ich das genau an und ist beim Uno das nicht vorhanden? Falls doch, wie dann beim Uno? Bin gerade neugierig geworden😊

Und oben ist mein neuer Code

UNO kennt nur Serial, der Due mehr, siehe Serial.

  Serial3.begin(9600);
  mp3_set_serial (Serial3);
// Copyright (c) Simon2008
// This Sketch should funkction as an OBD2-Soundgenerator and driving-data-monitor

/*
  What´s new?

  1.0 beta 1
  o reading of the engine speed, vehicle speed, engine load and the gear

  1.0 beta 2
  o reading of the engine speed, vehicle speed, engine load and the gear
  o Engine Startup Sound

  1.0 beta 3
  o reading of the engine speed, vehicle speed, engine load and the gear
  o Engine Startup Sound
  o Gear Changing Sound

  1.0 beta 4
  o reading of the engine speed, vehicle speed, engine load and the gear
  o Engine Startup Sound
  o Gear Changing Sound
  o Launch-Control Sound with Engine-Load and Vehicle-Speed

  1.0 beta 5
  o reading of the engine speed, vehicle speed, engine load and the gear
  o Engine Startup Sound
  o Gear Changing Sound
  o Launch-Control Sound with Engine-Load and Vehicle-Speed
  o Thrust Cut-Off Sound


  Coming Soon

  1.0 beta 6
  o reading of the engine speed, vehicle speed, engine load and the gear
  o Engine Startup Sound
  o Gear Changing Sound
  o Launch-Control Sound with Engine-Load and Vehicle-Speed
  o Thrust Cut-Off Sound
  o Engine Sound with Engine-Speed and Engine-Load
*/

#include <SoftwareSerial.h>
#include <DFPlayer_Mini_Mp3.h>
SoftwareSerial mySerial(11, 10); //(RX, TX);
#include <CAN.h>

// Most cars support 11-bit adddress, others (like Honda),require 29-bit (extended) addressing, set the next line to true to use extended addressing
const bool useStandardAddressing = true;
////////////////////////////////////////////////////////////////////////////////////////////////////////////
//Variablen/////////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////////////////
float Umfang = 2.001;
int gear = 1;
int gearold = 1;
int eloadold = 0;
int eloadint = 0;

////////////////////////////////////////////////////////////////////////////////////////////////////////////
//Setup/////////////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////////////////
void setup() {
  Serial.begin(9600);
  Serial.println("CAN OBD-II Soundgenerator");
  if (!CAN.begin(500E3)) {                    // start the CAN bus at 500 kbps
    Serial.println("Starting CAN failed!");
    while (1);
  }
  // add filter to only receive the CAN bus ID's we care about
  if (useStandardAddressing) {                // add filter to only receive the CAN bus ID's we care about
    CAN.filter(0x7e8);
  } else {
    CAN.filterExtended(0x18daf110);
  }
  mySerial.begin(9600);
  mp3_set_serial (mySerial);
  delay(10);
  mp3_set_volume (30);
  ////////////////////////////////////////////////////////////////////////////////////////////////////////////
  //Startup-Sound/////////////////////////////////////////////////////////////////////////////////////////////
  ////////////////////////////////////////////////////////////////////////////////////////////////////////////
  mp3_play(1);
}

////////////////////////////////////////////////////////////////////////////////////////////////////////////
//Loop//////////////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////////////////
void loop() {
  ////////////////////////////////////////////////////////////////////////////////////////////////////////////
  //vehicle speed/////////////////////////////////////////////////////////////////////////////////////////////
  ////////////////////////////////////////////////////////////////////////////////////////////////////////////
  if (useStandardAddressing) {
    CAN.beginPacket(0x7df, 8);
  } else {
    CAN.beginExtendedPacket(0x18db33f1, 8);
  }
  CAN.write(0x02); // number of additional bytes
  CAN.write(0x01); // show current data
  CAN.write(0x0d); // vehicle speed
  CAN.endPacket();
  while (CAN.parsePacket() == 0 ||  // wait for response
         CAN.read() < 2 ||          // correct length
         CAN.read() != 0x41 ||      // correct mode
         CAN.read() != 0x0d);       // correct PID
  float kmh = ((CAN.read()));
  Serial.print("Speed = ");
  Serial.println(kmh);
  ////////////////////////////////////////////////////////////////////////////////////////////////////////////
  //engine speed//////////////////////////////////////////////////////////////////////////////////////////////
  ////////////////////////////////////////////////////////////////////////////////////////////////////////////
  if (useStandardAddressing) {
    CAN.beginPacket(0x7df, 8);
  } else {
    CAN.beginExtendedPacket(0x18db33f1, 8);
  }
  CAN.write(0x02); // number of additional bytes
  CAN.write(0x01); // show current data
  CAN.write(0x0c); // engine RPM
  CAN.endPacket();
  while (CAN.parsePacket() == 0 ||  // wait for response
         CAN.read() < 3 ||          // correct length
         CAN.read() != 0x41 ||      // correct mode
         CAN.read() != 0x0c);       // correct PID
  float rpm = (((CAN.read()) * 256) / 4);
  Serial.print("Engine RPM = ");
  Serial.println(rpm);
  ////////////////////////////////////////////////////////////////////////////////////////////////////////////
  //Engine Load///////////////////////////////////////////////////////////////////////////////////////////////
  ////////////////////////////////////////////////////////////////////////////////////////////////////////////
  int eloadold = eloadint;
  if (useStandardAddressing) {
    CAN.beginPacket(0x7df, 8);
  } else {
    CAN.beginExtendedPacket(0x18db33f1, 8);
  }
  CAN.write(0x02); // number of additional bytes
  CAN.write(0x01); // show current data
  CAN.write(0x04); // engine load
  CAN.endPacket();
  while (CAN.parsePacket() == 0 ||  // wait for response
         CAN.read() < 2 ||          // correct length
         CAN.read() != 0x41 ||      // correct mode
         CAN.read() != 0x04);       // correct PID
  float eload = ((CAN.read()) / 2.55);
  int eloadint = (int)eload;
  Serial.print("Engine Load = ");
  Serial.println(eload);
  ////////////////////////////////////////////////////////////////////////////////////////////////////////////
  //geartranslation///////////////////////////////////////////////////////////////////////////////////////////
  ////////////////////////////////////////////////////////////////////////////////////////////////////////////
  float geartranslation = (rpm / ((kmh * 1000) / (Umfang * 60)));
  ////////////////////////////////////////////////////////////////////////////////////////////////////////////
  //gear//////////////////////////////////////////////////////////////////////////////////////////////////////
  ////////////////////////////////////////////////////////////////////////////////////////////////////////////
  gearold = gear;
  //NEUTRAL
  if (kmh == 0.0)  {
    Serial.println("Gear = N");
  }
  else
  {
    Serial.print(F("Gearwert: "));
    Serial.println(geartranslation);
    switch (uint16_t(10 * geartranslation))
    {
      //GEAR 1
      case 130 ... 150:
        Serial.println("Gear = 1");
        gear = 1;
        break;
      //GEAR 2
      case 70 ... 85:
        Serial.println("Gear = 2");
        gear = 2;
        break;
      //GEAR 3
      case 45 ... 60:
        Serial.println("Gear = 3");
        gear = 3;
        break;
      //GEAR 4
      case 35 ... 43:
        Serial.println("Gear = 4");
        gear = 4;
        break;
      //GEAR 5
      case 30 ... 33:
        Serial.println("Gear = 5");
        gear = 5;
        break;
      //GEAR 6
      case 20 ... 28:
        Serial.println("Gear = 6");
        gear = 6;
        break;
    }
  }
  ////////////////////////////////////////////////////////////////////////////////////////////////////////////
  //Gear-Changing Sound///////////////////////////////////////////////////////////////////////////////////////
  ////////////////////////////////////////////////////////////////////////////////////////////////////////////
  if ((gearold != gear) && (kmh > 10))
  {
    mp3_play(2);
  }
  ////////////////////////////////////////////////////////////////////////////////////////////////////////////
  //Launch-Control Sound//////////////////////////////////////////////////////////////////////////////////////
  ////////////////////////////////////////////////////////////////////////////////////////////////////////////
  if ((eload >= 98.0) && (kmh == 0.0))
  {
    mp3_play(3);
  }
  ////////////////////////////////////////////////////////////////////////////////////////////////////////////
  //Thrust-Cut-Off Sound//////////////////////////////////////////////////////////////////////////////////////
  ////////////////////////////////////////////////////////////////////////////////////////////////////////////
  if ((eloadold > (eloadint + 5)) && (gearold == gear))
  {
    mp3_play(4);
  }
  ////////////////////////////////////////////////////////////////////////////////////////////////////////////
  //Engine Sound with Engine-Load and Engine-Speed////////////////////////////////////////////////////////////
  ////////////////////////////////////////////////////////////////////////////////////////////////////////////
  float enginepercentrpm = (rpm*eload);
  
}

Deine Änderung mit dem Serial werde ich demnächst anwenden:)

Ich habe jetzt für das Verhältnis von Motordrehzahl und Motorlast eine Formel aufgestellt:
enginepercentrpm = (rpm*eload)
Vll ist es auch besser, Lautstärke und Sound getrennt zu lassen.

Jetzt ist meine Frage, ob es irgendwie möglich ist, anhand der unterschiedlichen Werte (Motordrehzahl zwischen 700 und 6500) unterschiedliche Soundfiles und Lautstärken (X9C104) auszugeben ohne eine riesige Menge an Code ständig durchlaufen zu müssen?

Bin gespannt auf die Antworten;)

MFG Simon2008

Deine Frage umformuliert: Wie funktionieren Felder oder Strukturen?

Zur Verdeutlichung mal Deine switch/case Verzweigung als Test herausgetrennt:

byte gearold, gear;

void setup() {
  Serial.begin(9600);
  Serial.println("Start");
  for (byte gt = 20; gt < 150; gt += 5) {
    gearold = gear;
    Serial.print(F("Gearwert: "));
    Serial.print(gt);
    switch (gt)
    {
      //GEAR 1
      case 130 ... 150:
        gear = 1;
        break;
      //GEAR 2
      case 70 ... 85:
        gear = 2;
        break;
      //GEAR 3
      case 45 ... 60:
        gear = 3;
        break;
      //GEAR 4
      case 35 ... 43:
        gear = 4;
        break;
      //GEAR 5
      case 30 ... 33:
        gear = 5;
        break;
      //GEAR 6
      case 20 ... 28:
        gear = 6;
        break;
    }
    Serial.print("\tGear = "); Serial.println(gear);
  }
}

void loop () {}

Jetzt zum Vergleich mit einem Feld von Strukturen:

struct Gaenge{
  const byte min;
  const byte max;
  const byte g;
};

Gaenge gaenge[]={
  {20,28,6},
  {30,33,5},
  {35,43,4},
  {45,60,3},
  {70,85,2},
  {130,150,1},
};

byte gearold, gear;

void setup() {
  Serial.begin(9600);
  Serial.println("Start");
  for (byte gt = 20; gt < 150; gt += 5) {
    gearold = gear;
    Serial.print(F("Gearwert: "));
    Serial.print(gt);
    for (byte j = 0; j < sizeof(gaenge)/sizeof(gaenge[0]); j++) {
      if (gt >= gaenge[j].min && gt <= gaenge[j].max) {
        gear = gaenge[j].g;
      }
    }
    Serial.print("\tGear = "); Serial.println(gear);
  }
}

void loop () {}

Bei mehr Gängen würden die drei Felder wachsen, nicht aber das Programm.

Dieses Prinzip läßt sich auch auf die MP3-Dateien übertragen.

Find ich gut die Idee, aber kannst du das mal für die MP3 darstellen. Wäre praktisch so, dass der erste Teil vom Byte die minimale Drehzahl, der zweite Teil die maximale Drehzahl und der dritte Teil vom Byte die zu spielende mp3 darstellt. Zb {700,710,6}. Hab ich das richtig verstanden? Komm gerade mit deiner oberen Schreibweise des Codes durcheinander weil diese Art des Programmierens mir unbekannt ist😅

Arduino wird mit C++ programmiert und ich verwende ein Feld von Strukturen mit Konstanten. Das bringt zusammen, was zusammengehört (Spruch von @combie).

Das sind die Äquivalente:

      case 45 ... 60:
        gear = 3;
  {45,60,3},

Also minimale, maximale Drehzahl und Gang. Das soll nur das Prinzip darstellen, mit einer MP3-Datei hat das noch nichts zu tun, ich bezog mich auf "ohne eine riesige Menge an Code".

Ja, ich kann, anstelle CAN-BUS nutze ich ein Poti (getestet mit ESP32, also andere Pins und analog bis 4096!):

/* verwendet wird Hardware Serial2
  ESP32 UART2 RX = GPIO16 - DFPlayer TX
  ESP32 UART2 TX = GPIO17 - 1 kOhm - DFPlayer RX
*/
#include "Arduino.h"
#include "DFRobotDFPlayerMini.h"

DFRobotDFPlayerMini myDFPlayer;

const byte pinBUSY = 35;
const byte pinPoti = 34;

struct Geraeusche {
  const uint16_t min;
  const uint16_t max;
  const uint16_t g;
};

Geraeusche geraeusche[] = {
  //min, max, g
  {0, 100, 1},
  {125, 175, 2},
  {225, 275, 3},
  {325, 375, 4},
  {425, 475, 5},
  {525, 575, 6},
  {625, 675, 7},
  {725, 775, 8},
  {825, 875, 9},
  {925, 1000, 10},
  {1001, 1023, 999}
};

void loop()
{
  static uint16_t id = 1;
  uint16_t potiWert = analogRead(pinPoti) / 4; // ADC1_CH6 (GPIO 34); "ADC2 pins cannot be used when Wi-Fi is used." Quelle: https://randomnerdtutorials.com/esp32-pinout-reference-gpios/
  bool busy = !digitalRead(pinBUSY); // BUSY: LOW means playing
  if (!busy) {
    Serial.print("potiWert: "); Serial.print(potiWert);
    for (uint16_t  j = 0; j < sizeof(geraeusche) / sizeof(geraeusche[0]); j++) {
      if (potiWert >= geraeusche[j].min && potiWert <= geraeusche[j].max) {
        id = geraeusche[j].g;
        break;
      }
    }
    myDFPlayer.playLargeFolder(1, id); // play specific mp3 in SD: (1, 27) means /01/027.mp3; Folder Name(1~10); File Name(1~1000)
    Serial.print("\tid: "); Serial.print(id);
    Serial.println();
    delay(50);
  }
}

void setup()
{
  pinMode(pinBUSY, INPUT_PULLDOWN);
  Serial.begin(115200);

  Serial.println();
  Serial.println(F("DFRobot DFPlayer Mini Demo"));
  Serial.println(F("Initializing DFPlayer ... (May take 3~5 seconds)"));

  Serial2.begin(9600);
  while (!myDFPlayer.begin(Serial2)) {
    delay(3000);
    Serial.println(F("Unable to begin:"));
    Serial.println(F("1.Please recheck the connection!"));
    Serial.println(F("2.Please insert the SD card!"));
  }
  Serial.println(F("DFPlayer Mini online."));

  myDFPlayer.setTimeOut(500); //Set serial communication time out 500ms
  myDFPlayer.volume(30); //0-30 möglich
  myDFPlayer.EQ(DFPLAYER_EQ_NORMAL);
  myDFPlayer.outputDevice(DFPLAYER_DEVICE_SD); //----Set device we use SD as default
  //myDFPlayer.playLargeFolder(1, 27); // play specific mp3 in SD:/01/027.mp3; Folder Name(1~10); File Name(1~1000)
}

Im Verzeichnis 01 können Dateien 000.mp3 bis 999.mp3 stehen.

Gibt es bei der Ansteuerung des DFplayers über den Arduino irgendwas zu beachten? Die benötigten pins des Moduls sind ja nur TX, RX, VCC, Ground, DAC-R und DAC-L oder? Oder muss noch ein Pin verwendet werden?

Also würden die Bytes für die MP3s wie folgt aussehen?

struct Gaenge {
  const byte min;
  const byte max;
  const byte m;
};

Gaenge gaenge[] = {
  {700, 709, 5},
  {710, 719, 6},
  {720, 729, 7},
  {730, 739, 8},
  {740, 749, 9},
  {750, 759, 10},
  {760, 769, 11},
  {770, 779, 12},
  {780, 789, 13},
  {790, 799, 14},
  {800, 809, 15},
  {810, 819, 16},
  {820, 829, 17},
  {830, 839, 18},
  {840, 849, 19},
  {850, 859, 20},
  {860, 869, 21},
  {870, 879, 22},
  {880, 889, 23},
  {890, 899, 24},
  {900, 909, 25},
  {910, 919, 26},
  {920, 929, 27},
  {930, 939, 28},
  {940, 949, 29},
  {950, 959, 30},
  {960, 969, 31},
  {970, 979, 32},
  {980, 989, 33},
  {990, 999, 34},
  {1000, 1009, 35},
  {1010, 1019, 36},
  {1020, 1029, 37},
  {1030, 1039, 38},
  {1040, 1049, 39},
  {1050, 1059, 40},
  {1060, 1069, 41},
  {1070, 1079, 42},
  {1080, 1089, 43},
  {1090, 1099, 44},
  {1100, 1109, 45},
  {1110, 1119, 46},
  {1120, 1129, 47},
  {1130, 1139, 48},
  {1140, 1149, 49},
  {1150, 1159, 50},
  {1160, 1169, 51},
  {1170, 1179, 52},
  {1180, 1189, 53},
  {1190, 1199, 54},
  {1200, 1209, 55},
  {1210, 1219, 56},
  {1220, 1229, 57},
  {1230, 1239, 58},
  {1240, 1249, 59},
  {1250, 1259, 60},
  {1260, 1269, 61},
  {1270, 1279, 62},
  {1280, 1289, 63},
  {1290, 1299, 64},
  {1300, 1309, 65},
  {1310, 1319, 66},
  {1320, 1329, 67},
  {1330, 1339, 68},
  {1340, 1349, 69},
  {1350, 1359, 70},
  {1360, 1369, 71},
  {1370, 1379, 72},
  {1380, 1389, 73},
  {1390, 1399, 74},
  {1400, 1409, 75},
  {1410, 1419, 76},
  {1420, 1429, 77},
  {1430, 1439, 78},
  {1440, 1449, 79},
  {1450, 1459, 80},
  {1460, 1469, 81},
  {1470, 1479, 82},
  {1480, 1489, 83},
  {1490, 1499, 84},
  {1500, 1509, 85},
  {1510, 1519, 86},
  {1520, 1529, 87},
  {1530, 1539, 88},
  {1540, 1549, 89},
  {1550, 1559, 90},
  {1560, 1569, 91},
  {1570, 1579, 92},
  {1580, 1589, 93},
  {1590, 1599, 94},
  {1600, 1609, 95},
  {1610, 1619, 96},
  {1620, 1629, 97},
  {1630, 1639, 98},
  {1640, 1649, 99},
  {1650, 1659, 100},
  {1660, 1669, 101},
  {1670, 1679, 102},
  {1680, 1689, 103},
  {1690, 1699, 104},
  {1700, 1709, 105},
  {1710, 1719, 106},
  {1720, 1729, 107},
  {1730, 1739, 108},
  {1740, 1749, 109},
  {1750, 1759, 110},
  {1760, 1769, 111},
  {1770, 1779, 112},
  {1780, 1789, 113},
  {1790, 1799, 114},
  {1800, 1809, 115},
  {1810, 1819, 116},
  {1820, 1829, 117},
  {1830, 1839, 118},
  {1840, 1849, 119},
  {1850, 1859, 120},
  {1860, 1869, 121},
  {1870, 1879, 122},
  {1880, 1889, 123},
  {1890, 1899, 124},
  {1900, 1909, 125},
  {1910, 1919, 126},
  {1920, 1929, 127},
  {1930, 1939, 128},
  {1940, 1949, 129},
  {1950, 1959, 130},
  {1960, 1969, 131},
  {1970, 1979, 132},
  {1980, 1989, 133},
  {1990, 1999, 134},
  {2000, 2009, 135},
  {2010, 2019, 136},
  {2020, 2029, 137},
  {2030, 2039, 138},
  {2040, 2049, 139},
  {2050, 2059, 140},
  {2060, 2069, 141},
  {2070, 2079, 142},
  {2080, 2089, 143},
  {2090, 2099, 144},
  {2100, 2109, 145},
  {2110, 2119, 146},
  {2120, 2129, 147},
  {2130, 2139, 148},
  {2140, 2149, 149},
  {2150, 2159, 150},
  {2160, 2169, 151},
  {2170, 2179, 152},
  {2180, 2189, 153},
  {2190, 2199, 154},
  {2200, 2209, 155},
  {2210, 2219, 156},
  {2220, 2229, 157},
  {2230, 2239, 158},
  {2240, 2249, 159},
  {2250, 2259, 160},
  {2260, 2269, 161},
  {2270, 2279, 162},
  {2280, 2289, 163},
  {2290, 2299, 164},
  {2300, 2309, 165},
  {2310, 2319, 166},
  {2320, 2329, 167},
  {2330, 2339, 168},
  {2340, 2349, 169},
  {2350, 2359, 170},
  {2360, 2369, 171},
  {2370, 2379, 172},
  {2380, 2389, 173},
  {2390, 2399, 174},
  {2400, 2409, 175},
  {2410, 2419, 176},
  {2420, 2429, 177},
  {2430, 2439, 178},
  {2440, 2449, 179},
  {2450, 2459, 180},
  {2460, 2469, 181},
  {2470, 2479, 182},
  {2480, 2489, 183},
  {2490, 2499, 184},
  {2500, 2509, 185},
  {2510, 2519, 186},
  {2520, 2529, 187},
  {2530, 2539, 188},
  {2540, 2549, 189},
  {2550, 2559, 190},
  {2560, 2569, 191},
  {2570, 2579, 192},
  {2580, 2589, 193},
  {2590, 2599, 194},
  {2600, 2609, 195},
  {2610, 2619, 196},
  {2620, 2629, 197},
  {2630, 2639, 198},
  {2640, 2649, 199},
  {2650, 2659, 200},
  {2660, 2669, 201},
  {2670, 2679, 202},
  {2680, 2689, 203},
  {2690, 2699, 204},
  {2700, 2709, 205},
  {2710, 2719, 206},
  {2720, 2729, 207},
  {2730, 2739, 208},
  {2740, 2749, 209},
  {2750, 2759, 210},
  {2760, 2769, 211},
  {2770, 2779, 212},
  {2780, 2789, 213},
  {2790, 2799, 214},
  {2800, 2809, 215},
  {2810, 2819, 216},
  {2820, 2829, 217},
  {2830, 2839, 218},
  {2840, 2849, 219},
  {2850, 2859, 220},
  {2860, 2869, 221},
  {2870, 2879, 222},
  {2880, 2889, 223},
  {2890, 2899, 224},
  {2900, 2909, 225},
  {2910, 2919, 226},
  {2920, 2929, 227},
  {2930, 2939, 228},
  {2940, 2949, 229},
  {2950, 2959, 230},
  {2960, 2969, 231},
  {2970, 2979, 232},
  {2980, 2989, 233},
  {2990, 2999, 234},
  {3000, 3009, 235},
  {3010, 3019, 236},
  {3020, 3029, 237},
  {3030, 3039, 238},
  {3040, 3049, 239},
  {3050, 3059, 240},
  {3060, 3069, 241},
  {3070, 3079, 242},
  {3080, 3089, 243},
  {3090, 3099, 244},
  {3100, 3109, 245},
  {3110, 3119, 246},
  {3120, 3129, 247},
  {3130, 3139, 248},
  {3140, 3149, 249},
  {3150, 3159, 250},
  {3160, 3169, 251},
  {3170, 3179, 252},
  {3180, 3189, 253},
  {3190, 3199, 254},
  {3200, 3209, 255},
  {3210, 3219, 256},
  {3220, 3229, 257},
  {3230, 3239, 258},
  {3240, 3249, 259},
  {3250, 3259, 260},
  {3260, 3269, 261},
  {3270, 3279, 262},
  {3280, 3289, 263},
  {3290, 3299, 264},
  {3300, 3309, 265},
  {3310, 3319, 266},
  {3320, 3329, 267},
  {3330, 3339, 268},
  {3340, 3349, 269},
  {3350, 3359, 270},
  {3360, 3369, 271},
  {3370, 3379, 272},
  {3380, 3389, 273},
  {3390, 3399, 274},
  {3400, 3409, 275},
  {3410, 3419, 276},
  {3420, 3429, 277},
  {3430, 3439, 278},
  {3440, 3449, 279},
  {3450, 3459, 280},
  {3460, 3469, 281},
  {3470, 3479, 282},
  {3480, 3489, 283},
  {3490, 3499, 284},
  {3500, 3509, 285},
  {3510, 3519, 286},
  {3520, 3529, 287},
  {3530, 3539, 288},
  {3540, 3549, 289},
  {3550, 3559, 290},
  {3560, 3569, 291},
  {3570, 3579, 292},
  {3580, 3589, 293},
  {3590, 3599, 294},
  {3600, 3609, 295},
  {3610, 3619, 296},
  {3620, 3629, 297},
  {3630, 3639, 298},
  {3640, 3649, 299},
  {3650, 3659, 300},
  {3660, 3669, 301},
  {3670, 3679, 302},
  {3680, 3689, 303},
  {3690, 3699, 304},
  {3700, 3709, 305},
  {3710, 3719, 306},
  {3720, 3729, 307},
  {3730, 3739, 308},
  {3740, 3749, 309},
  {3750, 3759, 310},
  {3760, 3769, 311},
  {3770, 3779, 312},
  {3780, 3789, 313},
  {3790, 3799, 314},
  {3800, 3809, 315},
  {3810, 3819, 316},
  {3820, 3829, 317},
  {3830, 3839, 318},
  {3840, 3849, 319},
  {3850, 3859, 320},
  {3860, 3869, 321},
  {3870, 3879, 322},
  {3880, 3889, 323},
  {3890, 3899, 324},
  {3900, 3909, 325},
  {3910, 3919, 326},
  {3920, 3929, 327},
  {3930, 3939, 328},
  {3940, 3949, 329},
  {3950, 3959, 330},
  {3960, 3969, 331},
  {3970, 3979, 332},
  {3980, 3989, 333},
  {3990, 3999, 334},
  {4000, 4009, 335},
  {4010, 4019, 336},
  {4020, 4029, 337},
  {4030, 4039, 338},
  {4040, 4049, 339},
  {4050, 4059, 340},
  {4060, 4069, 341},
  {4070, 4079, 342},
  {4080, 4089, 343},
  {4090, 4099, 344},
  {4100, 4109, 345},
  {4110, 4119, 346},
  {4120, 4129, 347},
  {4130, 4139, 348},
  {4140, 4149, 349},
  {4150, 4159, 350},
  {4160, 4169, 351},
  {4170, 4179, 352},
  {4180, 4189, 353},
  {4190, 4199, 354},
  {4200, 4209, 355},
  {4210, 4219, 356},
  {4220, 4229, 357},
  {4230, 4239, 358},
  {4240, 4249, 359},
  {4250, 4259, 360},
  {4260, 4269, 361},
  {4270, 4279, 362},
  {4280, 4289, 363},
  {4290, 4299, 364},
  {4300, 4309, 365},
  {4310, 4319, 366},
  {4320, 4329, 367},
  {4330, 4339, 368},
  {4340, 4349, 369},
  {4350, 4359, 370},
  {4360, 4369, 371},
  {4370, 4379, 372},
  {4380, 4389, 373},
  {4390, 4399, 374},
  {4400, 4409, 375},
  {4410, 4419, 376},
  {4420, 4429, 377},
  {4430, 4439, 378},
  {4440, 4449, 379},
  {4450, 4459, 380},
  {4460, 4469, 381},
  {4470, 4479, 382},
  {4480, 4489, 383},
  {4490, 4499, 384},
  {4500, 4509, 385},
  {4510, 4519, 386},
  {4520, 4529, 387},
  {4530, 4539, 388},
  {4540, 4549, 389},
  {4550, 4559, 390},
  {4560, 4569, 391},
  {4570, 4579, 392},
  {4580, 4589, 393},
  {4590, 4599, 394},
  {4600, 4609, 395},
  {4610, 4619, 396},
  {4620, 4629, 397},
  {4630, 4639, 398},
  {4640, 4649, 399},
  {4650, 4659, 400},
  {4660, 4669, 401},
  {4670, 4679, 402},
  {4680, 4689, 403},
  {4690, 4699, 404},
  {4700, 4709, 405},
  {4710, 4719, 406},
  {4720, 4729, 407},
  {4730, 4739, 408},
  {4740, 4749, 409},
  {4750, 4759, 410},
  {4760, 4769, 411},
  {4770, 4779, 412},
  {4780, 4789, 413},
  {4790, 4799, 414},
  {4800, 4809, 415},
  {4810, 4819, 416},
  {4820, 4829, 417},
  {4830, 4839, 418},
  {4840, 4849, 419},
  {4850, 4859, 420},
  {4860, 4869, 421},
  {4870, 4879, 422},
  {4880, 4889, 423},
  {4890, 4899, 424},
  {4900, 4909, 425},
  {4910, 4919, 426},
  {4920, 4929, 427},
  {4930, 4939, 428},
  {4940, 4949, 429},
  {4950, 4959, 430},
  {4960, 4969, 431},
  {4970, 4979, 432},
  {4980, 4989, 433},
  {4990, 4999, 434},
  {5000, 5009, 435},
  {5010, 5019, 436},
  {5020, 5029, 437},
  {5030, 5039, 438},
  {5040, 5049, 439},
  {5050, 5059, 440},
  {5060, 5069, 441},
  {5070, 5079, 442},
  {5080, 5089, 443},
  {5090, 5099, 444},
  {5100, 5109, 445},
  {5110, 5119, 446},
  {5120, 5129, 447},
  {5130, 5139, 448},
  {5140, 5149, 449},
  {5150, 5159, 450},
  {5160, 5169, 451},
  {5170, 5179, 452},
  {5180, 5189, 453},
  {5190, 5199, 454},
  {5200, 5209, 455},
  {5210, 5219, 456},
  {5220, 5229, 457},
  {5230, 5239, 458},
  {5240, 5249, 459},
  {5250, 5259, 460},
  {5260, 5269, 461},
  {5270, 5279, 462},
  {5280, 5289, 463},
  {5290, 5299, 464},
  {5300, 5309, 465},
  {5310, 5319, 466},
  {5320, 5329, 467},
  {5330, 5339, 468},
  {5340, 5349, 469},
  {5350, 5359, 470},
  {5360, 5369, 471},
  {5370, 5379, 472},
  {5380, 5389, 473},
  {5390, 5399, 474},
  {5400, 5409, 475},
  {5410, 5419, 476},
  {5420, 5429, 477},
  {5430, 5439, 478},
  {5440, 5449, 479},
  {5450, 5459, 480},
  {5460, 5469, 481},
  {5470, 5479, 482},
  {5480, 5489, 483},
  {5490, 5499, 484},
  {5500, 5509, 485},
  {5510, 5519, 486},
  {5520, 5529, 487},
  {5530, 5539, 488},
  {5540, 5549, 489},
  {5550, 5559, 490},
  {5560, 5569, 491},
  {5570, 5579, 492},
  {5580, 5589, 493},
  {5590, 5599, 494},
  {5600, 5609, 495},
  {5610, 5619, 496},
  {5620, 5629, 497},
  {5630, 5639, 498},
  {5640, 5649, 499},
  {5650, 5659, 500},
  {5660, 5669, 501},
  {5670, 5679, 502},
  {5680, 5689, 503},
  {5690, 5699, 504},
  {5700, 5709, 505},
  {5710, 5719, 506},
  {5720, 5729, 507},
  {5730, 5739, 508},
  {5740, 5749, 509},
  {5750, 5759, 510},
  {5760, 5769, 511},
  {5770, 5779, 512},
  {5780, 5789, 513},
  {5790, 5799, 514},
  {5800, 5809, 515},
  {5810, 5819, 516},
  {5820, 5829, 517},
  {5830, 5839, 518},
  {5840, 5849, 519},
  {5850, 5859, 520},
  {5860, 5869, 521},
  {5870, 5879, 522},
  {5880, 5889, 523},
  {5890, 5899, 524},
  {5900, 5909, 525},
  {5910, 5919, 526},
  {5920, 5929, 527},
  {5930, 5939, 528},
  {5940, 5949, 529},
  {5950, 5959, 530},
  {5960, 5969, 531},
  {5970, 5979, 532},
  {5980, 5989, 533},
  {5990, 5999, 534},
  {6000, 6009, 535},
  {6010, 6019, 536},
  {6020, 6029, 537},
  {6030, 6039, 538},
  {6040, 6049, 539},
  {6050, 6059, 540},
  {6060, 6069, 541},
  {6070, 6079, 542},
  {6080, 6089, 543},
  {6090, 6099, 544},
  {6100, 6109, 545},
  {6110, 6119, 546},
  {6120, 6129, 547},
  {6130, 6139, 548},
  {6140, 6149, 549},
  {6150, 6159, 550},
  {6160, 6169, 551},
  {6170, 6179, 552},
  {6180, 6189, 553},
  {6190, 6199, 554},
  {6200, 6209, 555},
  {6210, 6219, 556},
  {6220, 6229, 557},
  {6230, 6239, 558},
  {6240, 6249, 559},
  {6250, 6259, 560},
  {6260, 6269, 561},
  {6270, 6279, 562},
  {6280, 6289, 563},
  {6290, 6299, 564},
  {6300, 6309, 565},
  {6310, 6319, 566},
  {6320, 6329, 567},
  {6330, 6339, 568},
  {6340, 6349, 569},
  {6350, 6359, 570},
  {6360, 6369, 571},
  {6370, 6379, 572},
  {6380, 6389, 573},
  {6390, 6399, 574},
  {6400, 6409, 575},
  {6410, 6419, 576},
  {6420, 6429, 577},
  {6430, 6439, 578},
  {6440, 6449, 579},
  {6450, 6459, 580},
  {6460, 6469, 581},
  {6470, 6479, 582},
  {6480, 6489, 583},
  {6490, 6499, 584},
  {6500, 6509, 585},
};

Ich verwende noch BUSY zur Dateiendeerkennung, entspricht der LED auf dem Player, siehe im Programm pinBUSY. Außerdem habe ich einen kleinen Lautsprecher an SPK_1 und SPK_2, die DACs habe ich noch nicht probiert.

Das sind doch keine Gänge, sondern Drehzahlen, oder?

Die Drehzahlen passen nicht in ein Byte!

Wenn ich so drüber nachdenke, müßte nicht jeder Gang diesen Drehzahlberiech haben? Also je Gang ein Verzeichnis?