63-OneWire_DS18XX-Library (STM32F4)

Mit dieser Library können die OneWire Temperatur Sensoren vom Typ DS1822, DS1820, DS18B20, DS18S20 an den STM32F4 angeschlossen werden.

Die Sensoren haben einen Temperatur Bereich von -55°C bis +125°C. Die Auflösung liegt verschieden (je nach Typ) zwischen 0.0625°C und 0.5°C und die Genauigkeit auch je nach Typ zwischen +/- 0,5°C und +/- 2°C.

Die Library unterstützt alle 4 Typen und liefert die Temperatur als Float-Wert zurück. Falls gewünscht kann mit der Funktion “UB_DS18XX_TempToStr” der Wert in einen String umgewandelt werden. (Bei CoIDE ist dazu das Modul “Retarget Printf” nötig).

Bei den Sensor-Typen “DS1822″ und “DS18B20″ kann die Auflösung mit der Funktion “UB_DS1822B20_SetResolution” zwischen 9bit und 12bit verändert werden. Um die Auflösung fest im EEprom des Sensors zu speichern gibt es die Funktion “UB_DS1822B20_WriteResolution”.

Um einen Sensor auszulesen muss dessen eindeutiger RomCode bekannt sein. Dafür kann die LoLevel-Funktion “UB_OneWire_ReadRomCode” benutzt werden. Um dann z.B. per Debugger die 8 Bytes auszulesen. (siehe Beispiel in der OneWire-LoLevel-Library)

Wenn der RomCode bekannt ist, muss dieser als String mit 16 Hex-Ziffern den Temperatur-Funktionen übergeben werden.
Bei meinem Sensor lautet der RomCode : “22h, 0Eh, 6Dh, 33h, 00h, 00h, 00h, BBh”
Vorsicht : das ist bei jedem Sensor eine andere Nummer !!

Am Datenpin darf der 4k7 PullUp nicht vergessen werden und die Sensoren dürfen nicht über die Datenleitung versorgt werden, sondern brauchen eine eigene VCC.

Weil der OneWire-Bus benutzt wird, wird auch die OneWire-LoLevel-Library benötigt.

Voraussetzungen :

1
2
Benutzte Module der CooCox-IDE : (Retarget Printf)
Benutzte Librarys : STM32_UB_ONEWIRE

Funktionen  :

1
2
3
4
5
6
ErrorStatus UB_DS18XX_Init(void);                 // zum init der Library
float UB_DS1822B20_ReadTemp(char *rom_code);      // Typ : DS1822, DS18B20
float UB_DS1820S20_ReadTemp(char *rom_code);      // Typ : DS1820, DS18S20
ErrorStatus UB_DS1822B20_SetResolution(char *rom_code, uint8_t bit); // zum einstellen der Auflösung
ErrorStatus UB_DS1822B20_WriteResolution(char *rom_code, uint8_t bit); // zum speichern der Auflösung
void UB_DS18XX_TempToStr(float wert, char *ptr);  // zum umwandeln der Temp in einen String

Beispiel :

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
//--------------------------------------------------------------
// File     : main.c
// Datum    : 26.09.2013
// Version  : 1.0
// Autor    : UB
// EMail    : mc-4u(@)t-online.de
// Web      : www.mikrocontroller-4u.de
// CPU      : STM32F4
// IDE      : CooCox CoIDE 1.7.4
// GCC      : 4.7 2012q4
// Module   : CMSIS_BOOT, M4_CMSIS_CORE
// Funktion : Demo der DS18XX-Library
// Hinweis  : Diese zwei Files muessen auf 8MHz stehen
//              "cmsis_boot/stm32f4xx.h"
//              "cmsis_boot/system_stm32f4xx.c"
//--------------------------------------------------------------
 
#include "main.h"
#include "stm32_ub_uart.h"
#include "stm32_ub_ds18xx.h"
 
void Delay(volatile uint32_t nCount) {
  while(nCount--) {
  }
}
 
