Forum: Projekte & Code Onewire + DS18x20 Library


von Falk B. (falk)


Angehängte Dateien:

Lesenswert?

Hallo Gemeinde,

hier ein kleines, feines Projekt zum oben beschriebenen Problem. Das 
Demo läuft auf einem Arduino, der lag halt gerade rum. Alle 
Debugausgaben laufen über den UART. Im Moment ist das Pinout für den 
Arduino Mega 2560 und Pin PA0 / Arduino 22 eingestellt, man kann aber 
sehr leicht jeden anderen Pin auswählen, einfach die defines in 
onewire.h anpassen. Die Lib ist universell verwendbar. Unter 
/doxygen/html/index.html gibt es die Doku im HTML-Format. Als 
Testobjekte hatte ich die ICs

3xDS2401
1xDS18S20 (normale Stromversorgung)
1xDS18B20 (parasitäre Stromversorgung)

Das Auslesen des ROM-Codes läuft mit jedem beliebigen OneWire-IC.

Viel Spaß beim ausprobieren.

Falk

von ANDREAS (Gast)


Lesenswert?

Wie kann mann das in sein eigenes Projekt einfügen speziell die Setup.

Mit Arduino bin ich nich so bewandert.

Vielleicht könntest du das nochmal erläutern.
mfg

von (prx) A. K. (prx)


Lesenswert?

Bei längerer 1-Wire Verdrahtung würde ich die CRC nicht weglassen. 
Zumindest wenn das Ergebnis nicht nur als Temperaturanzeige dient. Sagt 
mir die praktische Erfahrung mit gelegentlich auftretenden Fehlern.

: Bearbeitet durch User
von Falk B. (falk)


Angehängte Dateien:

Lesenswert?

@ ANDREAS (Gast)

>Wie kann mann das in sein eigenes Projekt einfügen speziell die Setup.

Ist das nicht ersichtlich? Hast du dir das Projekt mal 15 Minuten in 
RUHE angeschaut?

>Mit Arduino bin ich nich so bewandert.

Das hat mit Arduino fast nix zu tun.

Man muss nur die 4 Dateien

ds18x20.h
ds18x20.c
onewire.h
onewire.c

in sein Projektverzeichnis kopieren und im jeweiligen Quelltext per

1
#include "onewire.h"
2
#include "ds18x20.h"

einfügen. Dann ändert man in der Datei onewire.h die Pinzuordung passend 
zu seiner Hardware.

1
#define ONEWIRE_BIT  PA0
2
#define ONEWIRE_PIN  PINA
3
#define ONEWIRE_PORT PORTA
4
#define ONEWIRE_DDR  DDRA

Das ist schon alles.

Im Arduino-Projekt steht
1
#include "ds18x20.c"
2
#include "onewire.c"

Das ist eigentlich häßlich bis falsch, geht aber scheinbar nicht anders. 
Denn entgegen der Behauptung, man könne auch bei Arduino mit mehreren 
Dateien im Projekt arbeiten, geht das real scheinbar nicht, der Compiler 
(genauer, der Linker) schmeißt Fehler, er würde die Funktionen in den 
anderen Dateien nicht erkennen, obwohl er sie als Objekte compiliert! 
Sehr merkwürdig. Wenn sich das jemand anschauen will, siehe Anhang.

https://www.arduino.cc/en/Hacking/BuildProcess

von Falk B. (falk)


Lesenswert?

@ A. K. (prx)

>Bei längerer 1-Wire Verdrahtung würde ich die CRC nicht weglassen.

Ok, wird mal als Feature Request vorgemerkt. Ich sammle mal eine Weile 
Rückmeldungen, dann wird das eingebaut.

von ANDREAS (Gast)


Lesenswert?

Hallo Falk,

#include "onewire.h"
#include "ds18x20.h"
Hab ich gemacht mein Port hab ich geändert

Nur in deiner Index finde ich mich nicht so richtig durch.

ich hab nur einen Sensor am Bus und der ist im normal mdus angeschlossen 
also nicht Parasitär.


Vielleicht könntest du mir weiterhelfen
1
 int16_t x;
2
    uint8_t i, j, crc;
3
    volatile uint8_t rc;  // volatile is used for timing measurement in simulation, not required for normal application
4
    uint8_t i_ds18B20, i_ds18S20;
5
    int16_t temp, vorkomma, nachkomma;
6
7
   //Serial.begin(9600);
8
    //Serial.println(F("\r\nOneWire (tm) demo"));
9
    // speed test in simulator, set breakpoints on next two lines
10
    rc=onewire_crc(buffer, 8);
11
    rc;
12
    // single device on bus, simple access without ROM code
13
    //Serial.println(F("\r\nReading ROM code of single device on bus."));
14
    rc=onewire_read_rom(buffer);    
15
    for (i=0, j=0; i<8; i++) j |= buffer[i];    // or all data
16
    crc=buffer[7];
17
    buffer[7]=0;
18
    if (rc==1) {
19
        //Serial.println(F("No response on bus!"));
20
        while(1);    // stop here
21
    } else if (rc==2) {
22
       // Serial.println(F("CRC error! "));
23
        //Serial.print(F("Received CRC  : 0x"));
24
        //Serial.println(crc, HEX);
25
        //Serial.print(F("Calculated CRC: 0x"));
26
        //Serial.println(onewire_crc(buffer, 8), HEX);
27
        //Serial.println(F("There is probably more than one device on the //bus.\r\n"));
28
    } else if (j==0) {
29
        //Serial.println(F("All rom data zero."));
30
        //Serial.println(F("There is probably more than one device on the //bus.\r\n"));    
31
    }
32
    buffer[7]=crc;
33
    //print_header();
34
    //print_rom(buffer, 0);
35
    // check if DS18S20 or DS18B20 are found on bus
36
    if (buffer[0]==DS18S20_ID) i_ds18S20 = 1; else i_ds18S20 = 0;       // family code for DS18S20
37
    if (buffer[0]==DS18B20_ID) i_ds18B20 = 1; else i_ds18B20 = 0;       // family code for DS18B20
38
    // read complete scratchpad (9 bytes)
39
    if (i_ds18S20 || i_ds18B20) {
40
        onewire_skip_rom();
41
        ds18x20_read_scratchpad(buffer);
42
        if (onewire_crc(buffer, 9)) {
43
            //Serial.println(F("CRC error in scratchpad data!"));
44
        }
45
        //print_scratchpad(buffer);
46
    }
47
    // temperature reading using normal power
48
    if (!i_ds18S20) { 
49
        //Serial.println(F("\r\nNo DS18S20 found on bus."));
50
    } else {
51
       // Serial.println(F("\r\nReading temperature of DS18S20 (9 Bit, 0.5 C resolution)"));
52
        //Serial.println(F("DS18S20 must be normal powered!"));
53
        //Serial.println(F("Press any key to stop"));
54
        while() {
55
            onewire_skip_rom();
56
            ds18S20_convert_t(0);        // normal power
57
            _delay_ms(750);
58
            onewire_skip_rom();
59
            x = ds18S20_read_temp();
60
            //Serial.print(F("T: "));
61
            //Serial.print(x/10);
62
            //Serial.print('.');
63
            //Serial.print(abs(x)%10);
64
            //Serial.println(F(" C"));
65
 
66
67
Wie bekomm ich jetzt die Temperratur angezeigt .
68
Die serial routinen kenn ich nicht nutze Arduino nicht.
69
       }
70
    }

von Falk B. (falk)


Lesenswert?

@ANDREAS (Gast)

>Nur in deiner Index finde ich mich nicht so richtig durch.

Wo?

>ich hab nur einen Sensor am Bus und der ist im normal mdus angeschlossen
>also nicht Parasitär.

Hast du einen passenden Pull-Up widerstand dran? 4K7 oder so?

>Vielleicht könntest du mir weiterhelfen

Was hast du denn für ein Board? Hast du dort schein eine 
Ausgabemöglichkeit per UART oder LCD?
Ist doch eigentlich nicht schwer. Mann muss nur die Serial.print() 
Funktionen durch die eigenen Ausgaben ersetzen.

[c]
    int16_t x;
    uint8_t i, j, crc;
    volatile uint8_t rc;  // volatile is used for timing measurement in 
simulation, not required for normal application
    uint8_t i_ds18B20, i_ds18S20;
    int16_t temp, vorkomma, nachkomma;

    // single device on bus, simple access without ROM code
    //Serial.println(F("\r\nReading ROM code of single device on 
