DS18S20 auslesen! Fehler im Code?

Hallo zusammen,

In dem unten zusehen Code habe ich ein Problem bzw. Ich finde den "Fehler" nicht. Mein Ziel ist es nach einem Befehl "OW01" den Sensor OW01 auszulesen und den Wert EINMAL zurück zugeben. Dann soll nichts mehr passieren bis ich einen anderen Befehl verwende.

Das ganze funktioniert fast. Allerdings wird der Wert nicht einmal ausgegeben sondern so lange bis ich einen neuen Befehl sende, also in einem sehr kurzen Intervall direkt den aktuellen Wert ausgegeben.

Ich würde mich über Hilfe sehr freuen.

Beste Grüße
Florian

#include <OneWire.h>
#include <DallasTemperature.h>

#define ONE_WIRE_BUS 2
#define RESOLUTION 10
OneWire oneWire(ONE_WIRE_BUS);
DallasTemperature sensors(&oneWire);
// Meine Sensoren
DeviceAddress sensor1 = { 0x28, 0xFF, 0x1C, 0xFC, 0x4C, 0x04, 0x00, 0xC7 };
DeviceAddress sensor2 = { 0x28, 0xFF, 0x25, 0xE9, 0x4E, 0x04, 0x00, 0x46 };
/* Die Sensoren, hast du ferwendet! Sind die Adressen Korrekt?
DeviceAddress sensor1 = { 0x10, 0x38, 0x27, 0x57, 0x2, 0x8, 0x0, 0x79 };
DeviceAddress sensor2 = { 0x10, 0x16, 0x2E, 0x57, 0x2, 0x8, 0x0, 0x2F };
*/
float temp1 = 0.0;
float temp2 = 0.0;

String Input=""; // Input von Serieller Schnittstelle
String Befehl=""; // Befehl aus Input

// -------------------------------------------------------------------
void setup()
{
Serial.begin(9600);
sensors.begin();
sensors.setResolution(sensor1, RESOLUTION);
sensors.setResolution(sensor2, RESOLUTION);
Serial.println("");Serial.println("Testausgabe");
} // ende setup
// -------------------------------------------------------------------
//
// ===================================================================
void loop(void)
{
if (Serial.available()) Einlesen();
sensors.requestTemperatures(); // Messwerte erneuern
//delay(400); // Nur bei Parasitaerer Beschaltung Notwendig! // Bei Notwendigkeit erhoehen
ausfuehren();
} // ende loop
// *******************************************************************
//
// ===================================================================
void Einlesen()
{
while (Serial.available())
{
char ch = Serial.read();
// Serial.print("Echo: ");
// Serial.println(ch);
Input=Input+ch;
// Serial.println(Input);
// delay(10);
}
Befehl = Input.substring(0, 4);
Serial.println("Befehl: " + Befehl);
Input="";
} // ende Einlesen()
// ===================================================================
//
// ===================================================================
void ausfuehren() // Ablauf korrigiert
{
if (Befehl=="OW01")
{
float temp1 = gibTemp(sensor1); // 'temp1' ohne weitere Auswertung?
tempAus(temp1); // weitere Auswertung
}
else if (Befehl=="OW02")
{
float temp2 = gibTemp(sensor2); // 'temp2' ohne weitere Auswertung?
tempAus(temp2); // weitere Auswertung
}
else
{
// Serial.println("fehl Eingabe! 'OW01' oder 'OW02' !!");
}
} // ende ausfueren()
// ===================================================================
//
// ===================================================================
// Gibt den Sensor Temperaturwert zurueck
float gibTemp(DeviceAddress deviceAddress)
{
float tempC = sensors.getTempC(deviceAddress);
if (tempC == -127.00)
{ // device disconnected code for Celsius
Serial.print("Error getting temperature, DS18B20 disconnected");
}
return (tempC); // Gibt den Wert in °C zurueck
} // ende gibTemp()
// ===================================================================
//
// ===================================================================
// Temperaturwert zu Serial Monitor und oder anderswo?
void tempAus(float temp)
{
Serial.println(temp);
} // ende gibTemp()

Bitte setze deinen Code in Code-Tags. Verwende dazu die Schaltfläche "</>".
Das kannst du auch noch nachträglich machen, dann wird der Sketch besser lesbar.

Versuch mal, Befehl am Ende von void ausfuehren() zu löschen. Ein leerer String darf dann natürlich nicht als Fehler analysiert werden, sondern als dritte Möglichkeit neben "OW01" und "OW02" gültig sein.

Hallo,

unbedingt deinen obigen Code in Code Tags setzen. Markieren und </> Button drücken.

Ich sehe aber schon paar Fehler.

das sind einfach nur leere definierte Strings. Nichts weiter.

String Input="";                    // Input von Serieller Schnittstelle
String Befehl="";                   // Befehl aus Input

und ein Stringvergleich mit == funktioniert nicht.

if (Befehl=="OW01")

Du mußt ein char Array definieren mit ausreichender Größe. Also längster bekannter Befehl + 1. +1 für das letzte nicht sichtbare Zeichen dem 0 Terminator.

in beide char Array passen hier 9 Zeichen rein.

const byte BUFFER_SIZE = 10;
char Input[BUFFER_SIZE];    // Input von Serieller Schnittstelle
char Befehl[BUFFER_SIZE];   // Befehl aus Input

so könnte das aussehen

if (strncmp(Befehl, "OW01", 4) == 0)  {     // Stringvergleich der ersten 4 Zeichen
  Serial.println(F("OW01 erkannt"));
  if (strlen(Befehl) < BUFFER_SIZE - 1)  {   // Stringlängenprüfung
    float temp1 = gibTemp(sensor1);   // 'temp1' ohne weitere Auswertung?
    tempAus(temp1);                   // weitere Auswertung
  }
} 
if (strncmp(Befehl, "OW02", 4) == 0)  {     // Stringvergleich der ersten 4 Zeichen
  Serial.println(F("OW02 erkannt"));
  if (strlen(Befehl) < BUFFER_SIZE - 1)  {   // Stringlängenprüfung
    float temp2 = gibTemp(sensor2);   // 'temp2' ohne weitere Auswertung?
    tempAus(temp2);                   // weitere Auswertung
  }  
}  
else  {
  Serial.println("Befehl unbekannt."); 
}
   memset(Befehl,'\0',sizeof(Befehl));  // Befehlsinhalt löschen

Doc_Arduino:
und ein Stringvergleich mit == funktioniert nicht.

Nicht mit C Strings. Mit der Arduino String Klasse geht es schon.

Die Einlese Routine ist aber trotzdem sehr schlecht gemacht. Die eigentliche Einlese-Routine hast du in deiner Verion aber weggelassen. So ist es vollständig:

const int SERIAL_BUFFER_SIZE = 16;
char serialBuffer[SERIAL_BUFFER_SIZE];

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

void loop() 
{
  if (readSerial() == true)
  {
    if (strcasecmp(serialBuffer, "OW01") == 0)  //case = Groß/Kleinschreibung ignorieren
    {
      Serial.println(F("OW01 erkannt"));
    }
    else if (strcasecmp(serialBuffer, "OW02") == 0)
    {
      Serial.println(F("OW02 erkannt"));
    }
    else
    {
     Serial.println(F("Unbekannter Befehl"));
    }
  }

}

bool readSerial()
{
  static byte index;

  while(Serial.available())
  {   
    char c = Serial.read();
    
    if(c >= 32 && index < SERIAL_BUFFER_SIZE - 1)
    {
      serialBuffer[index++] = c;
    }
    else if(c == '\n' && index > 0)
    {
      serialBuffer[index] = '\0';
      index = 0;
      return true;
    }
  }
  return false;
}

Oder strncasecmp() oder strncmp() wenn man nur die ersten n Zeichen vergleichen möchte

Dabei den Serial Monitor so einstellen dass ein Newline/Linefeed am Ende gesendet wird! Dadurch weiß man wann man fertig ist und auswerten kann

Das mit strlen() ist überflüssig. Einen Puffer-Überlauf muss man schon beim Einlesen verhindern!!

Hallo,

das mit der Stringklasse und == war mir nicht bewußt.
Außerdem ahnte ich das du hier eh vorbei schaust. :slight_smile: