Temperaturwert vom DS18B20 auf 8x16 DotMatrix darstellen

Hallo,
ich bin ganz neu bei Arduino und hab schon ein Problem.
Mein Projekt ist Temperatur vom DS18B20 auf ein 8x16 Dotmatrix Display anzuzeigen.
8x16 Display mit doppelter Höhe und 2 Zonen.

Ich benutze die md_parola Library.
Die Temperaturmessung funktioniert zwar per seriellen Ausgabe, jedoch passen wohl der Datentyp vom Temp. Sensor und der vom md_parola nicht so zusammen.

Ich habe es schon mit einem "globalem String" versucht aber immer wieder Fehlermeldungen.

Bin gerade nicht zu hause, werde nachher mal den Code mit posten.

Danke schonmal im vorraus

Poste mal ein Link zum Display.

Da gibt es so viele auf den Markt.

Gruß

Pucki

  • Code posten, inkl. exaktem Verweis auf die DS18B20 Library die du verwendest (wir müssen genau die gleiche finden!)
  • links zu den Modul das du verwendest
  • und einen genauen Schaltplan
  • und die exakte Fehlermeldung
#include <MD_Parola.h>
#include <MD_MAX72xx.h>
#include "Font_Data.h"
#include <OneWire.h>//Temperatur
#include <DallasTemperature.h> //Temperatur

// Data wire is plugged into pin 2 on the Arduino
#define ONE_WIRE_BUS 2 //DS18B20 Temp.Sensor

// Setup a OneWire instance to communicate with any OneWire devices
OneWire oneWire(ONE_WIRE_BUS);

// Pass OneWire reference to Dallas Temperature
DallasTemperature sensors(&oneWire);

// Uncomment according to your hardware type
#define HARDWARE_TYPE MD_MAX72XX::FC16_HW
//#define HARDWARE_TYPE MD_MAX72XX::GENERIC_HW

#define	MAX_DEVICES	20 //20 Module
#define MAX_ZONES 2 // 2 Zonen (oben 10 Module, unten 10 Module)
#define ZONE_SIZE (MAX_DEVICES/MAX_ZONES)

#define	CLK_PIN		13 //LED-Dot-Matrix
#define	DATA_PIN	11 //LED-Dot-Matrix
#define	CS_PIN		10 //LED-Dot-Matrix

// SUB-D 9pol
// 1 +5V
// 2 GND
// 3 Data DS18B20 Sensor
// 4
// 5
// 6
// 7
// 8
// 9

MD_Parola P = MD_Parola(HARDWARE_TYPE, DATA_PIN, CLK_PIN, CS_PIN, MAX_DEVICES);

void setup(void)
{
  Serial.begin(9600);
  delay(2000);
  P.begin(MAX_ZONES);
  P.setInvert(false);
  P.setIntensity(0);
  
  P.setZone(0, 0, ZONE_SIZE-1);
  P.setZone(1, ZONE_SIZE, MAX_DEVICES-1);
}

void loop(void)
{

    // call sensors.requestTemperatures() to issue a global temperature
    // request to all devices on the bus
    // Send the command to get temperature readings
 //   sensors.requestTemperatures();
    
    Serial.println("Temperature is: " + String(sensors.getTempCByIndex(0),1) + "°C");
    char MyPoolTemp[] = sensors.getTempCByIndex(0);

//    char MyPoolTemp[] = "30,2 'C"; // zum testen

    for (uint8_t i=0; i<3; i++)
    {
      Serial.println(i);
      switch(i) {
        case 1:
          P.setFont(0, BigFontBottom);
          P.setFont(1, BigFontUp);
          P.displayZoneText(0, "myPool", PA_CENTER, 30, 1000, PA_SCROLL_DOWN, PA_SCROLL_UP);
          P.displayZoneText(1, "myPool", PA_CENTER, 30, 1000, PA_SCROLL_UP, PA_SCROLL_DOWN);          
          P.synchZoneStart();
          break;
        case 2:
          P.setFont(0, BigFontBottom);
          P.setFont(1, BigFontUp);        
          P.displayZoneText(0, MyPoolTemp, PA_CENTER, 30, 2000, PA_SCROLL_DOWN, PA_SCROLL_UP);
          P.displayZoneText(1, MyPoolTemp, PA_CENTER, 30, 2000, PA_SCROLL_UP, PA_SCROLL_DOWN);
          P.synchZoneStart();
          break; 
      }
      while (!P.getZoneStatus(0) || !P.getZoneStatus(1))
      P.displayAnimate();
    }
}