bus."));
    rc=onewire_read_rom(buffer);
    for (i=0, j=0; i<8; i++) j |= buffer[i];    // or all data
    crc=buffer[7];
    buffer[7]=0;
    if (rc==1) {
        //Serial.println(F("No response on bus!"));
        while(1);    // stop here
    } else if (rc==2) {
       // Serial.println(F("CRC error! "));
        //Serial.print(F("Received CRC  : 0x"));
        //Serial.println(crc, HEX);
        //Serial.print(F("Calculated CRC: 0x"));
        //Serial.println(onewire_crc(buffer, 8), HEX);
        //Serial.println(F("There is probably more than one device on 
the //bus.\r\n"));
    } else if (j==0) {
        //Serial.println(F("All rom data zero."));
        //Serial.println(F("There is probably more than one device on 
the //bus.\r\n"));
    }
    buffer[7]=crc;
    //print_header();
    //print_rom(buffer, 0);
    // check if DS18S20 or DS18B20 are found on bus
    if (buffer[0]==DS18S20_ID) i_ds18S20 = 1; else i_ds18S20 = 0; 
// family code for DS18S20
    if (buffer[0]==DS18B20_ID) i_ds18B20 = 1; else i_ds18B20 = 0; 
// family code for DS18B20
    // read complete scratchpad (9 bytes)
    if (i_ds18S20 || i_ds18B20) {
        onewire_skip_rom();
        ds18x20_read_scratchpad(buffer);
        if (onewire_crc(buffer, 9)) {
            //Serial.println(F("CRC error in scratchpad data!"));
        }
        //print_scratchpad(buffer);
    }
    // temperature reading using normal power
    if (!i_ds18S20) {
        //Serial.println(F("\r\nNo DS18S20 found on bus."));
    } else {
       // Serial.println(F("\r\nReading temperature of DS18S20 (9 Bit, 
0.5 C resolution)"));
        //Serial.println(F("DS18S20 must be normal powered!"));
        //Serial.println(F("Press any key to stop"));
        while() {
            onewire_skip_rom();
            ds18S20_convert_t(0);        // normal power
            _delay_ms(750);
            onewire_skip_rom();
            x = ds18S20_read_temp();

>            //Serial.print(F("T: "));
Ein String

>            //Serial.print(x/10);

Vorkomma
>            //Serial.print('.');

Komma
>            //Serial.print(abs(x)%10);

Nachkomma

>            //Serial.println(F(" C"));

Noch ein String.

>Wie bekomm ich jetzt die Temperratur angezeigt .
>Die serial routinen kenn ich nicht nutze Arduino nicht.

Das sind GANZ EINFACHE Print Ausgaben, wie sie jede Programmiersprache 
hat!

       }
    }

von ANDREAS (Gast)


Lesenswert?

