SoftwareSerial wird nie available()

Hallo Arduino Gemeinschaft!

Ich beschäftige mich noch nicht so lang mit dem Arduino, habe aber gleich eine Frage. :slight_smile:

(M)ein Arduino-Projekt verwendet die SoftwareSerial-Bibliothek zur Kommunikation mit dem DFMiniMP3-Player.

Leider kann ich keine Befehle an den Player senden, da die SoftwareSerial-Schnittstelle nie available wird. Deshalb habe ich das Standardbeispiel dieser Bibliothek etwas abgeändert und keine weitere Peripherie (an den Arduino) angeschlossen.

#include <SoftwareSerial.h>

SoftwareSerial mySerial(2, 3); // RX, TX

void setup()
{
// Open serial communications and wait for port to open:
Serial.begin(115200);
while (!Serial) { ; // wait for serial port to connect. Needed for Native USB only
}

Serial.println("Goodnight moon!");

// set the data rate for the SoftwareSerial port
mySerial.begin(9600);
mySerial.println("Hello, world?");
}

void loop() // run over and over
{
if (mySerial.available())
Serial.write(mySerial.read()); // Serial -> mySerial-Inhalt
else
{
Serial.println("mySerial nicht bereit!");
delay(1000);
}

if (Serial.available())
mySerial.write(Serial.read()); // mySerial -> Serial-Inhalt
else
{
Serial.println("Serial nicht bereit!");
delay(1000);
}
}

Dies erzeugt im Serialmonitor die folgende Ausgabe:

Als Hardware verwende ich einen Arduino Nano (Clone). Kann es sein, dass SoftwareSerial nicht auf jeden Board läuft? Oder ist ein Fehler in meinem Sketch?

Kann ich die SoftwareSerial-Bibliothek anders überprüfen?

Vielen Dank für eure Hilfe!

Fred.

Setze deinen Sketch bitte in Code-Tags, so wie es auch in der Beschreibung zum Forum steht.
Warum verwendest du nicht ein originales Beispiel zum DFPlayer ? Dann wird es auch funktionieren. Um dem DFPlayer eine Information per SoftwareSerial zu schicken, musst du nicht vorher abfragen, ob diese "available" ist. Dies dient zum Empfang von Informationen auf der Schnittstelle und das willst du doch in dem Moment nicht.

available() gibt an, wieviele Zeichen bereits empfangen wurden, nicht ob die Schnittstelle betriebsbereit ist.

SoftwareSerial ist nach begin() betriebsbereit.

Hallo DrDiettrich!

Ich kann es im Moment nicht ausprobieren, aber die Bezeichnung ist schon sehr verwirrend.

Returns the number of bytes available to read. :grinning:

Vielen Dank für die Lösung!!!

Fred.

Was wäre denn deine 'logischere' Bezeichnung für die Funktion?

Hallo HotSystems!

Ich hatte so eine "Funktion" schon gesucht, aber Vorformatierter Text habe ich mit Code-Tags nicht assoziert! Sorry und Danke für den Hinweis!

Ich versuche immer den Code eines Sketch'es nachzuvollziehen. In diesem Fall habe ich mir das Beispiel aus der DFRobotDFPlayerMini: 3s einer Nummer spielen, herausgegriffen.
Allerdings habe ich mich hier geirrt. Ich dachte das die Abfrage:

  if (!myDFPlayer.begin(mySoftwareSerial)) {  //Use softwareSerial to communicate with mp3.
    Serial.println(F("Unable to begin:"));
    Serial.println(F("1.Please recheck the connection!"));
    Serial.println(F("2.Please insert the SD card!"));
    while(true);
  }

deshalb true wird, weil die mySoftwareSerial-Schnittstelle nicht funktioniert (was ich durch den hier geposteten Code prüfen wollte...), aber es scheint doch an einer anderen Ursache zu liegen. Die SD-Karte (Formatierung/Inhalt) kann ich allerdings ausschließen, da die Wiedergabe und Steuerung des Players über IO1/2 problemlos funktioniert.

Hier noch einmal der Gesamtcode des relevanten Teils ...

#include "Arduino.h"
#include "SoftwareSerial.h"
#include "DFRobotDFPlayerMini.h"
 
SoftwareSerial mySoftwareSerial(10, 11); // RX, TX
DFRobotDFPlayerMini myDFPlayer;
void printDetail(uint8_t type, int value);
 
void setup()
{
  mySoftwareSerial.begin(9600);
  Serial.begin(115200);
  
  Serial.println();
  Serial.println(F("DFRobot DFPlayer Mini Demo"));
  Serial.println(F("Initializing DFPlayer ... (May take 3~5 seconds)"));
  
  if (!myDFPlayer.begin(mySoftwareSerial)) {  //Use softwareSerial to communicate with mp3.
    Serial.println(F("Unable to begin:"));
    Serial.println(F("1.Please recheck the connection!"));
    Serial.println(F("2.Please insert the SD card!"));
    while(true);
  }
  Serial.println(F("DFPlayer Mini online."));
  
  myDFPlayer.volume(10);  //Set volume value. From 0 to 30
  myDFPlayer.play(1);  //Play the first mp3
}

Hallo Whandall!

So etwas wie ReciveCount z.B.

Oder?

Viele Grüße

Fred.

Ich finde available viel besser, ich bin mit allen Mitteln bemüht,
die Funktion als Anzeige eines einzelnen Zeichens zu benutzen,
also eher als Boolean.

Weiterhin empfinde ich bei Funktionen mit großem Anfangsbuchstaben,
den Geschmack von Konstruktoren.

Hallo Whandall!

So ganz verstanden habe ich deine Antwort (noch) nicht.

Funktion(en) / Methode(n) die (ein) Zeichen wiedergeben beginnen üblicherweise mit Get...().

Funktion(en) / Methode(n) die einen Boolean wiedergeben beginnen üblicherweise mit Is....().

Was ich nicht verstanden habe ist der Zusammenhang zwischen Zeichen und Boolean.

Methoden Deklarationen sollten lt. Microsoftspezifikation immer mit Großbuchstaben beginnen:

Methoden deklaration

MS Deklarationsregeln

Viele Grüße

Fred.

a) ist es müßig darüber zu diskutieren wie eine member Function heißt. Sie heißt nun mal available.

b) im Arduino Umfeld gibt es in vielen Libraries eine member Function available (Wire, Serial, EthernetClient, ... ). Daher ist es konsequent diese auch für SoftSerial zu verwenden.

c) Welche Relevanz hat eine MS Deklarationsregel für .NET im Arduino Umfeld wo wir in c++11 arbeiten? "Best Practice" und in den meisten Libs sind (member) Function klein in camelCase. Groß beginnen Strukturen und Klassen.

1 Like

Die "Arduino Sprache" sollte ursprünglich mal aussehen wie Processing (Java).
Da fangen Funktionsnamen traditionell mit einem Verb mit kleinem Anfangsbuchstaben an. Auch die geschweiften Klammern werden gern zeilensparend aber für manche weniger übersichtlich gesetzt.

void tuWas() {
   // oder doch nicht
}

Außerdem heißt available() nun mal available und liefert die Anzahl im Puffer wartender Zeichen zurück. Das kann also nie mehr geändert werden (hoffentlich :slight_smile: ).

Hallo noiasca, Hallo Michael!

Ich möchte den Namen der Funktion auch nicht "ändern". Es ist für einen nicht "Arduinoaner" nur am Anfang verwirrend, wenn eine Methode available heißt und eine Anzahl zurück gibt. Aber wenn es sich eingebürgert hat, dann kommt man schon damit zurecht!

Auch die Erklärung von Michael über die Herkunft der "Arduino Sprache" ist eingängig.

An solchen "Formalien" sollte die weitere Entwicklung nicht scheitern!

Vielen Dank (an Alle) für die helfenden Ratschläge!

Fred.

Ich habe mir das von Anfang an als 'sind Zeichen verfügbar' oder ist eine 'Antwort der Gegenstelle verfügbar' gemerkt, damals als ich auch noch 'nicht Arduinoaner' war.dies hat mir das verständnis und die Akzeptanz des Begriffes 'available sehr vereinfacht.

Es heißt in der Übersetzung ja auch "verfügbar", was man sowohl als "es ist etwas verfügbar", als auch "es sind x Zeichen verfügbar" interpretieren kann.

Gruß Tommy

Das denke ich doch auch!

Durchaus...
Einerseits ist es immer gut, wenn man reichlich Vorwissen mitbringt.
Andererseits ist es auch manchmal hinderlich und führt zu denk Blockaden.

Die kleinen Arduinos stellen besondere Anforderungen. z.B. 2kB Hauptspeicher ist eben nicht mit einem PC vergleichbar.

Außerdem ist es auch in C/C++ Konvention dass Variablen und Funktionen mit Kleinbuchstaben anfangen. Java hat das von C übernommen. Dass die API an Processing angelehnt ist stimmt, aber es hätte auch keinen Sinn gehabt bei den eigenen Elementen von der darunterliegenden Sprache abzuweichen.

Großbuchstaben am Anfang und danach CamelCase ist auch als PascalCase bekannt

Deshalb heißt ein Programm in Arduino ja auch 'Sketch' :wink:

Na ja, immerhin führt das dazu, dass man auch mit Processing gut klarkommt,
ohne allzu viel Java Grundwissen zu besitzen. Grundsätzlich ist die Syntax ja sehr verwandt.
Hilft natürlich, wenn man wenigstens Java stammeln kann, besser ist natürlich mehr.

Processing hat auch einen Haufen sehr interessanter Beispiele, da kann man viel abschauen.

Ja, dann kann man das doch stiefmütterlich behandelte, bis nicht vorhandene, Exceptionhandling nachrüsten.

Gruß Tommy

Wenn man in einem Steuerungsprogramm mit Exceptions zu kämpfen hat, dann ist ein Redesign unabdingbar. Wenn ein "Access Violation" oder "Guru Meditation" Fehler auftritt, und kein Benutzer da ist, der schnell genug und sinnvoll darauf reagieren kann, dann ist die Kacke am dampfen :frowning: