Werte von DS18B20 senden via UART -> empfange nur 0

Hallo Leute,

erstmals muss ich selbst einen Blog öffnen, da ich zum Thema nix Finde.
Vorerst vielen Dank euch allen, die tgl. helfen Probleme zu lösen!!!
Nun kurz zu mir.
Bin Quereinsteiger und Hobbyprogrammer.
Arduino und bissl Python.
Hab schon das ein oder andere Projekt befriedigend auf die Beine gestellt.
Aktuell verzweifle ich...

Mein Projekt:
5xDS18B20
1xSR04
1XPhotoresistor
Sind die Eingangssensoren eines Nanos.
Als Ausgabe dient ein LCD 16,2 welches über i2c die Daten der Sensoren ausgibt.
Bis dahin funktioniert alles super.
Weiterhin sollen alle Sensorwerte via UART, einem TTL RS485 Modul zum nächsten Nano gesendet werden.
Es sind 5xfloat und 2xint die jeweils als datentyp byte versendet und über Serial.read() vom zweiten Nano empfangen werden.
Alle Werte von den Temp Sensoren kommen als 0 an. Die anderen 2 kommen korrekt an.
Erst dachte ich es liegt an der Konvertierung der Datentypen float -> byte. Doch dies habe ich simuliert und funktioniert so weit. Selbst wenn ich die Byte Rohdaten vom byte[12] array von der dallas Funktion sende kommt nix an.
Woran kann das liegen?
Blockiert i2c oder oneWire eventuell uart?
Bin mit meinem Latein am Ende.
Natürlich kann ich die sketch hochladen, aber vielleich habt ihr ja gleich eine Ahnung was ich noch versuchen könnte. Danke im Voraus!!!

Wie sollen wir helfen, wenn wir deinen Sketch nicht kennen ?
Poste den bitte in Code-Tags.
In der IDE mit rechter Maustaste auf für Forum kopieren und dann hier einfügen.

///////////////////////////////////////////////Sender////////////////////////////////////////

#include <Arduino.h>
/*
 * Displays text sent over the serial port (e.g. from the Serial Monitor) on
 * an attached LCD.
 * YWROBOT
 *Compatible with the Arduino IDE 1.0
 *Library version:1.1
 */
#include <Wire.h> 
#include <OneWire.h>
#include <LiquidCrystal_I2C.h>
#include <Ultrasonic.h>

uint8_t a;
uint8_t b;

int enablePin = 13;//RS485 Master/Slave pin  Master = Sender = HIGH


LiquidCrystal_I2C lcd(0x27,16,2);  // set the LCD address to 0x27 for a 16 chars and 2 line display


Ultrasonic ultrasonic1(4, 5);	// An ultrasonic sensor HC-04
int distance = 0;

// OneWire DS18S20, DS18B20, DS1822 Temperature Example
//
// http://www.pjrc.com/teensy/td_libs_OneWire.html
//
// The DallasTemperature library can do all this work for you!
// https://github.com/milesburton/Arduino-Temperature-Control-Library

OneWire  ds(8);  // on pin 10 (a 4.7K resistor is necessary)

//Sensoren
float temperaturOfen = 0;
byte adresseOfenTemperaturSensor[] = {0x28, 0x22, 0x54, 0x55, 0x42, 0x20,0x01, 0xF4, 0xF8};//Dec={40,34,84,85,66,32,1,244,248};
float temperaturDach = 0;
byte adresseDachTemperaturSensor[] = {0x28, 0x83, 0x1B, 0x91, 0x42, 0x20, 0x01, 0x2E};//Dec={40,131,27,145,66,32,1,46};
float temperaturAussen = 0;
byte adresseAussenTemperaturSensor[] = {0x28, 0xE5, 0x4C, 0x92, 0x42, 0x20, 0x01, 0x13};//Dec={40,229,76,146,66,32,1,19};
float temperaturPufferOben = 0;
byte adressePufferObenTemperaturSensor[] = {0x28,0xF8,0xF3,0x64,0x42,0x20,0x01,0x5A};//{40,248,243,100,66,32,1,90};
float temperaturPufferUnten = 0;
byte adressePufferUntenTemperaturSensor[] = {0x28, 0x2B, 0x82, 0x5C, 0x42, 0x20, 0x01,0x33};//Dec={40,43,130,92,66,32,1,51};


//Variablen
unsigned long timerLcd = 5000;
unsigned long speicherMillisTimerLcd = 0;
int zaehlerLcd = 0;



float getTemperatur (byte adresseSensor[8])
{
          byte i;
          byte present = 0;
          byte type_s;
          byte data[12];
          byte addr[8];
          
          float celsius;
          
          for ( int a = 0;a < 8; a++){addr[a] = adresseSensor[a];}
          
          //Serial.print("ROM =");
          for( i = 0; i < 8; i++) {
            //Serial.write(' ');
            //Serial.print(addr[i], HEX);
            
          }

          if (OneWire::crc8(addr, 7) != addr[7]) {
              //Serial.println("CRC is not valid!");
              return;
          }
          //Serial.println();
        
          // the first ROM byte indicates which chip
          switch (addr[0]) {
            case 0x10:
              //Serial.println("  Chip = DS18S20");  // or old DS1820
              type_s = 1;
              break;
            case 0x28:
              //Serial.println("  Chip = DS18B20");
              type_s = 0;
              break;
            case 0x22:
              //Serial.println("  Chip = DS1822");
              type_s = 0;
              break;
            default:
              //Serial.println("Device is not a DS18x20 family device.");
              return;
          } 

          ds.reset();
          ds.select(addr);
          ds.write(0x44, 1);        // start conversion, with parasite power on at the end
          
          delay(1000);     // maybe 750ms is enough, maybe not
          // we might do a ds.depower() here, but the reset will take care of it.
          
          present = ds.reset();
          ds.select(addr);    
          ds.write(0xBE);         // Read Scratchpad

          //Serial.print("  Data = ");
          //Serial.print(present, HEX);
          //Serial.print(" ");
          for ( i = 0; i < 9; i++) {           // we need 9 bytes
            data[i] = ds.read();
            //Serial.print(data[i], HEX);
            //Serial.print(" ");
          }
          //Serial.print(" CRC=");
          //Serial.print(OneWire::crc8(data, 8), HEX);
          //Serial.println();

          // Convert the data to actual temperature
          // because the result is a 16 bit signed integer, it should
          // be stored to an "int16_t" type, which is always 16 bits
          // even when compiled on a 32 bit processor.
          int16_t raw = (data[1] << 8) | data[0];

          a = data[1];
          b = data[0];

          if (type_s) {
            raw = raw << 3; // 9 bit resolution default
            if (data[7] == 0x10) {
              // "count remain" gives full 12 bit resolution
              raw = (raw & 0xFFF0) + 12 - data[6];
            }
          } else {
            byte cfg = (data[4] & 0x60);
            // at lower res, the low bits are undefined, so let's zero them
            if (cfg == 0x00) raw = raw & ~7;  // 9 bit resolution, 93.75 ms
            else if (cfg == 0x20) raw = raw & ~3; // 10 bit res, 187.5 ms
            else if (cfg == 0x40) raw = raw & ~1; // 11 bit res, 375 ms
            //// default is 12 bit resolution, 750 ms conversion time
          }
          
          celsius = (float)raw / 16.0;
          //fahrenheit = celsius * 1.8 + 32.0;
          //Serial.print("  Temperature = ");
          //Serial.print(celsius);
          //Serial.print(" Celsius, ");
          //Serial.print(fahrenheit);
          //Serial.println(" Fahrenheit");
          return celsius;
}

int getValueUltrasonic()
{
  //Serial.print("Sensor 01: ");
  //Serial.print(ultrasonic1.read()); // Prints the distance on the default unit (centimeters)
  //Serial.println("cm");
  return ultrasonic1.read();
}


void sendeDatenRS485(float temp0,float temp1,float temp2,float temp3,float temp4, int ultra, int photo)
{
  unsigned char signMinus[7];//Vorzeichenerkennung 1 = Minus und negative Werte positiv machen zum senden
  if ( temp0 < 0.00) {signMinus[0] = 1; temp0 = temp0 * -1.00;} else { signMinus[0] = 0;}
  if ( temp1 < 0.00) {signMinus[1] = 1; temp1 = temp1 * -1.00;} else { signMinus[1] = 0;}
  if ( temp2 < 0.00) {signMinus[2] = 1; temp2 = temp2 * -1.00;} else { signMinus[2] = 0;}
  if ( temp3 < 0.00) {signMinus[3] = 1; temp3 = temp3 * -1.00;} else { signMinus[3] = 0;}
  if ( temp4 < 0.00) {signMinus[4] = 1; temp4 = temp4 * -1.00;} else { signMinus[4] = 0;}
  signMinus[5] = 0;
  signMinus[6] = 0;

  Serial.println('s');//1

  float f[] = {temp0,temp1,temp2,temp3,temp4};

  for ( int i = 0; i < 5; i++)
  {
    byte* bytes = (byte*) & f[i];
    Serial.print(signMinus[i]); Serial.print(',');//10 / 11
    for ( int j = 0; j < 4; j++)
          {
          Serial.print(bytes[j]); Serial.print(',');//40 / 51
          }
    Serial.println();

  } 

byte signMinus56[2];
signMinus56[0] = signMinus[5];
signMinus56[1] = signMinus[6];
unsigned int value[2];
value[0] = ultra * 100;
value[1] = photo * 100;

  for ( int i = 0; i < 2; i++)
  {
    byte a = value[i] / 255;
    byte b = value[i] % 255;
    Serial.print(signMinus56[i]); Serial.print(',');
    Serial.print(a); Serial.print(',');
    Serial.print(b); Serial.print(',');//12 byte / 63 byte

  }
   
Serial.println();


}

void printEinheit (String einheit)
{
    lcd.setCursor(10,1);
    lcd.print(einheit);
}

void visualisiereLcd(float temp1,float temp2,float temp3,float temp4,float temp5, int ultra, int photo)
{
if ( millis() > (speicherMillisTimerLcd + timerLcd))
  {
    speicherMillisTimerLcd = millis();
    zaehlerLcd++;
    if (zaehlerLcd > 7){zaehlerLcd = 1;}
  }
  lcd.clear();
  switch (zaehlerLcd)
  {
  case 1:
    lcd.setCursor(0,0);
    lcd.print("1/7 Ofen:");
    lcd.setCursor(0,1);
    lcd.print(temp1);
    printEinheit("GradC.");
    
    break;

   case 2:
    lcd.setCursor(0,0);
    lcd.print("2/7 PufferOben:");
    lcd.setCursor(0,1);
    lcd.print(temp2);
    printEinheit("GradC.");
    break;

   case 3:
    lcd.setCursor(0,0);
    lcd.print("3/7 PufferUnten:");
    lcd.setCursor(0,1);
    lcd.print(temp3);
    printEinheit("GradC.");
    break;

   case 4:
    lcd.setCursor(0,0);
    lcd.print("4/7 Aussen:");
    lcd.setCursor(0,1);
    lcd.print(temp4);
    printEinheit("GradC.");
    break;

   case 5:
    lcd.setCursor(0,0);
    lcd.print("5/7 Dach:");
    lcd.setCursor(0,1);
    lcd.print(temp5);
    printEinheit("GradC.");
    break;

   case 6:
    lcd.setCursor(0,0);
    lcd.print("6/7 Pellets:");
    lcd.setCursor(0,1);
    lcd.print(ultra);
    printEinheit("cm");
    break;

   case 7:
    lcd.setCursor(0,0);
    lcd.print("7/7 Licht:");
    lcd.setCursor(0,1);
    lcd.print(photo);
    printEinheit("/1023");
    break;
    
  }

}



void setup()
{
  lcd.init();                      // initialize the lcd 
  lcd.backlight();
  Serial.begin(9600);
  delay(10);
  pinMode(enablePin, OUTPUT);
  digitalWrite(enablePin,HIGH);//zum senden als Master


  for(int j = 0; j < 5; j++)
  {
          byte i;
          byte present = 0;
          byte type_s;
          byte data[12];
          byte addr[8];
          float celsius, fahrenheit;
          
          if ( !ds.search(addr)) {
            //Serial.println("No more addresses.");
            //Serial.println();
            ds.reset_search();
            delay(0);
            return;
          }
          
          //Serial.print("ROM =");
          for( i = 0; i < 8; i++) {
            //Serial.write(' ');
            //Serial.print(addr[i], HEX);
          }

          if (OneWire::crc8(addr, 7) != addr[7]) {
              //Serial.println("CRC is not valid!");
              return;
          }
          //Serial.println();
        
          // the first ROM byte indicates which chip
          switch (addr[0]) {
            case 0x10:
              //Serial.println("  Chip = DS18S20");  // or old DS1820
              type_s = 1;
              break;
            case 0x28:
              //Serial.println("  Chip = DS18B20");
              type_s = 0;
              break;
            case 0x22:
              //Serial.println("  Chip = DS1822");
              type_s = 0;
              break;
            default:
              //Serial.println("Device is not a DS18x20 family device.");
              return;
          } 

          ds.reset();
          ds.select(addr);
          ds.write(0x44, 1);        // start conversion, with parasite power on at the end
          
          delay(0);     // maybe 750ms is enough, maybe not
          // we might do a ds.depower() here, but the reset will take care of it.
          
          present = ds.reset();
          ds.select(addr);    
          ds.write(0xBE);         // Read Scratchpad

          //Serial.print("  Data = ");
          //Serial.print(present, HEX);
          //Serial.print(" ");
          //hier wird die Adresse vom angeschlossenen Dallas ausgegeben/////////////////////////////////////////////////////////////////
          for ( i = 0; i < 9; i++) {           // we need 9 bytes
            data[i] = ds.read();
            //Serial.print(data[i], HEX);
            //Serial.print(" ");
            //lcd.setCursor(0,0);lcd.print(i); lcd.print(">"); lcd.print(addr[i]); lcd.print(";"); delay(5000);lcd.clear();
          }
          //Serial.print(" CRC=");
          //Serial.print(OneWire::crc8(data, 8), HEX);
          //Serial.println();

          // Convert the data to actual temperature
          // because the result is a 16 bit signed integer, it should
          // be stored to an "int16_t" type, which is always 16 bits
          // even when compiled on a 32 bit processor.
          int16_t raw = (data[1] << 8) | data[0];
          if (type_s) {
            raw = raw << 3; // 9 bit resolution default
            if (data[7] == 0x10) {
              // "count remain" gives full 12 bit resolution
              raw = (raw & 0xFFF0) + 12 - data[6];
            }
          } else {
            byte cfg = (data[4] & 0x60);
            // at lower res, the low bits are undefined, so let's zero them
            if (cfg == 0x00) raw = raw & ~7;  // 9 bit resolution, 93.75 ms
            else if (cfg == 0x20) raw = raw & ~3; // 10 bit res, 187.5 ms
            else if (cfg == 0x40) raw = raw & ~1; // 11 bit res, 375 ms
            //// default is 12 bit resolution, 750 ms conversion time
          }
          celsius = (float)raw / 16.0;
          //fahrenheit = celsius * 1.8 + 32.0;
          //Serial.print("  Temperature = ");
          //Serial.print(celsius);
          //Serial.print(" Celsius, ");
          //Serial.print(fahrenheit);
          //Serial.println(" Fahrenheit");
  }

}



void loop()
{
  
//temperaturInput
temperaturOfen = getTemperatur(adresseOfenTemperaturSensor);
/*
temperaturPufferOben = getTemperatur(adressePufferObenTemperaturSensor);
temperaturPufferUnten = getTemperatur(adressePufferUntenTemperaturSensor);
temperaturAussen = getTemperatur(adresseAussenTemperaturSensor);
temperaturDach = getTemperatur(adresseDachTemperaturSensor);
*/
///////////////ultraschallSensor////////////////////////
//distance = getValueUltrasonic();
//Serial.println (distance);

///////////////photozelle////////////////////
//int lichtWert = analogRead (7);

///////////////lcd////////////////////////
//visualisiereLcd(temperaturOfen, temperaturPufferOben, temperaturPufferUnten,temperaturAussen, temperaturDach, distance, lichtWert);

//////////////RS485//////////////////////////
//sendeDatenRS485(temperaturOfen, temperaturPufferOben, temperaturPufferUnten,temperaturAussen, temperaturDach, distance, lichtWert);

Serial.print(a); Serial.println(b);

delay(1000);

}


/////////////////////////////////////////////////Empfänger///////////////////////////////////////////////

#include <Arduino.h>

//SLAVE CODE: (Arduino NANO):

//Slave code (Arduino NANO)
//Serial Communication Between Two Arduinos using RS-485
//Circuit Digest

const int NUMBER_OF_FIELDS = 21;//Anzahl der Felder die empfangen werden
int value[NUMBER_OF_FIELDS];//Speicherplätze für eingehende Felder
int fieldIndex = 0;

int enablePin = 13; //Schalter zwischen senden und empfangen


void setup() 
{

  Serial.begin(9600);                   // initialize serial at baudrate 9600:
  pinMode(enablePin, OUTPUT);
  delay(10);
  digitalWrite(enablePin, LOW);        //  (Pin 8 always LOW to receive value from Master)
  
}

void loop() 

{
int anzahl = 2;
unsigned char ch [anzahl];
while (Serial.available() >0)
{
  for ( int i = 0; i < anzahl; i++)
  {
    ch[i] = Serial.read();
  }
}

for ( int i = 0; i < anzahl; i++)
  {
    Serial.print(ch[i]);
  }
  //Serial.println();
  //delay(2000);



}
/*
{                                                  
  if ( Serial.available() > 0)
    {
      char ch = Serial.read();//einlesen eines Charakters
      
      if ( ch >= '0' && ch <= '9')//wenn Zahl..
        {
          if ( fieldIndex < NUMBER_OF_FIELDS)//wenn noch Felder erwartet werden ..
            {
              value[fieldIndex] = value[fieldIndex] * 10 + (ch - '0');//Charakter in Speicher schieben
              // *10 setzt eine Stelle höher und ch-0 verhindert, dass noch eine 0 mehr hinten angefülgt wird           
            }
        }


      else if (ch == ',')
        {
          fieldIndex++;//Sprung zum nächsten Feld
        }


      else
        {
          for ( int i = 0; i < min (NUMBER_OF_FIELDS, fieldIndex+1); i++)
          {
            Serial.print(i); Serial.print("->");Serial.println(value[i]);
            value[i]=0;
          }
          fieldIndex = 0;
        }
    }
 }
 */

Leider bekomme ich den Sender Code nicht hochgeladen. Maximal 2 Links. gibts eine ander Möglichkeit?

Als Code sollte das gehen.
(In der Arduino-IDE auf bearbeiten -> für Forum kopieren) und dann einfach in Dein Post einfügen.
Entweder mit STRG-V oder mit der rechten Maustaste und einfügen.

Wobei Dein Slave schon nicht schick ist.
Du suchst auf der Schnittstelle die Du mit dem USB-Kabel benutzt nach einem Zeichen.

Du brauchst wohl softwareserial.

Du kannst auch deinen Post #3 erweitern und den zweiten Sketch dahinter setzen.
Kurze Info "Sender-Sketch" dazwischen, damit wir das erkennen.

warum schreibst du nicht alles Daten hintereinander in einem "String" durch ein Zeichen ";" getrennt und trennst diese dann im Empfänger wieder ?

Ich bin mir nicht sicher ob ich die Stringvariante schon probiert habe, aber ich werde das noch testen.
Lediglich die Ds18b20 werte kommen nicht an. Die Integer kommen super an. Auch sonstige gesendete Werte kommen an.

Im LCD werde alle Temperaturwerte ordentlich angezeigt.
Verstehe nicht warum die Werte egal in welcher Form über uart nicht kommen..

Also beide Codes sind jetzt hochgeladen. Softwareserial sagt mir nix. Werde ich googln.

SofwareSerial finde ich interessant. Da hätte ich mir den USBasp zum programmieren wahrscheinlich sparen können.
Ich glaube trotzdem nicht daran, dass es daran liegt, da die Werte wie folgt Serial.print ausgegeben werden:
Nur ein Bsp.

0,0,0,0,0,0,0,0,0,0,0,9,134,0,12,230

Die ersten Nullen sind die Temperaturen und die letzten 6 werte sind die zerlegten Integer.

Du kannst den USBasp nicht durch SoftwareSerial ersetzen.
Mit SoftwareSerial hast du eine zusätzliche serielle Verbindung zu anderen Komponenten. Die nimmst du statt der Hardware seriellen.
USBasp zum programmieren per ISP.

Normal sollte es doch gehen, dass ich a und b Serial zum Empfänger Nano sende oder?

Habe Celsius jetzt nochmal zum int konvertiert und dann als string gesendet. Das gleiche...00

Werde am We nochmal mit SoftwareSerial experimentieren um read und print voneinander zu lösen aber irgendwie hab ich das Gefühl es ist ein anderes Problem.. nur welches...

Hast du denn auch die gewandelten Daten mal am seriellen Monitor angesehen ?
Evtl. funktioniert ja die Wandlung schon nicht richtig.

Kurz zur Ergänzung.
Zu Übertragung verwende ich char, um die Strings zu vermeiden.
Dazu muss auch ein entsprechender Puffer bereit gestellt werden.
Ich sende meine Daten als char und verbinde diese wie in folgendem Beispiel:

  char tmpValue[6];
  dtostrf (temperatur_1, 1, 1, tmpValue);
  strcat(wifiKomplMsg, tmpValue); 
  strcat(wifiKomplMsg, ":");

  dtostrf (temperatur_2, 1, 1, tmpValue);
  strcat(wifiKomplMsg, tmpValue); 
  strcat(wifiKomplMsg, ":");

  dtostrf (temperatur_3, 1, 0, tmpValue);
  strcat(wifiKomplMsg, tmpValue); 
  strcat(wifiKomplMsg, ":");

und trenne die char nach folgendem Beispiel:

  wert_1 = strtok(receivedChars, ":");
  wert_2 = strtok(NULL, ":");
  wert_3 = strtok(NULL, ":");

das lässt sich natürlich auch beliebig erweitern.
So oder ähnlich verwende ich es in verschiedenen Projekten.

Nein, das ist ein vollkommen falscher Weg.
Las das liegen.
Da auch ich erst am WE wieder bei bin, schau ich dann auf Deinen Ausgangssketch. Da liegt irgendwo der Wurm.

Nein habe ich nicht. Hab sie übers LCD ausgegeben, da alles ziemlich verbaut ist.
Da kamen alle 7 Variablen ordentlich an.
Werde am We alles zerlegen und schaun was überhaupt Serial rausgeht..

Diese Funktionen kannte ich noch nicht. Echt interessant.
Ich habe natürlich bevor ich das Problem gepostet habe schon viel probiert.
Die Integer zerlegt in byte oder char-> kam an!
Einzelne chars senden -> funktioniert ebenfalls.
Lediglich die floats wollen nicht.
Diese habe ich konvertiert zu int, zerlegt in bytes oder chars, geschickt via union struct oder bytes mit den >> operator direkt gebaut.
Immer Nullen.
Ich sah das Problem in der Konvertierung, vermute aber langsam das die variablen echt leer sind. Doch das verstehe ich nicht warum am LCD alles perfekt ausgegeben wird..

Daher solltest du dir ansehen, was nach der Konvertierung mit dem Inhalt ist.
Dem LCD ist es oft wurscht, was es anzeigen muss. Das nimmt "fast" alles.

This topic was automatically closed 120 days after the last reply. New replies are no longer allowed.