Hallo,
Ich hab dein Beispiel mal in mein Projekt eingefügt
Hier bekomm ich auch als Anzeige 127,5.
1
void read_T(void)
2
{
3
 int16_t x;
4
    uint8_t i, j, crc,Len;
5
    volatile uint8_t rc;  // volatile is used for timing measurement in simulation, not required for normal application
6
    uint8_t i_ds18B20, i_ds18S20;
7
    int16_t temp, vorkomma, nachkomma;
8
9
   //Serial.begin(9600);
10
    //Serial.println(F("\r\nOneWire (tm) demo"));
11
    // speed test in simulator, set breakpoints on next two lines
12
   rf12_txdata_TEST("DEMO",4);
13
    rc=onewire_crc(buffer, 8);
14
    rc;
15
    // single device on bus, simple access without ROM code
16
    //Serial.println(F("\r\nReading ROM code of single device on bus."));
17
    rc=onewire_read_rom(buffer);    
18
    for (i=0, j=0; i<8; i++) j |= buffer[i];    // or all data
19
    crc=buffer[7];
20
    buffer[7]=0;
21
    
22
  if (rc==1)
23
    {
24
        //Serial.println(F("No response on bus!"));
25
        rf12_txdata_TEST("No response on bus!",21);
26
    while(1);    // stop here
27
    } 
28
  
29
  else if (rc==2) 
30
  {
31
       rf12_txdata_TEST("crc error",11);
32
       // Serial.println(F("CRC error! "));
33
        //Serial.print(F("Received CRC  : 0x"));
34
        //Serial.println(crc, HEX);
35
        //Serial.print(F("Calculated CRC: 0x"));
36
        //Serial.println(onewire_crc(buffer, 8), HEX);
37
        //Serial.println(F("There is probably more than one device on the //bus.\r\n"));
38
    } 
39
  
40
  else if (j==0) 
41
  {
42
        //Serial.println(F("All rom data zero."));
43
        //Serial.println(F("There is probably more than one device on the //bus.\r\n"));    
44
     rf12_txdata_TEST("All rom data zero",21);
45
  }
46
    
47
  buffer[7]=crc;
48
    //print_header();
49
    //print_rom(buffer, 0);
50
    // check if DS18S20 or DS18B20 are found on bus
51
    if (buffer[0]==DS18S20_ID) i_ds18S20 = 1; else i_ds18S20 = 0;       // family code for DS18S20
52
    if (buffer[0]==DS18B20_ID) i_ds18B20 = 1; else i_ds18B20 = 0;       // family code for DS18B20
53
    // read complete scratchpad (9 bytes)
54
    
55
  if (i_ds18S20 || i_ds18B20) 
56
  {
57
        onewire_skip_rom();
58
        ds18x20_read_scratchpad(buffer);
59
        if (onewire_crc(buffer, 9)) 
60
    {
61
            //Serial.println(F("CRC error in scratchpad data!"));
62
        rf12_txdata_TEST("CRC error in scratchpad data",21);
63
    }
64
        //print_scratchpad(buffer);
65
     rf12_txdata_TEST((char*)buffer,10);
66
    }
67
    
68
  // temperature reading using normal power
69
    if (!i_ds18S20) 
70
  { 
71
        //Serial.println(F("\r\nNo DS18S20 found on bus."));
72
     rf12_txdata_TEST("No DS18S20 found on bus.",21);
73
    } 
74
  
75
  else 
76
  {
77
       // Serial.println(F("\r\nReading temperature of DS18S20 (9 Bit, 0.5 C resolution)"));
78
        //Serial.println(F("DS18S20 must be normal powered!"));
79
        //Serial.println(F("Press any key to stop"));
80
        rf12_txdata_TEST("Reading temperature.",21);
81
    while(22)
82
        {
83
            onewire_skip_rom();
84
            ds18S20_convert_t(0);        // normal power
85
            _delay_ms(750);
86
            onewire_skip_rom();
87
            x = ds18S20_read_temp();
88
            //Serial.print(F("T: "));
89
            //Serial.print(x/10);
90
            //Serial.print('.');
91
            //Serial.print(abs(x)%10);
92
            //Serial.println(F(" C"));
93
        vorkomma = x/10;
94
    nachkomma = abs(x)%10;   
95
sprintf(txbuf,"%d.%d ",vorkomma , nachkomma); 
96
  Len = strlen (txbuf);
97
  rf12_txdata_TEST(txbuf,Len);
98
 
99
100
101
       }
102
    } 
103
}

von Falk B. (falk)


Lesenswert?

@ ANDREAS (Gast)

>Ich hab dein Beispiel mal in mein Projekt eingefügt
>Hier bekomm ich auch als Anzeige 127,5.

>rf12_txdata_TEST("No response on bus!",21);

Wollen wir wetten, daß die die gleiche Person wie hier bist?

Beitrag "Delay mit Timer"

von ANDREAS (Gast)


Lesenswert?

Falk B. schrieb:
> @ ANDREAS (Gast)
>
>>Ich hab dein Beispiel mal in mein Projekt eingefügt
>>Hier bekomm ich auch als Anzeige 127,5.
>
>>rf12_txdata_TEST("No response on bus!",21);
>
> Wollen wir wetten, daß die die gleiche Person wie hier bist?
>
> Beitrag "Delay mit Timer"

JA
aber warum bekomm ich als ausgabe 127??????????????????

von (prx) A. K. (prx)


Lesenswert?

Weil du auf Antworten und Hinweise nicht reagierst.

von Falk B. (falk)


Angehängte Dateien:

Lesenswert?

Hier die etwas überarbeitete Version, nun auch mit CRC Prüfung beim 
Auslesen der Temperatur. Komischerweise geht der Alarm Search bei meinem 
DS18B20 nicht, egal ob mit normaler Power oder parasitic Power. Komisch. 
Scheint defekt zu sein, denn die Werte im Scratchpad passen. Der Rest 
geht aber?!? Egal.

Njoy

von ANDREAS (Gast)


Lesenswert?

A. K. schrieb:
> Weil du auf Antworten und Hinweise nicht reagierst.


Ich habe Falk sein Beispiel Benutzt so wie von ihm vorgeschlagen.

Ivh lese hier immer  du auf Antworten und Hinweise nicht reagierst.

Aber mir kann auch keiner von ihnen konkret sagen warum ich als Ausgabe 
127 erhalte.

Nicht jeder ist so bewandert wie ihr.

von Falk B. (falk)


Lesenswert?

@ Falk Brunner (falk)

>Wollen wir wetten, daß die die gleiche Person wie hier bist?

>JA
>aber warum bekomm ich als ausgabe 127??????????????????

Dan tu uns den Gefallen und schreibe nur in EINEM Thread! HIER nicht! 
Danke!

von Falk B. (falk)


Lesenswert?

Kleiner Tip für die Arduinos.

Beitrag "Re: I2CLCD Library für HD44780 LCDs"

Die .c Dateien müssen in.cpp umbenannt werden, dann kann man auch mit 
den normalen include-Anweisungen arbeiten.
1
#include "ds18x20.h"
2
#include "onewire.h"

von F. F. (foldi)


Lesenswert?

Hallo Falk,
ich bin gerade hier drüber gestolpert und habe in deinem Demo das Bild 
vom Anschluss gesehen.
Du hast die direkt an den Bus, mit einem Pullup angeschlossen?
Wie lang war denn der Bus?
Im Anfang habe ich das auch mal so gemacht, hatte irgendwie nicht 
geklappt.
Habe das danach auch generell verworfen, weil einmal ab höheren 
Temperaturen eh eine direkte Stromversorgung gefordert ist und bei 
längeren Bussen auch ein Fet einen "strong Pullup" ermöglichen soll.
Aber trotzdem interessiert mich, wie weit du damit kommst.

Davon abgesehen, die Diskussion übers auslesen.
Ich mach das auch nicht anders als die erst auslesen und dann die 
Nummern notieren und entsprechend einpflegen. Die werden dann doch nicht 
mehr gewechselt. Warum sollte man das ständig abfragen, welcher Sensor 
da gerade drin ist?
Den letzten habe ich vor ca. 2 oder 3 Jahren an die Fritzbox gepappt. Da 
habe ich die Fritzbox (sie stand bei meinem Sohn im Regal; steht immer 
noch dort ... na ja, ihr wisst ja) in eine Kiste mit Lüfter gesteckt. 
Weil die noch Garantie hatte, wollte ich an der FB nichts ändern. Lüfter 
war noch vom PC Netzteil da, noch ein Summer falls sie doch noch mal zu 
heiß werden sollte und fertig war die Kühlbox. Läuft immer noch und ohne 
Probleme.
Ich sehe da ehrlich gesagt keinen tieferen Sinn drin, den immer und 
immer zu fragen wie er heißt.

von Falk B. (falk)


Lesenswert?

@ F. Fo (foldi)

>Du hast die direkt an den Bus, mit einem Pullup angeschlossen?

Ja.

>Wie lang war denn der Bus?

ca. 20cm ;-)

>Im Anfang habe ich das auch mal so gemacht, hatte irgendwie nicht
>geklappt.

Dann hast du was verdreht.

>Habe das danach auch generell verworfen, weil einmal ab höheren
>Temperaturen eh eine direkte Stromversorgung gefordert ist

Ja, so ab 80°C.

> und bei
>längeren Bussen auch ein Fet einen "strong Pullup" ermöglichen soll.

Braucht man nicht zusätzlich, das macht der AVR allein, ist in der 
Software schon eingebaut.

>Aber trotzdem interessiert mich, wie weit du damit kommst.

Gestern hab ich zum testen mal 5m Kabel angeschlossen, lief problemlos.

>Nummern notieren und entsprechend einpflegen. Die werden dann doch nicht
>mehr gewechselt. Warum sollte man das ständig abfragen, welcher Sensor
>da gerade drin ist?

Muss man auch nicht.

>Ich sehe da ehrlich gesagt keinen tieferen Sinn drin, den immer und
>immer zu fragen wie er heißt.

Muss man auch nicht.

von Falk B. (falk)


Angehängte Dateien:

Lesenswert?

Ok, hier mal wieder ein Update. Folgende Dinge wurden geändert.

Timing optimiert, damit kann bis zu 15us Zeitkonstante am Bus noch 
verarbeitet werden! Das sind ~10nF Buslast bei 1,2kOhm Pull-Up 
Widerstand, das entspricht ~200m Leitung mit ca. 50pF/m!!!

Beitrag "Re: DS18B20 Problem Telfonkabel 4 polig"

Fehler im Demo des DS18B20 behoben, jetzt funktioniert auch der Alarm 
search. Hinweis! Die Schaltschwellen tl/th müssen erst ins Scratchpad 
und danach in den EEPROM kopiert werden! Der Vergleich und damit das 
Setzen/Löschen des Alarm Flags erfolgt mit den Werten im EEPROM, NICHT 
mit den Werten im Scratchpad!

Divere Schönheitskorrekturen und Aufräumarbeiten im Quelltext, die 
Anzahl der max. ROMs ist jetzt per #define einfach einstellbar und im 
gesamten Programm referenziert, keine magic numbers mehr.

von Falk B. (falk)


Lesenswert?

Wenn man die Interruptsperren nicht haben will, kann man den UART prima 
als Hardware für Onewire im Interruptbetrieb nutzen.

https://www.maximintegrated.com/en/app-notes/index.mvp/id/214

von Falk B. (falk)


Angehängte Dateien:

Lesenswert?

Keine Software ist jemals wirklich fertig ;-)
Meine kleine Lib ist da keine Ausnahme. Hier mal ein Update mit 
folgenden Korrekturen

- in ds18x20_convert_t() war noch falscher Restcode drin, welcher ein 
Reset und skip_rom ausführt, was natürlich einer allgemeinen Verwendung 
der Funktion entgegen spricht
- die Hardwarezugriffe wurden weiter gekapselt und in Richtung 
Headerfile onewire.h geschoben, dadurch muss bei einer Anpassung auf 
einen anderen Prozessor nur dort was geändert werden, nicht aber in 
onewire.c
- in onewire_crc() wurde ein Prüfung eingebaut, ob alle Daten == 0 sind, 
denn dann kommt als CRC auch 0 zurück und man glaubt irrtümlich, die CRC 
wäre OK. Ist sie aber nicht! Also wird in diesem Sonderfall 0xFF 
zurückgegeben.

von F. F. (foldi)


Lesenswert?

Bedankt!

Würde gern mal ein Bier mit dir trinken. :-)

von Andreas (Gast)


Lesenswert?

Hallo,

da der Onewire Bus nicht ganz trivial ist, ich mich aus Zeitgründen 
daher streng an dieses library richten möchte und aber durch ein Problem 
bei meiner Servoansteuerung mittels Timer (sehr zeitkritisch) die in 
atomic blocks gepackten delays entdeckt habe, wollte ich wissen, wie 
kritisch diese Zeiten sind?

Ich betreibe das Ganze an 8MHz, dh meine Interrupts würden die delays 
wohl nur um wenige µs verfälschen. Wenn die Atomic Blöcke jedoch bleiben 
sollen, werde ich mir wohl flags im Hauptprogramm zurechtlegen, welche 
das Auslesen der Sensoren nur zulassen, wenn in nächster Zeit keine 
Servosignale (müssen auf <10µs genau getimt werden) generiert werden.

lg
Andreas

von Falk B. (falk)


Lesenswert?

@Andreas (Gast)

>bei meiner Servoansteuerung mittels Timer (sehr zeitkritisch) die in
>atomic blocks gepackten delays entdeckt habe, wollte ich wissen, wie
>kritisch diese Zeiten sind?

Kritisch genug, als daß man sie nicht weglassen kann.

>Ich betreibe das Ganze an 8MHz, dh meine Interrupts würden die delays
>wohl nur um wenige µs verfälschen.

Sicher? Natürlich verträgt das Protokoll an einigen Stellen vielleicht 
10-20us Jitter, aber das würde ich nicht übertreiben wollen.

>Wenn die Atomic Blöcke jedoch bleiben
>sollen, werde ich mir wohl flags im Hauptprogramm zurechtlegen, welche
>das Auslesen der Sensoren nur zulassen, wenn in nächster Zeit keine
>Servosignale (müssen auf <10µs genau getimt werden) generiert werden.

Gute Idee.

Wenn das nicht geht, kann man OneWire auch mittels UART betreiben, da 
gibt es eine App-Note von Maxim. Dann muss man aber die Low Level 
Funktionen zum Bit- und Bytezugriff anpassen. Das ist schon einiges an 
Arbeit, zumal man den Rest verstehen muss.

https://www.maximintegrated.com/en/app-notes/index.mvp/id/214

: Bearbeitet durch User
von Jan H. (janiiix3)


Lesenswert?

uint8_t onewire_reset(void) {
    uint8_t err=0;

    ONEWIRE_PORT &= ~ONEWIRE_MASK;              // low
    ONEWIRE_DDR  |=  ONEWIRE_MASK;              // switch to ouput
    _delay_us(480);
    //ATOMIC_BLOCK(ATOMIC_RESTORESTATE) {
    uint8_t sreg_tmp=SREG; cli(); // Arduino workaround :-0
        ONEWIRE_DDR  &= ~ONEWIRE_MASK;              // switch to input
        _delay_us(66);
}

Verständniss Frage:
Wieso wird erst der "ONEWIRE_PORT" auf "low" gezogen und dann erst als 
Ausgang gesetzt?

Müsste das nicht anders herum sein?

von Peter D. (peda)


Lesenswert?

Naj H. schrieb:
> Müsste das nicht anders herum sein?

Ist schon richtig rum.
Man will ja open drain haben und kein strong high.
Strong high ist nur bei parasite Power erlaubt.

von Falk B. (falk)


Lesenswert?

Naj H. schrieb:
> Verständniss Frage:
> Wieso wird erst der "ONEWIRE_PORT" auf "low" gezogen und dann erst als
> Ausgang gesetzt?

Weil das so richtig ist ;-)

> Müsste das nicht anders herum sein?

Nein. Durch die Reihenfolge
1
    ONEWIRE_PORT &= ~ONEWIRE_MASK;              // low
2
    ONEWIRE_DDR  |=  ONEWIRE_MASK;              // switch to ouput

stellt man sicher, daß der Ausgang immer nur low aktiv treibt.

Wenn man es so machen würde.
1
    ONEWIRE_DDR  |=  ONEWIRE_MASK;              // switch to ouput
2
    ONEWIRE_PORT &= ~ONEWIRE_MASK;              // low

und das entsprechende Bit in ONEWIRE_PORT vorher auf HIGH steht, würde 
der Ausgang kurz aktiv auf HIGH treiben. Das ist zwar nicht 
superkritisch, aber auch nicht erwünscht, denn OneWire ist ein Open 
Drain Bus.

Es gibt nur wenige Moment, wo der OneWire bus aktiv auf HIGH gelegt 
werden darf, nämlich dann, wenn ein IC im parasitären Modus betrieben 
wird und mehr Strom braucht. Dann muss der Strong Pull Up aktiviert 
werden, sprich, der Bus muss niederohmig mit VCC getrieben werden. Das 
kann ein externer Transistor sein oder aber auch ein ausreichend starkes 
IO-Pin.

von Jan H. (janiiix3)


Lesenswert?

Was genau bedeutet parasitär in dem Zusammenhang?

von Route_66 H. (route_66)


Lesenswert?

Naj H. schrieb:
> Was genau bedeutet parasitär in dem Zusammenhang?

Die Datenleitung wird "parasitär" zum Zweck der Stromversorgung während 
der Temperaturmessung verwendet.

: Bearbeitet durch User
von eProfi (Gast)


Lesenswert?

Es gibt nicht nur Temperatursensoren mit OneWire, sondern auch 
Cryptoprozessoren, Eeproms etc. Die brauchen ebenfalls strongPullup.

von Route_66 H. (route_66)


Lesenswert?

eProfi schrieb:
> Es gibt nicht nur Temperatursensoren mit OneWire, sondern auch

Richtig. Im Threadtitel steht aber: ...DS18x20 Library!

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.