so, hier der Code....und ich möchte den Temperaturwert den er vom DS20B18 ausliest in den (String/Variablen....was auch immer) geschrieben haben.

Den Wert auslesen und und zum Serial Monitor schicken funktioniert ja,
Diverse Texte auf dem Display anzeigen geht auch....

aber irgendwie bringt der Sensor einen anderen Datentyp her als md_parola haben möchte.

Fehlermeldung:

V:\Arduino\Bibliotheken\_Pooltemperatur\BIGFONT\BIGFONT_003_TEMP\BIGFONT_003_TEMP.ino: In function 'void loop()':
V:\Arduino\Bibliotheken\_Pooltemperatur\BIGFONT\BIGFONT_003_TEMP\BIGFONT_003_TEMP.ino:62:48: error: initializer fails to determine size of 'MyPoolTemp'
     char MyPoolTemp[] = sensors.getTempCByIndex(0);
                         ~~~~~~~~~~~~~~~~~~~~~~~^~~
V:\Arduino\Bibliotheken\_Pooltemperatur\BIGFONT\BIGFONT_003_TEMP\BIGFONT_003_TEMP.ino:62:48: error: array must be initialized with a brace-enclosed initializer

exit status 1

Compilation error: initializer fails to determine size of 'MyPoolTemp'

md_parola: V3.7.3
Board: Arduino nano
Sensor: DS18B20 1M Cable Digital Stainless Steel Temperature Sensor Temperature Probe
Dot-Matrix-Module: LED matrix display - 4 x 64

Jetzt mal nur bezogen auf das Auslesen des Sensors. In setup() fehlt das sensors.begin() um die DS18B20 Klasse zu initialisieren.

Und du kannst keinen float Wert einfach so in ein von der Länge her nicht definiertes char Array zuweisen.

Eine Möglichkeit das zu machen wäre wie folgt:

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

// Data wire is plugged into pin 2 on the Arduino
constexpr byte ONE_WIRE_BUS {2}; //DS18B20 Temp.Sensor
constexpr byte MAX_TEMPARRAY_LENGTH {7}; // -99.99 + Arrayend '\0'

OneWire oneWire(ONE_WIRE_BUS);        // Setup a OneWire instance to communicate with any OneWire devices
DallasTemperature sensors(&oneWire);  // Pass OneWire reference to Dallas Temperature

void setup(void)
{
  Serial.begin(9600);
  sensors.begin();
  delay(2000);
}

void loop(void)
{
  sensors.requestTemperatures();
  char myPoolTemp[MAX_TEMPARRAY_LENGTH];
  dtostrf(sensors.getTempCByIndex(0),6,2,myPoolTemp); // 6 stellig insgesamt, mit zwei Nachkommastellen
  Serial.println(myPoolTemp);
  delay(2000);
}

so, also hab jetzt mal wieder etwas Zeit gehabt...trotzdem noch folgende Fehlermeldung...

V:\Arduino\Bibliotheken\_Pooltemperatur\BIGFONT\BIGFONT_003_TEMP\BIGFONT_003_TEMP.ino: In function 'void loop()':
V:\Arduino\Bibliotheken\_Pooltemperatur\BIGFONT\BIGFONT_003_TEMP\BIGFONT_003_TEMP.ino:87:93: error: no matching function for call to 'MD_Parola::displayZoneText(int, String&, textPosition_t, int, int, textEffect_t, textEffect_t)'
           P.displayZoneText(0, myPoolTemp, PA_CENTER, 30, 1000, PA_SCROLL_DOWN, PA_SCROLL_UP);
                                                                                             ^
In file included from V:\Arduino\Bibliotheken\_Pooltemperatur\BIGFONT\BIGFONT_003_TEMP\BIGFONT_003_TEMP.ino:1:0:
c:\Users\Stefan\Documents\Arduino\libraries\MD_Parola\src/MD_Parola.h:1497:8: note: candidate: void MD_Parola::displayZoneText(uint8_t, const char*, textPosition_t, uint16_t, uint16_t, textEffect_t, textEffect_t)
   void displayZoneText(uint8_t z, const char *pText, textPosition_t align, uint16_t speed, uint16_t pause, textEffect_t effectIn, textEffect_t effectOut = PA_NO_EFFECT);
        ^~~~~~~~~~~~~~~
c:\Users\Stefan\Documents\Arduino\libraries\MD_Parola\src/MD_Parola.h:1497:8: note:   no known conversion for argument 2 from 'String' to 'const char*'

exit status 1

Compilation error: no matching function for call to 'MD_Parola::displayZoneText(int, String&, textPosition_t, int, int, textEffect_t, textEffect_t)'

und hier der Code:

#include <MD_Parola.h>
#include <MD_MAX72xx.h>
#include "Font_Data.h"
#include <OneWire.h>//Temperatur
#include <DallasTemperature.h> //Temperatur

// Data wire is plugged into pin 2 on the Arduino
#define ONE_WIRE_BUS 2 //DS18B20 Temp.Sensor

// Setup a OneWire instance to communicate with any OneWire devices
OneWire oneWire(ONE_WIRE_BUS);

// Pass OneWire reference to Dallas Temperature
DallasTemperature sensors(&oneWire);

// Uncomment according to your hardware type
#define HARDWARE_TYPE MD_MAX72XX::FC16_HW
//#define HARDWARE_TYPE MD_MAX72XX::GENERIC_HW

#define	MAX_DEVICES	20 //20 Module
#define MAX_ZONES 2 // 2 Zonen (oben 10 Module, unten 10 Module)
#define ZONE_SIZE (MAX_DEVICES/MAX_ZONES)

#define	CLK_PIN		13 //LED-Dot-Matrix
#define	DATA_PIN	11 //LED-Dot-Matrix
#define	CS_PIN		10 //LED-Dot-Matrix

// DS18B20
// 1 GND  / GREEN / BLACK
// 2 DATA / YE    / WHITE
// 3 VDD  / RED   / RED

// SUB-D 9pol
// 1 +5V
// 2 GND
// 3 Data DS18B20 Sensor
// 4
// 5
// 6
// 7
// 8
// 9

MD_Parola P = MD_Parola(HARDWARE_TYPE, DATA_PIN, CLK_PIN, CS_PIN, MAX_DEVICES);

// declare one String:
String myPoolTemp;

void setup(void)
{
  Serial.begin(9600);
  delay(2000);
  P.begin(MAX_ZONES);
  P.setInvert(false);
  P.setIntensity(0);
  P.setZone(0, 0, ZONE_SIZE-1);
  P.setZone(1, ZONE_SIZE, MAX_DEVICES-1);
  Serial.begin(9600);
  sensors.begin(); // Start up the library

  myPoolTemp = String(); //String myPoolTemp;
}

