Datum:
Angehängte Dateien:Anbei der komplette Code für 1-Wire in C auf dem AVR. Wer meine AVR Assembler und C51 Beispiele schon kennt, wird große Ähnlichkeiten entdecken. Es werden alle gefundenen Sensoren in 0,1°C Schritten ausgegeben. Dabei erfolgt die Anzeige der DS1820 nur in 0,5°C Schritten. Die Routine muß für negative Werte leicht geändert werden. Die Ausgabe erfolgt über die UART. Die nötigen Delay-Zeiten für den 1-Wire werden mit dem Timer erzeugt. Dadurch ergibt sich eine Unabhängigkeit vom Compiler und die Quarzfrequenz kann einfach geändert werden. Peter
Datum:
Angehängte Dateien:@Peter: Ich mache erste Gehversuche mit C und WINAVR. Dein 1-wire Beispiel bekomme ich aber nicht fehlerfrei compiliert. Ich bekomme nach make all folgende Fehler: -------- begin -------- avr-gcc (GCC) 3.3.2 Copyright (C) 2003 Free Software Foundation, Inc. This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Linking: main.elf avr-gcc -mmcu=at90s8535 -I. -g -Os -funsigned-char -funsigned-bitfields -fpack-struct -fshort-enums -Wall -Wstrict-prototypes -Wa,-adhlns=main.o -std=gnu99 -Wp,-M,-MP,-MT,main.o,-MF,.dep/main.elf.d main.o 1WIRE.C DELAY.C TIMEBASE.C TEMPMEAS.C UART.C --output main.elf -Wl,-Map=main.map,--cref -lm cc1plus.exe: warning: "-std=gnu99" is valid for C/ObjC but not for C++ cc1plus.exe: warning: "-std=gnu99" is valid for C/ObjC but not for C++ cc1plus.exe: warning: "-std=gnu99" is valid for C/ObjC but not for C++ TIMEBASE.C: In function `void init_timer()': TIMEBASE.C:40: warning: assignment of negative value `-1' to `volatile unsigned int' TIMEBASE.C:40: warning: argument of negative value `-1' to `unsigned int' cc1plus.exe: warning: "-std=gnu99" is valid for C/ObjC but not for C++ TEMPMEAS.C: In function `void read_meas()': TEMPMEAS.C:37: error: invalid conversion from `unsigned char*' to `char*' TEMPMEAS.C:38: error: invalid conversion from `unsigned char*' to `char*' TEMPMEAS.C:45: error: invalid conversion from `unsigned char*' to `char*' TEMPMEAS.C:46: error: invalid conversion from `unsigned char*' to `char*' TEMPMEAS.C:47: error: invalid conversion from `unsigned char*' to `char*' TEMPMEAS.C:48: error: invalid conversion from `unsigned char*' to `char*' cc1plus.exe: warning: "-std=gnu99" is valid for C/ObjC but not for C++ UART.C: In function `void uinit()': UART.C:6: error: `UBRRL' undeclared (first use this function) UART.C:6: error: (Each undeclared identifier is reported only once for each function it appears in.) UART.C:7: error: `UBRRH' undeclared (first use this function) UART.C:8: error: `UCSRA' undeclared (first use this function) UART.C:9: error: `UCSRC' undeclared (first use this function) UART.C:9: error: `URSEL' undeclared (first use this function) UART.C:9: error: `UCSZ1' undeclared (first use this function) UART.C:9: error: `UCSZ0' undeclared (first use this function) UART.C:10: error: `UCSRB' undeclared (first use this function) make.exe: *** [main.elf] Error 1 > Process Exit Code: 2 Müssen bei Deinem Code SFR-Bezeichnungen für den AT90S8535 angepaßt werden? Was ist mit den Umwandlungen von Uchar zu Char?? Liegen die ganzen Fehlermeldungen möglicherweise an meinem makefile? Ich bin dankbar für jeden Hinweis. BTW: Danke für Deine zahlreichen Codebeispiele. Gruß Matthias
Datum:
Tut mir leid, aber mit dem make kenne ich mich nun überhaupt nicht aus. Ich compiliere immer in der DOS-Box mit einer Batch: @echo off :set mcu=90s2313 :set mcu=tiny26 set mcu=mega8 set main=test set ac=c:\avr\winavr path %ac%\bin;%path% avr-gcc.exe -Os -mmcu=at%mcu% -Wall -g -o main.out *.c if not exist main.out goto end cmd /c avr-objdump.exe -t -h -S main.out >%main%.lst cmd /c avr-objcopy.exe -O ihex main.out %main%.hex avr-size.exe -B main.out del main.out :end Peter
Datum:
@ Peter: Danke für die Antwort. Ich werds mal auf Deine Art probieren. Zwei Fragen zu Deinen Code habe ich noch: 1. Für welchen Controller hast Du Ihn geschrieben? Für den Mega8, wie Dein Batchfile andeutet? Ich könnte dann leichter die Fehlermeldungen mit den SFR-Definitionen verstehen. 2. Sind die Fehlermeldungen zu den Umwandlungen von uchar* nach char* in der TEMPMEAS.C berechtigt? Beispiel: TEMPMEAS.C:37: error: invalid conversion from `unsigned char*' to `char*' Zeile 37: sprintf( s, "%02X ", id[i] ); s ist uchar Grüße Matthias
Datum:
@Peter: Frage 1 hat sich erledigt: bei mcu=atmega8 sind die Fehlermeldungen zu den SFRs weg. Matthias
Datum:
Ich möchte mich nochmal bei Peter bedanken. Lange hatte ich mit dem 1-Wire-Protokoll rumgefummelt. Und irgendwie hat nichts so recht geklappt. Inzwischen geht es endlich, da ich hier ein sehr gutes Beispiel hatte. Somit bin ich zumindest schon in der Lage so ein Teil auszulesen. Was noch offen ist, wäre Search-ROM und Match-ROM. Das ist wirklich sehr schwer zu verstehen und vor allem umzusetzen, wenn man mal das iButton-Guide gelesen hat. Obwohl ja alles ausführlich dasteht.
Datum:
Matthias: Die Dateinamen müssen auf ".c" enden, sonst behandelt sie der Compiler als C++, nicht C: "cc1plus.exe: warning: "-std=gnu99" is valid for C/ObjC but not for C++"
Datum:
@ Andreas: Danke für den Hinweis. Meine C-Dateien waren "*.C". Ich verstehe deshalb die Meldung von make nicht. Ich nehme an, dass ich irgend einen Unsinn in meinem Makefile habe.
Datum:
Nun funktioniert es. Danke
Datum:
das gepostete batch file bringt bei mir [...Warnings...] uart.c: In function `uinit': uart.c:6: error: `UBRRL' undeclared (first use in this function) uart.c:6: error: (Each undeclared identifier is reported only once uart.c:6: error: for each function it appears in.) uart.c:7: error: `UBRRH' undeclared (first use in this function) uart.c:8: error: `UCSRA' undeclared (first use in this function) uart.c:9: error: `UCSRC' undeclared (first use in this function) uart.c:9: error: `URSEL' undeclared (first use in this function) uart.c:9: error: `UCSZ1' undeclared (first use in this function) uart.c:9: error: `UCSZ0' undeclared (first use in this function) uart.c:10: error: `UCSRB' undeclared (first use in this function) uart.c: In function `uputchar': uart.c:16: error: `UCSRA' undeclared (first use in this function) die dateien sind *.c in der main.h habe ich noch #include <avr/signal.h> verbessert sowie in der batch den pfad geändert.
Datum:
@Martin, lies alle Beiträge in Ruhe durch, besonders die von Matthias. Peter
Datum:
@ Peter, im Hauptprogramm setzt du die Sekunden auf 0. Must du eigentlich nicht auch den Prescaler auf 0 setzen, um das Timing sicherzustellen? In dieser Applikation evtl. nicht so wichtig, aber durch irgendwelche Interrupt-Sachen kann der Prescaler ja weiter zählen, bis im Hauptprogramm Sekunden auf Null gesetzt werden. Michael
Datum:
Hast recht, guter Programmierstil ist es, alle globalen Variablen zu initialisieren, damit das Programm besser lesbar ist. Oft wird das Initialisieren mit 0 weggelassen, da das der Compiler automatisch macht. Peter
Datum:
Hi ... nachdem ich Sie nirgends finden kann - Peter Dannegger hat mal Routinen in C51 veröffentlicht - gibts die noch irgendwo ? danke michael
Datum:
@peter ... On bigger applications this time may be longer, but should not exceed 500ms. Otherwise the user can think, there is Windows working inside ... W U N D E R B A R E S S T A T E M E N T!!! leo
Datum:
Hi! Ich brauche dringend Hilfe. Ich möchte den DS1820 mit meiner C-Control auslesen. Allerdings hab ich nur einen Assemblerocde ohne viele Erklärungen (http://www.b-kainka.de/ccbsp.htm; ganz unten). Kennt wer einen Beispielcode in Basic und Assemblercode? Gruß Bernie
Datum:
C-Control I oder II? Bei der C-Control I wird es nicht möglich sein das ganze in Basic zu machen. Das wird zu langsam und der Ein-Draht-Bus ist im Timing ziemlich empfindlich. Du wirst um Assembler nicht herumkommen, und da gehen ohne Tricks nur 256 Bytes, wenn ich mich nicht irre. Gruß Elektrikser
Datum:
Hi! Ja ich habe die C-Control I. Wenn Assemblercode dabei ist, wäre es ja nicht schlimm. Aber die oben genannten Seite beinhaltet nur den Assemblercode. Ich weiß nur nicht wie das Basic-Programm dazu aussieht. Gruß Bernie
Datum:
Autsch, die CControl ist bei mir schon lang her. Aber die asm-Datei müsste mit "syscode" in das Basic-Programm eingebunden werden. Und der Rest? Hmm, Das asm-Programm hat auf der linken Seite Sprungmarken, die du im Basic-Programm anspringen kannst. Da gab es noch den "sys"-Befehl. Schau mal in deine Beschreibung rein. In dem Assemblerprogramm müsste es; reset, byte_read, byte_write, delay geben. Ich muss mal suchen, ob ich überhaupt noch was mit der CControl habe... Ich hoffe, dass ich da jetzt nicht zuviel durcheinander gebracht habe. Gruß Elektrikser
Datum:
Wie ich den Assembler in den Code einbinde und "anspringe" habe ich auch schon herrausgefunden. Aber ich glaube, dass es im Basic-Programm noch mehr Code erforderlich ist um die Temperatur auszulesen, denn als Kommentar bei der Variabeldeklarierung steht: "bas_2 .equ $b8 ; zweite Basic Variable => Daten Rein&Raus". Falls du da durchblickst: Ich habe ein BASIC-Programm gefunden, aber es ist recht komplex und ich habe keine Erklärung dazu gefunden. (http://homepages.compuserve.de/BernardWeiler/DS1820.BAS). Ich habe den Code ausprobiert und auch etwas herum experimentiert aber ich bekomme nur Fehlermeldungen, dass der Sensor nicht gefunden worden ist. Da ich von diesem Code wenig Ahnung und keine Informationen habe, weiß ich nicht wo ich mit der Fehlersuche beginnen soll. Gruß Bernie
Datum:
Auch wenn ich diesen alten Thread mal wieder rauskrame, habe ich mal eine Frage zu der Leseroutine: Ich versuche gerade meine eigenen 1-Wire Funktionen zu schreiben, da das Lesen aber nicht so recht funktioniert habe ich mir mal die Funktionen von Peter angesehen. Aus dem Datenblatt des DS1820 verstehe ich den Read-Time Slot folgendermaßen: - 1 Byte über den 1-Wire Bus lesen: Ein Read-Time-Slot hat eine Mindestdauer von 60µs. Zwischen den einzelnen Slots muss einer Erholungszeit von mindestens 1µs liegen. Der Slot wird gestartet, indem der Master den Bus für mindestens 1µs auf 0 zieht, und dann wieder vom Pull-Up auf 5V gehen lässt. Der DS1820 überträgt daraufhin sein Bit: Lesen einer 0: Der DS1820 zieht den Bus nach der fallenden Flanke vom Master auf 0. Das Signal muss innerhalb von 15µs nach Beginn vom Master gesampelt werden. Lesen einer 1: Der DS1820 lässt den Bus weiterhin auf 5V (vom Pull-Up hochgezogen) Das Signal muss innerhalb von 15µs nach Beginn vom Master gesampelt werden. So habe ich das auch programmiert, erhalte aber keine Daten zurück. (Ich habe vorher ein READ ROM (0x33) gesendet) Die Funktion w1_bit_io() von Peter funktioniert auch anders: Er programmiert erst den Pin als Ausgang, nach 1µs Wartezeit dann wieder als Eingang, liest dann nach 14µs den Pin ein. Zum Abschluss wird der Pin nochmals als Eingang programmiert (wohl nur, weil die Funktion auch zum Bits senden benötigt wird). Wieso funktioert das bei Peter, obwohl er den Ausgang ja garnicht auf 0 zieht und dem Slave mitzuteilen dass der Slot gestartet wird?
Datum:
@Thomas es wird ja ein open-drain Ausgang benötigt, d.h. das Ausgangsbit bleibt immer auf 0 und mit dem Direktionbit wird dann nur der untere Transistor ein- bzw. ausgeschaltet. Peter
Datum:
Achso OK, das aktive auf 0 setzen des Ausgangs machst du nur einmal in der 1-Wire Initialisierungsroutine. Naja, reicht ja auch eigentlich, da diese vor jedem Übertragungsbeginn sowieso einmal durchlaufen wird.
Datum:
Hallo! Wo ich syscode ds1820.obj erhalten kann, das ich im Programm benötige. Danke!
Datum:
Das Du kann erhalten compilieren. Mit Compiler.
Datum:
Hallo Ich wollte einen anderen Pin verwenden. Habe die Zeilen #define OW_PIN PD6 #define OW_IN PIND #define OW_OUT PORTD #define OW_DDR DDRD auf #define OW_PIN PC5 #define OW_IN PINC #define OW_OUT PORTC #define OW_DDR DDRC geändert. Ich verwende einen ATMEGA8. Es funkt super aber eben nur mit dem PD6. Wenn ich die andere Festlegung verwenden funkt es auch.????? Aber nur über den PD6???? Vielleicht habe ich ja etwas übersehen. Gruß
Datum:
@Wolf4124 diese Macros stehen nirgends in meinem Code. Ist also kein Wunder, daß auf nicht verwendete Macros keine Reaktion erfolgt. Peter
Datum:
Upps Falsche Baustelle. ;-( Gruß
Datum:
Hallo Peter. Habe Deinen Source auf einem ATMEGA16 mit 8Mhz Quartz ausprobiert. Nachdem es immer die Meldung "DATA_ERR" gab, habe ich dann angefangen mit einem Scope zu messen. Als erstes habe ich mir eine kleine Schleife geschrieben, mit der ich messen konte, ob die delay-Funktion richtig funktioniert (timing). Das tat sie. Ich habe dann gesehen, daß Du bei einem READ immer erst nach 15usec. die Daten des Sensors einließt. Laut Spec. sollte das aber innerhalb von 15usec. passieren. Habe dann Deinen Code zum Testen wie folgt "gepatcht": #if 0 uchar w1_bit_io( bit b ) { cli(); W1_DDR |= 1<<W1_PIN; DELAY( DELAY_US( 1 )); if( b ) W1_DDR &= ~(1<<W1_PIN); DELAY( DELAY_US( 15 - 1 )); if( (W1_IN & (1<<W1_PIN)) == 0 ) b = 0; DELAY( DELAY_US( 60 - 15 )); W1_DDR &= ~(1<<W1_PIN); sei(); return b; } #else uchar w1_bit_io( bit b ) { cli(); W1_DDR |= 1<<W1_PIN; DELAY( DELAY_US( 1 )); if( b ) { W1_DDR &= ~(1<<W1_PIN); DELAY( DELAY_US( 10 - 1 )); // beim LESEN kurzer delay } else DELAY( DELAY_US( 15 - 1 )); if( (W1_IN & (1<<W1_PIN)) == 0 ) b = 0; DELAY( DELAY_US( 60 - 15 )); W1_DDR &= ~(1<<W1_PIN); sei(); return b; } #endif Damit funktionierte es. Der DS1820 hat bei einer "0" das Signal schon nach 15usec wieder auf 1 gesetzt. Das hatte ich mit dem Scope gesehen. Darum natürlich "DATA_ERR". Jetzt frage ich mich, wieso hat das bei Euch funktioniert? Sind die Teile vom Timing so unterschiedlich? Allerdings laut meinem Datenblatt (DS18S20) soll man auch innerhalb der 15usec lesen. Liegt es an dem DS18S20 (S!!!!)? Hast Du eine Idee? Danke und Gruß Joachim
Datum:
@Joachim, ich habs nicht nachgemessen. Ich hab auch einige Meter Leitung dazwischen, deren Kapazität wird wohl die Flanke etwas verzögern. Der genaue Wert, wann der Slave wieder auf 1 geht, darf laut Datenblatt irgendwo zwischen 15µs und 60µs liegen. Du hast warscheinlich ein Exemplar erwischt, was genau am unteren Limit liegt. Peter
Datum:
Angehängte Dateien:kann mir jemand beim 1 wire port helfen,ich muss das in c programmiern!
Datum:
hey kann mir wer sagen,ob das hier richtig ist!
#include<reg517.h>
#include<stdio.h>
//---------------------------------------
// Initialize serial port
//---------------------------------------
void InitSerial(void)
{
TMOD = 0x20; // Timer 1=8-Bit-relod
TH1 = 0xFD; // TH1
TR1 = 1; // Timer 1 starten
SCON = 0x52; // Freigabe von Sender & Empfänger
}
bei mir steht immer undefined identifier! jedoch sollte es meiner
meinung stimmen,blick da jetzt ned durch
Datum:
Good day, Peter! Thanks for the "1Ware.zip"! Best regards, P.S.
Datum:
Hallo
Ich habe das Programm ProfiLab Expert. Mit dem Programm kann man
Schaltungen am PC realisieren.
Für meine Anwendung (Heizungsregeler) muss ich Temperaturen erfassen die
ich über den 1 wire Bus auslesen möchte. Es gibt fertige Lösungen z.B.
von der Firma Hygrosens, die mir aber etwas zu teuer sind.
In ProfiLab kann man aber DLL Dateien importieren die in C++ oder Delphi
geschrieben werden müssen.
Gibt es eine DLL um den 1 wire Bus in Profilab Expert auszulesen um
damit die Temperatur zu messen?
Ich habe hier einmal einen Auszug der Hilfe zum DLL-Import von ProfiLab
reingestellt.
DLL-Import
Funktion
Mit dem DLL-Import haben Sie ein Bauteil zur Verfügung, dass eine
Programmierschnittstelle darstellt, die es ermöglicht selbst eigene
Bauteile, z.B. zur Ansteuerung spezieller Hardware, o.ä., für ProfiLab
zu programmieren. Dazu benötigen Sie natürlich eine Programmiersprache,
die es ermöglicht DLL-Dateien (Dynamic Link Libraries) zu erzeugen,
sowie die entsprechenden Programmierkenntnisse.
Bei der Programmierung der DLL müssen Sie sich an bestimmte Vorgaben von
ProfiLab halten. So muss Ihre DLL bestimmte Routinen enthalten und
exportieren, mit denen Sie die Anzahl der Ein- und Ausgänge, deren
Bezeichnung und natürlich die interne Funktion des Bauteils bestimmen.
Folgende Funktionen muss Ihre DLL bereitstellen:
Delphi: function NumInputs: Byte;
C++: unsigned char _stdcall NumInputs()
Das Ergebnis dieser Funktion muss einen Bytewert mit der gewünschten
Anzahl von Bauteileingängen zurückliefern.
Delphi: function NumOutputs: Byte;
C++: unsigned char _stdcall NumOutputs()
Das Ergebnis dieser Funktion muss einen Bytewert mit der gewünschten
Anzahl von Bauteilausgängen zurückliefern.
Delphi: function InputName(Channel: Byte): ShortString;
C++: void _stdcall GetInputName(unsigned char Channel, unsigned char
*Name)
Das Ergebnis dieser Funktion muss einen Text für die Beschriftungen
jedes Eingangs (Channel) zurückliefern. Das Bauteil ruft diese Funktion
für jeden Eingang (Channel) auf und fragt so die Beschriftung für jeden
Eingangs-Pin ab. Der Parameter CHANNELS gibt an welcher Pin gemeint ist,
und läuft von 0 bis NumInputs-1.
Delphi: function OutputName(Channel: Byte): ShortString;
C++: void _stdcall GetOutputName(unsigned char Channel, unsigned char
*Name)
Das Ergebnis dieser Funktion muss einen Text für die Beschriftungen
jedes Ausgangs (Channel) zurückliefern. Das Bauteil ruft diese Funktion
für jeden Eingang (Channel) auf und fragt so (von oben nach unten) die
Beschriftung für jeden Eingangs-Pin ab. Der Parameter CHANNELS gibt an
welcher Ausgangs-Pin gemeint ist, und läuft von 0 bis NumOutputs-1.
Delphi: Procedure Calculate(PInput,POutput,PUser: PDLLParams);
C++: void _stdcall CCalculate(double *PInput, double *POutput, double
*PUser)
Die ist die zentrale Berechnungsroutine Ihres DLL-Bauteils, die die
Funktion des Bauteils definiert. Mit den Parametern PINPUT, POUTPUT und
PUSER bekommt die Routine drei Zeigervariablen (Pointer) übergeben die
folgende Funktion haben:
Der Pointer PINPUT zeigt auf einen Speicherbereich, der dazu dient die
Eingangswerte des Bauteils an die DLL zu übergeben.
Der Pointer POUTPUT zeigt auf einen Speicherbereich, der dazu dient die
berechneten Ausgangswerte der DLL an das Bauteil zurückzugeben.
Der Pointer PUSER stellt einen Pointer auf einen Speicherbereich zur
Verfügung, in dem die DLL eigene (lokale) Werte speichern kann.
Hintergrund: Variablen, die die DLL selbst deklariert sind globale
Variablen. Werte die in diesen Variablen gespeichrt werden, würden sich
gegenseitig überschreiben, wenn man dieselbe DLL mehr als einmal in
einem ProfiLab-Projekt verwendet. Um lokale Werte speichern zu können,
stellt ProfiLab der DLL den lokalen Speicherbereich zur Verfügung, auf
den PUSER zeigt. (Alternativ kann man auch Variablen in der DLL selbst
deklarieren. Dann muß man die DLL aber mehrfach unter verschiedenen
Dateinamen speichern und importieren, um sie mehrfach in einem
ProfiLab-Projekt verwenden zu können.)
Alle drei Pointer PINPUT, POUTPUT und PUSER zeigen jeweils auf einen
Speicherbereich in dem 100 Variablen vom Typ EXTENDED in einem Array
abgelegt sind. Die Pointer sind vom Typ PDLLParams, dessen Deklaration
in Delphi so aussieht:
type TDLLParams = array[0..100] of extended;
PDLLParams = ^TDLLParams;
Die Extended-Variablen des Pointers PINPUT enthalten die
Eingangszustände des Bauteils. Auf den Wert eines Eingangs des Bauteils
können Sie wie folgt zugreifen:
PInput^[0] enthält den numerischen Eingangswert des 1. Eingangs,
PInput^[1] enthält den numerischen Eingangswert des 2. Eingangs, usw.
Die Extended-Variablen des Pointers POUTPUT nehmen die Ausgangszustände
des Bauteils auf. Um den Wert der Ausgänge des Bauteils zu setzen,
benutzen Sie:
POutput^[0] nimmt den numerischen Ausgangswert des 1. Ausgangs auf,
POutput^[1] nimmt den numerischen Ausgangswert des 2. Ausgangs, usw.
Entsprechend können Sie mit PUser^[0] bis PUser^[99] frei verwenden um
eigene Werte zu speichern. Die Werte in diesen Variablen werden von
ProfiLab mit in der Projektdatei abgespeichert, und sind so beim
nächsten Laden des Projekts wieder verfügbar. Die Variable PUser^[100]
wird von ProfiLab gesetzt, und enthält die Nummer des DLL-Bauteils in
Ihrem Projekt: 1 für DLL1, 2 für DLL2, usw.
Die Routine Calculate wird im RUN-Modus ständig von ProfiLab aufgerufen,
um neue Eingangswerte zu übergeben und neue Ausgangswerte für das
Bauteil abzurufen. Diese Routine muss daher unbedingt zeitoptimiert
programmiert werden, und sollte auf keinen Fall Pausen (in Form von
SLEEP-Befehlen oder Warteschleifen) enthalten. Nach dem Abfragen der
Eingangswerte und dem Setzen der Ausgangswerte sollte die Routine so
schnell wie möglich wieder verlassen werden. Die Rechenzeit für die
Routine wirkt sich unmittelbar auf die Simulationsfrequenz von ProfiLab
aus.
Delphi: Procedure SimStart(PInput,POutput,PUser: PDLLParams);
C++: void _stdcall CSimStart(double *PInput, double *POutput, double
*PUser)
Diese Routine wird beim Starten eines ProfiLab-Projekt aufgerufen, und
kann z.B. benutzt werden, um Anfangswerte Ihrer DLL zu initialisieren.
Die Funktion der Parameter wurde zuvor bereits beschrieben.
Delphi: Procedure SimStop(PInput,POutput,PUser: PDLLParams);
C++: void _stdcall CSimStop(double *PInput, double *POutput, double
*PUser)
Diese Routine wird beim beenden des RUN-Modus eines ProfiLab-Projekt
aufgerufen, und kann z.B. um geöffnete Dateien zu schliessen, etc.. Die
Funktion der Parameter wurde zuvor bereits beschrieben.
Delphi: Procedure Configure(UserValues: PDLLParam);
C++: void _stdcall CConfigure(double *PUser)
Sofern Ihre DLL diese Prozedur exportiert, wird die Schaltfläche
EINSTELLUNGEN... im Eigenschaftendialog des DLL-Bauteils aktiviert. Wird
dann diese Schaltfläche betätigt, so springt ProfiLab die
CONFIGURE-Prozedur in Ihrer DLL an. Hier können Sie dann z.B. einen
eigenen Dialog zum Konfigurieren Ihrer DLL ausführen.
Mit diesen Routinen haben Sie alle Möglichkeiten um eigene Bauteile für
ProfiLab programmieren zu können. Der Fantasie sind dabei keine Grenzen
gesetzt. Sie könnten z.B. Treiber für eigene Hardwaregeräte
programmieren, einen eigene Programminterpreter integrieren, oder
beliebige andere komplexe Berechnungen in einer DLL ausführen. Um
digitale Bauteile zu programmieren, setzen Sie den numerischen
Ausgangswert auf 5 um einen HIGH-Pegel zu erzeugen und auf 0 um einen
LOW-Pegel zu erzeugen. Ebenso entspricht ein Eingangswert >2.5 einem
logischen HIGH-Pegel und ein Eingangswert darunter einem logischen
LOW-Pegel.
Beim Laden einer DLL-Datei über den Eigenschaften-Dialog des
DLL-Bauteils, werden die aus der DLL importierten Routinen zur Kontrolle
aufgelistet. Das Bauteil erscheint danach mit den von Ihnen definierten
Ein- und Ausgängen im Schaltplan. Um den Aufrufkonventionen von
C-Compilern zu genügen, kann dem Namen von exportierten Funktionen und
Prodeduren jeweils auch ein Unterstrich _ vorangestellt sein, z.B.
_SimStart statt SimStart. Derart exportiere Routinen werden
gleichermassen von ProfiLab erkannt und importiert. Beim Compilieren
eigener DLL-Projekte müssen Sie ggf. darauf achten, dass Sie die
Linkeroption "Dynamische RTL" deaktivieren. Anderfalls kann Ihre DLL auf
Systemen ohne installierte C++-Umgebung nicht geladen werden.
Datum:
@Karl, für ellenlange Texte hat der Forenbetreiber den Dateianhang gedacht. Ein PC für ne Heizungsregelung wäre mir zu unzuverlässig, teuer und stromfressend. Hier im MC-Forum nimmt man eigentlich nen MC dafür. Fragen zur PC-Programmierung sind außerdem besser in der Rubrik "PC-Programmierung" aufgehoben. Peter
Datum:
@Peter Dannegger > Ein PC für ne Heizungsregelung wäre mir zu unzuverlässig, teuer und > stromfressend. Der PC IST die Heizung ;-) MFG Falk
Datum:
@ Peter Danke für die schnelle Antwort und den Tip mit dem anderen Forum. Nur noch eine Frage: Kann man mit einem PC den überhaupt den 1 wire bus auslesen, ohne ein MC dazwischenzuschalten (ist der PC schnell genug)? P.S. Die Energiekosten die der PC zur Steuerung braucht, spar ich durch geringere Pumpenlaufzeiten ein. Außerdem kenne ich mich mit MC nicht so aus. MFG Karl
Datum:
@Karl > Kann man mit einem PC den überhaupt den 1 wire bus > auslesen, ohne ein MC dazwischenzuschalten (ist der PC schnell genug)? Naja, es sollte schon mindestens ein P4 mit 3 GHz sein ;-) Im Ernst, der PC ist schnell genug, aber das Timing der One-wire ICs ist recht schnell und du brauchst dafür einen Low-Level Treiber. Knifflige Sache. Für einen uC kein Problem, der muss nicht WinXP mit sich rumschleppen. Ich behaupte mal, der Aufwand sich in uC einzuarbeiten ist geringer als eine low-level Treiber für winXP zu schreiben. Und am Ende hast du eine wesentlich bessere und zweckmässigere Heizungssteuerung. uCs kannst du einfach in C programmieren, so wie deinen PC auch. MFG Falk
Datum:
>P.S. Die Energiekosten die der PC zur Steuerung braucht, spar ich durch >geringere Pumpenlaufzeiten ein Wozu dann die Steuerung, wenn es keine Verbesserung gibt? (Ich hab mir nicht den langen Post durchgelesen; vielleicht gibt es die Antwort ja auch in Kurzform...). >Außerdem kenne ich mich mit MC nicht so aus. Was spricht dagegen, das zu ändern? Schade, dass ich sonst nichts zu diesem Thema beitragen kann.
Datum:
Den 1-wire bus kann man sehr schön auch in Java programmieren. Gibt es auf der Herstellerseite www.maxim.de. Schnell genug ist der PC. Am einfachsten geht es mit dem DS9490R über USB. Und hier ein Link für eine einfache Ansteuerung : lena.franken.de/hardware/temperaturmessung.html Selbst mit einem Epia-Board braucht der PC immer noch 20W. Mit Mikrocontroller liegt man eher bei 20mW (!). 20W sind immerhin 175kWh pro Jahr... Das Problem bei den DS1820 ist die breite Messfläche. Lufttemperatur lässt sich gut messen, aber als Anlegesensoren sind sie eher weniger geeignet. Die Sensoren muss man sehr gut isolieren, wenn man sie direkt auf das Kupferrohr klebt. Ich habe teilweise bis zu 5 Grad Unterscheid zur Heizungsregelung gehabt. Wärmeleitpaste und schön Festzurren (Kabelbinder) hilft auch ein bischen. Gruss, Pete
Datum:
"Kann man mit einem PC den überhaupt den 1 wire bus auslesen, ohne ein MC dazwischenzuschalten (ist der PC schnell genug)?" Gibt es Digitemp für. Ältere Versionen liefen auch unter Windows. Da wird die serielle Schnittstelle für verwendet. Gruss Axel
Datum:
@Karl Hallo Karl, ich betreibe seit ca. 1 Jahr meine kpl. Haus-Heizungssteuerung via PC. Als Sensorik fungieren 32 DS18B20 (Boden-, Luft-, Vor- und Rücklauftemperaturen). Die Sensoren sind via DS2482-800 und I2C via Parallel-Port angeschlossen. Die komplette Steuerung (nebst kpl. Haussteuerung) ist in C++ geschrieben. Wenn ich Dir diesbezüglich weiterhelfen kann, gern.
Datum:
Hallo EFI Danke für dein Angebot. Ich kenne mich in C++ nicht aus, deshalb wollte ich meine Steuerung mit ProfiLab Expert realisieren. Mit dem Programm kann man Schaltungen erstellen, ohne eine Zeile zu programmieren. In dem Programm ist schon einiges an Hardware eingebunden, aus für den 1 wire bus. Es gibt aber ein Bauteil womit man eine DLL-Datei importieren kann. Diese DLL-Datei kann in C++ geschrieben werden und müste den 1-wire bus bzw die angeschlossenen Sensoren auslesen. Bei der Programmierung der DLL-Datei müssen nur einige Vorgaben eingehalten werden. Wie leicht oder schwer ist es in C++ zu programmieren und wie lange hast du für dein Programm gebraucht gebraucht? Ist deine Steuerung kpl. in C++ und ist sie visualisiert d.h Temperaturanzeigen, Temperaturganglinien, Optischer und Akustischer Alarm, Welche Eingabe möglichkeiten gibt es usw.. Wie Regelst du die Heizung nach Vor oder Rücklauftemperatur, Heizkurve, Zeit, Warmwasseraufbereitung? Also nochmals Danke!!!
Datum:
Hallo Forum! Ich hab mal studienhalber die Bibliotheken getestet und alles funktioniert wunderbar. Da ich jedoch verstehen will wie das alles so tickt (bin AVR-Anfänger) hab ich mein Problem bei der Funkion w1_reset bit w1_reset(void) { bit err; W1_OUT &= ~(1<<W1_PIN); W1_DDR |= 1<<W1_PIN; DELAY( DELAY_US( 480 )); cli(); W1_DDR &= ~(1<<W1_PIN); DELAY( DELAY_US( 66 )); err = W1_IN & (1<<W1_PIN); // no presence detect sei(); DELAY( DELAY_US( 480 - 66 )); if( (W1_IN & (1<<W1_PIN)) == 0 ) // short circuit err = 1; return err; } 1. Problem mit der Zeile err = W1_IN & (1<<W1_PIN); err ist ein bit und kann 0 oder 1 werden W1_IN ist doch der Status des Eingangs doch mit dem & (1<<W1_PIN); komm ich nicht klar Was passiert da? 2. DELAY( DELAY_US( 480 - 66 )); Die DELAY-Funktion bekommt dann als Argument DELAY_US....? vielen Dank schon mal
Datum:
@EFI: Wie weit sind deine Sensoren voneinander entfernt? lg Jan
Datum:
Hallo Peter, ich habe mir deinen 1Wire C-Code heruntergeladen. Zuerst habe ich auf dem AT90S8535 (8Mhz Takt) die Reset Funktion getestet. Wenn ich die Funktion ResetDS1820 ausführe erhalte ich immer den Wert 2. Das verstehe ich nicht. Dies bedeutet doch dass der DS1820 nicht erkannt wurde oder? // Diese Funktion habe ich zuerst erstellt. Ohne dass ich deinen Code // kannte // Bei der Ausführung dieser Funktion erhalte ich "0" char ResetDS1820(void) { presence = 0xFF; DDRD.2=1; // PORTD.2 --> OUTPUT PORTD.2 = 0; // PORTD.2 den Wert 0 ausgeben delay_us(480); // Zeitverzögerung von 500us PORTD.2 = 1; // PORTD.2 den Wert 0 ausgeben delay_us(66); // Zeitverzögerung von 70us DDRD.2=0; // PORTD.2 --> INPUT presence = PIND.2; // Signal mit PIND.2 einlesen und der Variable // presence zuweisen delay_us(480-66); // Zeitverzögerung von 250us DDRD.2=1; // PORTD.2 --> OUTPUT return presence; // Ausgabe von presence }// 0=presence, 1=no part // Diese Funktion habe ich von deiner ZIP Datei übernommen #ifndef W1_PIN #define W1_PIN PORTD.2 #define W1_IN PIND #define W1_OUT PORTD #define W1_DDR DDRD #endif unsigned char w1_reset(void) { unsigned char err; err = 0x00; W1_OUT &= ~(1<<W1_PIN); W1_DDR |= 1<<W1_PIN; delay_us(480); // 480 us W1_DDR &= ~(1<<W1_PIN); delay_us(66); err = W1_IN & (1<<W1_PIN); // no presence detect delay_us(480-66); if( (W1_IN & (1<<W1_PIN)) == 0 ) // short circuit err = 1; return err; } Hier erscheint bei mir immer 2 als Rückgabewert. Ich programmiere mit dem CodeVision AVR
Datum:
Frank Se. wrote: > #define W1_PIN PORTD.2 So gehts nicht. Der Code ist für WINAVR geschrieben und der kennt keine Bitvariablen. Also mußt Du da die Bitnummer (0..7) eintragen. > Hier erscheint bei mir immer 2 als Rückgabewert. Das ist möglich, wenn Du Pin 1 eines Ports benutzt. 0 = o.k. !0 = Fehler Peter
Datum:
Danke Peter für die Unterstützung. Ich habe die Funktion nochmals auf den CodeVision_AVR abgestimmt. An Pin PD2 ist die Datenleitung vom DS1820 angeschlossen. #define W1_PIN PORTD.2 // Ausgang #define W1_IN PIND.2 // Eingang #define W1_OUT PORTD.2 // Ausgang #define W1_DDR DDRD.2 // die Richtung kann hiermit bestimmt werden. unsigned char w1_reset(void) { unsigned char err; err = 0x00; W1_OUT &= ~(W1_PIN); W1_DDR |= W1_PIN; delay_us(480); // 480 us W1_DDR &= ~(W1_PIN); delay_us(66); err = W1_IN & (W1_PIN); // no presence detect delay_us(480-66); if( (W1_IN & (W1_PIN)) == 0 )// short circuit err = 1; return err; } Leider erscheint auf meinem Display eine "1". Dies bedeutet DS1820 wurde nicht erkannt. Warum eigentlich "W1_PIN" und "W1_IN"? Es kann sein das ich bei der Definition noch einen Fehler habe. ich weiss allerdings nicht wo.
Datum:
Ich verstehe es nicht. WIe müsste ich dann die Definitionen unter CodeVision_AVR deklarieren?
Datum:
Also ich denke die Definition ist bei mir falsch. Wie müsste die Definition dann bei mir aussehen? #ifndef W1_PIN #define W1_PIN PD6 #define W1_IN PIND #define W1_OUT PORTD #define W1_DDR DDRD #endif
Datum:
So ich habe mal das ganze ohne define erstellt.
unsigned char w1_reset(void)
{
unsigned char err;
err = 0x00;
PORTD.2=0;
DDRD.2=1;
delay_us(480);
DDRD.2=0;
delay_us(66);
err = PIND.2;
delay_us(480-66);
if( (PIND.2) == 0 )
err = 1;
return err;
}
Wenn ich diese Funktion ausführe, dann erhalte ich auch den Wert "0".
Also funktioniert doch das ganze oder?
Datum:
W1_OUT &= ~(1<<W1_PIN); --> PORTD.2=0; W1_DDR |= 1<<W1_PIN; --> DDRD.2=1; W1_DDR &= ~(1<<W1_PIN); --> DDRD.2=0; W1_IN & (1<<W1_PIN); --> PIND.2 Stimmt meine Interpetation so?
Datum:
Vielen Dank nochmals! Der DS1820 läuft bei mir jetzt. Bin jetzt voll happy. Nur noch eine Sache hätte ich da, ich kann nur ganze Temperaturen darstellen, wie z.B. 21 C°. Was muss ich tun, damit ich z.B. so einen Wert 21.5 C° auslesen kann?
Datum:
Servus Peter, irgendwie bekomm ich dieses 1wire zeug einfach nicht zum laufen. mein hardwaresetup habe ich nun mehrmals aufgebaut. die strippen und widerstaende ausgetauscht. alles ohne erfolg. deine software meldet mir BusError. funktioniert dein code auch mit ds1821? hast du nen vorschlag wie ich den bus debuggen koennte? mfg hansl
Datum:
ok, der ds1821 hat einen andren befehlssatz und funtionen. dennoch, debugginbgtips fuer 1wire?
Datum:
@hansl, wenn mich nicht alles täuscht, hat der DS1821 gar keine Adresse. Die ganzen ROM-Kommandos gehen also nicht. Nach dem Reset macht man sofort die gewünschte Aktion (Messung starten, Wert auslesen usw.). Es gibt da allerdings auch noch nen Temperaturschaltermodus. Wenn er da drin ist, muß man ihn erstmal mit ner speziellen Sequenz zurückschalten. Er kann auch kein parasite Power. Peter
Datum:
danke peter, werd mich jetzt mal ans portieren deines programms machen und hier hoffentlich bald die ds1821 version hochladen. mfg hansl
Datum:
Hi Leutz, bin grad am rumtesten mit dem von P.D. geposteten Code. Mit einem DS1820 Sensor funktioniert alles wunderbar. Nun hab ich hier ausm Forum/Markt DS1822 gekauft. Leider läuft keiner dieser Sensoren an der Schaltung. Laut Datasheets sind die Dinger völlig identisch bis auf die größere Ungenauigkeit des DS1822. Oder hab ich das was übersehen? Gruß - Markus
Datum:
Hansl wrote: > mit der portierung auf DS1821 wirds nun endgueltig nix. hab nun meinen > zweiten sensor verpolt und gegrillt. Gehörst Du etwa auch zu den unbelehrbaren, die ein 5V/100A PC-Netzteil zum Basteln benutzen ? Für MC-Experimente nehme ich ne Wandwarze und nen 78L05 dahinter. Der 78L05 begrenzt auf etwa 100mA, dann wird nichts mehr gegrillt. Peter
Datum:
leider erhalte ich immer den folgenden Fehler:
../TEMPMEAS.C:37: error: invalid conversion from 'unsigned char*' to 'char*' ../TEMPMEAS.C:37: error: initializing argument 1 of 'int sprintf(char*, const char*, ...)' ../TEMPMEAS.C:38: error: invalid conversion from 'unsigned char*' to 'char*' ../TEMPMEAS.C:38: error: initializing argument 1 of 'void uputs(char*)' |
woran kann das liegen?
Datum:
@Andreas, das hat historische Gründe: Früher wurden nur 7Bit Zeichen verwendet und deshalb sind die C-Stringfunktionen vom Typ char, was eigentlich Blödsinn ist, denn es gibt keine negativen Zeichen. Heutzutage ist ASCII 8Bit unsigned (0..255), aber die Funktionen sind scheinbar vorzeichenbehaftet geblieben. Scheinbar deshalb, weil sie die ASCII Zeichen intern als unsigned char behandeln. Es sind also die ASCII-Zeichen von 0..255 erlaubt und gültig. Um nun nicht durcheinander zu kommen, machen Compiler üblicher Weise eine implizite Pointerkonvertierung, wenn der Bassistyp stimmt. Dein Compiler scheint nun weit über das Ziel hinausgeschossen zu sein, indem er das verweigert. Als Workaround bleibt dann nur eine explizite Pointerkonvertierung: sprintf( (char*)s ... Man könnte auch das Array als char definieren, dann könnte aber der Compiler wieder meckern, wenn man ASCII-Zeichen >127 reinschreibt. Peter P.S.: Könnte das ne neue Macke des AVR-GCC 4.1.1 sein ?
Datum:
Wenn "char" mit Vorzeichen ist, dann ist die "char *" zwar kompatibel mit "signed char "*, nicht aber mit "unsigned char *". Alles andere wäre ein Compilerfehler. Die Entscheidung dafür, "char" vorzeichenbehaftet zu verstehen, geht zurück auf Eigenschaften der ersten Implementierung auf einer PDP-11. Und lässt sich mit -funsigned-char beheben. Soweit C, soweit so einfach. Interessanter wird es bei C++. Hier möglicherweise relevant, da ohne ausdrückliche Gegenwehr ein gross geschriebenes ".C" als C++ übersetzt wird. Da man beim Overloading sonst in Teufel's Küche landet, hat man sich nach anfänglichem Durcheinander zu 3 Varianten entschlossen. "char", "signed char" und "unsigned char". Sachlich sind davon zwar 2 gleich, es sind aber dennoch 3 verschiedene Typen.
Datum:
A.K. wrote: > Soweit C, soweit so einfach. Interessanter wird es bei C++. Hier > möglicherweise relevant, da ohne ausdrückliche Gegenwehr ein gross > geschriebenes ".C" als C++ übersetzt wird. Stimmt, daran kanns liegen. Ich schreibe deshalb immer: avr-gcc.exe -xc ... Peter
Datum:
Hallo, ich verstehe in der Datei tempmeas.c folgenden Ausdruck nicht:
sprintf( s, "%4d.%01d", temp >> 4, (temp << 12) / 6553 ); // 0.1 auflösung |
genauer gesagt den Part wo die Kommastelle gebildet wird. Warum wird durch 6553 geteilt? Ich versuche das ganze in 0,5° Schritten darzustellen und komme nicht weiter. Sehe ich das richtig, wenn ich negative Zahlen darstellen möchte, das ich das zwölfte Bit auswerten muss ? Viele Grüße Paul
Datum:
hey Leute ich versuche gerade die 1wire zip zu kompelieren und bekomme da ein paar fehler. kann mir da vieleicht jemand weiter helfen > "make.exe" all -------- begin -------- avr-gcc (GCC) 4.1.2 (WinAVR 20070525) Copyright (C) 2006 Free Software Foundation, Inc. This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Compiling: main.c avr-gcc -c -mmcu=atmega32 -I. -g -Os -funsigned-char -funsigned-bitfields -fpack-struct -fshort-enums -Wall -Wstrict-prototypes -Wa,-adhlns=main.lst -std=gnu99 -Wp,-M,-MP,-MT,main.o,-MF,.dep/main.o.d main.c -o main.o Linking: main.elf avr-gcc -mmcu=atmega32 -I. -g -Os -funsigned-char -funsigned-bitfields -fpack-struct -fshort-enums -Wall -Wstrict-prototypes -Wa,-adhlns=main.o -std=gnu99 -Wp,-M,-MP,-MT,main.o,-MF,.dep/main.elf.d main.o 1WIRE.C DELAY.C TIMEBASE.C TEMPMEAS.C UART.C --output main.elf -Wl,-Map=main.map,--cref -lm cc1plus.exe: warning: command line option "-Wstrict-prototypes" is valid for C/ObjC but not for C++ cc1plus.exe: warning: command line option "-std=gnu99" is valid for C/ObjC but not for C++ cc1plus.exe: warning: command line option "-Wstrict-prototypes" is valid for C/ObjC but not for C++ cc1plus.exe: warning: command line option "-std=gnu99" is valid for C/ObjC but not for C++ cc1plus.exe: warning: command line option "-Wstrict-prototypes" is valid for C/ObjC but not for C++ cc1plus.exe: warning: command line option "-std=gnu99" is valid for C/ObjC but not for C++ cc1plus.exe: warning: command line option "-Wstrict-prototypes" is valid for C/ObjC but not for C++ cc1plus.exe: warning: command line option "-std=gnu99" is valid for C/ObjC but not for C++ TEMPMEAS.C: In function 'void read_meas()': TEMPMEAS.C:37: error: invalid conversion from 'unsigned char*' to 'char*' TEMPMEAS.C:37: error: initializing argument 1 of 'int sprintf(char*, const char*, ...)' TEMPMEAS.C:38: error: invalid conversion from 'unsigned char*' to 'char*' TEMPMEAS.C:38: error: initializing argument 1 of 'void uputs(char*)' TEMPMEAS.C:45: error: invalid conversion from 'unsigned char*' to 'char*' TEMPMEAS.C:45: error: initializing argument 1 of 'int sprintf(char*, const char*, ...)' TEMPMEAS.C:46: error: invalid conversion from 'unsigned char*' to 'char*' TEMPMEAS.C:46: error: initializing argument 1 of 'void uputs(char*)' TEMPMEAS.C:47: error: invalid conversion from 'unsigned char*' to 'char*' TEMPMEAS.C:47: error: initializing argument 1 of 'int sprintf(char*, const char*, ...)' TEMPMEAS.C:48: error: invalid conversion from 'unsigned char*' to 'char*' TEMPMEAS.C:48: error: initializing argument 1 of 'void uputsnl(char*)' cc1plus.exe: warning: command line option "-Wstrict-prototypes" is valid for C/ObjC but not for C++ cc1plus.exe: warning: command line option "-std=gnu99" is valid for C/ObjC but not for C++ make.exe: *** [main.elf] Error 1 > Process Exit Code: 2 > Time Taken: 00:02 wäre echt klasse wenn wir das hin bekommen würden. viel dank Fabio
Datum:
Versuch mal: avr-gcc -xc Peter
Datum:
Sorry das verstehe ich nicht so ganz. Ich bin noch in der lernphase und kenne deswegen noch nicht alle kürzel usw. Vieleicht hilft ja das ich programmiere mit Programmers Notepad 2. mfg Fabio
Datum:
Dein Compiler versucht die Datei(en) nach C++ Standard zu kompilieren. mit dem Compilerparameter -xc erzwingt man (denke ich?) den C Standard. Alternativ kannst du die Dateieendung von ".C" nach ".c" ändern. Daran erkennt der Compiler das nämlich.
Datum:
alles klar klingt logisch sagt ja auch der compiler. Also habe ich die datei endungen von "C" auf "c" geändert. Tut sich aber nichts! gleicher fehler. Kann man das irgendwo einstellen ? mfg Fabio
Datum:
Musst den Namen im Makefile/Projektfile ändern. Wenn im Protokoll .C statt .c drinsteht hast du verloren.
Datum:
Sorry das ich euch nochmal belästigen muss aber ich bin leider nicht so
der crack! der alte Fehler ist behoben aber dafür giebt es einen neuen.
Compiling: TEMPMEAS.c
avr-gcc -c -mmcu=atmega32 -I. -g -Os -funsigned-char
-funsigned-bitfields -fpack-struct -fshort-enums -Wall
-Wstrict-prototypes -Wa,-adhlns=TEMPMEAS.lst -std=gnu99
-Wp,-M,-MP,-MT,TEMPMEAS.o,-MF,.dep/TEMPMEAS.o.d TEMPMEAS.c -o TEMPMEAS.o
TEMPMEAS.c: In function 'read_meas':
TEMPMEAS.c:37: warning: pointer targets in passing argument 1 of
'sprintf' differ in signedness
TEMPMEAS.c:38: warning: pointer targets in passing argument 1 of 'uputs'
differ in signedness
TEMPMEAS.c:45: warning: pointer targets in passing argument 1 of
'sprintf' differ in signedness
TEMPMEAS.c:46: warning: pointer targets in passing argument 1 of 'uputs'
differ in signedness
TEMPMEAS.c:47: warning: pointer targets in passing argument 1 of
'sprintf' differ in signedness
TEMPMEAS.c:48: warning: pointer targets in passing argument 1 of
'uputsnl' differ in signedness
Compiling: UART.c
avr-gcc -c -mmcu=atmega32 -I. -g -Os -funsigned-char
-funsigned-bitfields -fpack-struct -fshort-enums -Wall
-Wstrict-prototypes -Wa,-adhlns=UART.lst -std=gnu99
-Wp,-M,-MP,-MT,UART.o,-MF,.dep/UART.o.d UART.c -o UART.o
UART.c:1: error: expected identifier or '(' before numeric constant
UART.c:19:11: error: invalid suffix "B9" on integer constant
UART.c:21:11: error: invalid suffix "BC" on integer constant
UART.c:23:11: error: invalid suffix "BB8" on integer constant
UART.c:25:6: error: invalid digit "8" in octal constant
UART.c:26:6: error: invalid suffix "a" on integer constant
UART.c:26:11: error: invalid suffix "BD" on integer constant
UART.c:28:6: error: invalid suffix "c" on integer constant
UART.c:29:6: error: exponent has no digits
UART.c:29:11: error: invalid suffix "AB9" on integer constant
UART.c:31:11: error: invalid digit "9" in octal constant
UART.c:44:11: error: invalid suffix "D9B" on integer constant
UART.c:45:11: error: invalid suffix "C0" on integer constant
UART.c:47:11: error: invalid suffix "CB9" on integer constant
UART.c:49:6: error: invalid digit "8" in octal constant
UART.c:49:11: error: invalid digit "9" in octal constant
UART.c:60:6: error: invalid suffix "a" on integer constant
UART.c:61:6: error: invalid suffix "c" on integer constant
UART.c:61:11: error: invalid suffix "C0" on integer constant
UART.c:67:6: error: exponent has no digits
UART.c:67:11: error: invalid suffix "D9B" on integer constant
UART.c:68:11: error: invalid suffix "C0" on integer constant
UART.c:76:11: error: invalid suffix "CB9" on integer constant
UART.c:83:6: error: invalid digit "8" in octal constant
UART.c:84:6: error: invalid suffix "a" on integer constant
UART.c:84:11: error: invalid suffix "F4" on integer constant
UART.c:86:6: error: invalid suffix "c" on integer constant
UART.c:86:11: error: invalid digit "9" in octal constant
UART.c:98:6: error: exponent has no digits
UART.c:104:11: error: invalid suffix "D9B" on integer constant
UART.c:105:11: error: invalid suffix "C0" on integer constant
UART.c:107:11: error: invalid suffix "DE0" on integer constant
UART.c:108:6: error: invalid digit "8" in octal constant
UART.c:108:11: error: invalid suffix "CB9" on integer constant
UART.c:112:6: error: invalid suffix "a" on integer constant
UART.c:112:11: error: invalid digit "9" in octal constant
UART.c:119: error: stray '\' in program
UART.c:119: error: stray '\' in program
UART.c:119: error: stray '\' in program
UART.c:119: error: stray '\' in program
UART.c:119:56: error: invalid suffix "f" on integer constant
UART.c:120: error: stray '\' in program
UART.c:120: error: stray '\' in program
UART.c:120: error: stray '\' in program
UART.c:120: error: stray '\' in program
UART.c:120:56: error: exponent has no digits
UART.c:121: error: stray '\' in program
UART.c:121: error: stray '\' in program
UART.c:121: error: stray '\' in program
UART.c:121: error: stray '\' in program
UART.c:121:56: error: invalid suffix "d" on integer constant
UART.c:122: error: stray '\' in program
UART.c:122: error: stray '\' in program
UART.c:122: error: stray '\' in program
UART.c:122: error: stray '\' in program
UART.c:123: error: stray '\' in program
UART.c:123: error: stray '\' in program
UART.c:123: error: stray '\' in program
UART.c:123: error: stray '\' in program
UART.c:124: error: stray '\' in program
UART.c:124: error: stray '\' in program
UART.c:124: error: stray '\' in program
UART.c:124: error: stray '\' in program
UART.c:125: error: stray '\' in program
UART.c:125: error: stray '\' in program
UART.c:125: error: stray '\' in program
UART.c:125: error: stray '\' in program
UART.c:126: error: stray '\' in program
UART.c:126: error: stray '\' in program
UART.c:126: error: stray '\' in program
UART.c:126: error: stray '\' in program
UART.c:126:56: error: invalid suffix "a" on integer constant
UART.c:127: error: stray '\' in program
UART.c:127: error: stray '\' in program
UART.c:127: error: stray '\' in program
UART.c:127: error: stray '\' in program
UART.c:127:56: error: exponent has no digits
make.exe: *** [UART.o] Error 1
> Process Exit Code: 2
> Time Taken: 00:01
was könnte das sein ?
Datum:
Un Anbetracht der Tatsache, dass uart.c nur 33 Zeilen hat, möchte ich mal die These aufstellen, dass du dieses File mittlerweile durch etwas anderes ersetzt hast. Und die Fehlermeldungen in tempeas sind m.E. recht selbsterklärend.
Datum:
Moin Moin, so hat funktioniert! ich kann alles kompalieren. Ist aber irgendwie komisch da ich mich nicht errinern kann in der Datei groß was geändert zu haben aber naja egal. Aber 1ne hab ich noch. Ich denke mal das die Funktionen Start_meas für das starten der messung ist und Read_meas für das auslesen der Temperatur. Ich will die Temperatur auf mein LCD anzeigen lassen und frage mich nun in welcher Variablen der Wert drin steht! vieleicht kann mir da ja nochmal jemand helfen. Ach und 1 wollte ich nochmal los werden. VIELEN VIELEN DANK AN ALLE DIE SICH MEINE TEXTE DURCHLESEN UND MIR SO WEITERHELFEN! mfg Fabio
Datum:
hi Leute sagt mal in welcher Variablen ist der Temperatur wert gespeichert ? mfg Fabio
Datum:
Fabio wrote: > hi Leute sagt mal in welcher Variablen ist der Temperatur wert > gespeichert ? mfg Fabio Nirgends. Er wird vom Sensor ausgelesen und per sprintf ausgegeben (erst in hex, dann dezimal). Peter
Datum:
ok danke kannst du mir vieleicht die datei nennen und die zeile in der das geschieht? vielen dank
Datum:
moin leute, also wenn ich das richtig sehe dann wird der temperaturwert mit sprintf( s, "%4d.%01døC", temp >> 4, (temp << 12) / 6553 ); // 0.1øC; dieser zeile in der Tempeas.c ausgelesen oder ? Temperatur = sprintf( s, "%4d.%01døC", temp >> 4, (temp << 12) / 6553 ); // 0.1øC; dann müste doch der Temperatur wert in der Variablen gespeichert werden oder ? danke
Datum:
hey leute, wie bekomme mann das hin das der Temparaturwert in eine Variable geschrieben wird? bitte helft mir. mfg Fabio
Datum:
hast du dir die syntax von sprintf schonmal angeschaut? ansonsten, der wert steht schon in der variablen temp...
Datum:
steht er da dezimal drin ? ich habe zu dem befehl irgendwie keine gute referenz gefunden. nur für php aber ich denke mal das der da vieleicht ein bischen anders ist. vielen dank fabio
Datum:
Hallo, danke erstmal für die Lib. Allerdings bekomme ich hier an einem Mega8 auf dem STK500 (mit 3,86MHz Osz) immer "nur" ein Bus-Error. Ich habe den DQ Pin mit PD6 und per 4,7KOhm mit +5V verbunden. Den VDD und GND Pin habe ich auf GND gelegt. Wenn ich z.B. den Sensor mit +5V auf VDD Speise dann bekommme ich keinen Bus-Error, dann findet er gar keinen Sensor oder gibt "Short Circuit" aus! Was kann ich (noch) tun?
Datum:
Hi, mich würde das auch mal interessieren in welcher Form der Wert in der VAriable temp abgespeichert ist....
Datum:
Angehängte Dateien:SD1 IN SD2 IN SD3 GND SD4 +3.3V SD5 IN SD6 GND SD7 OUT SD8 D1 SD9 D2 PKN (OFF) START(ON)
Datum:
Hallo, ich versuche gerade das Programm auf einen ATMEGA32 mit einem internen Takt von 1 MHz laufen zu lassen. Jedoch erhalte ich immer einen Bus Fehler... Was ich nicht blicke ist, das wenn ich die CPU auf 8 MHz am kaufen habe klappts. Wenn ich aber die Fuse Bitas auf 1 MHz unstelle und in der main.h die Frequenz anpasse klappts es nicht mehr... Der Buss Fehler resultiert aus einem Fehler bei der Verarbeitung der Funktion w1_bit_io , ich vermute mal das es am Timing liegt, jedoch steige ich da nicht so ganz durch ;-( Kann mir hier vielleicht jemand helfen? Gruss
Datum:
Christian wrote: > Der Buss Fehler resultiert aus einem Fehler bei der Verarbeitung der > Funktion w1_bit_io , ich vermute mal das es am Timing liegt, jedoch > steige ich da nicht so ganz durch ;-( Ja, kann sein, daß bei 1MHz das Timing zu knapp wird, d.h. die Zykluszeit der CPU dominiert. Warum willst Du nicht 4MHz oder 8MHz nehmen ? Peter
Datum:
Es ging ums RS232, habe jetzt aber ein 8MHz Quarz genommen und dadurch lief auch die RS232 stabil ;-) Kann mir mal jemand erklären wie ich den Messwert ordentlich in ein Char konvertiert bekomme? Ich möchte den via Funk übertragen und da habert es noch am Format und ich bin icht gerade der Programmier Held ;-)
Datum:
Also ich habe den "SEARCH ROM" mechanismus noch nicht richtig verstanden. Nach dem "Flowchart 2" müsste ich beliebig viele Devices finden können. Das will ich auch aber ich versteh den eine Stelle einfach nicht! Und zwar handelt es sich um: "Set search_direction bit to id_bit_number bit in ROM_NO" ATmega8 6Mhz DS18s20 link: http://www.maxim-ic.com/appnotes.cfm/appnote_number/187
Datum:
Ich habe da eine Frage zu der Globalen Variable Second... Alle fünf Sekunden wird ja ein Messwert via UART übertragen. Ich würde aber gerne nur alle 20 Sekunden durchführen. Dazu würde es doch genügen in main.c folgenden Code einzufügen/zu ändern:
for(;;) { if( second == 3 ) { start_meas(); second = 4; } if( second == 6 ) { read_meas(); //second = 0; } if ( second == 20) { second=0; } } |
Leider klappt das nicht. Er wartet zwar, aber überträgt mir dann 32 Messwerte statt nur einen ??!!?? Woran kann das liegen? Bzw. ist meine Überlegung mit der Varibale so richtig? Viele Grüße
Datum:
Ich habe herrausgefunden das er in der zweiten ebene read_meas hängen bleibt und diese mehrmals durchläuft -nur warum?-
Datum:
ok ;-) habs selbst gefunden... Ich muss im Fall second=6 nach erfolgreicher Durchführung um eins hochzählen ;-))
Datum:
Kleine Korrektur an Peters Code: Am Ende der w1_bit_io Routine sollte nach der Deaktivierung des Ausgangs eine Verzögerung von einigen µs eingebaut werden. Laut 1-Wire Doku reicht es zwar aus, wenn das Signal für 1µs high ist, was sich bei langsamen Prozessoren von selbst ergibt, aber das kann je nach Leitungslänge und sich daraus ergebender kapazitiver Last zu wenig sein, weil der übliche Pullup-Widerstand die Leitung in der Zeit nicht schnell genug hochgezogen bekommt. Vor allem wenn man es auch noch mit einer schnellen CPU zu tun hat. Also lieber 10µs dort einplanen, bei langen Leitungen darf es auch deutlich mehr sein.
Datum:
> Also lieber 10µs dort einplanen, bei langen Leitungen darf es auch > deutlich mehr sein. Naja, wenn mehr als 10µs nötig, dann scheitert das woanders, da muss der Widerstand kleiner werden. Aber 10µs erscheinen mir schon sinnvoll.
Datum:
Hello my friends :) ;)
Datum:
Hallo, ein sehr Interessanter Thread, der aber leider einige gestellte Fragen unbeantwortet lässt (ok bei manchen is das verständlich ;) ), aber manche sind dabei die gerade mich momentan auch interessieren. So zum Beispiel: "Ich habe den DQ Pin mit PD'x' und per 4,7KOhm mit +5V verbunden. Den VDD und GND Pin habe ich auf GND gelegt." soweit ok... aber: "Wenn ich z.B. den Sensor mit +5V auf VDD Speise dann bekommme ich keinen Bus-Error, dann findet er gar keinen Sensor oder gibt "Short Circuit" aus! Was kann ich (noch) tun?" So auch meine Frage! Vielen Dank im voraus!
Datum:
Ricardo wrote: > Was kann ich (noch) tun?" Nicht so zugeknöpft sein, das hier ist kein Hellseherzirkel. Welcher Code, AVR, Takt, Schaltung? Vielleicht VDD mit GND vertauscht (Datenblattansicht ist von unten!). Peter
Datum:
Sorry, wenn das blöd rüber kam! Die gestellte Frage war ein Zitat von "Manuel B." un interessierte mich eben auch. Wurde aber eben leider nicht beantwortet damals. Bei mir handelt es sich um einen ATmega8 mit 8MHz. Ich verwende im moment den Code von Dir Peter zum Testen im AVR Studio mit GCC Compiler. Mittlerweile hab ich nach langer suche doch noch einen ausschlaggebenden Hinweis bekommen im Forum. Geholfen hat letztendlich der zusätzliche Compilereintrag "-xc" um alles C-konform und nicht C++-konform zu kompilieren. Jetzt funktioniert es auch. Vorher hatte ich einfach versucht den Code so "hinzubiegen" in eines meiner Programme, was aber fehl schlug. Btw vielen Dank für die Unterstützung in der 1-Wire Angelegenheit! Komm jetz erstmal klar soweit! .. bis zum nächsten Prob ;)
Datum:
Hallo zusammen, ich muss (leider) nochmals auf meinen Post vom 09.08.2007 zurück kommen nachdem das Projekt nun fast ein Jahr geschlafen hat. Ich bekomme weiterhin einen "Bus Error". Verwendet habe ich den Original Quellcode von Peter, compiliert mit AVR Studio. Der BUS ERROR tritt auf, sobald ich den Pull-Up Widerstand vom PD6 auf VCC anklemme. Evtl. kann der Sensor das Signal nicht gegen GND ziehen? Evtl defekt?
Datum:
@Peter Dannegger ich wollte deine biblios für meinem Tempsensor nehmen, dazu hätte ich ein paar Fragen. Erstmal allgemein, kannst du mir sagen was das an Vorteile bringt ein Programm in soviele unterprogramme, header und c files zu zerlegen? Ich habe bisher immer nur im main programm und vllt mal 1,2 datein eingebunden.... und nun zu meinem hauptproblem was binde ich denn bei dir wo ein, oder einfach main file compilieren? Zur info: Takt: 16 Mhz AVR Atmega16 Danke marco
Datum:
Hallo zusammen, ich hab auch ein komisches Problem mit meinen DS18S20 Sensoren. Nutze einen Atmega32 mit dem auf dem STK500 befindlichen Oszillator bei 3,68 MHZ (UART Timing funktioniert) Code natürlich angepasst: #define F_CPU 3686400 #define XTAL 3686400 Habe Pin1 (GND) und Pin3 ( Vdd ) gebrückt und zusammen an GND angeschlossen. Pin2 geht an PC6 und via 4,7kOhm an VTG (+5V) Code hab ich natürlich entsprechend angepasst: #ifndef W1_PIN #define W1_PIN PC6 #define W1_IN PINC #define W1_OUT PORTC #define W1_DDR DDRC #endif FEHLERBILD: Wenn alles angeschlossen ist, bekomme ich ein "Bus Error". Ziehe in den Sensor aus meinem Experimentierboard raus, bekomme ich ein "No Sensor Found" Entferne ich das kabel zum PC6 bekomme ich ein "Short Circuit. No Sensor Found" Habe auch schon den code von http://www.siwawi.arubi.uni-kl.de/avr_projects/tem... probiert. Selbes Problem/Selbe Fehlermeldungen :-( Weis einer was ich noch versuchen kann? Bin AVR Anfänger, also ist es sicher irgend eine kleinigkeit. Grüße, Frank
Datum:
@Frank, die 15µs könnten etwas zu lang sein:
DELAY( DELAY_US( 15 - 1 )); |
Versuch mal statt der 15 Werte von 5..10. Peter
Datum:
Hi Peter, klappt leider nicht :( verzweifel
Datum:
Habe das Prg mit dem Pollin Board getestet. Funktioniert mit DS18S20. Sensor tauschen? Gruß Kurt
Datum:
@Frank, Schreib besser: #define XTAL 3686400L Versuch mal nen schnelleren Quarz, z.B. 11.0592MHz Peter
Datum:
Hi Peter, dank dir :-) das wars! Hab jetzt erstmal den internen Oszi mit 8 MHZ am laufen... und es funzt ;) Lag also an den 3,68mhz die wohl zu langsam waren ( komischerweise ) Naja jetzt läufts. Danke nochmal! Grüße, Frank
Datum:
Angehängte Dateien:Hallo Peter Hallo Zusammen ich verwende das Olimex P28 Board (siehe Datei) und das Program lässt sich einwandfrei compilieren und rennt auf meinem ATMega8 mit 8Mhz. Wenn kein Sensor angeschlossen ist, kommt die entsprechende Meldung. Leider bekomme ich die Meldung "Buss Error", wenn ich einen anschliesse. Es ist ein DS18S20 - sollte also Funktionieren. Da ich ein Rookie in Sache MC bin, bin ich sicher, dass ich den Wiederstand falsch angeschlossen habe. Kannst Du mir bitte - gerne auch per Hand oder screenshot, PPT oder sonstwie die Schaltung so ergänzen, dass ein DS18S20 an PC1 dran ist? Ich möchte damit meinen Aufbau Zuhause kontrollieren. Vielen Dank - und Asche auf mein Haupt... Gruss, Axel
Datum:
athobaben wrote: > Kannst Du mir bitte - gerne auch per Hand oder screenshot, PPT oder > sonstwie die Schaltung so ergänzen, dass ein DS18S20 an PC1 dran ist? So, wie im Datenblatt, GND an 0V, VCC an 5V und den Datenpin an den IO. und nen Pullup (2,2k) gegen 5V. Peter
Datum:
Hallo Peter mit GND des Sensors an 0V und DG mit 4,7k Pullup gegen den Datenpin funktioniert meine Schaltung. ID: 10 60 4F 4E 01 08 00 96 T: 0188 = 24.5?C Ich habe auch kapiert, wie die Fuse mit dem Takt und der Baudrate zusammenspielen. Soweit so gut... Leider habe ich noch 2 ungereimtheiten. 1) wenn ich VCC an 5V lege bekomme ich einen Bus-Error - da Du irgendwo im Source etwas von Parasite Power schreibst, habe ich den Pin weggelassen. Wenn meine Schaltung und das Mess-Objekt Mass-Kontakt haben ist alles i.O und ich kann wunderbar messen. Ist das richtig? 2) Wenn ich nun 2 DS18S20 an den Anschluss klemme (GND1 und GND2 an OV und DG1 mit DG2 an den selben Datenpin mit dem selben 4,7k Pullup) kommt leider wieder ein Bus-Error. Kannst Du mir den Neben lichten und mir ggf. den Thread nennen, in dem Du das bestimmt schon zig mal erklärt hast? Es sind sehr viele und z.T. sehr lange Threads... . Ich würde gerne mehr als einen Sensor auswerten. Danke für den Code und die bisher geleistete Hilfe. Gruss, Axel
Datum:
Der Bus-Error kann daran liegen,. daß die 15µs in "w1_bit_io" vielleicht etwas zu lang sind. Schreib da mal 5 oder 10 rein. Die älteren Sensoren hatten wohl ein langsameres Timing. Peter
Datum:
Hallo Peter ich habe
DELAY( DELAY_US( 15 - 1 )); |
in "w1_bit_io" von 2 bis 15 in 1-Schritten durchgetestet. Leider immer noch Buss-Error, wenn ich mehr als einen DS1820 dranhänge. Weiter oben gibst Du den Rat einen schnelleren Quarz zu nehmen - ATMega8 und 8Mhz - sollten doch aber funktionieren wenn ich oben das so lese... . Für prasitäre Spannungsversorgung muss doch GND und VDD vom Sensor zusammen auf 0V und der DQ mit 4,7k Pullup auf den IO Pin. Wenn ich das machen komme ich immer Bus-Error, wenn ich VDD offen lasse geht es wenigstens mit einem Sensor. Idee? Danke und GRuss, Axel
Datum:
Nur weil ich gerade (mal wieder) ein Bild gesehen habe auf dem ein User den Vcc Pin bei Parasite Power offen gelassen hat (und sich wundert warum sein DS18x20 nicht funktioniert). Wer sich das Datenblatt durchliest erfährt: "Den soll man auf GND legen!"
Datum:
AThobaben wrote: > in "w1_bit_io" von 2 bis 15 in 1-Schritten durchgetestet. Leider immer > noch Buss-Error, wenn ich mehr als einen DS1820 dranhänge. Benutzt Du die Optimierung -Os ? Stimmt denn Dein Takt wirklich mit der Definition von XTAL überein? Hast Du noch andere Interupts im Programm? Poste mal Dein komplettes Programm mit dem erzeugten Assemblerlisting. Peter
Datum:
Hallo Peter, Hallo Werner @Werner: Das komische ist ja, wenn ich VCC auf GND lege - bekomme ich den Bus-Error, wenn er offen bleibt funktioniert ein DS18S20 aber eben nur einer. @Peter: Sorry das es länger gedauert hat. Kann Sein, dass die Optimierung wirklich auf -Os steht. Ich setze die mal auf -O1 oder -O3 und teste das. Nein - meines Wissens habe ich keine anderen Dinge drin ausser die, die Du in Deinem ersten Thread gaaaanz oben geposted hast. Ich kann aber gerne ein ZIP posten mit allem, was drinnen ist... XTAL steht auf 800000 (8Mhz) sollte das auf 800000L stehen? Gruss und Danke, Axel
Datum:
Axel Thobaben wrote:
> XTAL steht auf 800000 (8Mhz) sollte das auf 800000L stehen?
weder noch, 8MHz entspricht 8000000L.
Peter
Datum:
Hallo Petter, mit schnelleren Takt funktioniert alles wunderbar aber nicht mit 1 MHz. Gibts da neue Lösungen oder Ansätze? thx PS benutze 18s20
Datum:
Hallo Peter, ich hab mir mal deinen 1 wire Code heruntergeladen und hab jetzt folgende Probleme mit AVR Studio 4: AVR Studio melde mir folgende Fehler: ../main.h:11:16: error: io.h: No such file or directory ../main.h:12:23: error: interrupt.h: No such file or directory ../main.h:15:20: error: signal.h: No such file or directory wenn ich jetz die dateien aus AVR lade mit #include <avr/io.h> #include <avr/interrupt.h> meckert AVR Studio ../TEMPMEAS.C:37: error: 'sprintf' was not declared in this scope ../TEMPMEAS.C:48: error: initializing argument 1 of 'void uputsnl(char*)' usw. kannst du mir sagen wo ich den Fehler suchen muss By Wolfgang
Datum:
Angehängte Dateien:Hallo Wolfgang Lies mal den ganzen Thread durch. Wenn ein C-Programm mit einem GROSSEN .C endet, bedeutet das für aktuelle C-Compiler, dass dies ein C++ Programm ist. Du hast wohl den Code von Peter genommen, und nicht alle Files auf Kleinbuchstaben geändert. Aendere alle Filenamen auf Kleinbuchtstaben, und es sollte gehen. Hab das Ganze mal für den GCC 4.3.0 angepasst. Bei mir kommen so keine Fehlermeldungen mehr. Ob es läuft weiss ich nicht, da ich keinen ATmega8 habe und ich auch noch nicht weiss, ob der GCC 4.3.0, welcher bei meinem aktuellen Ubuntu Linux 8.10 dabei ist, fehlerfrei ist. Daniel
Datum:
Danke für den Tipp c ist halt leider nicht Pascal By Wolfgang
Datum:
Hi, ich habe versucht die hier angegebenen Files zu verwenden. Und zwar für einen ATmega16 im AVR-Studio mit avrgcc. Beim kompilieren bekomm ich folgende Fehler: ../../../../../WinAVR-20080610/avr/include/TEMPMEAS.C:37: error: invalid conversion from 'unsigned char*' to 'char*' ../../../../../WinAVR-20080610/avr/include/TEMPMEAS.C:37: error: initializing argument 1 of 'int sprintf(char*, const char*, ...)' Der dazu passende Code-Ausschnitt: sprintf( s, "%02X ", id[i] ); Diese Fehler bekomm ich bei jeder sprintf(). Kenn mich selber aber nicht so gut aus. Kann mir jemand sagen wo das Problem liegt und wie ich es beheben kann. grüße Johannes
Datum:
Johannes wrote: > ../../../../../WinAVR-20080610/avr/include/TEMPMEAS.C:37: error: invalid > conversion from 'unsigned char*' to 'char*' Kann ich mir nur so erklären, daß Du in Deinem Make nen Schalter hast: wandle Warnings in Errors um. Die AVR-GCC-ler haben so nen Spleen, daß es negative Buchstaben gibt, daher müssen die vom Typ char sein, kein anderer 8-bit Typ wird geduldet. Ist ähnlich nervig, wie die überflüssigen Klammer-Warnings. > sprintf( s, "%02X ", id[i] ); Mach nen cast
> sprintf( (char*)s, "%02X ", id[i] ); |
Peter
Datum:
Danke Peter! Funktioniert nun einwandfrei, vielen dank für die Hilfe. Übrigens echt tolle software!
Datum:
hallo, ich würde auch gerne die 1wire ds1820 auslesen, nur möchte ich die temperaturen auf einem lcd angezeigt bekommen die routinwn für den lcd sind mir bereits bekannt, nur ist mir nicjht wirklich klar, welche funktion oder variable ich auf dem lcd ausgeben muss?? kann mir da jm helfen oder hat soetwas schon jm mal gemacht?? mfg
Datum:
Hallo, Ich hätte da mal ne Frage. Wenn ich nun einen Systemtakt benutzte der nicht durch 256 teilbar ist, dann wird ja nach jeweils 256 Overflows der Rest aus der Divison von Systemtakt durch 256 zum Comparewert hinzugefügt. Nun stellt sich mir die Frage: Wird dann nicht jedesmal der Abstand zu einer Sekunde größer, weil es ja dann von einer zu nächsten sekunde immer länger dauert bis Prescaler 256 erreicht oder mach ich da einen Denkfehler?
SIGNAL (SIG_OUTPUT_COMPARE1A)
{
uchar tcnt1h = TCNT1H;
OCR1A += XTAL / DEBOUNCE; // new compare value
if( ++prescaler == (uchar)DEBOUNCE ){
prescaler = 0;
second++; // exact one second over
#if XTAL % DEBOUNCE // handle remainder
OCR1A += XTAL % DEBOUNCE; // compare once per second
#endif
}
TCNT1H = tcnt1h; // restore for delay() !
}
|
Ich hoffe es ist verständlich was ich meine. MFG Daniel L.
Datum:
Kann jemand mir vielleicht helfen,ein funktionierende C-Code für DS18S20,die auf Infineon XC164CM (mit Keil MicroVision3) zu erzeugen?Oder ein paar Tipps und Links,wo ich die C-Code finden kann? Gruss Aaron
Datum:
Moin, versuche gerade dem Code auf nem atmega32 zum laufen zu bringen. Benutze AVR Studio mit GCC Compiler... nachdem ich das "GROßSCHREIBEPROBLEM" oben schon gefunden habe taucht bei mir was Neues auf: H:\1 Wire\default/../Main.c:13: undefined reference to `init_timer' H:\1 Wire\default/../Main.c:14: undefined reference to `uinit' H:\1 Wire\default/../Main.c:16: undefined reference to `uputsnl' H:\1 Wire\default/../Main.c:17: undefined reference to `second' H:\1 Wire\default/../Main.c:20: undefined reference to `second' H:\1 Wire\default/../Main.c:21: undefined reference to `start_meas' H:\1 Wire\default/../Main.c:22: undefined reference to `second' H:\1 Wire\default/../Main.c:24: undefined reference to `second' H:\1 Wire\default/../Main.c:25: undefined reference to `read_meas' H:\1 Wire\default/../Main.c:26: undefined reference to `second' Verstehe nicht warum der die nicht kennt! z.B. wird `init_timer' doch aus "timebase.h" in "main.h" includiert! Kann mir mal jemand nen Tip geben was ich hier falsch mache?!? Danke.
Datum:
Angehängte Dateien:Hallo Proteus, ich kenne zwar deinen Code nicht bei mir funkts aber mit atmega 32 problemlos sende dir mal meinen bisherigen code beinhaltet Temperaturauswertung DS18B20 und noch etwas mehr vielleicht hilft es dir by Wolfgang
Datum:
Hast du evtl. ein Leerzeichenproblem?
> H:\1 Wire\default/../Main.c:26: undefined reference to ...
---
Datum:
Wow, danke für die viele schnelle Hilfe! @ Werner B. War ne gut Idee, hat abe auch nicht geholfen, werde trotzdem in Zukunft mit sowas aufpassen! @ Wolfgang Prima, dein Code läss sich Fehlerfrei bei mir compilieren! Auch der 1wire Part! Damit komme ich auf jeden Fall schon mal weiter! Gruss Proteus
Datum:
Hallo! Lt. anderem Beitrag konnte ich jetzt kompilieren. Soweit so gut. einen Sensor habe ich bisher nicht angeschlossen. Hyperteminal zeigt mir keinerlei (vom Mega32 gesendete Zeichen) Oszilloskop bestätigt, das der tx-Pin schön auf high bleibt. Sendet die SW nur, wenn ein Sensor vorhanden ist? Oder wann genau wird was gesendet? Danke im Voraus!
Datum:
Timo P. schrieb: > Sendet die SW nur, wenn ein Sensor vorhanden ist? > Oder wann genau wird was gesendet? Schau in den Code und analysiere ihn. So schwer ist das nicht. Fremden Code einfach so zu übernehmen, ohne zu wissen was man da tut und ohne ein gewisses Grundlagenwissen in der verwendeten Programmiersprache zu haben funktioniert nun mal nicht.
Datum:
habe es jetzt gesehen im code. short circuit und no sensor found kommt beides
Datum:
Den code anzupassen ist nicht das Ding! trotzdem ist es oft hilfreich, einer zipdatei eine readme beizufügen, wo in ein paar sätzen kurz und knapp der programmablauf beschrieben ist. Dies spart zeit und macht den code( wenn er wie hier) für andere offengelegt wird viel attraktiver. Bitte nicht als negative Kritik aufnehmen. C-Code ist mir wohl ein Begriff, also das Verständnis ist nicht das problem, auch wenn es vorhin mit den includes vllt so schien. z.B habe ich statt <headerfile> "headerfile" ausprobiert. soweit ich weiß, sucht der compiler die headers via <> im compilerverzeichnis und via "" im aktuellen source-verzeichnis. anmerkung: ich finde es toll, das es Leute gibt, die hier ihren Code veröffentlichen, und sich auch noch den Problemen der Leute annehmen. Besten Dank für den Code an PEDA!
Datum:
hallo! Hat jemand einen sinnvollen tip in Bezug auf Eigenerwärmung? Bisher betreibe ich einen DS18S20 mit externer Versorgung. Derzeit 5V. 1) Bald habe ich eine Schaltung, die mit 3v3 läuft.(müsste doch eigentlich die Eeigenerwärmung reduzieren??) 2) Den Sensor werde ich dann in Zeitintervallen bestromen(vielmehr die SensorEN) sollte auch was bringen. noch eine Frage: 3) Hat jemand eine Berechnung für negative Temperaturwerte realisiert?
Datum:
im Datenblatt steht was von: Highbyte ist entweder 0xFF oder 0x00. bei Highbyte = 0xFF hat man ne negative Zahl die Werte für low und highbyte kombiniert sind bei mir aber z.B 44 für +22.5°C anstatt: mindestens 65280 also: 1111 1111 xxxx xxxx
temp =1_byte_rd(); // low byte temp |= (uint)w1_byte_rd() << 8; // high byte sprintf(s,"Hier temp als dezimalzahl : %d \r\n", temp); uputs(s ); |
Datum:
>Bald habe ich eine Schaltung, die mit 3v3 läuft.(müsste doch >eigentlich die Eeigenerwärmung reduzieren??) Bei +-0.5°C Fehlergrenze würde ich mir keine Gedanken darüber machen MfG
Datum:
Hallo Leute, ALso momentan basstel ich gerade mit 1-Wire rum und komme net wirklich weiter. Ich benutze das myAVR Workpad weil ich mit dem Studio nicht wirklich klar komme. Irgendwie bekomme das Programm nicht richtig übersetzt, das ich es sauber in das Workpad bekomme, hatt einer von euch damit schon gearbeitet und weis rat. Bzw. Hatt das programm schon in dem Format. Ich benutze die Aktuelle WinAVR. Es reicht mir ja schon das ich nur einen Sensor auslesen kann. Hardware: myAVR MKII Board --> ATmega8 --> 3,68400 MHz Bitte um Hilfe Danke
Datum:
@p1ng: Hast du deine Schaltung ans Laufen bekommen? Wenn ja, wie hast du Timing-Probleme in den Griff bekommen? Bin der Meinung, dass der gewählte Quarztakt zu niedrig ist wenn du Pedas SW nutzt.
Datum:
Hallo Peter, erstmal, ein schönes neues Jahr 2010 wünsche ich Dir und schöne Weihnachten. Ich habe den Code 1Wire übersetzt und den Stk500 an den PC angeschlossen. Aber ich bekomme keine Ausgabe der Temperaturen über RS232. Was mach ich falsch??? Ich habe Atmega8515 und DS1820. Viele Grüsse hakan
Datum:
Da der Code nachweislich funktioniert, jedenfalls bei nicht zu langem Kabel oder bei längerem Kabel und langsam getaktetem Controller, kann es nicht an Peters Code liegen. Folglich hast du was falsch gemacht. Mehr lässt sich aufgrund der überbordenden Detailfülle deines Beitrags kaum sagen. Es könnte beispielsweise helfen, wenn du mitteilst wie du den angeschlossen hast. Und wie die entsprechenden Anpassungen im Code bei dir aussehen. Ganz ohne geht's ja nicht.
Datum:
Hallo, kann mir jemand erklären, wozu der Search Rom Algorithmus in der Praxis gut sein soll ? Man kann damit zwar die Rom-IDs aller Bausteine ermitteln, aber: wenn ich z.B. 10 DS1820 im System habe, bekomme ich 10 IDs, weiß aber trotzdem nicht, welche ID zu welchem Sensor gehört, kann also keine sinnvolle Zuordnung des Sensors zu einem bestimmten Meßpunkt machen. Vielen Dank Harald
Datum:
Wenn man sie nacheinander dranhängt ist das überhaupt kein Problem. In manchen Anwendungen kann man die Sensoren auch über den Wert unterscheiden, d.h. man zeigt in der Systemkonfiguration alle gefundenen Sensoren mitsamt Wert an und überlässt dem Anwender die Zuordnung zu beispielsweise Aussen/Innen/Wassertemperatur.
Datum:
Hallo A.K, bei zwei, drei Sensoren ist das sicherlich kein Problem. Was aber wenn man 10 und mehr Sensoren einsetzt, die in einer Anlage Temperaturen messen, die im gleichen Bereich liegen z.B. 20 - 80 Grad und dann immer nur um 10 - 20 Grad differieren ? Dann kommst Du so aber nicht weiter. Harald
Datum:
(1) Man die steckbar und schliesst sie nacheinander an. (2) Man hat ein Prüfgerät, das vor Einbau der Sensoren die ID anzeigt.
Datum:
So hatte ich mir das auch gedacht. Ich war nur etwas verwundert über den doch recht "aufwendigen" ROM search algorithmus und was der dann in der Praxis bringen sollte. Vielen Dank und noch schöne Festtage Harald
Datum:
Hi, ich hatte vergessen den kompilierten Code in den Atmega8515 zu brennen. Jetzt klappt es. Nur ich bekomme irgendwie falsche werte. Habe schon mit verschiedenen Baudraten versucht. Kann es daran liegen, dass ich DS1820 verwende und nicht den DS18B20? Oder vielleicht die Schaltung nicht richtig? da ich GND und VCC des PORTD von Stk500 benutze. Viele Grüsse viel spaaass hakan
Datum:
Angehängte Dateien:Hallo, ich habe das Programm so geändert, dass es mir den Temperaturwert auf einem LCD darstellt. (Atmega8 auf Pollin Evu-Board, DS1820, 2x16 LCD. AVR-Studio 4.15, WinAVR.) Ich würde aber gerne 2 Temperaturwerte auf dem Display darstellen. Schließe ich 2 Sensoren an den Bus an wird nur die ID und die Temperatur eines Sensors angezeigt. Meine Überlegeung bisher war folgende: In der tempmeas.c geht der ja in die for-schleife und sucht die Sensoren und gibt dann die ID und Temperatur nacheinander für beide Sensoren aus. Beim UART bestimmt kein Problem aber für die Darstellung auf dem LCD unbrauchbar. Soll ich in der main.c 2 Messungen aufrufen? Wie ist es mir möglich einen Sensor gezielt abzufragen? über die ID? Wahrscheinlich ist diese Herangehensweise total falsch. Habt ihr Ideen wie ich mein kleines Projekt am Besten umsetzen kann? Anbei der Code im zip-file.
Datum:
Angehängte Dateien:DS18x20 mit Namen versehen Die DS1820 haben doch zwei Byte Ram, in die man selbst was reinschreiben kann, z.B. einen Namen aus zwei Buchstaben; die ID braucht man dann gar nicht zu kennen. Ich habe die erforderlichen Änderungen in die Datei „TEMPMEAS.c“ aus clouds Post vom 08.01.2010 eingepflegt, konnte aber nur bis zur fehlerfreien Compilierung testen, da ich keine passende Hardware habe (mein LCD ist mittels I2C angeschlossen). Die ursprüngliche Version, die ich auch vor ca. zwei Jahren als Ausgangspunkt genommen habe, stammt wohl von Peter Dannegger (vielen Dank dafür; seine Programme waren mir schon an vielen Stellen eine große Hilfe und eine gute Lehre). Meine aktuelle Version ist mittlerweile zu sehr auf meine eigenen Bedürfnisse zugeschnitten und wäre so für viele nicht brauchbar, so dass ich diesen Weg vorgezogen habe. Die Ausgabe-Funktionen gehören eigentlich nach main.c, aber ich habe es vorgezogen, nur eine Datei zu verändern. Wenn man es so lässt, müssen in main.c die Zeilen, die für die LCD-Ausgabe zuständig sind, noch entfernt werden. Die Funktionsweise ist folgende (weiter Kommentare im Quelltext): In einer Überschrift (die dann in meinem Projekt zusammen mit den Messdaten über SD-Karte oder UART schließlich auf dem PC landen und mit Excel weiter verarbeitet werden) stehen die Namen, die die Sensoren erhalten sollen. In der Lese-Funktion wird zusätzlich zu ID und Temperatur noch der zwei-buchstabige Name ausgelesen. Dann wird geprüft, ob dieser Name in der Überschrift existiert. Wenn ja, ist damit auch bekannt, an welche Stelle im Array mit den Temperaturen der Wert eingetragen werden muss. Zusätzlich wird in einem BitArray (valid) vermerkt, welcher Name schon gefunden wurde. Wenn der Name nicht in der Überschrift vorkommt, wird davon ausgegangen, dass es sich um einen neuen Sensor handelt, dem noch kein Name zugewiesen wurde. Diese Sonderbehandlung findet aber nur im zweiten Durchgang statt (initReady==1). Dafür darf im ersten Durchgang (initReady==0) am Ende valid nicht gelöscht werden, damit im zweiten Durchgang noch bekannt ist, welche Namen schon erkannt wurden. Dann wird der erste noch nicht erkannte Name aus der Überschrift in den Sensor geschrieben. Bei der Inbetriebnahme schließt man also die Sensoren in der Reihenfolge einzeln an, wie sie in der Überschrift stehen, und schaltet jeweils einmal kurz ein. Sollte einmal ein Sensor defekt sein, kann man ihn einfach durch einen neuen ersetzen, einschalten und fertig.
Datum:
Hey danke schonmal für das C. Habe nur eine frage Wie kann ich am einfachsten negative werte ausgeben ? Mfg strikeforce
Datum:
Die Umwandlung der Temperaturen habe ich nach einigen umständlichen Ansätzen wie folgt gelöst: 1. Das High-Byte mit 10 multiplizieren (als int16). 2. Aus dem Low-Byte die Nachkommastelle berechnen (als Wert zwischen 0 .. 9). 3. Diesen Wert zum (High-Byte * 10) addieren. 4. Nun hat man die mit 10 multiplizierte Temperatur incl. Nachkommastelle. Um ein Dezimaltrennzeichen einzubauen, kann man die Zahl in einen String umwandeln, das letzte Zeichen um 1 nach rechts schieben, statt dessen ein Komma einfügen (und dann ggf. wieder ein terminierendes 0 anhängen. Die Nachkommastellen berechne ich so: Das Low_Byte >> 4 um 4 Stellen nach rechts schieben und mit 0.625 multiplizieren (das geht natürlich so nicht !!). Statt dessen wird mit 625 multipliziert und durch 1000 dividiert. Einfacher ist, mit 640 zu multiplizieren und durch 1024 zu dividieren. Wenn man auch die Schiebeaktion mit in die Berechnung einbaut, dann kann man alternativ rechnen: (Low_Byte / 16) * (640 / 1024) = Low_Byte * 40 / 1024. Im Moment haben wir ja die richtigen Temperaturen, um die Funktionsfähigkeit dieser Berechnung im Bereich unter 0° zu prüfen. Michael S.
Datum:
Die beiden Pins für die UART findest Du im Datenblatt. Die Pins für LCD und 1-Wire können beliebige IO-Pins sein. Peter
Datum:
Hallo Peter Ja aber bezogen auf die CodeBeispiele von : Autor: Josef D. (Gast) Autor: cloud (Gast) ich sehe das aus dem code nicht sofort raus wie ich es zusammenlöten muss. Ich wollte erst löten und dann den code fertig nehmen zum basteln. grüße Sebastian
Datum:
Angehängte Dateien:Konvertierung (negativer) Temperaturwerte beim DS18B20 Zu diesem Thema hatte ich kürzlich eine Anmerkung gemacht. In der Annahme, dass das Datenformat des DS18B20 und des DS1631 gleich sind, zumindest sehen die Datenblätter zunächst wie Kopien aus. Aber leider sind die Formate nur fast gleich. Während beim DS1631 die 12 Datenbits linksbündig ausgerichtet sind, stehen sie beim DS18B50 rechtsbündig. Daher müssen die Nibbles beim DS18B50 anders geschoben werden als ich es beschrieben habe. Dazu ein Codeschnipsel als Anlage und Korrektur. Michael S.
Datum:
Angehängte Dateien:Hallo zusammen, ich habe die w1_byte_wr() Funktion um eine CRC Prüfung erweitert. Auslesevorgang: w1_crc auf 0 setzten. scratchpad komplett auslesen. wenn w1_crc gleich null ist dann war die CRC Prüfung erfolgreich. Vielleicht kann es jemand brauchen. Ich habe allerdings die Funktion nur mit dem Scratchpad vom DS18S20 und ohne ROM SEARCH getestet. Grüße Timo
Datum:
Angehängte Dateien:Hallo Josef D. ich verwende deinen Code. Bei mir tritt aber ein Anzeigefehler auf. Ganze zahlen wie 23,24,25 Grad werden gut angezeigt. Kommazahlen wie 23,5 werden als 23.-5 angezeigt (siehe Foto) Gibt es dafür eine Lösung ? Grüße Sebastian
Datum:
Hallo Sebastian, wenn ich mich recht erinnere, stammt der Code für die Ausgabe nicht von mir, wohl aber die Bemerkung, dass der für negative Werte falsche Ergebnisse liefert, mit einem Kommentar, wie man das korrigieren kann. Aus deinem Beitrag geht nicht hervor, ob du meine vorgeschlagene Änderung eingebaut hast. Für eine Hilfe wären die paar Zeilen Code, die bei dir zu der Ausgabe führen, schon sehr hilfreich. Josef D.
Datum:
Hallo Sebastian, erst beim nochmaligen Lesen ist mir aufgefallen, dass es dir gar nicht um negative Werte geht. Habe daraufhin noch mal den von mir geposteten Code angesehen und festgestellt, dass doch wohl meine Änderung für den Fehler verantwortlich ist, die ich nicht testen konnte, wie ich auch angemerkt hatte. Vermutliche Lösung (auch nicht getestet): Es muss in der for-Schleife uint16_t temp statt int16_t temp heißen, wenn man nur mit nicht-negativen Werte rechnen und den unveränderten Code verwenden will (eine Variable uint temp wird weiter ebenfalls benutzt, da hätte ich besser auch einen anderen Namen gewählt) Sorry Josef D.
Datum:
Perfekt ! Danke !
jetzt sind Kommawerte kein Problem mehr.
für den Rest der Welt.
Diese Zeile (140) muss geändert werden :
int16_t temp=thermoValues[i];
in
uint16_t temp=thermoValues[i];
Noch eine Frage :
was muss ich anstellen um mehr als einen Sensor zu lesen ?
Ein Sensor T1 wirft den Output aus wie auf dem Bild weiter oben.
Schalte ich einen weiteren Sensor dazu (Parallel) änders sich nichts.
T2 und T3 zeigen nichts an. Werden die ID´s für T1 fest im µProc
abgelegt?
Muss man T2 neu anlernen? Achso ich habe zwei sensoren die beide einzeln
als T1 laufen, nur zusammen eben nicht.
Sorry die Fragen aber ich mache Hardware + AVR + GCC erst seit 5 Tagen.
und bin schon recht weit ...
grüße
Sebastian
Datum:
Problem selber gelöst und neue erkenntnis gewonnen : - Der EEprom im Ds1820 bleibt dauerhaft geschrieben. - Der erst Sensor heist T1 und legt das auch im Sensor so ab. - Wenn man nun wieder einen Sensor anschließt wird er wieder T1 genannt - Schließt man beide an hat man zwei T1 Sensoren und das geht nicht. Also - aus T1 bis T3 in dem Code zb. A1 bis A3 machen - Sensor 1 an schließen und A1 einlernen - Sensor 2 dazu anschließen --> sensor zwei bekommt A2 gelernt jetzt gehts ... Grüße Sebastian
Datum:
Hallo ih verwende die 1Wire.zip Routine. ich habe Sie erweitert damit man 0.1 Grad sprünge mit dem DS18S20 sieht. Leider verstehe ich die Routinen von Peter nicht so genau. Gibt es zum Code von Peter eine Readme? ich möchte gerne die Read Messung so abwandeln das ich die sensoren einzeln ansprechen kann? Wo werden die ID´s gespeichert? wie kann ich sie einzeln abrufen? Fragen über Fragen ... eine Readme währe hilfreich. Thanks Stefan M. aus Eisenach
Datum:
Hallo kannst Du dein C Programm mal hier hochladen. Ich kann jetzt eine Temperatur auf meinem Display (4bit) darstellen, jedoch nur ein Sensor und keine negativen Temperaturen. christoph
Datum:
Angehängte Dateien:Hallo,
Ich spreche nict Deutsch, please forgive me...
Can anybody help me with reading and store the device ID from 18b20 on
1-wire? I enclose my simple source code. I use the LCD 2x16 and one
18b20 succesfully. I would like improve :
1. The time of temperature reading (with only tvo decimal-pointed, not
four)
2. how to add the second temperature sensor 18b20. ?
In enclosed file there are full functional project for AVRstudio, photos
and schematics (schema.jpg).
I see, that you are good in this area.
THX a lot
JOZO
PS:
(main program:ATmegatest.c, sensor:therm_ds18b20.c and h., owi.c,h is
not used)
In main program for measure the temperature,i use only this:
char x[20] = {0};
therm_read_temperature(x);
lcd_puts("T= ");
lcd_puts(x);
Datum:
Angehängte Dateien:Messung der Luftfeuchte (psychometer) mittels DS1820 Also ich habe das jetzt so gemacht. 2x Ds1820 mit 0.1C auslösung (formel siehe datenblatt) 1x ATmega8 1x LCD 2x40 1x Modul mit lüfter + bewässerung (eigenbau) Routinen von Peter mit nur kleinen Änderungen. Messwete: - Feuchte - Taupunkt - Temperatur grüße Sebastian
Datum:
Sebastian Albrecht schrieb: > Problem selber gelöst und neue erkenntnis gewonnen : > > - Der EEprom im Ds1820 bleibt dauerhaft geschrieben. > - Der erst Sensor heist T1 und legt das auch im Sensor so ab. > - Wenn man nun wieder einen Sensor anschließt wird er wieder T1 genannt > - Schließt man beide an hat man zwei T1 Sensoren und das geht nicht. > > Also > > - aus T1 bis T3 in dem Code zb. A1 bis A3 machen > - Sensor 1 an schließen und A1 einlernen > - Sensor 2 dazu anschließen --> sensor zwei bekommt A2 gelernt Einen Sensor ran, erkennen lassen, zweiten ran und Prozessor resetten. Wenn dieser erkannt ist, dritten Sensor ran und Prozessor resetten. So ging es bei mit. Christoph. !!!!!!!!!!!!!!!!!!!!1 Wie kann ich denn die Routine abändern, damit negative Tempraturen und Nachkomma korrekt dargestellt wird ?. ---------------------------------------- sprintf( (char*)s, "%3d.%01dC", temp >> 4, (temp << 12) / 6553 ); // 0.1øC // Achtung: liefert bei negativen Temperaturen falsche Ergebnisse! ---------------------------------------- > > jetzt gehts ... > > Grüße Sebastian
Datum:
@Christoph Scheicht Negative Werte habe ich nicht benötigt. Deshalb auch keine Idee. Die Nachkommawerte sind mit der Formel aus dem Datenblatt recht einfach zu errechnen.
TEMPERATURE = TEMP READ - 0.25 + COUNT PER C- COUNT REMAIN ------------------------- COUNT PER C Beispiel : TEMPERATURE = 25C - 0.25 + 16 - 12 = 24,5C ------- 16 |
COUNT PER C und COUNT REMAIN werden aus dem Scratchpad ausgelesen. grüße Sebastian XXlXX
Datum:
Hallo Sebastian, wie misst du die Luftfeuchte mit dem DS1820? Der Taupunkt errechnet sich doch aus Druck, Temperatur und Feuchte, oder? Lieg ich falsch? Grüße, Konstantin
Datum:
Google mal "Psychrometer" http://www.centennialofflight.gov/essay/Dictionary... http://en.wikipedia.org/wiki/Hygrometer#Psychrometers
Datum:
Ja du hast recht der Druck wird benötigt. ABER : für diesen Wert nutzt man einen Mittelwert. Das macht keinen großen Unterschied. Ich habe das Gerät mal zum prüfen einem Wettermann mitgegeben. Mein Gerät hat 2% Abweichung wenn ich es min 5 Minuten laufen lasse. Zur bestimmung der Hausfeuchte (neubau) ist das jetzt so prima. grüße Sebastian
Datum:
Angehängte Dateien:NACHTRAG hier mal die Formel als Excel. Ist dann einfach in C umzusezen. Grüße Sebastian xxlxx
Datum:
Hallo Sebastian, koenntest Du mir bitte den Titel und ISBN Nummer von Deinem PDF Dokument bekannt geben. Gruss, Gerhard
Datum:
Gerhard O. schrieb: > koenntest Du mir bitte den Titel und ISBN Nummer von Deinem PDF Dokument > bekannt geben. Leider habe ich PDF auch nur so von meinem Wettermann bekommen. Sorry grüße Sebastian
Datum:
Vielen Dank, Sebastian ! Gruss, Gerhard Sebastian schrieb: > Gerhard O. schrieb: > >> koenntest Du mir bitte den Titel und ISBN Nummer von Deinem PDF Dokument >> bekannt geben. > > Leider habe ich PDF auch nur so von meinem Wettermann bekommen. > > Sorry > > > grüße > Sebastian
Datum:
Der Text (PDF) kommt von : http://openlibrary.org/b/OL4622634M/Aspirations-Ps... Deutscher Wetterdienst grüße Sebastian
Datum:
I used your source code from this forum and it works now fine. I solved only problem with negative temperature additionally.
Datum:
Sorry Leute ich meinte ATMega128. Sag ich ja ich bin ein Anfänger. Danke vorhinein MfG Wolfi
Datum:
Ja also das wird nicht reichen was du da so schreibst. Ein AVR + DS1820 ist schnell genbaut. Ohne Dispaly oder Ausgabe wird nie einer prüfen können ob dú alles richtig gemacht hast. Wie möchtest du dein Endprudukt haben ? Ich bin auch Anfänger vor ca 30 Baustundenstunden gewesen. nach 30 Stunden habe ich das Endprodukt fertig gehabt. (Siehe weiter oben die Bilder) Grundlagen : - AVR beschalten (+ - usw.) - Sensoren an einen eingangspin - Genial ist ein display zum testen & prüfen - dann die Codes hier aus dem Forum auf dem AVR brennen (mit Brenner) - Sehen was passiert und Grundlagenforschung betreiben. So ging es bei mir erste erfolge hatte ich nach ca 2 Stunden. Es gibt fertige Test Boards mit allem schon drauf. Oder selber bauen (Viel Billiger) Grüße Sebastian
Datum:
>hastekene schrieb: > Autor: hastekene (Gast) > Datum: 08.07.2009 17:35 > Angehängte Dateien: Heizung-32-4.zip (163,8 KB, 446 Downloads) > Hallo Proteus, > ich kenne zwar deinen Code nicht bei mir funkts aber mit atmega 32 > problemlos > sende dir mal meinen bisherigen code beinhaltet Temperaturauswertung > DS18B20 und noch etwas mehr > vielleicht hilft es dir > > by Wolfgang Hallo an Alle und Danke für alle angehängten Programme. Hab ca 1Woche AVR-GCC erfahrung, hab aber den DS18S20 über Bascom auf FabianG. Testboard mit LCD am laufen. Hab mit dem original ZIP GCC Probleme, Bei den 'neueren' Prog's kompiliert er mit Atmega8 mit 0Error. Dann ändere ich im Makefile Atmega8->Atmega88, dann hagelt es ERROR's. Das Obige Prog ist auch auf M8 nicht auf M32 mit den selben Umstellungsproblemen. Hier meker er wegen PortA, den hat der Mega8 aber auch nicht. Mal sehen ob irgendwo doch der M32 definiert ist??? Sonst muss ich einen M8 einsetzten, aber das LCD hab ich auch zum Laufen gebracht. Gruss Toni
Datum:
Gratulation ! Ich habe das auch am ATmega8. Meine Luftfeuchtessung funktioniert super. Damals hatte ich auch erst 10 tage Erfahrung und dann gleich das projekt : Mega8 + LCD + DS1820 + Eigenbau (kein Board) ... Aber das forum hier ist super und hat mir sehr geholfen. grüße Sebastian ( xxlxx )
Datum:
Danke für die Aufmunterung. Ich hab zwar schon viel erfahrung mit Elektronik(5Jahre Nachrichtentechnik Schule mit Abi vor 20Jahren). 2004 hab ich die JCU (Java Control Unit) für meine Kachelofensteuerung erworben und Programiert mit Messverstärker und i2c Schrittmotor. Für kritische Anwendungen ist mir dieser Controller zu teuer und mager mit I/O. Hab aber Bascom-Avr Erfahrung, dort muss man meist nur eine Zeile ändern, dann Compiliert es mit der anderen yC Einstellung. Aber wenn man die Routinen mal hat, is es kein Problem mehr. Bascom mit 1Wire lief innerhalb 15Minuten, musste nur etwas Code entfernen, da über 4KB mit der Demo nicht compiliert wird. Abber mit GCC wirds auch bald. Hab ja noch DCF77 und CAN vor mir. Und Auto Drehzahlmesser wird irgendwann auch noch in C konvertiert. Das Testboard ist mit Tonertransfer nach [[http://www.kreatives-chaos.com/artikel/atmega168-t...]] nachgebaut. Das 32/64 Board hab ich auch, aber etwas stark geätzt. Gibts Registerlisten zB für Timer1 für ATmega8-48/88/168 nur im Datenblatt, oder kann man die in den IncludeDateien auch schnell finden, dann wäre das Handkonvertieren wesentlich einfacher. Danke Toni
Datum:
Hallo, ich bekomme mit Peters Code bei 50m Kabel den besagten Bus-Error. Da ich mit Bascom bereits die entsprechende Schaltung mit der Kabellänge zum laufen bekomme habe, habe ich mir Peters Code nochmal genau angeschaut. Das Problem entsteht hier:
b = w1_bit_io( 1 ); // read bit if( w1_bit_io( 1 ) ){ // read complement bit |
Zu beginn der w1_bit_io wird der Bus auf high geschaltet. Am ende wieder of low. Durch den direkt hintereinander folgenden Aufruf der Funktion scheint die zeit die vergeht für 50m Kabel einfach zu gering. Wenn man am ende der w1_bit_io noch ein delay von 1ms einfügt funktioniert das ganze bei mir einwandfrei.
Datum:
hopala, ich mein natürlich 1us und nicht 1ms ;) hier noch ein Beispiel um die Temperatur eines DS18S20 in einen String umzuwandeln:
void temp_to_string( signed int temp, char *s ) { itoa( temp >> 1, s, 10 ); while( s++ && *s != '\0' ); // search end of string *s = '.'; s++; if( temp & 1 ) { *s = '5'; } else { *s = '0'; } s++; *s = '\0'; } |
Das interessante ist, dass der DS18S20 die Temperatur bereits als signed integer liefert. Somit kann man wunderbar mit itoa umwandeln.
Datum:
Angehängte Dateien:Hallo ich habe die Software von Matthias heruntergeladen (vielen Dank!!) und versucht für den ATMEGA8 zu complimieren. Leider bekomm ich immer einen Fehler: uint8_t docrc8 ( uint8_t number_of_bytes_to_read ) /// HIER ist der Fehler { uint8_t crc; uint16_t loop_count; uint8_t bit_counter; uint8_t data; uint8_t feedback_bit; crc = CRC8INIT; for (loop_count = 0; loop_count != number_of_bytes_to_read; loop_count++) { data = ow_buffer[loop_count]; bit_counter = 8; do { feedback_bit = (crc ^ data) & 0x01; if ( feedback_bit == 0x01 ) { crc = crc ^ CRC8POLY; } crc = (crc >> 1) & 0x7F; if ( feedback_bit == 0x01 ) { crc = crc | 0x80; } data = data >> 1; bit_counter--; } while (bit_counter > 0); } return crc; } Mit folgender Fehlermeldung: ../crc8.c:10: error: expected '=', ',', ';', 'asm' or '__attribute__' before 'uint8_t' Ich weis leider nicht wiso, ich habe die h - Files includiert und denke das diese passen müssten. Weis jemand von euch an was dies liegen könnte? Ich habe das komplette Projekt hochgeladen, vl ist es einfacher was zu finden. ( Ich verwende AVR Studio 4.16 und WinAVR-20090313) Grüße Luke
Datum:
uint8_t ist nicht definiert, weil "#include <stdint.h>" fehlt
Datum:
Hi Lukas, poste mal den Code-Teil davor, der ist interessant, den in Deiner Fehlermeldung steht "....before 'uint8_t'" ! Da liegt wohl auch der Hase begraben. Wahrscheinlich ein ';' vergessen oder so etwas!
Datum:
Hallo, danke für die Tipps, es lag leider nicht am #include <stdint.h>; Der fehler befindet sich im crc8.c... Weis leider nicht weiter der Vorherige Code:
/* please read copyright-notice at EOF */ #include <stdint.h> #include "global.h" #define CRC8INIT 0x00 #define CRC8POLY 0x18 //0X18 = X^8+X^5+X^4+X^0 uint8_t docrc8 ( uint8_t number_of_bytes_to_read ) { uint8_t crc; uint16_t loop_count; uint8_t bit_counter; uint8_t data; uint8_t feedback_bit; |
grüße Lukas
Datum:
Hier der Verlauf der Scratchpad- und 12-Bit-Werte um den Nullpunkt herum: Beitrag "Re: DS18S20 - extended resolution bei Temperaturen um 0°C" Hier gibt es kompakten Code zum Berechnen des 12-Bit-Wertes für DS18[S]20 und zu dessen Ausgabe mit zwei Nachkommastellen, Unterdrückung führender Nullen mit Verschiebung des Vorzeichens, ohne Verwendung von speicherfressenden printf, itoa * % / etc. Beitrag "Re: DS18S20 - extended resolution bei Temperaturen um 0°C" (leider ist der erste Teil des Posts eine Kopie des vorigen) Im mittleren Teil eine Version, die die Vorkomma- und Nachkommabits direkt aus dem Scratchpad errechnet und ausgibt, im letzten Teil eine Version, die die Vorkomma- und Nachkommabits über den 12-Bit-Wert berechnet und ausgibt.
Datum:
Hallo, im Code steht ja das 0.1 Schritten ausgegeben werden. Bei mir wird die Temperatur in 0.5 schritten ausgegeben. Muss ich was beachten damit das klappt? Oder ist das einfach falsch?
Datum:
Hallo 0,5 Werte kann der Sensor ohne Umrechnung ausgeben. 0,1 Werte müssen berechnet werden. Formel steht im Datenblatt. Ich habe das auch so gemacht. Wichtig ist noch welche Sensoren du hast. Da1820 gibt es mit unterschiedlichen Auflösungen.
Datum:
Die Formel habe ich gesehen, hat bei mir aber mit dem Code von Peter nicht richtig funktioniert. Werde gleich nochmal versuchen. Verwende DS18S20
Datum:
Was ich gerade versuche ist:
float count_remain = id[6]; float count_per_c = id[7]; float bruch = ((count_per_c - count_remain) / count_per_c); int temp_read = temp >> 4; float ftemp = temp_read - 0.25 + bruch; int v = (int)ftemp; int n = (ftemp - v)*10; sprintf(s, "%4d.%01d, v, n"); |
Bekomme jetzt immer 22.7 Grad oder halt 23.7. Also immer x.7
Datum:
Ich habe das immer so gemacht. Alle Werte ausgeben lassen auf ein Display. Und dann das ganze auf dem papier probiert. Dann ein paar testreihen gemacht. Wenns dann stimmt den Code dazu getippt. Anders gings bei mir auch nicht. Das gleiche habe ich dann mit minus Temperatur gemacht. Peter sein Code kann glaube ich nur plus grade. Wenn du's nicht hinbekommst such ich morgen mal den Code. Baue gerade ein temp datenlogger mit sd Karte. Da steht die Formel im Code ... Gruesse
Datum:
Danke das wäre nett. Das Problem liegt glaube ich nicht an der Formel (die sollte ja richtig sein), sondern viel mehr an der id[x]. count_per_c ist bei mir 0. Kann sein, dass ich es schon dort falsch mache.
Datum:
Schicke mal deinen kompletten Code als zip. Lese mal alle werte vom scratchpad aus 0-7 und häng sie mal an. Den Fehler werden wir schon finden.
Datum:
Hallo, ich bekomme folgende Werte: 10-57-15-29-02-08-00-24-31 Ist etwas umständlich, weil ich es über LCD ausgeben muss.
Datum:
Hallo --> Hiorica (Gast) also irgend etwas läuft bei dir schief.
byte 0 Temperature LSB (AAh) byte 1 Temperature MSB (00h) EEPROM byte 2 TH Register or User Byte 1 byte 3 TL Register or User Byte 2 byte 4 Reserved (FFh) byte 5 Reserved (FFh) byte 6 COUNT REMAIN (0Ch) byte 7 COUNT PER °C (10h) byte 8 CRC* |
wenn ich nun die 10 (byte0 = 0001 0000) und die 57 (byte1 = 0101 0111) mal als temperatur nehme. kommt da keine zimmertemperatur raus. MSB + LSB 0101 0111 0001 0000
TEMPERATURE/DATA RELATIONSHIP Table 2 +85.0°C* 0000 0000 1010 1010 00AAh +25.0°C 0000 0000 0011 0010 0032h +0.5°C 0000 0000 0000 0001 0001h 0°C 0000 0000 0000 0000 0000h -0.5°C 1111 1111 1111 1111 FFFFh -25.0°C 1111 1111 1100 1110 FFCEh -55.0°C 1111 1111 1001 0010 FF92h |
zur info byte 7 ist immer 10h nur bei dir nicht?
Note that the COUNT PER °C register is hard-wired to 16 (10h) |
sind deine angaben in HEX oder dezimal ? aber bit 7 muss 10H (dezimal 16) sein. prüfe das mal bitte und sende mal den code zu als zip! sebastian
Datum:
NACHTRAG : ändert sich was an deinem code bei temperaturwechsel ? wenn nicht dann könnte es sein das du hier die Seriennummer vom Chip darstellst oder so. prüfe das mal bitte
Datum:
Angehängte Dateien:Hallo, es kommen keine Änderung, wenn sich die Temperatur ändert. Leider verstehe ich den Code von Peter noch nicht so ganz. Die Temperatur in 0.5 Schritten klappte damals soweit.
Datum:
Hallo Hatte ich mir fast gedacht. Warum eigentlich 0.1 grad ? Ich habe 20 Sensoren auf eine metall Platte geklebt. Alle ausgelesen und Werte von - + 2 grad erhalten. Die sensoren haben auch leichte eigenerwärmung. Für mein Projekt weiter oben hier im forum (Bilder mit gelben gehäuse) habe ich von den 20 Sensoren die besten zwei genommen. Ich guck mal deinen Code heute Abend durch.
Datum:
Ja es geht mir nicht um das genauere messen. Das bekomme ich mit den DS18S20 nie hin, ich will nur das die Anzeige in 0.1 Schritten sich ändert. Soweit ich das nun verstehe, ist das wirklich die ID vom Chip die ich auslese.
Datum:
Hallo ich habe was angepasst. die anderen id´s wurden nicht gelesen. es müssen alle 9 byte gelesen werden.
void read_meas( unsigned char *s )
{
uchar id[8], diff;
uchar i;
uint temp;
for( diff = SEARCH_FIRST; diff != LAST_DEVICE; ) {
diff = w1_rom_search( diff, id );
if( diff == PRESENCE_ERR ) {
sprintf( s, "no Sensor Found" );
return;
}
if( diff == DATA_ERR ) {
sprintf( s, "bus error" );
return;
}
if( id[0] == 0x28 || id[0] == 0x10 ) { // temperature sensor //prüfung ob Ds1820 Version S oder B
w1_byte_wr( READ ); // read command
temp = w1_byte_rd(); // low byte // ID[0] Bit 0 lesen und in temp ablegen
temp |= (uint)w1_byte_rd() << 8; // high byte // ID[1] bit 1 lesen und an temp anbinden MSB + LSB
if( id[0] == 0x10 ) // 9 -> 12 bit // prüfen ob 9 oder 12 Bit sensor (wie oben) du hast 10
temp <<= 3;
id[2] = w1_byte_rd(); //id[2] einlesen
id[3] = w1_byte_rd(); //id[3] einlesen
id[4] = w1_byte_rd(); //id[4] einlesen
id[5] = w1_byte_rd(); //id[5] einlesen
id[6] = w1_byte_rd(); //id[6] einlesen
id[7] = w1_byte_rd(); //id[7] einlesen
id[8] = w1_byte_rd(); //id[8] einlesen
unsigned char temp[20];
sprintf( temp, "%2X-%2X-%2X-%2X-%2X", id[0], id[1], id[2], id[3], id[4] ); // ausgabe vorbereiten
lcd_string_xy( temp, 0, 1 ); // display ausgabe zeile 1
sprintf( temp, "%2X-%2X-%2X-%2X", id[5], id[6], id[7], id[8] ); // ausgabe vorbereiten
lcd_string_xy( temp, 0, 2 ); // display ausgabe zeile 2
// sprintf( s, "%4d.%01d C", temp >> 4, (temp << 12) / 6553 ); // 0.1øC
}
}
}
|
Datum:
Hiorica schrieb: > Soweit ich das nun verstehe, ist das wirklich die ID vom Chip die ich > auslese. nein du hast ID[0] bis [id8] nie eingelesen. Du hast ID oben definiert aber dann nie werte da hin geschrieben. die temp werte liegen in der Variable temp. viel spaß beim bauen ... NACHTRAG nach 10 minten denken .... kann es sein das der code von dir aus zwei codes zusammengeschmissen ist? du legst die Variable "ID" fest. und fragst dann ab ob ID[0] 10 oder 28 ist. Ohne aber vorher den chip zu lesen und ID[0] zu befüllen? wenn ich richtig liegen sollte das du code zusammengeschmissen hast dann sollte man den ganzen code berichtigen. aktuell ist es nur zufall das der code geht, weil ID[0] mit 10 gefüllt ist ... :-)
Datum:
Hallo, der Code ist Original von Peter. Ich habe es nur für meine Zwecke auf ein LCD umgeschrieben. Die Werte für ID werden in der Funktion w1_rom_search( diff, id ) beschrieben. Gibt es vielleicht ein besser Beispiel?
Datum:
Hallo Ja aber Peter ließt nur bit 0 + Bit 1 ein. Teste mal mein Code. Viel Spaß
Datum:
Hallo w1_rom_search( diff, id ) ließt nur die ID ein. das Scratchpad wird nicht von peter komplett gelesen. Sebastian hat recht der Code sieht ganz gut aus. grüße stefan
Datum:
Hallo, Vielen Dank, es funktoniert nun. Bekomme nun das richtige Scratch pad.
Datum:
Angehängte Dateien:hallo. hab mich jetzt im Forum so durchgelesen aber nichts gefunden, was man für einen PIC 18F4550 verwenden könnte. könnte jemand vielleicht codes bereitstellen. ich versuche derzeit über ds1820 treiber mit vorgefertigten Funktionen den Befehl für eine Temperaturmessung zu geben, doch mein µC hängt sich auf dabei.
sensor_count = 0; if ( DS1820_FindFirstDevice() ) { do { // Die Rohtemperatur des DS18B20 erhalten (Aufloesung 1/256°C) temperature_raw = DS1820_GetTempRaw(); // Konvertiere die Rohdaten in ein String fuer die Ausgabe DS1820_GetTempString(temperature_raw, temperature); // Temperatur als Float-Werte erhalten temperature_float = DS1820_GetTempFloat(); // Ausgabe ueber USB-RS232 emulator an PC /* putsUSART("Sensor %d: %s°C (temperature_float = %f), temperature_raw = %ld)\n\r", sensor_count, temperature, temperature_float, temperature_raw); */ putsUSART("TEST\n"); sensor_count ++; } while ( DS1820_FindNextDevice() ); sensor_count = 0; } |
Ich habe versucht über Matlab mir den String "Test" ausgeben zu lassen, aber offensichtlich kommt er gar nicht erst ins if- rein. 2. wie kann ich dem Sensor (ohne die Treiber zu verwenden) befehlen, eine Messung durchzuführen?
Datum:
Ich schätze dass es am delay liegt, weil er den PIC abschaltet. die verbindung über USB wird damit auch unterbrochen. wie könnte man das noch machen, ohne ein delay zu benutzen. Danke im Voraus. Lg, alptech
Datum:
Ich denke mal du bist falsch hier. In diesem Beitrag geht es immer um atmega CPU's. Ich habe hier auch schon viel getippt aber bei deinem Problem kann ich dir nicht helfen. Sebastian xxlxx
Datum:
wo finde ich den was. ich habe schon wie wild im forum rumgesucht, aber bisher nichts gefunden. oder wo platziere ich mein frage. lg,
Datum:
Versuche doch mal teile von deinem grundcode zu suchen. Ich denke mal du hast fertige Teile genommen. Wenn du dann im Forum was findest - schliese sich Diesem Beitrag an. Dein Thema ist sehr komplex USB ds1820 + pic. Für die ds1820 gibt es gute pdf beim Hersteller. Bekommst du eine datenverbundung hin? Daten vom pic zum pc senden ? Wenn ja dann ccersuche dir doch einen code helper zu bauen. Jeder step eine Ausgabe und an jeder Position was anzeigen. Dann siehst du schnell wo der Fehler liegt. Ich mache das oft mit nur einer LED. 1 x blinken = in der Schleife usw. Viel spaß Sebastian xxlxx
Datum:
verbindung zum pc funktioniert. doch wenn ich die fertigen funktionen für den ds1820 aufrufe hängt es sich auf, die leds blinken dann nicht mehr. ich probier es mal so wie du es sagst. danke. lg, alptech
Datum:
Was mir noch einfällt : ein ds1820 kann auch falsch angeschlossen sein. Wie versorgst du ihn ? Hast du einen oszi? Verlass dich nicht auf fertigen Code. Ich denke auch dein Code muss wie beim atmega an die Hardware angepasst werden. Sebastian Xxlxx
Datum:
hallo. ist alles richtig angeschlossen. hab jetzt auch den code fürs abrufen der temperatur. ich kriege auch werte in den PIC geschrieben, doch wie gebe ich die aus. die usb-verbindung zum PIC funktioniert seit dem aufrufen der Temperatur nicht mehr. kann man mit dem PIC18F4550 an eine R232 gehen und dann von hier mit einem USB-Adapter zum PC. hier ist der Code für die USB-Ansteuerung:
// USBTasks() // "Service loop for USB tasks." void USBTasks(void) { /* * Servicing Hardware */ USBCheckBusStatus(); // Must use polling method if(UCFGbits.UTEYE!=1) USBDriverService(); // Interrupt or polling method #if defined(USB_USE_CDC) CDCTxService(); #endif } // High priority interrupt vector #pragma code InterruptVectorHigh = 0x08 void InterruptVectorHigh (void) { _asm goto InterruptHandlerHigh //jump to interrupt routine _endasm } // High priority interrupt routine // Hier Behandlung von Trigger- und Timer-Interrupt #pragma code #pragma interrupt InterruptHandlerHigh |
. . . // LED-Blinken zur USB-Statusanzeige // beide an: "Attached" // Nur RC0 an: "Powered" // Nur RC1 an: "Default" // Nur RC0 blinkt: "Address" // Nur RC1 blinkt: "Detached" // Abwechselndes Blinken: "Configured" (funktionsfähiger Zustand) |
Im moment leuchten beide LEDs. Lg, alptech
Datum:
Nachtrag: Ich habe einen Oszi an dem 1-wire-bus angeschlossen. dabei habe ich gemerkt, dass der bus nie auf 0 gezogen wird. wenn ich den ds1820 rausnehmen, sehe ich die flanken usw. aber mit dem ds1820 wird es nur auf 5V-480mV runter gezogen. offenbar verhindert er dass die leitung komplett auf 0 gezogen wird. warum ist das so? angeschlossen habe ich (wie im Datenblatt steht) Gnd-> Gnd, mittleren Pin (DQ)-> Port des PIC und den VDD-> 5V. Bin für jede Hilfe dankbar. Lg, malptech
Datum:
Hallo Ich habe den Code von Peter aus dem ersten Post eingebunden und zum Laufen bekommen - allerdings sind die angezeigten Werte etwas mysteriös: Bei einem Sensor bekomme ich die Zahl "10.6250" angezeigt, welche auch bei Temperaturänderungen gleich bleibt - ich gehe davon aus, dass dieser Sensor kaputt ist (?), denn: Zwei andere liefern "3.xxx", wenn ich sie einsetze und sinken dann langsam auf exakt "3.000". Hat jemand eine Idee, was hier schief läuft (denn hier ist es definitiv wärmer als 3 Grad :-))? Ich benutze einen DS1820 (ohne S, Jahre altes Sample) an einen ATmega8 (16 MHz Quarz). VDD ist direkt verbunden, also kein Parasite Power. Als Pullup verwende ich einen 5kOhm-Widerstand (2x 10kOhm), da ich 4,7kOhm nicht parat habe. Könnte hier die Ursache liegen? Oder klingt das eher nach einem Software-Fehler?
Datum:
hört sich an wie software fehler. pullup ist unkritisch. hast du ein display oder wie machst du die ausgabe ? versuche doch mal das scratchpad in Hex zu lesen. es kann sein das du da einfach die falschen hexwerte nimmst. ich habe damit viel gebaut und code selber geschrieben. ließ mal beitrag von mir 16.2.2011 da hatte einer glaub ich auch so ein problem. ich kann dir nur das pdf vom hersteller empfehlen da steht drin wie sich das scratchpad zusammen setzt. also viel erfolg
Datum:
Versuche seit Stunden die Datei 1wire.zip zum laufen zu bringen. Die Verschachtelung ist ein Alptraum. Es ist kaum was Beschriftet. Ich könnte heulen. Im Main wird auf "#include "main.h" "hingewiesen. im "main.h" wird auf: #include "1wire.h" #include "delay.h" #include "tempmeas.h" #include "timebase.h" #include "uart.h" hingewiesen und zu jeder header datei exestiert eine .c datei. Ein Alptraum. Das AVR Studio erkennt die .c Dateien nicht obwohl ich diese ins Verzeichnis kopiert habe. Habe versucht alles in eine main zu stopfen aber nun is das ganze kommplett unübersichtlich. Hat jemand eine Version die auch mit AVR Studio 5.0 geht oder ein Tip warum die Dateien trotz #include Befehl nicht erkannt werden. Danke im vorraus Software: AVR Studio 5.0 Programmiersprache: C IC: Atmega16 Board: Pollin Eva Board v.2.01
Datum:
Hallo Ich habe inzwischen eine 1wire Lösung die aus ca 8 Funktionen besteht und man kann sie einfach in die Main kopieren ohne Zusatz Daten. Leider kann sie nur einen Sensor pro Portpin. Reicht dir das ?
Datum:
Was soll der Unsinn alles in die Main zu kopieren? Das ist Unsinn. Einfach die .c Dateien dem Projekt hinzufügen und kompilieren. Fertig.
Datum:
Simon K. schrieb: > Was soll der Unsinn alles in die Main zu kopieren? Das ist Unsinn. wer war hier gemeint ? ich ?
Datum:
Alle die sowas machen sind natürlich gemeint.
Datum:
Simon K. schrieb: > Alle die sowas machen sind natürlich gemeint. Ein Code der nur 50 Zeilen hat wird doch in die Main.c gehören. Warum sollte ich so etwas auslagern ?
Datum:
Angehängte Dateien:Hab den Fehler gefunden. Es lag an dem Programm AVR Studio 5.0. Die Verschachtelung wird in das Projekt nicht aufgenommen wenn man die zusatz Header Dateien (.h) in das verzeichnis kopiert und im Programm #include .... eingibt. In dem "Solution Explorer" Fenster (rechtses extra Fenster) muss man erst auf "Show all files" klicken und dann unter "Output files" die ganzen .h dateien mit rechter maus taste ins Projekt hinzufügen. Schwups es wird alles gefunden und ausgeführt. Würde mich trotzdem über eine einfachere Lösung freuen. Möchte nur den einen Temp. Sensor zum laufen bringen und danach versuchen die Funktionsweise zu erkunden. MfG ede
Datum:
Mal ne Frage an alle Temperaturmesser: Ich benutze auch die hier veröffentlichten Routinen, um 3 Sensoren auszulesen, die mit maximal 15 Meter langen Zwillingslitzen im parasite power Modus angeschlossen sind. Normalerweise funktioniert dies auch wunderbar. Ich starte alle 20 Sekunden eine Konvertierung. Das geht meist gut, aber so etwa alle 3-15 Minuten bekomme ich nach einer Messung von allen drei Sensoren den Wert 85 °C zurück. Also wie nach dem Start, bevor eine Messung eingeleitet wurde. Ich habe schon mit dem Pullup-Widerstand experimentiert von 1 kOhm bis 3,3 kOhm - aber immer das selbe. Auch das Timing der Funktionen w1_reset(), w1_rom_search() und w1_bit_io() habe ich leicht geändert - ebenfalls ohne Erfolg. Auch habe ich die Wartezeit zwischen der Initialisierung der Messung und dem Auslesen des Scratchpads bis zu 2 Sekunden verlängert. Auch ohne Erfolg. Hat jemand ähnliche Probleme oder eine Idee, woran das liegen könnte? Lassen sich bei euch alle Sensoren immer fehlerfrei auslesen? Ich bin etwas ratlos. Dass immer ALLE 3 Sensoren hin und wieder 85 Grad zurückmelden ist seltsam, denn dann muss es doch eigentlich ein systemisches Problem sein und kann keine Störung bei der Übertragung sein. Danke schon vorab für spannende Ideen oder Kommentare! :-) Tschö, Volker
Datum:
ede schrieb: > Würde mich trotzdem über eine einfachere Lösung freuen. Möchte nur den > einen Temp. Sensor zum laufen bringen und danach versuchen die > Funktionsweise zu erkunden. Hallo diesen code verwende ich. Hier die Grundlage : http://www.mikrocontroller.net/attachment/highlight/20338
//*************************************************************** //************ T E M P E R A T U R - S E N S O R **************** //*************************************************************** //Reset 1-Wire-Bus //------------------------------------------------------------- unsigned char ow_reset(void) { uint8_t stat; DDRC = 0xff; //PortC auf Ausgang PORTC = 0x00; //PortC = "Low" delay1(151); //480us warten DDRC = 0x00; //PortC auf Eingang stat = PINC; delay1(29); return(stat); } //Bit auf 1-Wire schreiben //------------------------------------------------------------- void write_bit(char bit) { DDRC = 0xff; //PortC auf Ausgang PORTC = 0x00; //PortC = "Low" if(bit==0) delay1(30); //30 us warten if(bit==1) { delay1(1); PORTC = 0xFF; delay1(30); } DDRC = 0x00; //PortC auf Eingang } //Byte auf 1-Wire schreiben //------------------------------------------------------------- void write_byte(char val) { unsigned char i; unsigned char temp; for(i=0;i<8;i++) { temp = val >> i; temp &= 0x01; write_bit(temp); } delay1(15); } //Bit von 1-Wire lesen //------------------------------------------------------------- unsigned char read_bit(void) { uint8_t bitstat; DDRC = 0xff; //PortC auf Ausgang PORTC = 0x00; //PortC = "Low" delay1(0); DDRC = 0x00; //PortC auf Eingang bitstat=PINC; return(bitstat); } //Byte von 1-Wire lesen //------------------------------------------------------------- unsigned char read_byte(void) { unsigned char i; unsigned char value = 0; for(i=0;i<8;i++) { if(read_bit()) value|=0x01<<i; delay1(15); } return(value); } //Temperatur auswerten //------------------------------------------------------------- void get_temperatur(void) { char get[10],i; unsigned char temp_lsb,temp_msb; int k; unsigned char negative; ow_reset(); //Reset write_byte(0xCC); //Skip Rom write_byte(0x44); //Convert T delay1(15); ow_reset(); //Reset write_byte(0xCC); //Skip Rom write_byte(0xBE); //Read Scratchpad for(k=0;k<9;k++){get[k]=read_byte();} temp_msb = get[1]; temp_lsb = get[0]; negative = 0; i = (temp_msb << 8) + temp_lsb; if (i < 0) { negative = 1; i = -i; } i = (i * 10) / 16; if (negative == 1) i = -i; Transmit_string_to_LCD((LCD_DDRAM_Line_1+0),"101"); /*if(temp_msb<=0x80){temp_lsb = (temp_lsb/2);} temp_msb = temp_msb & 0x80; if(temp_msb>=0x80){temp_lsb = (~temp_lsb)+1;} if(temp_msb>=0x80){temp_lsb = (temp_lsb/2);} if(temp_msb>=0x80){temp_lsb = ((-1)*temp_lsb);}*/ } //************************************************************************************************* //************************************************************************************************* void main(void) { get_temperatur(); } |
Datum:
Volker U. schrieb: > Hat jemand ähnliche Probleme oder eine Idee, woran das liegen könnte? Hi 85 grad kommt ja oft vor. Ich habe im haus ca 20 sensoren. und hatte dieses problem sehr oft. ich habe dann 3 adern 5V - Ground - Daten gemacht. der fehler war weg. kannst du aber testen. hänge doch in 15 metern einfach 3x1,5V Zellen dran um erstmal zu prüfen. Was für kabel benutzt du ( mm²)? ich habe netzwerkkabel - Telefonkabel verdrillt genommen. grüße Sebastian
Datum:
Hi Sebastian! Vielen Dank für deine Hinweise! Erstmal beruhigt es mich, dass das Problem nicht nur bei mir auftritt. sebastian xxlxx schrieb: > 85 grad kommt ja oft vor. Ich habe im haus ca 20 sensoren. und hatte > dieses problem sehr oft. ich habe dann 3 adern 5V - Ground - Daten > gemacht. der fehler war weg. kannst du aber testen. hänge doch in 15 > metern einfach 3x1,5V Zellen dran um erstmal zu prüfen. Ja, ich hatte auch schon die Vermutung, dass es mit der Beschaltung über Parasite Power zusammenhängt. > Was für kabel benutzt du ( mm²)? Leider muss ich ein sehr dünnes Spezialkabel verwenden, da die Leitung auf Putz über Wände geht und nicht groß auffallen darf. Daher habe ich eine hochflexible Zwillingslitze mit 2 x 0,14 mm² (Spezialkabel von Klasing) genommen, die auch nicht verdrillt ist. Der Schleifenwiderstand des Kabels beträgt bei 15 Meter Anschlusslänge (also 30 m Kabellänge) ca. 5 Ohm. Der Widerstand kann hier also keine Rolle spielen. Kämen noch elektromagnetische Störungen in Frage. Was die Störungen betrifft, gibt es aber ein sehr gewichtiges Argument dagegen: Wenn Störungen auftreten würden, warum dann nur beim Konvertierungskommando (CONVERT_T) und niemals beim Auslesen des Scratchpads? Das Auslesen des Scratchpads mit 9 Bytes ist doch viel aufwändiger und störanfälliger als das kurze CONVERT_T-Kommando! Ich habe aber noch NIEMALS einen CRC-Fehler gehabt! Und das spricht erheblich gegen irgendwelche Störungen als Ursache der Probleme. Prüfst du auch die CRC-Summe, oder liest du nur die Temperaturwerte aus? Ich denke, es hat nur was mit der Parasite Power zu zun und nicht mit den Kabeln. Ich fürchte, es ist ein systemischer Fehler in den Sensoren, da ja wohl alle das gleiche Problem haben. Gruß, Volker
Datum:
hi ja das mit dem kabel sollte kein problem sein. teste doch mal das mit dem power. so musst du erstmal kein kabel verlegen wenn du 3x1,5V Zellen nimmst. Das sollte reichen ging ja bei mir auch :-) aus dem Datenbaltt : The power-on reset value of the temperature register is +85°C. was ich auch schon hatte : bei temperaturen um 10-40 grad war alles ok. alles was über 40 grad lag zeige der sensor 85 grad an. da reicht die power nicht aus. 5V an den sensor und schon ging es wieder. viel spaß und berichte über deine ergebnisse sebastian
Datum:
sebastian xxlxx schrieb: > ja das mit dem kabel sollte kein problem sein. teste doch mal das mit > dem power. so musst du erstmal kein kabel verlegen wenn du 3x1,5V Zellen > nimmst. Das sollte reichen ging ja bei mir auch :-) Joa, aber bei allen drei Sensoren einen Batterieklotz dranhängen ist auch keine besonders elegante Lösung ;-). Die Sensoren sollen ja nicht groß auffallen. Aber zum Testen ist das auf jeden Fall mal eine Maßnahme. Im Notfall muss ich eben damit leben, dass nicht jede Konvertierung okay ist. Ich mache es auch jetzt schon so, dass ich, wenn alle drei Sensoren +85,0°C melden, die Werte verwerfe und sofort eine erneute Konvertierung einleite. Meist klappt das dann auch sofort beim nächsten Mal. > was ich auch schon hatte : bei temperaturen um 10-40 grad war alles ok. > alles was über 40 grad lag zeige der sensor 85 grad an. da reicht die > power nicht aus. 5V an den sensor und schon ging es wieder. Ich habe einen Sensor mal zum Testen in einen Kochtopf gehängt und im Wasser gekocht. Da gab es keine Probleme bis 100°C. Begeisternd ist wirklich die hohe Genauigkeit der Sensoren. Diese ist bei mir deutlich höher als im Datenblatt angegeben. Ich löse auf 0,1°C auf und die Temperatur ist von 0 bis 100 Grad etwa auf 0,2°C genau. In meinem kochenden Wasser wurden bei geschlossenem Topfdeckel und nach einigen Minuten Kochen exakt 100,0 Grad angezeigt. Damit hatte ich absolut nicht gerechnet! Und im Eiswasser wurden exakt 0,0° angezeigt. Die Genauigkeit entschädigt allemal für die kleinen Fehler. > viel spaß > und berichte über deine ergebnisse Vielen Dank! Das werde ich tun! Tschaui, Volker
Datum:
Sodele, das Problem ist gelöst!!! Mein System läuft seit mehreren Stunden ohne eine einzige Fehl-Konvertierung! Und Schuld war (wie so oft) nicht die Hardware, sondern die Software. Unsere ganzen Vermutungen waren völlig richtig: Es hatte nichts mit Störungen auf der Leitung zu tun, sondern lediglich mit einem nicht korrekt verarbeiteten CONVERT_T Kommando und mit falscher Parasite Power. Die Hersteller-Dokumentation ist in dem Punkt leider etwas unzureichend. Und so ist mal wieder nicht der Hardware-Produzent schuld, sondern der Software-Entwickler. Die Parasite Power muss SOFORT nach dem CONVERT_T Kommando geschaltet werden. Da darf man keine 10 us warten. Im vorliegenden Fall wird sie in der Funktion start_meas() in tempmeas.c geschaltet. Das ist aber VIEL zu spät, weil zwischen der Übertragung des letzten Bit von CONVERT_T (0x44) und dem Schalten des Ausgangs auf High viel zu viel Zeit vergeht! Die Parasite Power muss schon in der Funktion w1_bit_io() in 1Wire.c geschaltet werden. Und zwar sofort nach der Übertragung des letzten Bit zur Konvertierung. Da darf nicht vorher erst wieder der Ausgang hochohmig geschaltet und noch zahlreiche weitere Operationen ausgeführt werden. D.h. die Funktionen w1_bit_io(), w1_byte_wr() und w1_rom_search() müssen modifiziert werden. w1_bit_io() könnte so aussehen:
uchar w1_bit_io( bit b, bit pull )
{
cli();
W1_DDR |= 1<<W1_PIN;
DELAY( DELAY_US( 2 ));
if( b )
W1_DDR &= ~(1<<W1_PIN);
DELAY( DELAY_US( 10 - 2 ));
if( (W1_IN & (1<<W1_PIN)) == 0 )
b = 0;
DELAY( DELAY_US( 60 - 10 ));
if( pull ) {
W1_OUT |= (1<<W1_PIN);
W1_DDR |= (1<<W1_PIN);
} else
W1_DDR &= ~(1<<W1_PIN);
sei();
return b;
} |
Wenn das "pull"-Flag True ist, wird der W1_PIN nicht erst hochohmig geschaltet, sondern sofort auf Ausgang und auf High, damit die Parasite Power anliegt. Zu beachten ist auch, dass ich das Timing DELAY_US() etwas verändert und den Spezifikationen besser angenähert habe. w1_byte_wr() ist natürlich entsprechend zu modifizieren:
uint w1_byte_wr( uchar b )
{
uchar i = 8, j;
bit cnv = (b == CONVERT_T);
do {
j = w1_bit_io( b & 1, cnv && i == 1 );
b >>= 1;
if( j )
b |= 0x80;
} while( --i );
return b;
} |
Wurde ein CONVERT_T Kommando abgesetzt, wird beim letzten zu übertragenden Bit (i == 1) das "pull"-Flag gesetzt. Alle weiteren Aufrufe von w1_bit_io() müssen jetzt natürlich um den zweiten Parameter (das "pull"-Flag) ergänzt werden, das dann immer auf "0" steht. Diese Aufrufe finden nur noch in w1_rom_search() statt:
uchar w1_rom_search( uchar diff, uchar idata *id )
{
uchar i, j, next_diff;
bit b;
if( w1_reset() )
return PRESENCE_ERR; // error, no device found
w1_byte_wr( SEARCH_ROM ); // ROM search command
next_diff = LAST_DEVICE; // unchanged on last device
i = 8 * 8; // 8 bytes
do {
j = 8; // 8 bits
do {
b = w1_bit_io( 1, 0 ); // read bit
_delay_us(2);
if( w1_bit_io( 1, 0 ) ){ // read complement bit
if( b ) // 11
return DATA_ERR; // data error
} else {
if( !b ){ // 00 = 2 devices
if( diff > i ||
((*id & 1) && diff != i) ){
b = 1; // now 1
next_diff = i; // next pass 0
}
}
}
w1_bit_io( b, 0 ); // write bit
*id >>= 1;
if( b ) // store bit
*id |= 0x80;
i--;
} while( --j );
id++; // next byte
} while( i );
return next_diff; // to continue search
} |
Bei mir konvertiert er nun schon stundenlang ohne einen einzigen Fehler. Und das mit 3 Sensoren an insgesamt 30 Meter langen, unverdrillten und unabgeschirmten Leitungen, die quer durch die Gegend laufen. Selbst ein kräftiges Gewitter, das vorhin war, konnte da nix stören! Nun ist meine Begeisterung für den DS18S20 wirklich komplett :-). Tschö, Volker
Datum:
Hallo Perfekt & super erklärt !!!
Datum:
sebastian xxlxx schrieb: > Perfekt & super erklärt !!! Danke, es freut mich, wenn ich hilfreich sein konnte :). Ich habe übrigens in mittlerweile 24 Stunden nur einmal einen Konvertierungsfehler gehabt. Dies war aber kein 85-Grad-Fehler, sondern ein DATA_ERR in w1_rom_search(). Beim Lesen des Complement Bits ist wohl was schief gelaufen. Aber ich denke, bei 10000 Lesevorgängen darf ruhig mal ein Fehler auftreten ;-). Das ist schon enorm wenig. Übrigens habe ich nochmal ins Datenblatt geschaut und festgestellt, dass Maxim sehr wohl exakte Angaben über das Pullup macht! Dort steht: Time to Strong Pullup On (Start Convert T Command issued): 10 us. 10 us sind also maximal erlaubt zwischen CONVERT_T und dem Pullup am Ausgangs-Pin. Mein Controller läuft "nur" mit 4 MHz. D.h. jeder Taktzyklus ist 0,25 us lang. Nach CONVERT_T dürfen also bis zum Pullup nur 40 Taktzyklen vergehen. Und das war bei 4 MHz mit dem "alten" Code von Peter Dannegger nicht gewährleistet. Wenn man den Controller mit 8 oder 10 MHz taktet, tritt das Problem vermutlich nicht auf. Grüßle, Volker
Datum:
Ich bekomme beim kompilieren immernoch diese Fehler, hab mir den Beitrag hier schon 5 mal durchgelesen. Ich weiß nicht was ich machen soll. Was führt zu dem Fehler?
../TEMPMEAS.C:37: error: invalid conversion from 'unsigned char*' to 'char*' ../TEMPMEAS.C:37: error: initializing argument 1 of 'int sprintf(char*, const char*, ...)' ../TEMPMEAS.C:38: error: invalid conversion from 'unsigned char*' to 'char*' ../TEMPMEAS.C:38: error: initializing argument 1 of 'void uputs(char*)' ../TEMPMEAS.C:45: error: invalid conversion from 'unsigned char*' to 'char*' ../TEMPMEAS.C:45: error: initializing argument 1 of 'int sprintf(char*, const char*, ...)' ../TEMPMEAS.C:46: error: invalid conversion from 'unsigned char*' to 'char*' ../TEMPMEAS.C:46: error: initializing argument 1 of 'void uputs(char*)' ../TEMPMEAS.C:47: error: invalid conversion from 'unsigned char*' to 'char*' ../TEMPMEAS.C:47: error: initializing argument 1 of 'int sprintf(char*, const char*, ...)' ../TEMPMEAS.C:48: error: invalid conversion from 'unsigned char*' to 'char*' ../TEMPMEAS.C:48: error: initializing argument 1 of 'void uputsnl(char*)' |
Datum:
Hallo Welche Version benutzt du ??? 4 oder schon 5.
Datum:
avr studio 4
Datum:
Hi 4 nutze ich auch. Bei nur ging es sofort. Ich meine schon einmal etwas gelesen zu haben das das ".C" am Ende der Datei klein sein muss damit der Code richtig erkannt wird. Leider kann ich dir da aber auch nicht weiterhelfen. Gib doch mal den output in die Suche ein. Sebastian
Datum:
Also normalerweise sollte die implizite typkonvertierung von unsigned auf signed char kommentarlos erfolgen. Vielleicht hilft ja ein expliziter cast. Also vor die variable s überall ein (signed char *) setzen?! Gruß, volker
Datum:
Da wird aber kein (signed char *) erwartet sondern ein (char *). Normalerweise sollte das kein Fehler sonder eine Warnung sein. Mal die Compileroptions anschauen.
Datum:
(char *) und (signed char *) sind das selbe. Normalerweise ist (char *) immer vorzeichenbehaftet, es sei denn, es wurde anders deklariert. printf erwartet einen zeiger auf einen vorzeichenbehafteten string. Du hast aber recht, dass das höchstens eine warnung erzeugen sollte.
Datum:
Volker U. schrieb: > Normalerweise ist (char *) > immer vorzeichenbehaftet, es sei denn, es wurde anders deklariert. Du schreibst es ja selber, man kann char (per Compileroption) auch anders deklarieren. Dann ist dein (signed char *) aber falsch. Das (char *) aber richtig. Da wird ein char* verlangt, also kommt auch nur ein (char *) als cast in Frage.
Datum:
DirkB schrieb: > Da wird ein char* verlangt, also kommt auch nur ein (char *) als cast in > Frage. Aber nicht, wenn (char *) aus irgendeinem grund als unsigned umdefiniert wurde, wie du ja selbst schriebst. Dann wäre (char *) falsch, weil printf immer einen signed erwartet. Es sei denn, man hat auch seine printf-funktion umdefiniert, wovon ich aber mal nicht ausgehe! Die diskussion ist aber akademisch, weil im vorliegenden fall aller wahrscheinlichkeit nach beides richtig wäre. (char *) ebenso wie (signed char *).
Datum:
Hi Das wird beks nicht weiter helfen. Er nimmt den Code von der Seite hier und bekommt diesen Fehler. Da der Code ob Char hin oder her bei den anderen und mir geht. Muss wohl etwas bei den Optionen nicht stimmen. Oder ? Sebastian
Datum:
Wo du recht hast, hast du recht, sebastian. :-) Ich benutze winavr und nicht avr studio. Das wäre vielleicht nochmal ne maßnahme: Winavr, "programmers notepad" und dann ein nativ generiertes makefile... dann klappt es auch mit dem übersetzen. ;-)
Datum:
Hallo Ich nutz Avr Studio 4. @ Beks kannst du den Code mal gezippt schicken? Bzw. Welchen Code von der Seite hier nutzt du. Hier gibt es viele Files inzwischen. Sebastian.
Datum:
Falls ihr die Ursache findet, bitte hier posten! Könnte für andere ja auch interessant sein...
Datum:
hier meldet sich Beks nicht mehr ... erst frage stellen und dann weg sein ... wie schade ... :(
Datum:
Tja, ohne fleiß kein preis. Das muss der gute wohl noch lernen. Bei der heutigen jugend muss ja alles immer sofort klappen, sonst wirds hingeschmissen. Da ist man dann allerdings in der elektro- und softwaretechnik ganz falsch, weil man nur misserfolge erntet. ;-)
Datum:
Wie jetzt :) grinse gerade da ich 24 Jahre bin. Aber ein Vollblut Elektroniker & It Mensch im Beruf. Und dieses Forum hier ist echt Klasse! Habe gerade meine erste heizungssteuerung gebaut. Wärmepumpe + Solar Kopplung und alles mit einem atmega. So macht optimieren Spaß ... Den die Buderus und alpha Inotec steuerteile hatten viele kleine Macken die ich jetzt nicht mehr habe. Ds1820 ist da ein super Sensor! Sebastian
Datum:
:-) Ausnahmen bestätigen die regel. Aber es ist schon so, dass natur- aber vor allem ingenieurwissenschaften zunehmend unbeliebter wurden. Kein wunder, wenn die kids sehen, dass man auch ganz ohne mühe viel geld verdienen kann. Ich habe dieses forum zu nutzen begonnen, als ich mit atmel mcs angefangen habe. Vorher hatte ich motorola benutzt. Aber die waren käse. Deshalb habe ich fast nur analogtechnik entwickelt. Mein erstes projekt zum kennenlernen von atmels war eine temperaturmessstation mit 3 sensoren ds18s20 (innen- u. außentemperatur), lc-display, dcf-empfänger, datenspeicher, untertemperaturwarnung und pc-ankopplung über rs232. Damit mache ich jetzt klimadiagramme. ;-) Ganz lustig und sogar nützlich. Hast du technische unterlagen zu dem heizungssystem gehabt? Denn aus dem stehgreif ist es ja sicher kaum möglich, so eine anlage sinnvoll zu regeln, oder?
Datum:
Ja so schlimm war das gar nicht. Die Anlage hatte ich mit meinem Bruder geplant. Dann erstmal so gebaut wie es sein sollte. Dann eine Wetterstation in der Nähe gefragt um jeden Tag Daten zu bekommen. Nach ca 1 Jahr hatte ich so viele Daten die ich auswerten konnte. Viele Daten habe ich mit ds1820 und atmel + sd Card geloggt. Dann bemerkte ich die Fehler in der Steuerung der wärmepumpe. Es gab Tage wo die Sonne schien aber die Leistung im Puffer Stillstand. Eine wärmepumpe zu steuern ist gar nicht so schwer. Es gibt 3 Sensoren ( Vorlauf - Rücklauf - Kompressor temp ) der Rest sind Pumpe und Mischer. Ich kenne meine Anlage sehr genau. Das reine steuern war recht einfach. Was echt krass war ist eine menu Steuerung. Ich habe ca 40 Werte im original gerät die man ändern kann. Diese ganzen Werte mussten im atmel auch gemacht werden. So Werte wie bei 2 grad ausen muss der Vorlauf immer laufen damit das Wasser im ausenbereich nicht in der wärmepumpe einfriert. Es waren ca 100 Tage Planung - 10 Tage bauen - einbauen und dem original zuschalten ( Vorteil notsteuerung ). War aber ein schönes Projekt für kalte Regentage :) Es gibt da noch ein super Forum für haustechnik wo sich viele wie ich treffen. Meine Heizung kostet im Jahr ca 400 Euro das gleiche haus nebenan benötigt 1400€. Da macht das sparen mehr Spaß :)
Datum:
peter dannegger schrieb: > Die Routine muß für negative Werte leicht geändert werden. Weiss jemand, wie man die Routine ändern muss, damit positive und negative Werte angezeigt werden können?
Datum:
Hi Das kann man im Handbuch sehen. Ich glaube ich hab's so gemacht. Ist das erste Bit ff ff ff ff dann ist das plus. Ist es 00 00 00 00 dann war's Minus. Sieht man aber anhand der Tabelle in der PDF ganz gut. Einfach das erste Bit auswerten. Meine Routinen sind immer so aufgebaut. Wenn es nicht klappt Schau ich mal nach. Viel Spaß Sebastian unterwegs vom iPhone :)
Datum:
Hi! Danke für die schnelle Antwort. Das die Bits 8 bis 15 das Vorzeichen bestimmen habe ich schon verstanden :) Bei 1111 1111 xxxx xxxx wäre laut dem Handbuch negativ. Ich denke mal im Code müsste man dann in der Funktion void read_meas(void) etwas ändern? Ich bin nur noch nicht dahinter gestiegen, wie ich die ersten Bits bekomme und dann prüfen kann. Gruß Robin
Datum:
hi es gibt in der datei tempmeas.c die leseroutine
w1_byte_wr( READ ); // read command
temp = w1_byte_rd(); // low byte
temp |= (uint)w1_byte_rd() << 8; // high byte
if( id[0] == 0x10 ) // 9 -> 12 bit
temp <<= 3;
sprintf( s, " T: %04X = ", temp ); // hex value
uputs( s );
sprintf( s, "%4d.%01døC", temp >> 4, (temp << 12) / 6553 ); // 0.1øC
uputsnl( s );
|
diese habe ich so ersetzt :
w1_byte_wr( READ ); // read command
bite1 = w1_byte_rd(); // byte 1
bite2 |= (uint)w1_byte_rd() << 8; // high byte
if( id[0] == 0x10 ) // 9 -> 12 bit
bite1 <<= 3;
bite3 = w1_byte_rd(); // byte 3
bite4 = w1_byte_rd(); // byte 4
bite5 = w1_byte_rd(); // byte 5
bite6 = w1_byte_rd(); // byte 6
count_remain = w1_byte_rd(); // byte 7
count_per_c = w1_byte_rd(); // byte 8
bite9 = w1_byte_rd(); // byte 9
|
so lese ich alle bits ein. jetzt kann ich auswerten und spielen. ich mache damit eine luftfeuchtemessung. hier die ganze datei. ist aber viel formel für Wetterberechnung
#include "main.h" #include "util/delay.h" #include <stdio.h> void start_meas( void ){ if( W1_IN & 1<< W1_PIN ){ w1_command( CONVERT_T, NULL ); W1_OUT |= 1<< W1_PIN; W1_DDR |= 1<< W1_PIN; // parasite power on }else{ set_cursor(0,2); lcd_string( "Short Circuit !" ); } } void read_meas( void ) { uchar id[8], diff; uint bite1; uint bite3; uint count_remain; uint count_per_c; uchar i; uchar s[30]; float temper1; float temper2; float temp_all; float temp_komma; float muell; float muell1; char output[20]; for( diff = SEARCH_FIRST; diff != LAST_DEVICE; ){ diff = w1_rom_search( diff, id ); if( diff == PRESENCE_ERR ){ set_cursor(0,2); lcd_string( "No Sensor found" ); break; } if( diff == DATA_ERR ){ set_cursor(0,2); lcd_string( "Bus Error" ); break; } if( id[0] == 0x28 || id[0] == 0x10 ){ // temperature sensor set_cursor(0,1); //lcd_string( "ID:" ); //Wert der ID ausgeben // for( i = 0; i < 8; i++ ){ // sprintf( (char*)s, "%02X ", id[i] ); // lcd_string( (char*)s ); // _delay_ms (500); // } w1_byte_wr( READ ); // read command bite1 = w1_byte_rd(); // low byte bite1 |= (uint)w1_byte_rd() << 8; // high byte if( id[0] == 0x10 ) // 9 -> 12 bit bite1 <<= 3; bite3 = w1_byte_rd(); // low byte bite3 = w1_byte_rd(); // low byte bite3 = w1_byte_rd(); // low byte bite3 = w1_byte_rd(); // low byte count_remain = w1_byte_rd(); // low byte count_per_c = w1_byte_rd(); // low byte bite3 = w1_byte_rd(); // low byte //Messwert in Grad Celsius auf LCD ausgeben //sprintf( (char*)s, "%3d.%01dC ", bite1>> 4, (bite1 << 12) / 6553 ); // 0.1øC set_cursor(0,2); //lcd_string( (char*)s ); bite1 = bite1 >> 4; muell = bite1 - 0.25; muell1 = count_per_c - count_remain; temp_all = muell +(muell1 / count_per_c); temp_komma = temp_all; if (id[1]== 0x83 ) { temper1=temp_komma; set_cursor(0,2); dtostrf (temper1,3,2,output); lcd_string( output); lcd_string(" Nass"); } if (id[1] == 0xE6) { temper2=temp_komma; set_cursor(20,2); dtostrf (temper2,3,2,output); lcd_string( output); lcd_string(" Trocken"); //formel double luftdruck; double klein_e; double gross_e_TF; double gross_e_T; double bsp_1; //FEUCHT double bsp_2; //TROCKEN double feuchte; luftdruck= 1013.25; // ca. Luftdruck bsp_1 = temper1; // 19 Grad nass bsp_2 = temper2; // 20 grad Trocken gross_e_TF = 6.11 * exp((17.017 * bsp_1) / (234.175 + bsp_1 )); gross_e_T = 6.11 * exp((17.017 * bsp_2) / (234.175 + bsp_2 )); klein_e = gross_e_TF - 1013.25*(bsp_2 - bsp_1) / 1515; feuchte = klein_e / gross_e_T * 100; dtostrf (feuchte,3,2,output); set_cursor(0,1); lcd_string("Luftfeuchte: "); lcd_string( output); lcd_string("% "); double logEx; double taupunkt; double h; double t; t = temper1; h = feuchte; logEx = 0.66077+7.5*t / (237.3+t) + (log10(h)-2); taupunkt = (logEx - 0.66077)*237.3/(0.66077+7.5-logEx); dtostrf (taupunkt,3,2,output); set_cursor(21,1); lcd_string("Taupunkt: "); lcd_string( output); lcd_string("C "); } } } } |
grüße Sebastian
Datum:
nachtrag : steht im text weiter oben schon drin. Datum: 16.02.2011 16:44 Bitte besser alles von oben nach unten lesen ... grüße Sebastian
Datum:
Könnte mir denn bitte mal eiiner von euch sagen was ich im Code umändern muss damit auch negative Temperraturen ausgegeben werden. Mfg
Datum:
Hallo Schau dir die PDF an. Dort siehst du Beispiele. Du Must nur das Byte auswerten ich glaube ff oder 00 ist - oder +. War eigentlich ganz einfach. Guck dir die Beispiele an.
Datum:
Also das geht in C doch automatisch. Der Sensor liefert den Wert als Zweierkomplement. D.h. man steckt die 2 Bytes, also den 16 Bit Wert in ein int16_t Datentyp und hat automatisch das korrekte Vorzeichen. Wenn man die Temperatur in Grad haben möchte kann man das auch in einen double stecken und durch 16 Teilen. Fertig. Da muss absolut nichts selber rumgerechnet werden mit dem Vorzeichen. Selbst wenn die eigentliche 1Wire-Routine nur einen Unsigned Typ liefert reicht ein Cast nach int16_t aus. Hier mal ein Auszug aus meinem Code. Die ow_read_word Funktion liefert auch nur einen unsigned typ:
uint16_t ow_read_word() {
uint8_t b1=ow_read_byte();
uint8_t b2=ow_read_byte();
uint16_t result=b2;
result<<=8;
result+=b1;
return result;
}
int16_t DS18B20_getRawTemp() {
ow_reset();
ow_write(OW_SKIP);
ow_write(DS_CMD_TEMP);
_delay_ms(1500);
ow_reset();
ow_write(OW_SKIP);
ow_write(DS_CMD_READ);
return ow_read_word();
}
void DS18B20_getTempAsText(int16_t t,char *s) {
char tmp[10];
int16_t t1=t/16;
int16_t t2=abs(t % 16);
t2*=10;
t2/=16;
itoa(t1,s,10);
strcat(s,",");
itoa(t2,tmp,10);
strcat(s,tmp);
tmp[0]=(char)223;
tmp[1]='C';
tmp[2]='\0';
strcat(s,tmp);
}
|
gruß cyblord
Datum:
HALLO, vielen Dank erstmal,aber bei mir haut das nicht hin. ich bekomme nur eine vorkommastelle und eine nachkommastelle angezeigt, 2,9 und ohne vorzeichen. vielleicht kann mir hier von ihnen jemand weiterhelfen mfg
// --- lokale Variablen ------------------------------------------------------- // --- lokale Funktionen ------------------------------------------------------ uint8_t OWReset(void); void OWWriteByte(unsigned char byte_value); void OWWriteBit(unsigned char bit_value); uint8_t OWReadByte(void); uint8_t OWReadBit(void); uint8_t docrc8( uint8_t number_of_bytes_to_read ); // ---------------------------------------------------------------------------- // liest den ROM-Code des in diesem Moment einzigen (!) angeschlossenen One-Wire-Devices, // der ROM-Code steht anschließend im globalen Array ow_buffer[]. // Danach wird die CRC geprüft // Rückgabe: - TRUE wenn CRC und Family-Code stimmt uint8_t OW_read_rom_code(void) { uint8_t i; OWReset(); OWWriteByte(READ_ROM); for (i = 0; i < 8; i++) ow_buffer[i] = OWReadByte(); // nun steht der ROM-Code in ow_buffer put_c(13); for (i = 0; i < 8; i++) // ROM-Code ausgeben { put_s(utoa(ow_buffer[i], msg, 16)); put_c(' '); } if ((ow_buffer[7] == docrc8(7)) && (ow_buffer[0] == DS18B20)) { put_s("ok "); return (TRUE); // TRUE zurückgeben, wenn CRC identisch } else { put_s("crc"); // Fehlermeldung geben, wenn CRC nicht stimmt return (FALSE); } } // ---------------------------------------------------------------------------- // liest das komplette Scratchpad eines Temperatursensors aus, // die Daten steht anschließend im Array ow_buffer[], // es wird noch die CRC geprüft uint8_t OW_read_scratchpad(uint8_t idx) { uint8_t i; EEPROM_read_rom_code(idx); // den zugehörigen ROM-Code aus dem // EEprom nach ow_buffer[] einlesen OWReset(); // ein Reset senden OWWriteByte(MATCH_ROM); for (i = 0; i < 8; i++) OWWriteByte(ow_buffer[i]); OWWriteByte(READ_SCRATCHPAD); for (i = 0; i < 9; i++) ow_buffer[i] = OWReadByte(); // nun steht der ROM-Code in ow_buffer return (ow_buffer[8] == docrc8(8)); } // ---------------------------------------------------------------------------- // sendet ein SKIP ROM mit nachfolgendem CONVERT an alle mithörenden Sensoren // danach muss ca. 1 Sekunde gewartet werden, bis die konvertierten Daten aus // den einzelnen Sensoren ausgelesen werden können. void OW_convert_all(void) { uint8_t i = 80; OWReset(); OWWriteByte(SKIP_ROM); OWWriteByte(CONVERT); // ggf. DQ auf HIGH ziehen // ONE_WIRE_PORT &= ~(1<<ONE_WIRE_POWER_PIN); while(i--) _delay_ms(10); // 0.8 Sekunden warten // ggf. DQ wieder freigeben // ONE_WIRE_PORT |= 1<<ONE_WIRE_POWER_PIN; // rx_flag = FALSE; // während des Wartens empfangene Kommandos verwerfen } // ---------------------------------------------------------------------------- // liefert FALSE, wenn im EEPROM kein Platz mehr für Sensordaten ist, // sonst den Index für den nächsten freien Speicherplatz // Die Eeprom-Adresse wird aus dem Index ermittelt durch Multiplikation mit 8 ! uint8_t OW_eeprom_free(void) { uint8_t i; for (i = 1; i < (EEPROM_SIZE / 8); i++) // die Adressen 0 - 7 sind reserviert { if (ee_read_byte(i * 8) == 0xFF) { return(i); // die erste Stelle zurückgeben, an der } // Byte.0 == 0xFF } // denn bei einem Sensor muss hier der Family-Code stehen return(0); // wenn kein freier Platz gefunden } // ---------------------------------------------------------------------------- // durchsucht das EEPROM, ob der neu angelernte ROM_CODE im Array ow_buffer[] // bereits im EEPROM gespeichert ist, // liefert TRUE, wenn der Code bereits vorhanden ist ! uint8_t OW_rom_code_exists(void) { uint8_t i, j, z, result = FALSE; for(i = 8; i < (EEPROM_SIZE - 8); i = i+8) { z = 0; for (j = 0; j < 8; j++) { if (ee_read_byte(i + j) == ow_buffer[j]) z++; } if (z == 8) { result = TRUE; // wenn alle 8 Bytes identisch waren break; // die Suche abbrechen } } return (result); } // ---------------------------------------------------------------------------- // liest das EEPROM aus, ermittelt die Anzahl der Sensoren (sensor_cnt) // liest das Messintervall (messintervall) ein. // void OW_read_eeprom(void) { uint8_t i; sensor_cnt = 0; for (i = 8; i < (EEPROM_SIZE - 8); i += 8) { if ((ee_read_byte(i) == DS18B20)) // der Family-Code muss 0x28 sein { sensor_cnt++; // Anzahl der registrierten Sensoren } } messintervall = (ee_read_byte(ADR_MESSINTERVALL) << 8); // high-Byte messintervall += ee_read_byte(ADR_MESSINTERVALL + 1); // low-Byte // wenn == 0xFF, dann default-Wert wählen if (messintervall == 0xFFFF) messintervall = MESSINTERVALL; start_modus = ee_read_byte(ADR_AUTOSTART); } // ---------------------------------------------------------------------------- // wandelt den Messwert, der aus 2 Byte besteht, in einen String (mit einer Nachkommastelle) um. // Der Messwert steht rechtsbündig in den globalen Variablen ow_buffer[0] und ow_buffer[1], // (die Werte entsprechen scratchpad.Byte[0] / scratchpad.Byte[1]) // Das Ergebnis wird über den globalen String msg[] zurückgegeben. void DS18B20_convert_temperatur(void) { int16_t temp16; uint8_t i = 0; ow_buffer[1] = ow_buffer[1] << 4; // lower nibble im high-Byte nach links schieben // upper nibble im low-Byte nach rechts schieben und // zum high-Byte addieren. ow_buffer[1] += (ow_buffer[0] >> 4); // die Vorkommastellen stehen jetzt in ow_buffer[1] // da upper-nibble der Nachkommastellen maskieren, ow_buffer[0] &= 0x0F; // die Nachkommastellen stehen in ow_buffer[0] temp16 = (int16_t) ow_buffer[1] * 10; // die Nachkommastelle: temp_lo * 0.625 = temp_lo * 625 / 1000 = temp_lo * 640 / 1024 temp16 += (int16_t)ow_buffer[0] * 640 / 1024; // Nun das Dezimaltrennzeichen einschmuggeln: itoa(temp16, msg, 10); // die Zahl in einen String umwandeln while(msg[i]) i++; // die Position der terminierende /0 finden msg[i] = msg[i - 1]; // die Nachkommastelle nach rechts schieben msg[i - 1] = '.'; // statt dessen ein Dezimaltrennzeichen einfügen msg[++i] = 0; // Am Ende wieder eine /0 anfügen } //----------------------------------------------------------------------------- // 1-Wire Functions to be implemented for a particular platform //----------------------------------------------------------------------------- //----------------------------------------------------------------------------- // Reset the 1-Wire bus and return the presence of any device // Return TRUE : device present // FALSE : no device present // alle Wartezeiten gem. APP_Note 126, Page 2-3 // Gesamtdauer: DELAY_G + DELAY_H + DELAY_I + DELAY_J = 1 + 480 + 70 + 410 = 921us uint8_t OWReset(void) { uint8_t r; _delay_us(DELAY_G); DQ_LOW; // DQ auf Low ziehen _delay_us(DELAY_H); DQ_INPUT; // DQ als Eingang schalten DQ_HIGH; // auf high schalten (Pullup aktivieren) _delay_us(DELAY_I); // warten bis zum Lesen der Antwort r = DQ_READ; // Antwort einlesen if (r) r = FALSE; else r = TRUE; // die Leitung sollte auf LOW gezogen sein DQ_OUTPUT; // DQ wieder als Ausgang schalten _delay_us(DELAY_J); return(r); } //----------------------------------------------------------------------------- // Send 8 bits of data to the 1-Wire bus // void OWWriteByte(unsigned char byte_value) { uint8_t i = 8; while(i--) { OWWriteBit(byte_value & 0x01); // das rechts stehende Bit senden byte_value = byte_value >> 1; // um 1 Stelle nach rechts schieben } } //----------------------------------------------------------------------------- // Send 1 bit of data to the 1-Wire bus // DG ist durchgängig als Ausgang geschaltet // alle Wartezeiten gem. APP_Note 126, Page 2-3 // Gesamtdauer: DELAY_A + DELAY_B = DELAY_C + DELAY_D = 6 + 64 = 60 + 10 = 70us void OWWriteBit(uint8_t bit_value) { cli(); DQ_LOW; // DQ auf Low ziehen if (bit_value) // Write 1 { _delay_us(DELAY_A); // 5 us auf Low lassen DQ_INPUT; // DQ durch Pullup auf High ziehen _delay_us(DELAY_B); // 40us warten } else // Write 0 { _delay_us(DELAY_C); // 45us auf Low lassen DQ_INPUT; // DQ durch Pullup auf High setzen // DQ_HIGH; _delay_us(DELAY_D); } DQ_OUTPUT; // DQ wieder als Ausgang schalten DQ_HIGH; sei(); } // ---------------------------------------------------------------------------- uint8_t OWReadByte(void) { uint8_t i = 8; uint8_t data = 0; while(i--) { data >>= 1; if (OWReadBit()) data |= 0x80; } return(data); } //----------------------------------------------------------------------------- // Read 1 bit of data from the 1-Wire bus // Return 1 : bit read is 1 // 0 : bit read is 0 // alle Wartezeiten gem. APP_Note 126, Page 2-3 // Gesamtdauer: DELAY_A + DELAY_E + DELAY_F = 6 + 9 + 55 = 70us uint8_t OWReadBit(void) { uint8_t r; cli(); DQ_LOW; // DQ auf Low ziehen _delay_us(DELAY_A); // 6 us warten DQ_INPUT; // als Eingang schalten DQ_HIGH; _delay_us(DELAY_E); // warten und dann messen r = DQ_READ; _delay_us(DELAY_F); DQ_OUTPUT; // DQ wieder als Ausgang schalten sei(); return (r); } // ---------------------------------------------------------------------------- // liest den ROM_Code von Device idx (ROM-ADresse = idx * 8) aus dem EEProm // und schreibt ihn in das globale Array ow_buffer[] // gibt TRUE zurück, wenn die CRC stimmt uint8_t EEPROM_read_rom_code(uint8_t idx) { uint8_t i; idx *= 8; // jeweils 8 Byte bilden einen ROM_Code for ( i = 0; i < 8; i++) ow_buffer[i] = ee_read_byte(idx + i); return (ow_buffer[7] == docrc8(7)); // wenn die CRC stimmt, TRUE zurückgeben } // ---------------------------------------------------------------------------- // schreibt den ROM_Code aus ow_buffer[] ins EEPROM an die Position idx // die EEPROM-Adresse dazu ist mit vorher mit 8 zu multplizieren void EEPROM_write_rom_code(uint8_t idx) { uint8_t i; idx *= 8; // jeweils 8 Byte bilden einen ROM_Code for ( i = 0; i < 8; i++) ee_write_byte((idx + i), ow_buffer[i]); } // ---------------------------------------------------------------------------- // vergleicht den ROM_Code aus ow_buffer[] mit dem im EEPROM an der Stelle idx // liefert TRUE zurück, wenn ROM_CODE in ow_buffer[] == ROM_CODE im Eeprom // Der ROM-Code steht an der EEPROM-Adresse idx * 8. uint8_t EEPROM_compare_rom_code(uint8_t idx) { uint8_t i; uint8_t cmp = TRUE; idx *= 8; // jeweils 8 Byte bilden einen ROM_Code for ( i = 0; i < 8; i++) if(!(ee_read_byte(idx + i) == ow_buffer[i])) cmp = FALSE; return (cmp); } |
Datum:
also bei mir sinds derzeit 23.1 grad aber als ausgabe erhalte ich nur 3.1 kann mir keiner weiterhekfen mfg
Datum:
Leider mal wieder nicht das komplette Programm gepostet. Die fehlende '2' könnte durch eine fehlerhafte Ausgabefunktion verursacht sein, die ich nicht kenne. Bist du sicher, dass DS18B20_convert_temperatur() das macht, was du erwartest (besonders für negative Zahlen)? Vorschlag: für alle möglichen Werte in einer Schleife testen. Vermutlicher Fehler: ow_buffer[1] += (ow_buffer[0] >> 4); ow_buffer ist vermutlich signed char (im Post nicht definiert). Wenn das höchst Bit gesetzt ist, werden bei >> 1en eingefügt, die hier vermutlich falsch wären.
Datum:
Der DS18B20 liefert das Ergebnis in 16-tel Grad vorzeichenbehaftet als 16-bit-Zahl, die bei dir in ow_buffer[0] und ow_buffer[1] ankommt. Du möchtest aber 10-tel Grad haben. Also musst du nur doch nur die beiden Bytes richtig auf eine int16_t zuweisen, mit 10 multiplizieren und durch 16 dividieren (bitte selbst testen):
int16_t temp16 = (uint16_t)ow_buffer[0]; // low-Byte temp16 |= ((uint16_t)ow_buffer[1]<<8); // high-Byte temp16 *=10; // Anzeige als 10-tel Grad temp16 /=16; // Sensor liefert 16-tel |
Datum:
Josef D. schrieb: > Der DS18B20 liefert das Ergebnis in 16-tel Grad vorzeichenbehaftet als > 16-bit-Zahl, die bei dir in ow_buffer[0] und ow_buffer[1] ankommt. > Du möchtest aber 10-tel Grad haben. > Also musst du nur doch nur die beiden Bytes richtig auf eine int16_t > zuweisen, mit 10 multiplizieren und durch 16 dividieren > (bitte selbst testen): >
> int16_t temp16 = (uint16_t)ow_buffer[0]; // low-Byte > temp16 |= ((uint16_t)ow_buffer[1]<<8); // high-Byte > temp16 *=10; // Anzeige als 10-tel Grad > temp16 /=16; // Sensor liefert 16-tel > |
Steht btw genau so in dem Code den ich hier gepostet habe.
Datum:
"so ähnlich" würde ich ja gelten lassen. Die Sonderbehandlung der Nachkommastelle(n) und negativer Zahlen ist nicht erforderlich und fehlerträchtig. Auch der Modulo-Operator hat so seine Tücken: http://embeddedgurus.com/stack-overflow/2011/02/ef...
Datum:
Moin moin, vielleicht kann ja jemand was mit dem Code anfangen, den ich seit über einem Jahr sehr zuverlässig zum Auslesen meiner Sensoren benutze. Er basiert auf dem Code von Peter Dannegger (*.h Dateien sowie 1wire.c) sowie meiner weiter oben vorgestellten Anpassung zur Verhinderung von Fehlkonvertierungen durch zu langsam zugeschaltete Parasite Power. Er liest sämtliche am Bus angeschlossene Sensoren aus (egal ob DS18S20 oder DS18B20). Für die Zwischenspeicherung der in temp zurückgelieferten Werte muss man bei Anschluss mehrerer Sensoren allerdings selbst sorgen. Die Routine arbeitet mit Komplementbildung, ist aber mit allen Temperaturen getestet (auch nahe 0°, also -0.1, 0.0, +0.1 etc.) und arbeitet absolut sauber. Außerdem kann sie von selbst erkennen, ob ein DS18S20 oder DS18B20 Sensor angeschlossen ist. Der DS18B20 kann konfiguriert werden auf 9, 10, 11 oder 12 Bit Auflösung. Der Rückgabewert in der Integer-Variablen Temp ist in 1/10 Grad. Also -456 für -45.6 Grad oder 237 für +23.7 Grad.
#define DS_TEMP_LS 0 #define DS_TEMP_MS 1 #define DS_TH 2 #define DS_TL 3 #define DS_RES1 4 #define DS_RES2 5 #define DS_REM 6 #define DS_PER 7 #define DS_CRC 8 // Initialisierung der Sensoren void init_meas( unsigned char resolution ) { // resolution in Bit (9-12) uchar id[8], diff; for( diff = SEARCH_FIRST; diff != LAST_DEVICE; ){ diff = w1_rom_search( diff, id ); if( diff == PRESENCE_ERR ) return; if( diff != DATA_ERR && id[0] == 0x28 ){ w1_byte_wr( WRITE ); // write command w1_byte_wr( '\0' ); w1_byte_wr( '\0' ); w1_byte_wr( (uchar)( resolution << 5 ) ); } } temp_buffer[DS_TEMP_ERR] = 0; /* Error-Register */ } // Messung starten void start_meas( void ) { if( W1_IN & 1<< W1_PIN ){ w1_command( CONVERT_T, NULL ); //W1_OUT |= 1<< W1_PIN; //W1_DDR |= 1<< W1_PIN; // parasite power on } else { temp_buffer[DS_TEMP_ERR] = 1; /* Error-Register */ //softuart_puts( "DS1820: Short Circuit !\r\n" ); } } // Daten auslesen (vorher ausreichend Zeit warten - je nach // Sensor-Auflösung zwischen 100 und 800 ms) void read_meas( void ) { uchar id[8], diff; uchar scratchpad[9]; int temp; for( diff = SEARCH_FIRST; diff != LAST_DEVICE; ) { diff = w1_rom_search( diff, id ); temp_buffer[DS_TEMP_ERR] = 0; /* Error-Register */ if( diff == PRESENCE_ERR ){ temp_buffer[DS_TEMP_ERR] = 2; /* Error-Register */ //softuart_puts( "DS1820: No Sensor found\r\n" ); break; } if( diff == DATA_ERR ){ temp_buffer[DS_TEMP_ERR] = 3; /* Error-Register */ //softuart_puts( "DS1820: Bus Error\r\n" ); break; } if( id[0] == 0x28 || id[0] == 0x10 ){ // temperature sensor (10h = DS18S20, 28h = DS18B20 // Scratchpad im Temperatursensor lesen w1_byte_wr( READ ); // read command for( temp = 0; temp < 9; temp++ ) scratchpad[temp] = w1_byte_rd(); // Scratchpad füllen (9 Bytes) // CRC8 berechnen if (crc8( scratchpad, 8 ) != scratchpad[DS_CRC] ) { temp_buffer[DS_TEMP_ERR] = 5; /* Error-Register */ break; } if( id[0] == 0x10 ) { // DS18S20 if( scratchpad[DS_TEMP_MS] ) { // Negativer Temperaturwert scratchpad[DS_TEMP_LS] ^= 0xFF; // Einer-Komplement scratchpad[DS_TEMP_LS]++; // inkrementieren } scratchpad[DS_TEMP_LS] >>= 1; // rechtes Bit für 0,5 °C rausschieben (durch 2 teilen) // Temperatur mit 0,1 °C Genauigkeit berechnen temp = (int)scratchpad[DS_TEMP_LS]*100 - 25 + (int)(scratchpad[DS_PER] - scratchpad[DS_REM]) * 100 / scratchpad[DS_PER]; if( scratchpad[DS_TEMP_MS] ) // Negativer Temperaturwert temp *= -1; temp /= 10; // Zweite Nachkommastelle abtrennen } else { // 0x28: DS18B20 if( scratchpad[DS_TEMP_MS] & 0xF8 ) { // Negativer Temperaturwert scratchpad[DS_TEMP_LS] ^= 0xFF; // Einer-Komplement scratchpad[DS_TEMP_LS]++; // inkrementieren scratchpad[DS_TEMP_MS] ^= 0xFF; // Einer-Komplement temp = -( ((int)scratchpad[DS_TEMP_MS] << 8) | (int)scratchpad[DS_TEMP_LS] ) * 10 / 16; } else { temp = ( ((int)scratchpad[DS_TEMP_MS] << 8) | (int)scratchpad[DS_TEMP_LS] ) * 10 / 16; } } if( (temp == 850 && temp_buffer[DS_TEMP_ERR] == 0 ) { // Konvertierung nicht erfolgreich oder nicht abgeschlossen temp_buffer[DS_TEMP_ERR] = 4; /* Error-Register */ } else { // Hier die erfolgreich gelesenen Temperaturwerte verarbeiten und zwischenspeichern } } } } |
Datum:
Bei meinem obigen Beispiel ist der Parameter "resolution" bei init_meas() etwas missverständlich beschrieben. Für 9 bit Auflösung muss als Wert in resolution 0 übergeben werden, für 10 Bit eine 1, für 11 Bit 2 und für 12 Bit 3. Also nicht etwa der Wert 9-12, wie man vermuten könnte. Sorry! Volker
Datum:
Der Beitrag von Sebastian ist zwar schon über ein Jahr alt, aber bisher wurde er nicht kommentiert. Aus meiner Erfahrung heraus ist dazu aber was zu sagen: Sebastian xxlxx schrieb: > Warum eigentlich 0.1 grad ? > Ich habe 20 Sensoren auf eine metall Platte geklebt. > Alle ausgelesen und Werte von - + 2 grad erhalten. > Die sensoren haben auch leichte eigenerwärmung. Also das mit der Eigenerwärmung stimmt, ist aber nur relevant, wenn man bei sehr niedrigen Temperaturen (unter -10 Grad) in Luft arbeitet und jede Sekunde eine Messung mit 12 Bit Auflösung durchführt. Nur dann kommt es meiner Erfahrung nach zu Abweichungen von mehr als 0,1 Grad. Wenn der Sensor auf einer Metallplatte klebt, ist eine so extreme Abweichung von 2 Grad (oder gar 4 Grad absolut) für mich nicht nachvollziehbar! Ich habe 10 Sensoren aus 3 unterschiedlichen Chargen nebeneinander liegend (in Luft) getestet und keiner zeigte eine größere Abweichung als 0,1 Grad an. Die Auflösung war dabei 12 Bit und das Messintervall 5 Sekunden. Die großen Abweichungen müssen meiner Meinung nach andere Ursachen haben und liegen sicher nicht an der Hardware der Sensoren. Es sei denn, die von dir getesteten Sensoren sind sehr alt und Maxim hat vor einigen Jahren die Produktion geändert. Neuere Sensoren sind m.E. nicht so extrem ungenau. Tschö, Volker
Datum:
ich nutze den DS18S20 Temperratur wird auch richtig ausgegeben wie Volker es beschrieben hat. nun meine Frrage, ich wollte das gerne so lösen das ich als ausgabe bei Plus-Temperraturen zB. +22.3 oder +05.3 als Ausgabe erhalte und bei den Minuswerten das gleiche. nur bei der Umsetzung tu ich mich ein bischen schwer. so wie ichs jetzt habe bekomme ich ein minus und plus als Vorzeichen und der Temperraturwert stimmt auch nicht mehr vielleicht kann von euch mir da noch weiterhelfen. mfg
char gs[30]; int8_t Vorzeichen; int temp1; int temp; int8_t Vorkommastelle; int16_t Nachkommastelle; if( scratchpad[DS_TEMP_MS] ) { // Negativer Temperaturwert scratchpad[DS_TEMP_LS] ^= 0xFF; // Einer-Komplement scratchpad[DS_TEMP_LS]++; // inkrementieren } scratchpad[DS_TEMP_LS] >>= 1; // rechtes Bit für 0,5 °C rausschieben (durch 2 teilen) // Temperatur mit 0,1 °C Genauigkeit berechnen temp = (int)scratchpad[DS_TEMP_LS]*100 - 25 + (int)(scratchpad[DS_PER] - scratchpad[DS_REM]) * 100 / scratchpad[DS_PER]; if( scratchpad[DS_TEMP_MS] ) // Negativer Temperaturwert { temp *= -1; } else { Vorzeichen = '+'; // } // temp /= 10; // Zweite Nachkommastelle abtrennen Vorkommastelle = temp; Nachkommastelle = temp; Nachkommastelle = (temp1 * 10.0); Nachkommastelle = (Nachkommastelle % 100); Nachkommastelle = Nachkommastelle % 10; sprintf(gs,"%2d,%1d", Vorkommastelle, Nachkommastelle); put_c(Vorzeichen); put_s( gs); |
Datum:
ein kleiner fehler
char gs[30]; int8_t Vorzeichen; int temp1; int temp; int8_t Vorkommastelle; int16_t Nachkommastelle; if( scratchpad[DS_TEMP_MS] ) { // Negativer Temperaturwert scratchpad[DS_TEMP_LS] ^= 0xFF; // Einer-Komplement scratchpad[DS_TEMP_LS]++; // inkrementieren } scratchpad[DS_TEMP_LS] >>= 1; // rechtes Bit für 0,5 °C rausschieben (durch 2 teilen) // Temperatur mit 0,1 °C Genauigkeit berechnen temp = (int)scratchpad[DS_TEMP_LS]*100 - 25 + (int)(scratchpad[DS_PER] - scratchpad[DS_REM]) * 100 / scratchpad[DS_PER]; if( scratchpad[DS_TEMP_MS] ) // Negativer Temperaturwert { temp *= -1; } else { Vorzeichen = '+'; // } // temp /= 10; // Zweite Nachkommastelle abtrennen Vorkommastelle = temp; temp1= temp; Nachkommastelle = (temp1 * 10.0); Nachkommastelle = (Nachkommastelle % 100); Nachkommastelle = Nachkommastelle % 10; sprintf(gs,"%2d,%1d", Vorkommastelle, Nachkommastelle); put_c(Vorzeichen); put_s( gs); |
Datum:
Also erst einmal: Vorkommastelle ist ein char und temp ein Integer. Das Zuweisen von temp an Vorkommastelle fürt zu einer unzulässigen Datenkonvertierung. Vorkommastelle muss also auch ein Integer sein (int16_t). temp enthält zudem die Temperatur in 1/100 Grad. So wird ein Schuh draus:
int16_t Vorkommastelle; [..] Vorkommastelle = temp / 100; temp1= temp; Nachkommastelle = (temp1 % 100); Nachkommastelle = (Nachkommastelle / 10); printf("%2d,%1d", Vorkommastelle, Nachkommastelle); |
Zu beachten ist, dass temp auch negativ sein kann. Wenn du das Vorzeichen also manuell erzeugst, musst du entweder die Zeile "temp *= -1;" weglassen, oder auf temp bzw. auf die daraus erzeugten Daten später die Funktion abs() anwenden. Gruß, Volker
Datum:
Volker U. schrieb: > Zu beachten ist, dass temp auch negativ sein kann. Wenn du das > vorzeichen also manuell erzeugst, musst du entweder die Zeile "temp *= > -1;" weglassen, oder auf temp später die Funktion abs() anwenden. > ich wollte nur das Plus zeichen separat ausgeben aber leider funktiniert das bei mir nicht. der sensor liegt grad im eisfach dort sinds -9.0grad aber das Pluszeichen wird mitausgegeben. Laut Datenblat; The sign bits (S) indicate if the temperature is positive or negative: for positive numbers S = 0 and for negative numbers S = 1. if( scratchpad[DS_TEMP_MS] == 1 ) // Negativer Temperaturwert { temp *= -1; } else { Vorzeichen = '+'; // } Vorkommastelle = temp / 100; temp1= temp; Nachkommastelle = (temp1 % 100); Nachkommastelle = (Nachkommastelle / 10); sprintf(gs,"%2d,%1d", Vorkommastelle, Nachkommastelle); put_c(Vorzeichen); put_s( gs);