int main(void)
{
  float temp;
  ErrorStatus check;
  char buf[20];
 
  SystemInit(); // Quarz Einstellungen aktivieren
 
  // init vom UART
  UB_Uart_Init();
 
  // init vom DS1822
  check=UB_DS18XX_Init();
 
  if(check==ERROR) {
    UB_Uart_SendString(COM3,"error",CRLF);
  }
 
  while(1)
  {
    if(check==SUCCESS) {
      // kleine Pause
      Delay(500000);
      // Temperatur vom DS1822 auslesen
      temp=UB_DS1822B20_ReadTemp("220E6D33000000BB");
      // in String umwandeln
      UB_DS18XX_TempToStr(temp,buf);
      // per UART senden
      UB_Uart_SendString(COM3,buf,CRLF);
    }
  }
}

Hier die Library zum Download :

ub_stm32f4_onewire_ds1822_v102

Hier der komplette CooCox-Projektordner zum Download :

Demo_63_OneWire_DS1822


22 Antworten auf 63-OneWire_DS18XX-Library (STM32F4)

  1. Cortex-Einsteiger sagt:

    klasse!
    funktioniert perfekt (getestet mit ds18b20 und ds18s20)
    Ungewohnt kompliziert ist allerdings das auslesen des Romcodes und das anschließende selbstständige wandeln in einen HEX-String)
    Es wäre eine RomCode2Str hilfreich oder um das Problem zu umgehen könntest du die Funktion “SkipRom” vom Sensor nutzen.

    Gestern mit testen angefangen und gedacht, es wäre schön die Auflösung einstellen zu können und schon hast du es nachgereicht :)
    Man sollte allerdings beachten, dass die Einstellung bei jedem Einschalten gemacht werden muss und nicht dauerhaft im Sensor gespeichert wird.

    • admin_ub sagt:

      Ich dachte mir, man steckt ja nicht alle halbe stunde einen anderen Sensor dran, da ist der Aufwand zum auslesen dann nicht “soo” schlimm. Eine Funktion zum ausgeben als String könnte ich noch reinmachen. Und zum dauerhaften speichern gibt es theoretisch auch eine Funktion im Sensor. Version 1.2 : demnächst in diesem Theater.

  2. Joerg sagt:

    Hallo Uwe ich habe die Lib gerade zur stemWIN hinzugefügt. Funktioniert alles problemlos bis auf das benötigte Retarget Printf.
    Geht das auch beim 429 und wenn ja wie?

  3. Joerg sagt:

    ok printf aus dem repo funktioniert

  4. Joerg sagt:

    Ich habe öfters, das als Ergebnis, 0,063 heraus kommt und dann wieder normal.

    Woran kann das liegen?

  5. Helgo sagt:

    Getestet die Demo-Projekt mit DS18B20. Temperatur ist ständig -0,0625. Was könnte das Problem sein?

    • Joerg B. sagt:

      Ändere mal in stm32_ub_onewire.c Zeile 28
      zu
      volatile uint32_t ow_akt_delay;

      Das hat zumindest meine Fehler beseitigt.

      Ansonsten stimmt dein Pullup Widerstand? Bei 3 Volt ist 3,3 K besser als 5 K wie empfohlen.

      • Helgo sagt:

        Dankeschön!

        • Joerg B. sagt:

          Was war es nun?

          • Helgo sagt:

            Keine dieser Optionen ist nicht das Problem gelöst. Ich fing an, TMP35GT9Z Analog Devices verwenden.

          • Alex sagt:

            Hallo, habe die Libary auf den STM32F0 angepasst. Habe das gleiche Problem mit dem -0,0625… gibt es noch andere Lösungsvorschläge?

            Ansonsten super Libary auf dem STM32F4 läuft sie problemlos….

  6. Joerg B. sagt:

    +/- 3 Grad, da kann man auch den Finger in den Wind halten :D

    • Helgo sagt:

      Ich würde den Finger in den Motor des Autos nicht halten.

  7. Zaxu sagt:

    sorry but on wich pin should i use the tmperature sensor?

    • admin_ub sagt:

      you can use any free gpio pin. defined in the file “stm32_ub_onewire.h” the default pin is “PD3″ and dont forget the external 4k7 pull-up

  8. dynahenry sagt:

    Moin Uwe,

    Vielen Dank für die Libraries und für die viele Arbeit, die Du in die Dokumentation rein gesteckt hast. Es hat mir sehr geholfen die ersten Schritte mit dem STM32F407 Discovery zu machen.
    Nun komme ich nicht mehr weiter.
    Ich möchte einen Temperaturlogger für mehrere Kanäle aufbauen. Dazu habe ich die Demos Lib63 und Lib32 kombiniert.
    Beide Beispiele laufen für sich perfekt. Temperaturen werden gemessen und ich kann Text auf den USB-Stick schreiben.
    Ich habe die Demo Lib32 in die Demo63 kopiert und beschreibe zunächst nur den Text auf den Stick. Dann springe ich in die Tempteraturmessung. Der Text wird korrekt in den USB-Stick geschrieben, doch die Temperaturmessungen sind falsch.
    Normalerweise braucht eine 12Bit Messung ca. 700 ms. Steckt der USB-Stick, dann laufen die Messungen viel schneller und sind falsch. Ziehe ich den USB-Stick ab, sind die Messungen wieder ok.
    Ich vermute, daß sich beide Demos irgendwie stören, wenn der USB-Stick steckt.
    Aber warum?
    Ich habe gesehen, daß die OneWire Lib den TIM7 und einen Interrupt benutzt. Kann es da Konflikte geben, wenn der USB-Stick steckt? benutzt USB_MSC_HOST auch den TIM7 oder Interrupts?
    Was kann ich tun? Ich habe das main.c mal angehängt.

    Kannst Du oder jemand anders mir helfen?

    Gruß Heinrich

    //————————————————————–
    // File : main.c
    // Datum : 26.09.2013
    // Version : 1.0
    // Autor : UB
    // EMail : mc-4u(@)t-online.de
    // Web : http://www.mikrocontroller-4u.de
    // CPU : STM32F4
    // IDE : CooCox CoIDE 1.7.4
    // GCC : 4.7 2012q4
    // Module : CMSIS_BOOT, M4_CMSIS_CORE
    // Funktion : Demo der DS18XX-Library kombiniert mit
    // Funktion : Demo der USB-MSC-HOST-Library
    // Hinweis : Diese zwei Files muessen auf 8MHz stehen
    // “cmsis_boot/stm32f4xx.h”
    // “cmsis_boot/system_stm32f4xx.c”
    // History : Modifiziert von H.Fischer am 27.2.2015
    //————————————————————–

    #include “main.h”
    #include “stm32_ub_led.h”
    #include “stm32_ub_usb_msc_host.h”
    #include “stm32_ub_uart.h”
    #include “stm32_ub_ds18xx.h”
    #include “stm32_ub_led.h”

    void Delay(volatile uint32_t nCount) {
    while(nCount–) {
    }
    }

    float temp1, temp2, temp3;
    ErrorStatus check;
    char temp_buf[20];

    int main(void)
    {
    FIL myFile; // Filehandler
    uint8_t write_ok=0, prt_ok=0;

    SystemInit(); // Quarz Einstellungen aktivieren

    // Init der LEDs
    UB_Led_Init();

    // init vom UART
    UB_Uart_Init();

    UB_Uart_SendString(COM3,”Start USB”,CRLF);

    // Init vom USB-OTG-Port als MSC-HOST
    // (zum lesen/schreiben auf einen USB-Stick)
    UB_USB_MSC_HOST_Init();

    while(write_ok==0)
    {
    // pollen vom USB-Status
    if(UB_USB_MSC_HOST_Do()==USB_MSC_DEV_CONNECTED) {
    // wenn USB-Stick erkannt wurde
    UB_Led_On(LED_GREEN);
    UB_Uart_SendString(COM3,”USB-Stick erkannt”,CRLF);

    // wenn File noch nicht geschrieben wurde
    if(write_ok==0) {
    write_ok=1;
    UB_Led_On(LED_RED);
    // Media mounten
    if(UB_Fatfs_Mount(USB_0)==FATFS_OK) {
    // File zum schreiben im root neu anlegen
    if(UB_Fatfs_OpenFile(&myFile, “USB_File.txt”, F_WR_NEW)==FATFS_OK) {
    // ein paar Textzeilen in das File schreiben
    UB_Fatfs_WriteString(&myFile,”Test der WriteString-Funktion”);
    UB_Fatfs_WriteString(&myFile,”hier Zeile zwei”);
    UB_Fatfs_WriteString(&myFile,”ENDE”);
    // File schliessen
    UB_Fatfs_CloseFile(&myFile);
    }
    // Media unmounten
    UB_Fatfs_UnMount(USB_0);
    }
    UB_Led_Off(LED_RED);
    UB_Uart_SendString(COM3,”USB-Stick geschrieben”,CRLF);
    }
    }
    else {
    // wenn kein USB-Stick vorhanden Text nur eimal ausgeben
    UB_Led_Off(LED_GREEN);
    if (prt_ok==0) {
    UB_Uart_SendString(COM3,”Kein USB-Stick”,CRLF);
    prt_ok=1;
    }
    }
    }

    UB_Uart_SendString(COM3,”Start Temperatur Messung”,CRLF);

    // init vom DS1822
    check=UB_DS18XX_Init();

    if(check==ERROR) {
    UB_Uart_SendString(COM3,”Sensor Init error”,CRLF);
    }

    UB_Led_On(LED_GREEN);

    // Auflösung der Sensoren setzen
    check=UB_DS1822B20_SetResolution(“28FF6E12631402EE”,11); // Sensor 1
    check=UB_DS1822B20_SetResolution(“28FF7415631402A9″,11); // Sensor 2
    check=UB_DS1822B20_SetResolution(“28FF825B63140266″,11); // Sensor 3

    if(check==ERROR) {
    UB_Uart_SendString(COM3,”Error set Resolution”,CRLF);
    }

    while(1)
    {
    if(check==SUCCESS) {
    UB_Led_On(LED_GREEN);
    // kleine Pause
    Delay(5000000);
    UB_Led_Off(LED_GREEN);
    UB_Led_On(LED_ORANGE);
    // Temperatur vom DS1822 auslesen
    //temp=UB_DS1822B20_ReadTemp(“220E6D33000000BB”);
    temp1=UB_DS1822B20_ReadTemp(“28FF6E12631402EE”); //Sensor 1
    UB_Led_Off(LED_ORANGE);
    UB_Led_On(LED_RED);
    temp2=UB_DS1822B20_ReadTemp(“28FF7415631402A9″); //Sensor 2
    UB_Led_Off(LED_RED);
    UB_Led_On(LED_BLUE);
    temp3=UB_DS1822B20_ReadTemp(“28FF825B63140266″); //Sensor 3
    UB_Led_Off(LED_BLUE);
    UB_Led_On(LED_GREEN);
    // in String umwandeln
    UB_DS18XX_TempToStr(temp1,temp_buf);
    // per UART senden
    UB_Uart_SendString(COM3,temp_buf,NONE);
    // Leerzeichen
    UB_Uart_SendByte(COM3, 32);
    // in String umwandeln
    UB_DS18XX_TempToStr(temp2,temp_buf);
    // per UART senden
    UB_Uart_SendString(COM3,temp_buf,NONE);
    // Leerzeichen
    UB_Uart_SendByte(COM3, 32);
    // in String umwandeln
    UB_DS18XX_TempToStr(temp3,temp_buf);
    // per UART senden
    UB_Uart_SendString(COM3,temp_buf,CRLF);
    }
    }
    }

    • admin_ub sagt:

      ein Timer wird bei der USB-Library nicht benutzt. Aber das gepostete Programm kann m.M. nach so nicht funktionieren. Wenn kein USB-Stick gesteckt ist. dürfte die “while(write_ok==0)” niemals verlassen werden und das Programm kann nicht zur stelle mit dem TempSensor kommen. Egal wie…Fehlersuche musst du schon selber machen.

      • dynahenry sagt:

        Danke für die Antwort.
        Das ist richtig. Der USB-Stick steckt zu Anfang. Die 2 Zeilen werden auf den Stick geschrieben.
        Die Messung ist dann falsch.
        Ziehe ich den USB-Stick danach ab, dann sind die Messungen ok.
        Irgentwie stört der USB-Stick die 1-Draht-Messung wenn er steckt.
        Das Progrämmchen sollte nur zum Test dienen, ob die Beispiele zusammen funktionieren. Das ist leider nicht der Fall.
        Die nächste Stufe ist, die Messwerte auf den Stick zu schreiben.
        Das Ganze möchte ich dann mit der RTC kombinieren, um z.B. alle 60 Sekunden Meßwerte auf den Stick zu schreiben.
        Eben ein Temperatur-Logger.
        Wenn er fertig ist, könnten Andere vielleicht interessiert sein.
        Hat jemand anderes eine Idee?
        Gruß
        Heinrich

  9. Joerg B. sagt:

    Moin Heinrich,
    ich habe letztes Jahr mit Uwes libs sowas in der Art zusammen geschustert… ;)
    Allerdings auf dem 429 Disc.

    //--------------------------------------------------------------
    // File : main.c
    // Datum : 08.11.2013
    // Version : 1.0
    // Autor : UB
    // EMail : mc-4u(@)t-online.de
    // Web : http://www.mikrocontroller-4u.de
    // CPU : STM32F429
    // IDE : CooCox CoIDE 1.7.4
    // GCC : 4.7 2012q4
    // Module : CMSIS_BOOT, M4_CMSIS_CORE
    // Funktion : Demo der USB-MSC-Host-Library
    // Hinweis : Diese zwei Files muessen auf 8MHz stehen
    // "cmsis_boot/stm32f4xx.h"
    // "cmsis_boot/system_stm32f4xx.c"
    // In Configuration diese Define hinzufügen :
    // "STM32F429_439xx" , "__ASSEMBLY__" , "USE_STDPERIPH_DRIVER"
    //--------------------------------------------------------------

    #include „main.h“
    #include „stm32_ub_led.h“
    #include „stm32_ub_usb_msc_host.h“
    #include „stm32_ub_ds18xx.h“
    #include „stm32_ub_lcd_ili9341.h“
    #include „stm32_ub_font.h“
    #include „stm32_ub_rtc.h“
    #include
    #include

    void Delay(volatile uint32_t nCount) {
    while(nCount–) {
    }
    }

    int main(void)
    {
    FIL myFile; // Filehandler
    float temp;
    ErrorStatus check;
    char buf[40];
    char logstring[60];

    RTC_STATUS_t rtccheck;
    uint8_t old_sek=0, readnow=1;
    uint32_t sectik=0, nextread=60;
    char time_str[10];
    char date_str[10];
    char romc[8];
    char file_str[20];
    char firstds[8];
    char secondds[8];

    SystemInit(); // Quarz Einstellungen aktivieren

    // Init vom LCD
    UB_LCD_Init();
    // Init der Layer
    UB_LCD_LayerInit_Fullscreen();
    // auf Hintergrund schalten
    UB_LCD_SetLayer_1();
    // Hintergrund komplett mit einer Farbe füllen
    UB_LCD_FillLayer(RGB_COL_WHITE);
    // auf Vordergrund schalten
    UB_LCD_SetLayer_2();
    // Vordergrund komplett mit einer Farbe füllen
    UB_LCD_FillLayer(RGB_COL_WHITE);

    // Init der LEDs
    UB_Led_Init();

    // Init und start der RTC
    rtccheck=UB_RTC_Init();

    /*
    UB_RTC.std=20;
    UB_RTC.min=11;
    UB_RTC.sek=0;
    UB_RTC.tag=14;
    UB_RTC.monat=6;
    UB_RTC.jahr=14;
    UB_RTC.wotag=6;
    UB_RTC_SetClock(RTC_DEC);
    */

    // Init vom USB-OTG-Port als MSC-HOST
    // (zum lesen/schreiben auf einen USB-Stick)
    UB_USB_MSC_HOST_Init();

    while(1)
    {
    UB_RTC_GetClock(RTC_DEC);
    if(UB_RTC.sek!=old_sek) {
    // wenn eine Sekunde um ist
    old_sek=UB_RTC.sek;
    sectik++;

    if (sectik > nextread){
    readnow=1;
    nextread=sectik+3;
    }

    old_sek=UB_RTC.sek;
    sprintf(time_str,“%02d:%02d:%02d“,UB_RTC.std, UB_RTC.min, UB_RTC.sek);
    sprintf(date_str,“%02d.%02d.%02d;“,UB_RTC.tag, UB_RTC.monat, UB_RTC.jahr);
    sprintf(file_str,“%02d-%02d-%02d.log“,UB_RTC.tag, UB_RTC.monat, UB_RTC.jahr);

    UB_Font_DrawString(10,10,time_str,&Arial_16x25,RGB_COL_BLACK,RGB_COL_WHITE);
    UB_Font_DrawString(10,50,date_str,&Arial_16x25,RGB_COL_BLACK,RGB_COL_WHITE);
    }

    check=UB_DS18XX_Init();
    UB_OneWire_ReadRomCode();
    UB_OneWire_RomCode2Str(firstds);
    Delay(500);

    UB_OneWire_ReadRomCode();
    UB_OneWire_RomCode2Str(secondds);

    if(UB_USB_MSC_HOST_Do()==USB_MSC_DEV_CONNECTED) {
    if(check==SUCCESS && readnow==1) {
    readnow=0;
    Delay(50);
    temp=UB_DS1822B20_ReadTemp(firstds);
    UB_DS18XX_TempToStr(temp,logstring);
    UB_Font_DrawString(50,150,logstring,&Arial_16x25,RGB_COL_BLACK,RGB_COL_WHITE);

    temp=UB_DS1822B20_ReadTemp(secondds);
    UB_DS18XX_TempToStr(temp,buf);
    strcat(logstring,“;“);
    strcat(logstring,buf);
    strcat(logstring,“;“);
    UB_Font_DrawString(50,200,buf,&Arial_16x25,RGB_COL_BLACK,RGB_COL_WHITE);
    UB_Led_On(LED_GREEN);
    UB_Led_On(LED_RED);

    strcat(logstring,date_str);
    strcat(logstring,time_str);

    if(UB_Fatfs_Mount(USB_0)==FATFS_OK) {
    UB_Led_Off(LED_GREEN);
    // File zum schreiben im root anfügen
    if(UB_Fatfs_OpenFile(&myFile, file_str, F_WR_NEW)==FATFS_OK) {
    UB_Fatfs_WriteString(&myFile,logstring);
    UB_Fatfs_CloseFile(&myFile);
    }
    UB_Fatfs_UnMount(USB_0);

    }
    UB_Led_Off(LED_RED);

    }

    }
    }
    }

     

    • dynahenry sagt:

      Danke Jörg,
      Ich werd es mal ausprobieren.
      Bei mir auf dem STM32F407 vertragen sich die DS18xx und die USB Libraries nicht sobald der USB Stick steckt. Am Timer TIM7 liegt es nicht.

      In der Zwischenzeit habe ich die Libray aus dieser Quelle verwendet.
      http://stm32f4-discovery.com/2014/05/13-reading-temperature-with-dallas-ds18b20-on-stm32f429-discovery-board/
      Damit bleibt die Temperaturmessung richtig und ich kann Daten auf den Stick schreiben. Nun fehlt mir nur noch die RTC. Da muß ich mir den Quarz besorgen.

  10. Jozsef Schubert sagt:

    Hello Jörg,

    I read your article about STM32F4 and DS18xx. I is very interesting form me. Thank you.
    But I am a beginner STM32F user. So I downloded your example project and translate it with Coocox. But I do not know which pins are used. Olease can you dend me a circuit about DS18xx using.

    I forward your answer.

    Best regards,

    SJ


Wie hat Dir dieser Artikel gefallen?

1 Stern2 Sterne3 Sterne4 Sterne5 Sterne (Noch keine Bewertungen)
Loading...

Ein Kommentar zu 63-OneWire_DS18XX-Library (STM32F4)

  1. Alessandra sagt:

    Can I use this with STM32F7?

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert.