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
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
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.
@ 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
@ 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.
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_tx;
2
uint8_ti,j,crc;
3
volatileuint8_trc;// volatile is used for timing measurement in simulation, not required for normal application
4
uint8_ti_ds18B20,i_ds18S20;
5
int16_ttemp,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
}elseif(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
}elseif(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;elsei_ds18S20=0;// family code for DS18S20
37
if(buffer[0]==DS18B20_ID)i_ds18B20=1;elsei_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!"));
@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!
}
}
@ 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"
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??????????????????
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
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.
@ 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!
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.
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.
@ 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.
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.
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.
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
@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
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?
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.
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.
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.
Hallo,
ich hatte die letzten Tage mit meinem STK500 erhebliche Probleme den
DS18S20 einzulesen.
Nachdem ich die Software von Falk gefunden und das Ganze zunächst auf
einem arduino uno getestet hatte, konnte ich die Temperatur des DS18S20
sofort ohne Fehler einlesen. Ich hatte lediglich den Port PB6 auf PB0
geändert.
Anschliessend habe ich die Datei "onewire_demo.ino" so abgeändert, dass
man die jetzt auch mit dem gcc für jeden anderen Controller ohne die IDE
des arduino compilieren kann.
Da ich hier noch diverse Controller liegen hatte, habe ich es heute mit
folgenden Controllern getestet:
- ATMega328P auf dem Arduino Uno R3 mit 16MHz externem Quarz
- ATMega32, ATMega328P auf dem STK500 mit 8MHz externem Quarz
- AT90CAN128 auf dem STK501 mit 8MHz externem Quarz
- ATMega2560 auf dem STK600 mit 8MHz externem Quarz
- ATMega32 auf dem STK500 mit internem Quarz
Für den AT90S8515 und ATMega163 liess sich die Software zwar
compilieren, aber der RAM war zu klein.
Vielleicht kann es jemand für seine eigenen Tests nochmal gebrauchen.
Alle erforderlichen Dateien sind in der Zip-Datei enthalten.
Viele Grüße
Andreas