void loop(void)
{
    myPoolTemp = "";
    myPoolTemp = myPoolTemp + sensors.getTempCByIndex(0) + " 'C";  
    Serial.println(myPoolTemp);  // prints real Temperatur
    for (uint8_t i=0; i<3; i++)
    {
      Serial.println(i);
      switch(i) {
        case 1:
          P.setFont(0, BigFontBottom);
          P.setFont(1, BigFontUp);
          P.displayZoneText(0, myPoolTemp, PA_CENTER, 30, 1000, PA_SCROLL_DOWN, PA_SCROLL_UP);
          P.displayZoneText(1, myPoolTemp, PA_CENTER, 30, 1000, PA_SCROLL_UP, PA_SCROLL_DOWN);          
          P.synchZoneStart();
          break;
        case 2:
          P.setFont(0, BigFontBottom);
          P.setFont(1, BigFontUp);        
          P.displayZoneText(0, myPoolTemp, PA_CENTER, 30, 2000, PA_SCROLL_DOWN, PA_SCROLL_UP);
          P.displayZoneText(1, myPoolTemp, PA_CENTER, 30, 2000, PA_SCROLL_UP, PA_SCROLL_DOWN);
          P.synchZoneStart();
          break; 
      }
      while (!P.getZoneStatus(0) || !P.getZoneStatus(1))
      P.displayAnimate();
    }
}

so wie ich das sehe müsste man den String in const char umwandeln bevor er angezeigt werden soll. .....aber wie?
Danke schonmal für eure Hilfe...

Ich verstehe nicht so recht, wenn man die Antwort schon vor der Nase hat, warum sie dann nicht verwendet wird.

#include <MD_Parola.h>
#include <MD_MAX72xx.h>
#include "Font_Data.h"
#include <SPI.h>

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

constexpr byte CLK_PIN {13};
constexpr byte DATA_PIN {11};
constexpr byte CS_PIN {10};

// constexpr byte HARDWARE_TYPE {MD_MAX72XX::PAROLA_HW};
constexpr byte HARDWARE_TYPE {MD_MAX72XX::FC16_HW};
constexpr byte MAX_DEVICES	{20}; //  20 Module
constexpr byte MAX_ZONES	{2};  // 2 Reihen
constexpr byte ZONE_SIZE {MAX_DEVICES/MAX_ZONES};

// Data wire is plugged into pin 2 on the Arduino
constexpr byte ONE_WIRE_BUS {2}; //DS18B20 Temp.Sensor
constexpr byte MAX_TEMPARRAY_LENGTH {7}; // -10.00 + Arrayend '\0'

MD_Parola P = MD_Parola(HARDWARE_TYPE, DATA_PIN, CLK_PIN, CS_PIN, MAX_DEVICES);

OneWire oneWire(ONE_WIRE_BUS);        // Setup a OneWire instance to communicate with any OneWire devices
DallasTemperature sensors(&oneWire);  // Pass OneWire reference to Dallas Temperature

void setup(void)
{
  Serial.begin(9600);
  P.begin(MAX_ZONES);
  P.setInvert(false);
  P.setIntensity(0);
  P.setZone(0, 0, ZONE_SIZE-1);
  P.setZone(1, ZONE_SIZE, MAX_DEVICES-1);
  sensors.begin();
  delay(2000);
}

void loop(void)
{
  sensors.requestTemperatures();
  const char myPoolTemp[MAX_TEMPARRAY_LENGTH];
  dtostrf(sensors.getTempCByIndex(0),6,2,myPoolTemp);
  Serial.println(myPoolTemp);

  for (uint8_t i=0; i<3; i++)
  {
    Serial.println(i);
    switch(i) {
      case 1:
        P.setFont(0, BigFontBottom);
        P.setFont(1, BigFontUp);
        P.displayZoneText(0, myPoolTemp, PA_CENTER, 30, 1000, PA_SCROLL_DOWN, PA_SCROLL_UP);
        P.displayZoneText(1, myPoolTemp, PA_CENTER, 30, 1000, PA_SCROLL_UP, PA_SCROLL_DOWN);          
        P.synchZoneStart();
        break;
      case 2:
        P.setFont(0, BigFontBottom);
        P.setFont(1, BigFontUp);        
        P.displayZoneText(0, myPoolTemp, PA_CENTER, 30, 2000, PA_SCROLL_DOWN, PA_SCROLL_UP);
        P.displayZoneText(1, myPoolTemp, PA_CENTER, 30, 2000, PA_SCROLL_UP, PA_SCROLL_DOWN);
        P.synchZoneStart();
        break; 
    }
    while (!P.getZoneStatus(0) || !P.getZoneStatus(1))
    P.displayAnimate();
  }
  delay(2000);
}

Fehlermeldung taucht auf...

V:\Arduino\Bibliotheken\_Pooltemperatur\BIGFONT\BIGFONT_003b_TEMP\BIGFONT_003b_TEMP.ino: In function 'void loop()':
V:\Arduino\Bibliotheken\_Pooltemperatur\BIGFONT\BIGFONT_003b_TEMP\BIGFONT_003b_TEMP.ino:51:22: error: 'BigFontBottom' was not declared in this scope
         P.setFont(0, BigFontBottom);
                      ^~~~~~~~~~~~~
V:\Arduino\Bibliotheken\_Pooltemperatur\BIGFONT\BIGFONT_003b_TEMP\BIGFONT_003b_TEMP.ino:52:22: error: 'BigFontUp' was not declared in this scope
         P.setFont(1, BigFontUp);
                      ^~~~~~~~~

exit status 1

Compilation error: 'BigFontBottom' was not declared in this scope

Bei der Übertragung wurde #include "Font_Data.h" vergessen. Das ist aber inzwischen korrigiert.

ja cool soweit, es fehlt mich aber noch das " °C" hinter der Temperatur...
im form von "myPoolTemp = myPoolTemp + " °C";" gehts ja nicht...

da ich ja neu auf dem Gebiet bin würde ich Morgen mal einige Fragen bezüglich einiger Befehle geben...wenns ok ist

Sofern dein gewählter Font das ° Zeichen "kennt", sollte es so funktionieren:

#include <MD_Parola.h>
#include <MD_MAX72xx.h>
#include "Font_Data.h"
#include <SPI.h>

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

constexpr byte CLK_PIN {13};
constexpr byte DATA_PIN {11};
constexpr byte CS_PIN {10};

// constexpr byte HARDWARE_TYPE {MD_MAX72XX::PAROLA_HW};
constexpr byte HARDWARE_TYPE {MD_MAX72XX::FC16_HW};
constexpr byte MAX_DEVICES {20};   //  20 Module
constexpr byte MAX_ZONES {2};      // 2 Reihen
constexpr byte ZONE_SIZE {MAX_DEVICES / MAX_ZONES};

// Data wire is plugged into pin 2 on the Arduino
constexpr byte ONE_WIRE_BUS {2};           // DS18B20 Temp.Sensor

// Array size definitions
constexpr byte MAX_TEMPARRAY_LENGTH {7};   // -10.00 + Arrayend '\0'
constexpr byte MAX_BUFFER_LENGTH {10};     // -10.00 °C + Arrayend '\0'

MD_Parola P = MD_Parola(HARDWARE_TYPE, DATA_PIN, CLK_PIN, CS_PIN, MAX_DEVICES);

OneWire oneWire(ONE_WIRE_BUS);         // Setup a OneWire instance to communicate with any OneWire devices
DallasTemperature sensors(&oneWire);   // Pass OneWire reference to Dallas Temperature

void setup(void) {
  Serial.begin(9600);
  P.begin(MAX_ZONES);
  P.setInvert(false);
  P.setIntensity(0);
  P.setZone(0, 0, ZONE_SIZE - 1);
  P.setZone(1, ZONE_SIZE, MAX_DEVICES - 1);
  sensors.begin();
  delay(2000);
}

void loop(void) {
  static char buffer[MAX_BUFFER_LENGTH];

  sensors.requestTemperatures();
  const char myPoolTemp[MAX_TEMPARRAY_LENGTH];
  dtostrf(sensors.getTempCByIndex(0), 6, 2, myPoolTemp)
  snprintf(buffer, MAX_BUFFER_LENGTH, "%s%cC", myPoolTemp,0xB0); // 0xB0 = degree sign
  Serial.println(buffer);

  for (uint8_t i = 0; i < 3; i++) {
    Serial.println(i);
    switch (i) {
      case 1:
        P.setFont(0, BigFontBottom);
        P.setFont(1, BigFontUp);
        P.displayZoneText(0, buffer, PA_CENTER, 30, 1000, PA_SCROLL_DOWN, PA_SCROLL_UP);
        P.displayZoneText(1, buffer, PA_CENTER, 30, 1000, PA_SCROLL_UP, PA_SCROLL_DOWN);
        P.synchZoneStart();
        break;
      case 2:
        P.setFont(0, BigFontBottom);
        P.setFont(1, BigFontUp);
        P.displayZoneText(0, buffer, PA_CENTER, 30, 2000, PA_SCROLL_DOWN, PA_SCROLL_UP);
        P.displayZoneText(1, buffer, PA_CENTER, 30, 2000, PA_SCROLL_UP, PA_SCROLL_DOWN);
        P.synchZoneStart();
        break;
    }
    while (!P.getZoneStatus(0) || !P.getZoneStatus(1)) { P.displayAnimate(); }
  }
  delay(2000);
}

Wenn es Fragen gibt, dann stelle sie.

+ ist zwar kein Befehl sondern ein Operator, aber der ist zum Addieren, nicht zum Texte zusammenzaubern. Brauchst du auch nicht, denn

float wert=123.456;
Serial.print(wert,2);
Serial.println("°C");

gibt den gewünschten Text "123.46°C" aus.
(Falls das '°' Zeichen in deinem Editor bei der Texteingabe dasselbe ist, das das Anzeigeprogramm kennt.)

Hallo,
hatte leider erst heute wieder Zeit...

warum kann man nicht normalen Text an md_parola mit Zonen übergeben wie wenn man keine Zonen hat. Da gehts ja auch...

kannst du mir bitte diese beiden Zeilen kurz erklären?

  dtostrf(sensors.getTempCByIndex(0), 6, 2, myPoolTemp)
  snprintf(buffer, MAX_BUFFER_LENGTH, "%s%cC", myPoolTemp,0xB0);

erste Zeile die , 2, ist die Nachkommastelle... soweit hab ich es schon probiert...aber mit probieren kommt man ja nicht weiter...

und es fehlt ein Leerzeichen vor dem °C

Danke schonmal

Beim ersten Code, den du warum auch immer, ignoriert hast stand noch ein Kommentar dabei dtostrf(sensors.getTempCByIndex(0),6,2,myPoolTemp); // 6 stellig insgesamt, mit zwei Nachkommastellen .

Diese Anweisung wandelt eine Zahl vom Typ Float in ein Char-Array um, welches insgesamt 6 Zeichen lang sein kann und zwei Nachkommastellen hat.
Die längste Zahl, die so darstellbar wäre ist -99.99 bzw. 999.99. Das Char-Array ist myPoolTemp[7]. Sieben Zeichen, weil das Stringende-Zeichen ’\0’ auch mit zählt. Der Rückgabewert der Methode sensors.getTempCByIndex(0) hat den Datentyp float.

Die zweite Anweisung baut einen neuen C-String zusammen und nutzt dafür das Char-Array buffer[MAX_BUFFER_LENGTH]. Der Formatstring „%s%cC“ nimmt die beiden Parameter myPoolTemp (%s s steht für string) und 0xB0 (%c steht für Character) auf. 0xB0 ist der Ascii Code für das Grad Zeichen.

Das große C ist einfach ein Buchstabe und wird so übernommen. Wenn Du also ein Leerzeichen haben willst mach einfach „%s %cC“ draus. Das aufnehmende Char-Array (hier buffer) muss groß genug sein, um die ganzen Zeichen aufnehmen zu können.

Wenn du nach den zwei Anweisungen googelst, wirst Du sehr viele Informationen dazu finden.

1 Like

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