Hallo zusammen,
auch wir haben uns etwas intensiver mit dem 1-Wire-Bus beschäftigt und
das Ganze in einem kleinen Projekt einmal ganz speziell für den Anfänger
und den Einsteiger "ganz von unten her" aufgezogen.
Fertige Softwarelösungen gibt es ja schon einige, aber oftmals möchte
man auch wissen, wie man selbst entsprechende Funktionen für den
1-Wire-Bus erstellt.
Auch gibt es ja noch mehr Bausteine für dieses Bussystem als nur den
DS18S20er.
In unserem Projekt erklären wir also die Theorie und zeigen dann
schrittweise auf, wie man sebst Programme in C entwickelt.
Für die praktische Seite haben wir ein kleines 1-Wire-Experimental-Board
entwickelt, mit dem die digitalen Temperatursensoren DS1820 / DS18S20,
der 4-fach A/D-Wandler DS2450 und der 8-fach digital I/O-Expander DS2408
betrieben werden können. Ergänzt wird der Funktionsumfang noch durch ein
LC-Dispaly mit 4 Zeilen und 20 Spalten am 1-Wire-Bus.
Als 1-Wire-Bus-Master kommt ein 8051er zum Einsatz und die Software ist
in C geschrieben für die IDE µC/51.
Alle Infos werden frei und offen zu Verfügung gestellt und können
beliebig weiter benutzt werden.
So ist auch ein einfacher Transfer auf andere µC-Plattformen möglich.
Das ganze Projekt ist in drei Teile aufgeteilt, die nach und nach hier
veröffentlicht werden.
Heute startet der erste Teil.
Viel Spaß wünschen
Bernd u. Peter
Hi,
ich möchte mich schonmal für das schöne PDF bedanken. Ich mach zwar
nicht so oft was mit 1Wire, werds aber als Lektüre zum Nachschlagen auf
alle Fälle mal ausdrucken.
Gruß - Markus
Hallo zusammen !
Es geht weiter mit unserem Projekt:
im Anhang findet ihr die Version V1.1 mit den neuen Kapiteln 4 und 6,
d.h. nun wird der DS18S20er ausführlich beschrieben und die komplette
DS18S20er-API ist enthalten incl. eines ausführlichen Demo-Programms.
Viel Spaß
Bernd
Danke für die Ausarbeitung, ich bin gerade dabei für ein Projekt die
geeigneten Temperatursensoren auszuwählen, werde mir wohl mal zum testen
einen DS18S20 besorgen.
Sowas könnte bei verschiedenen Compilern unterschiedlich optimiert
werden, kann also durchaus mal nicht das gewünschte Delay bewirken.
Besser:
1
voidow_delay(unsignedchardelay)
2
{
3
while(--delay);
4
}
Das while(--x) entspricht in Assembler direkt dem DJNZ, ergibt also
2*delay Zyklen Verzögerung.
2.
1
ow_delay(73);// 496 us warten
Solche festen Werte sind sehr unschön. Wenn Du mal nen anderen Quarz
nimmst oder ein Derivat mit anderer Zykluszahl, geht das große
Fehlersuchen los.
Der C-Compiler rechnet Konstanten schon zur Kompilezeit aus. Tu Dir also
keinen Zwang an und schreib einfach die Formel hin.
Dann mußt Du auch nur an einer Stelle was ändern:
Nur ein Gedanke:
_delay_us(xy)
Könnte man sich dann nicht die Formel sparen. Bitte verbessert mich
falls das nicht geht. Ich bin erst vor kurzem in die uC-Programmierung
eingestiegen.
Ich freu mich schon auf den nächsten Teil der Doku. Bis jetzt ist sie
sehr gut verständlich.
Gruß Franz
Hallo zusammen !
Nun geht es weiter mit unserem 1-Wire-Projekt:
das PT-1-Wire-ExBo ist mittlerweile fertig und wird getestet.
Als neuen 1-Wire-Slave beschreiben wir den 4-fach A/D-Wandler DS2450 und
nehmen diesen in Betrieb - API und Demo-Software gibts natürlich dazu.
Das komplette Kapitel 7 beschäftigt sich mit diesem Chip.
Im Anhang gibts dazu die aktuelle Projekt-Doku mit allen Source-Files
!!!
Als nächstes wird der 8-fach PIO-Baustein DS2408 in unseren Bus
integriert !
@ Peter:
Bist Du sicher, daß so etwas:
void ow_delay(unsigned char delay)
{
while( --delay );
}
nicht auch von den Compilern wegoptimiert wird ?
Die Idee mit dem berechneten delay werden wir beim nächsten Up-Date mit
einbauen, wenn unser Compiler das mit macht.
Vielen Dank für den Tip !
@ Einsteiger:
Viele Compiler kennen zwar ´delay_ms(...)´ aber ´delay_µs(...)´ kann
unser Compiler nicht und ich glaube auch nicht, daß es so etwas fertig
bei anderen Compilern gibt.
Viel Spaß mit dem 1-Wire-Bus !
Bernd u. Peter
Hallo Zusammen,
erstmal Danke für dieses tolle Projekt. Werd es mir wohl einfacher
machen und die API von microchip verwenden (bei PIC ergibt sich das so),
aber dieses Projekt hilft mir super für das Verständnis.
(auch wenn ich nicht alle Operatoren kenne :( )
Nun eine Frage, einmal wird geschrieben, dass die anderen Slaves wieder
in den Stand-by verfallen wenn einer angesprochen wird und beim anderen
Mal steht, dass sofort nach dem Ansprechen eines Slaves das nächste
angesprochen werden kann.
Welcher Fall ist nun richtig? (bzw. wann wird in den Stand-by gegangen
und der Bedarf nach einem erwachen ist da, Reset)
(Leider liegt das Dokument grade nicht neben mir und auf der Arbeit
downloaden ist immer so ne Sache für sich.)
Hi,
super Beschreibung und API. Hier ein kleiner Optimierungsvorschlag :
Statt :
unsigned char ow_rd_byte(void)
{
unsigned char i;
unsigned char wert = 0;
// 8 Bits hintereinander einlesen, LSB zuerst
for(i=0; i<8; i++)
{
if (ow_rd_bit()) wert |=0x01 << i;
}
return(wert);
}
so:
unsigned char ow_rd_byte(void)
{
unsigned char i;
unsigned char wert = 0;
// 8 Bits hintereinander einlesen, LSB zuerst
for(i=0; i<8; i++)
{
if (ow_rd_bit())
{
wert |=0x01;
}
wert <<= 1;
}
return(wert);
}
Dies hätte den Vorteil, dass je Schleifendurchlauf nur einmal geschoben
werden muss. Das Byte würde sich so von rechts nach links langsam
füllen. Bei deiner Lösung würde bei logisch "1" jedesmal x-mal
geschoben, da die "1" zuerst an ihre endgültige Position gesetzt wird
bevor die "ver-ODER-ung" kommt. Dies benötigt einfach mehr Laufzeit.
Aber dennoch super Projekt. Mein Einwand soll auch keine Kritik sein, es
ist mir halt aufgefallen.
Hallo Bernd und Peter,
tolles Projekt, werde ich gut gebrauchen können.
A propos, Projekt Nr. 275, gibt es noch weitere Projekte aus Eurer
Feder?
Viele Grüße
Lautersoft
Hallo,
mal eine Frage, wie bekomme ich eigentlich die Seriennummer von einen
neuen 1-Wire Baustein am Bus, oder wie ist der Ablauf wenn der One Wire
Viewer den Bus scannt und alles Seriennummern am Bus anzeigt?
Schöne Grüße
Thomas
Hallo zusammen,
vielen Dank erst einmal für die ganzen Anregungen zu unserem Projekt.
So nach und nach werden wir versuchen, diese mit einzubauen.
Zunächst möchten wir das Projekt zum Abschluß bringen, d.h. die Teile
mit dem DS2408er fertig stellen und das PT-1-Wire-ExBo fertig machen.
Die Teile mit dem DS2408er (dig. I/O und LC-Display-Ansteuerung) laufen
bereits und die Demo-Software-Pakete sind schon fertig.
Momentan wird alles noch "schön" beschrieben, so daß wir wahrscheinlich
gegen Ende August fertig sein werden.
Nun noch zu den Fragen:
@Lautersoft:
es gibt noch eine Menge kleinere Projekte, speziell für Anfänger auf dem
Gebiet der µC-Technik, die alle auf unserem kleinen Experimentalsystem
laufen.
Da es sich hierbei aber vorzugsweise um SPI-, I2C- und
1-Wire-Bus-Projekte handelt, können diese natürlich auch mit anderen
Plattformen betrieben werden.
Die Software ist duchgängig in ´C´ geschrieben und kann daher auch
leicht angepaßt werden.
Nach dem 1-Wire-Projekt werden wir noch andere Projekte veröffentlichen.
@Thoams:
die Serien-Nummer von 1-Wire-Slaves kann auf zwei Arten ermittelt
werden:
1) Mit Hilfe des Befehls ´Read ROM´, aber nur dann, wenn genau ein
Baustein am Bus angeschlossen ist.
Aus diesem Chip kann der Master dann die Seriennummer auslesen.
So machen wir das in unserer Software und Du kannst die Lösung dort
nachlesen.
2) Wenn mehrere Slaves am Bus angeschlossen sind, kannst Du den
Suchalgorithmus mit ´Search ROM´ verwenden und der Master kann so eine
Liste mit allen Serien-Nummern von allen Slaves am Bus ermitteln.
Dieses Verfahren hat aber einen großen Nachteil:
Wenn Du im System z.B. 10 Temperatursensoren DS18S20er verbaut hast, so
bekommst Du eine Liste mit 10 Seriennummern, aber was dann ?
Du weist dann eben nicht, wo welcher Sensor eingebaut ist, bzw. welche
Sensor-Nr. zu welchem Sensor gehört.
Du mußt also jeden Sensor einzeln ausmessen und dann einbauen und Dir im
Programm "irgendwie" merken, welcher Sensor welche Nr. hat.
Viel Spaß weiterhin mit dem 1-Wire-Bus
Bernd u. Peter
1Wirrerer ;) schrieb:> Nun eine Frage, einmal wird geschrieben, dass die anderen Slaves wieder>> in den Stand-by verfallen wenn einer angesprochen wird und beim anderen>> Mal steht, dass sofort nach dem Ansprechen eines Slaves das nächste>> angesprochen werden kann.>>>> Welcher Fall ist nun richtig? (bzw. wann wird in den Stand-by gegangen>> und der Bedarf nach einem erwachen ist da, Reset)
Na toll und ich werde übergangen :(
Hallo 1Wirrerer ;)
ich habe angenommen, daß sich die Frage schon erledigt hat, da Du das
Dokument nur nicht auf der Arbeit hast, sondern zu Hause.
Aber hier die Antwort:
Durch einen Master-Reset werden alle Slaves aufgeweckt (das ist u.a. der
Sinn dieses Impulses) und antworten ihrerseits mit dem Presence-Impuls.
Danach hängt es vom nächsten Befehl ab, wie die Slaves weiter reagieren:
ist der Befehl für sie "gemeint" bleiben sie aktiv, z.B. bei einer Read
ROM-, bei einer Skip ROM- oder bei einer Match ROM Anweisung mit ihrer
Adresse. (Wobei Read-ROM und Skip-ROM i.a. natürlich nur bei einem Slave
am Bus richtig funktionieren, Ausnahmen gibts u.a. beim DS18S20er),
Ansonsten gehen die Slaves wieder in den Stand-By-Zustand.
Viele Grüße
Bernd
Hallo,
ich habe mal die Bussignale beim auslesen eines DS2450 aufgezeichnet,
vielleicht interessiert es ja jemanden.
@Bernd u. Peter
Wegen dem Search ROM, ich nutze eine fertige Software diese scannt den
Bus nach neuen Teilnehmern, doch hat die Software eine Serie DS2438
nicht gefunden, daher wollte ich mal wissen wie das mit den Search ROM
funktioniert.
Dank eurer Anleitung habe ich den Fehler gefunden, die DS2438 haben
einen unüblichen Family Code.
Beitrag "1-Wire DS2438 mit Family Code A6?"
Schöne Grüße
Thomas
1Wirrerer ;) schrieb:> und beim anderen>> Mal steht, dass sofort nach dem Ansprechen eines Slaves das nächste>> angesprochen werden kann.
Das wollte ich ja wissen, dann ist obere Text nicht ganz korrekt, da ja
vorher noch ein Reset ausgeführt werden muss.
Hallo,
@Bernd u. Peter
Ihr könnt die Bausteine und Protokolle wirklich gut erklären, vielleicht
nehmt ihr noch mal den DS2438 mit in euer Projekt mit auf.
Schöne Grüße
Thomas
Hallo,
unter http://frank.bol.ucla.edu/2313Temper8.htm habe ich eine sehr gute
Beschreibung bzgl. der Berechnung der erweiterten Temperaturberechnung
des DS18s20 mittels des CounterRemain-Registers gefunden.
Zuerst wird das komplette Scratchpad[0-8] eingelesen und dann der
folgende Code zur Berechnung durchgeführt.
Hier einmal meine C Umsetzung als Interger Wert :
// Auf negative Temperatur prüfen
if (aucScratchpad[1] != 0) // Wenn negativ, dann
{
aucScratchpad[0] = (~aucScratchpad[0]) + 1; // 2er Komplement !
}
// Formel des obigen Links (!)
// Temperatur = (((16*aucScratchpad[0])+12-aucScratchpad[6])*25)/4
usExtTemperature = (aucScratchpad[0]>>1); // Low-Byte durch 2
teilen
usExtTemperature = usExtTemperature * 16;
usExtTemperature = usExtTemperature + 12;
if(aucScratchpad[6] > 12) // Damit kein Überlauf bei T=0°C passiert!
{
usExtTemperature = usExtTemperature - 12;
}
else
{
usExtTemperature = usExtTemperature - aucScratchpad[6];
}
usExtTemperature = usExtTemperature * 25;
usExtTemperature = usExtTemperature >> 2;
=> usExtTemperature (vom Datentyp : unsigned short bzw. unsigned int)
enthält wie im obigen Link beschrieben die Temperatur in 0.06°C
Auflösung sprich 85°C = 8500 = 85.00 bzw. -55°C = 5500 = 55.00 (bei
negativen Vorzeigen muss sich das Vorzeichen bei der ersten if-Abfrage
gemerkt werden (Vorzeichenflag, im obgien Code entfernt!)
Auch wenn dieser Code-Schnipsel nicht alle Tricks und Kniffe (wie z.B.
Verwendung von /= , += etc.) enthält finde ich ihn halt sehr
verständlich und durchschaubar, gerade für Anfänger. Ganz nebenbei, er
funktioniert sogar.
Hallo,
ich habe eine kleine Verständnisfrage (bin noch Anfänger). Ich versuche
gerade das Programm für den DS1820 für meinen Atmega8 umzuschreiben.
Entspricht die Zeile
zw = DQ; // DQ einlesen und speichern
aus der Funktion unsigned char ow_rd_bit(void) in ow.h dieser Zeile:
zw = PC0; ???
(der Tempsensor hängt an Port C0)
Danke für eure Hilfe. Ich frage nach, da ich nicht schon bei den
grundlegenden Funktionen etwas falsch machen möchte.
Viele Grüße
Winston
Hallo zusammen !
Es ist geschafft !
Unser 1-Wire-Projekt ist, bis auf einige kleine Punkte, fertig gestellt.
Im Anhang sind also alle Beschreibungen und alle Programme zum Betrieb
von wichtigen 1-Wire-Komponenten enthalten:
- Temperatursensor DS1820
- 4-fach-A/D-Wandler DS2450
- 8-fach digitale Port-Erweiterung DS2408 zur Ansteueurng von:
- Relais, LEDs, Taster, Summer
- alphanumwerisches LC-Display, 4 Zeilen á 20 Zeichen
und das alles über NUR EINEN digitalen I/O-Port-Pin des µCs !!
Das 1-Wire-Bus-Experimental-Board (PT-1-Wire-ExBo) ist in ca. 3 Wochen
erhältlich.
Wir werden nach und nach weitere interessante 1-Wire-Bausteine
vorstellen und in das Projekt mit einbinden.
Also viel Spaß mit dem 1-Wire-Bus !
Bernd und Peter.
Meine Herren...!
Ich gebe 7 große Daumen für diese gute Arbeit! Es verdient Respekt, ein
solch gutes und einfach verständliches Projekt zu erarbeiten.
Ich verwende meinen DS18S20 nun dank diesem Projekt innerhalb eines
Tages, obwohl ich bis heute von 1Wire nix gehört hatte. Echt ganz großes
Kino!
tieferKnicks von mir für diese Arbeit!
Hallo Ihr beiden!
Erstmal ein RIESENGROSSES Dankeschön für das tolle Howto!
Ich hab aber trotzdem noch ne frage, und zwar zum Einlesen von Bits:
In der Grafik ist der Master-Sample beides mal VOR "T0 +15us" und in der
Beschreibung steht, dass SPÄTESTENS nach "T0 +15us" der Master den Wert
einliest.
Im Codebeispiel wartet Ihr aber MINDESTENS 15us (nach den Messungen
15,2us).
Was ist jetzt richtig? mindestens oder maximal 15us?
@Winston:
Falls dus nicht schon selber gefunden hast:
in ow.h wird DQ initialisiert.
das wirft bei mir selber ne frage auf: DQ ist doch durch "unsigned char
bit DQ @ 0xb4;" nem Register zugeordnet. Ich hab bis jetzt in der uni
nur an atmega32 programmiert und da war es so, dass man den pin über das
PORTx Register ansprechen musste, also z.b. PORTA |= 1<<3; setzt PORTA
pin 4 auf logisch 1. Aber jetzt ist doch der Pin P3.4 (aus den
kommentaren) nicht auf register 0xb4 auf bit 0, oder? ich hab da im
datasheet nichts dazu gefunden.
mfg Daniel
Gust schrieb:> Dies hätte den Vorteil, dass je Schleifendurchlauf nur einmal geschoben> werden muss. Das Byte würde sich so von rechts nach links langsam> füllen. Bei deiner Lösung würde bei logisch "1" jedesmal x-mal> geschoben, da die "1" zuerst an ihre endgültige Position gesetzt wird> bevor die "ver-ODER-ung" kommt. Dies benötigt einfach mehr Laufzeit.
Es wird aber das niederwertigste Bit zuerst gelesen(V1.3 S. 43). Mit
deiner Methode wird das erste bit aber immer weiter nach oben geshiftet.
mfg Daniel
ds1820.c:
// Fehler-Prüfung: Scrartch-Pad-Inhalt aufaddieren
sum = 0; // Fehler-Summe löschen
for(i=0; i<9; i++) sum = sum + ds1820[i];
if(sum == 2295) ftemp = 555;
Easy-CRC ;-)
Da sollte man lieber nochmal drüberschauen...
Ansonsten: schön gemacht!
Ich spiele mich gerade hiermit:
Title: DS18X20-Functions via One-Wire-Bus
Author: Martin Thomas <eversmith ät heizung-thomas.de>
http://www.siwawi.arubi.uni-kl.de/avr-projects
Hat auf Anhieb funktioniert, aber ebenfalls noch Optimierungspotential.
Hallo zusammen
Ich bin gerade dabei den Code auf einen AtMega 8 umzuschreiben.
Ich habe jetzt leider noch Probleme mit der zuweisung der Variablen DQ
für den Port. Das ist ja Inline Assembler für Neumann Compiler. Ich
verwende aber den gcc. Wie kann ich da den Pot in Inline zuweisen?
Stoß mich mal jemand bitte etwas an!
Daniel S. schrieb:> Gust schrieb:>> Dies hätte den Vorteil, dass je Schleifendurchlauf nur einmal geschoben>> werden muss. Das Byte würde sich so von rechts nach links langsam>> füllen. Bei deiner Lösung würde bei logisch "1" jedesmal x-mal>> geschoben, da die "1" zuerst an ihre endgültige Position gesetzt wird>> bevor die "ver-ODER-ung" kommt. Dies benötigt einfach mehr Laufzeit.>> Es wird aber das niederwertigste Bit zuerst gelesen(V1.3 S. 43). Mit> deiner Methode wird das erste bit aber immer weiter nach oben geshiftet.>> mfg Daniel
dann verodere eben mit 0x80 und schiebe nach rechts.
auf jeden fall keine "1 << i" - orgie ;-)
p.s. sorry fuers kleinschreiben. "großmach" - taste ist kaputt
Hallo,
ich hoffe es liest jemand noch diesen Thread. Ich hab das mal so gemacht
wie beschrieben und es funktioniert sogar :-).
Den Sensor habe ich mit 5V gespeist (also nicht parasitär) und lese nun
die Temperatur aus.
Aber die Werte sind doch arg daneben. Der zeigt mir eine
Zimmertemperatur von knapp 26 Grad an, die hab ich aber garnicht. Halte
ich den Finger dran wird es wärmer. Ich hab den Code von visitor (Gast)
vom 28.08.2010 17:24 benmutzt.
Kann es sein dass die 5V Speisung eine Eigenerwärmung des Sensors
bewirken? Ich lese ihn alle 20 Sekunden aus und lasse ihn dazwischen in
Ruhe. Hat da jemand Erfahrungen gesammelt?
Danke vorab für eure Meinungen.
Thomas
Hallo Thomas!
ich hab auch erst am Sonntag den Thread hier angefangen zu lesen.
Ich wollte etwas eigenes basteln und siehe da, es gibt diese
hervorragende Arbeit der beiden. Großes Lob und Dank.
Hast Du jetzt vor einen Kühlkörper an den Sensor zu bauen?
Ich wollte mir nämlich ein paar von den Sensoren zulegen und vielleicht
kann ich die Bestellliste noch erweitern.
Gruß
Hi,
von mir stammt der Code Schnippsel vom 28.08.2010 17:24 und ich kann nur
sagen, dass der korrekt rechnet. Meine DS18s20 zeigen auch Temperaturen
an welche mit anderen Thermometern einem Vergleich stand halten.
Weiterhin kann ich keine übermäßige Erwärmung an den Sensoren
feststellen.
@Thomas
Meine Vermutung ist, dass bei Deinem Aufbau etwas nicht stimmt und der
Sensor seine Eigenerwärmung misst. Dem Thema Kühlkörper stehe ich
skeptisch gegenüber. Irgendwie wiederspricht das einem Temperatursensor
!!!
Hallo,
ich hab auf parasitäre Versorgung umgestellt, zwei Drähte dran gelötet
und das Teil mal etwas ins "Abseits" gestellt.
Es kann sein dass in der Nähe des Prozessors auf der Platine (es ist
eine Jumbo Uhr mit Thermometer) etwas Wärme entsteht.
So etwas entfernt zeigt es richtig an, auch ohne Kühlkörper.
Also es war der Abstand zum Rest der Schaltung der es gebracht hat.
@visitor: Danke für den Codeschnipsel, das rechnet richtig, kann ich
bestätigen.
Schönen Abend,
Gruß aus dem Rhein Main Gebiet
Thomas
Hallo
Ich habe vom Fuchs Onlineshop den LinkHub-E Multichannel.
Wollten uns eigentlich die Temperatursensoren bauen, aber sobald ich
mehr als 2 anschließe, habe ich eine Fehlerhafte Kommunikation.
Weiß jemand ob der LinkHub-E limitiert ist?
Danke!
BvB schrieb:> Hallo zusammen !> Es geht weiter mit unserem Projekt:> im Anhang findet ihr die Version V1.1 mit den neuen Kapiteln 4 und 6,> d.h. nun wird der DS18S20er ausführlich beschrieben und die komplette> DS18S20er-API ist enthalten incl. eines ausführlichen Demo-Programms.>> Viel Spaß>> Bernd
Hallo Bernd,
zwar noch nicht jetzt, da ich erstmal noch mit Arduino lerne, aber
sicher werde ich den bald brauchen.
Unter Arduino hatte ich den zwar schon zum laufen, aber nicht so wie ich
wollte und da ich noch Luftfeuchte brauchte, habe ich den DHT11
genommen.
Aber vielen, vielen Dank! Leute wie dich braucht die Welt (zumindest ein
kleiner Teil davon (ich)).
Lieben Gruß
Frank
Hallo Bernd,
Super Erklärung der 1-Wire.
Ich würde gerne eure library auf einem ATmega8 zum laufen bringen.
Ich verstehe nicht wie ich die ow.h ändern muss um einen
PIN für die Datenleitung auszuwählen.
Ich verwende das AVR Studio.
unsigned char bit DQ @ 0xb4; // Port-Pin P3.4 = b4h
Wie muss ich diese Zeile abändern, um z.B den PIN PC5 als
Datenpin zu verwenden?
Danke im Voraus.
MfG Tom
BvB schrieb:> 2) Wenn mehrere Slaves am Bus angeschlossen sind, kannst Du den> Suchalgorithmus mit ´Search ROM´ verwenden und der Master kann so eine> Liste mit allen Serien-Nummern von allen Slaves am Bus ermitteln.> Dieses Verfahren hat aber einen großen Nachteil:> Wenn Du im System z.B. 10 Temperatursensoren DS18S20er verbaut hast, so> bekommst Du eine Liste mit 10 Seriennummern, aber was dann ?> Du weist dann eben nicht, wo welcher Sensor eingebaut ist, bzw. welche> Sensor-Nr. zu welchem Sensor gehört.> Du mußt also jeden Sensor einzeln ausmessen und dann einbauen und Dir im> Programm "irgendwie" merken, welcher Sensor welche Nr. hat.
Ich habe die alle auf dem Breadboard drauf, lese die Rom's ein, lese
dann alle Temperaturen und dann halte ich mal einen Finger auf einem
nach dem anderen drauf und schon hab ich die passende Nummer. Danach
kann ich den gezielt in anderer Schaltung ansprechen.
Im Datenblatt zum DS18B20 steht der ganze 1-Wire Bus komplett
beschrieben, da bleiben eigentlich keine Fragen offen. Sind auch nur 22
Seiten.
1w-slave selbst programmieren
bei der umstellung von 5v auf 3v microcontroller - wegen TFT - ergab
sich das Problem, dass die über transistoren angeschlossenen 9 RElais
nicht mehr geschaltet haben. Ich habe dann zwei shift-register 74hc595
eingebaut und über drei der früher 9 Ausgänge geschaltet. Das
funktionierte mit dem 5Volt Controller, bei 3Volt kamm es trotz pullup
zu Störungen.
Die nächste Überlegung war, die shift-register durch einen
pin-kompatiblen mega8 zu ersetzen und diesen über den 1wire-bus zu
steuern. Da ds18b20-Sensoren auch mit 3 Volt zuverlässig ausgelesen
werden, müsste dies eigentlich problemlos gehen, weil Empfangs- und
Senderoutinen ohnehin vorhanden sind.
Ein fertiger 1w-shift-register baustein soll nicht verwendet werden,
weil der m8 potentiell auch weitere Funktionen übernehmen kann, z.b.
watchdog für den Hauptcontroller und Notprogramm.
Leider funktionierte das ganze nicht. Im us-Bereich war kein Signal mehr
zu erkennen.Ich habe mir dann mit einem vereinfachten bus im ms_Bereich
geholfen. Sehr langsam aber sehr zuverlässig. Trotzden stellt sich die
Frage, ob man einen DS-1wire-Slave nicht mit den vorhandenen Sende- und
Empfangsroutinen selbst programmieren kann.
Als Anregung mein Code:
#include "config.h"
#define owx_port B
#define owx_pin 0
#define lcd_test 0
#define owx_out
sbi(DDR(owx_port),owx_pin);cbi(PORT(owx_port),owx_pin)
#define owx_in
cbi(DDR(owx_port),owx_pin);sbi(PORT(owx_port),owx_pin)
#define owx_signal !gbi(PIN(owx_port),owx_pin)
#define owx_out_high sbi(PORT(owx_port),owx_pin)
#define owx_out_low cbi(PORT(owx_port),owx_pin)
#define ERROR wait;led_off;return(0xffff);
//======================================================================
==========
void sub_owx_senden(u16 dat){
owx_out;
_delay_ms(15);//Prüfsignal
owx_out_high;
_delay_ms(15);
for(u8 i=0;i<16;i++){
owx_out_low;
_delay_ms(15);
if(dat & 0x8000)_delay_ms(10);
dat = dat<<1;
owx_out_high;
_delay_ms(15);
}
owx_in;
}
//======================================================================
==========
u16 sub_owx_empfangen(void){
u16 dat=0xffff,i=0,teiler;
u16 testdat[18];
led_on;
while(owx_signal && i<65000)i++;//Prüfsignal
//testdat[0]=i;
teiler=i/3*4;//i*9/4
i=0;
while(!owx_signal && i<65000)i++;//
for(u8 j=0;j<16;j++){
i=0;
while(owx_signal && i<65000)i++;
//if(i<(teiler/2))ERROR;
//if(i>(teiler*2))ERROR;
//i=i/teiler;
//testdat[j+1]=i/teiler;
//li(i/teiler);
//if(i==0)ERROR;//Problem????
if(i/teiler==1)dat++;
//if(i>1)ERROR;
if(j<15)dat<<=1;
while(!owx_signal && i<65000)i++;//
}
//if(i!=3)ERROR;
/*lgi(1,1,testdat[0]);lw("-");
li(testdat[1]);lw("-");
li(testdat[2]);lw("-");
li(testdat[3]);lw("-");
li(testdat[4]);lw("-");
li(testdat[5]);lw("-");
lgi(2,1,testdat[12]);lw("-");
li(testdat[13]);lw("-");
li(testdat[14]);lw("-");
li(testdat[15]);lw("-");
li(dat);
//li(testdat[16]);
//lgi(10,1,testdat[13]);
*/
//lgi(1,1,dat);
//lgi(1,1,i);lw("-");
return(dat);
}
//======================================================================
==========
//=================================================
void main(void){
u8 signal,i=255;
u16 dat=0xffff;//error
u16 timer;
u8 timer2;
init_all();
owx_in;
#if lcd_test
lcd_init();
lw("test");
#endif
while(1){//#######################################
timer++;
if (timer==10){timer2++;}
if
(timer2==10){timer2=0;led_on;_delay_ms(25);led_off;}//Bereitschaftsanzei
ge
//if(gbi(PINC,3))sbi(PORTC,4);else cbi(PORTC,4);
//_____________________________________________________
//_____________________________________________________
if (owx_signal) {timer2=0;dat=sub_owx_empfangen();}
if(dat!=0xffff){//
if(dat>(511)){//fehler nur 9bits, da nur 9 relais
wait;led_off;
}else{
//dat=511;
if(gbi(dat,0))out0_on;else out0_off;//WP b6
if(gbi(dat,1))out1_on;else out1_off;//P1 b7
#if lcd_test
lgi(1,1,dat);lw(" ");//lcd an d4...d7
#else
if(gbi(dat,2))out2_on;else out2_off;//WW d5
if(gbi(dat,3))out3_on;else out3_off;//Wz d6
if(gbi(dat,4))out4_on;else out4_off;//Ku d4
#endif
if(gbi(dat,5))out5_on;else out5_off;//Bd d0
if(gbi(dat,6))out6_on;else out6_off;//lu d1
if(gbi(dat,7))out7_on;else out7_off;//No d2
if(gbi(dat,8))out8_on;else out8_off;//Le d3
/* */
//bestätigung gültiges signal 3secd
led_blink;//ok-signal anzeige
led_off;
// wait;
}
dat=0xffff;
}// !=0xffff
}// while
}// main
Kann mir jemand helfen, ich bekomme immer nur eine Null angezeigt(Kein
slave am bus).Was ist das Problem bei der Read Funktion???
Benutze AtMega16 f=8MHz
Hallo zusammen,
ich las gerade in der Anleitung:
> Während der Kommunikation über den 1-Wire-Bus darf der> Mikrocontroller durch KEINE INTERRUPTS gestört werden,> alle Interrupts müssen also während der Kommunikation> disabled sein!
Ich bin gerade dabei, das Protokoll ohne delay-Schleifen, also mit
Timer-Interrupts umzusetzen. Da bei mir parallel noch I²C- und
UART-Kommunikation laufen sollen und mehrere PWMs erzeugt werden sollen,
geht das m.E. kaum anders. I²C und UART erzeugen ja auch Interrupts und
für die PWMs brauche ich auch einen Timer-Interrupt, da ich bei mir
nicht genügend Capture/Compare Blocks frei habe.
Wie hier zu sehen, arbeite ich mit einem zusätzlichen
32768Hz-Uhrenquarz:
http://www.mikrocontroller.net/articles/1-wire_als_Hausbus#mit_Interrupts
Ich habe bisher in diesem Forum noch nie Code gepostet und wundere mich
immer, wenn in Forumsbeiträgen irgenwo Code "vergraben" ist. Soll ich
den Code besser im Wiki ablegen oder von dort hierher verlinken oder wie
macht man das am besten? Welche Wiki-Seite wäre dafür die richtige?
VG Torsten
Moinsen die Herren und Damen,
habe mich gerade darüber gefreut diesen Thread gefunden zu haben. Danke
für die Mühen an dieser Stelle.
Habe selber grade den Plan mit 1-Wire zu experimentieren, allerdings
benötige ich SEEEEEEEEEEEHR viele Slavebausteine. Jetzt musste ich lesen
das Maxim/Dallas der einzige Hersteller von 1-Wire Chips ist? Ist das
immernoch so? Wenn ja, wie groß ist der Adressbereich in diesen
Bausteinen?
Hoffe meine Frage wird hier noch gefunden ^^
Icke_wa schrieb:> Wenn ja, wie groß ist der Adressbereich in diesen> Bausteinen?
Der Adressbereich ist praktisch unendlich, da jedes Device seine
eineindeutige ROM-ID hat.
Es gibt aber sicher eine Grenze, ab der die Bus-Belastung zu groß wird.
Müsste sich in den Datenblättern finden.
Da spricht dann aber nix dagegen, deine seeeeehr vielen Slaves auf
mehrere Busse aufzuteilen.
Michael Reinelt schrieb:> … auf mehrere Busse aufzuteilen.
Ja, genau. Und falls der Master-Knoten kein "Massenprodukt" werden soll
und es nicht auf ein paar Cent an kommt, gibt es dafür z.B. den
DS2482-800 8-Channel 1-Wire Master
Die Lösung wäre sehr skalierbar: Bis zu 8 verschiedene I²C-Adressen,
also bis zu 8 x 8 = 64 1wire-Busse.
Oh ja habe grade den Adressbereich gefunden ... Sollte reichen ^^ Das
mit der Belastung wird sowieso mein großes Problem. Jeder Slave muss bis
zu 4 LEDs gleichzeitig ansteuern. Insgesammt sollte sich dafür ein Strom
im ganzen Ampere-Bereich ergeben. Daten werden aber wohl um so seltener
ausgetauscht.
Mehrere Busse war auch schon eine Idee. Gut zu wissen, dass es auch da
schon einen Baustein für gibt ;) Auf ein paar Cent kommt es
wahrscheinlich nicht an ... so groß sollte die Auflage nicht werden XD
Werd mich mal weiter einlesen. Für Fragen scheint hier ja ne Menge know
how zu sein. Danke schonmal für die schnellen und hilfreichen Antworten!
Icke_wa schrieb:> Jeder Slave muss bis> zu 4 LEDs gleichzeitig ansteuern.LEDs????
Bist du sicher dass du 1-Wire Devices verwendest, und nicht z.B. WS2812
RGB-LEDs? Letzteres ist kein 1-Wire, sondern irgendein proprietäres
serielles Protokoll
Ok ich erläuter die Idee mal etwas genauer. Jeder Slave besteht aus
einem MC und 6 LEDs bzw. 2xRGB. Jeder Knoten Slave soll jetzt seperat
ansprechbar sein und seine Farbe individuell ändern können. Das große
Problem ist wegen des Umfelds die Menge an Leitungen. Am liebsten wären
mir halt nur zwei (also One Wire) im schlimmsten Fall könnte man wohl
auf drei erweitern (Gnd + Vcc + Data).
Was genau ist dieses WS2812? Kommt das mit 2 Leitungen aus?
Icke_wa schrieb:> Jeder Slave besteht aus einem MC und 6 LEDs bzw. 2xRGB.
Das klingt nach einem LPD8806, der kostet nur ein paar Cent, die Pins
sind schön weit auseinander (1,27mm) und er hat Konstantstrom! Ein µC
hat keine Konstantstrom-Ausgänge. Gibt es sowas auch mit One-Wire?
http://www.aliexpress.com/snapshot/269538586.html
Also wenn ich mir das mit dem WS2812 anscaue, sieht das schon ziemlich
genau nach dem aus, was ich gerne hätte. Scheint zwar ein brutalstes
gefrickel zu sein, aber dafür ist die LED so wunderbar kompakt ... denke
das könnte klappen ... und wenns nich one wire ist dann ist das auch
nich so wichtig. Hauptsache maximal 2 Leitungen. Den LPD werd ich mir
auch mal anschauen, aber das sieht so erstmal nicht nachdem was ich
brauche aus.
Besten Dank für die Tipps und Hinweise. Das könnte mir unter Umständen
sehr viel arbeit abnehmen ;)
So nach recht wenig Recherche wurde klar, dass die WS2812 zwar toll
sind, aber leider 3 statt 2 Leitungen benoetigen. Koennte man aber ja
theoretisch auch noch hinbekommen, wenn man davor einfach einen One Wire
Slave setzt, der quasi nochmal Daten von Versorgung trennt. Wenn der
WS2812 aber die One Wire Versorgung bekommt (die ja bei Datenverkehr
auch gerne mal ploetzlich verschwindet um wieder aufzutauchen) ist der
WS2812 da sicherlich ungluecklich oder? Meint ihr man koennte mit einem
Kondi die Versorgung von dem WS2812 so gerade biegen, dass er nicht
ausfaellt? Sorry meine Hardwaretage sind ne Weile her :(
Nebenher kommt mir aber noch ein ganz anderes Problem. Durch die vielen
bunten Laempchen kommt ein ganz schoener Strom zusammen.
Kurzes Rechenbeispiel:
2xRGB Led pro Slave (angenommen das max. 2 LEDs pro RGB-LED laeuchten.
Ergo: worst case Stromaufnahme pro Slave = 2x2x30mA = 120mA)
Bei 10 Slaves habe ich also schon mehr als 1A auf der Leitung. Gibt es
einen Masterbaustein der mit so einer Groessenordnung von Strom noch
umgehen kann? Was fuer Probleme auf der Leitung koennten mir entgegen
treten?
Besten Dank fuer den Gehirnschmalz ;)
Icke Wa schrieb:> wenn man davor einfach einen One Wire> Slave setzt, der quasi nochmal Daten von Versorgung trennt.
Das wird nicht funktionieren. One Wire hat auch 3 Leitungen. Nur im
"parasite power" Modus wird mit einem Kondensator gepuffert.
120mA puffern kannst Du versuchen, auch ohne 1wire, also mit der WS2812.
Aber der Kondensator und ggf. die Spannungs-Stabilisierung wird deutlich
größer als die LED.
Was Du suchst, ist vielleicht ein Power-Line-Modem. genau das trennt die
Daten von der Versorgung.
PS: Außerdem haben die WS2812 keine "Adresse" (wie bei 1wire). Daher
müssen alle auf einmal (dasy chain) beschrieben werden. Die Puffer-Zeit
würde damit immens steigen.
Warum der Aufwand? Warum nicht einfach drei Leitungen nehmen?
Hehe glaub mal die Option einfach drei Leitungen zu nehmen gehe ich
jeden Tag wieder durch. Die LEDs sollen quasi einzeln auf eine
Schraublochmatrix aufschraubbar sein und dann individuell bedienbarsein.
Dabei ist nicht gesagt in welchem Winkel die LED-Kloetze aufgeschraubt
werden. Sprich ich brauche schon bei zwei Adern, zwei Schleifkontakte um
in jeder moeglichen Anschraubposition eine Verbindung zum LED-Klotz zu
haben. Die Kloetzchen selber sind unterschiedlich gross. Nach unten gibt
es keine Grenze ausser: "so klein wie moeglich" :/
Habe auch schon ueberlegt ob ich nicht auf WLAN, Bluetooth oder
aehnliches Umsteige. Bin bisher nur in der Hoffnung, dass ich es kleienr
als das hinbekomme ...
Hi,
und BT/WLAN ist kleiner als ein IC und 3 Leitungen?
Mit drei Ringen bist du durch mit den Schleifringen, vielleicht sogar
Masse ueber die Schraube, mittig. Je nachdem wieviele Du von den Dingern
brauchst lohnt eine kleine Leiterplatte die bei unterschiedlichen
Klotzgroessen immer das Grundmmodul ist. Aberr Achtung, da ist noch ein
Denkfehler, die Kette braucht 4 Leitungen fuer die Daisy Chain...
V+, V-, Data_in, Data_out (zum naechsten Modul).
Was auch noch geht ist Data mit IR Diode, dann mit eigenem Protokoll
dahinter um die Kette zu eleminieren. Wird ggf. langsam....
//hufnala
Icke Wa schrieb:> Die LEDs sollen quasi einzeln auf eine> Schraublochmatrix aufschraubbar sein
Verstehe ich nicht.
Hallo Icke_wa, ich denke, Du solltest einen neuen Thread aufmachen, dort
eine Skizze dran hängen und hier auf den neuen Thread verweisen. Dann
kommen wir besser voran.
Hallo zusammen,
würde die ow-h gerne auf einen ATmega16 verwenden, jedoch habe
Schwierigkeiten diese Zeile
( unsigned char bit DQ @ 0xb4; // Port-Pin P3.4 = b4h )
passend umzuschreiben.
habe gelesen das dieses bereits mehrfach hier gefragt wurde, jedoch gab
es hierzu leider noch keine Antwort. Ich selber möchte den Pin2 an Port
B benutzen.
Wäre super wenn jemand eine Idee hätte.
Vielen Dank
Peter D. schrieb:> #define DELAY_US(us) (unsigned int)(F_CPU / 12.0 1e6 2 *> us)
Uhi ist jetzt schon ein paar "Tage" her..
Verstehe diese Formel nicht so ganz.. Vill. kann mir jemand mal erklären
was das für Konstante sind?
F_CPU ist die CPU Taktfrequenz, der Divisior 12.0 sind die Takte/ Befehl
bei guten, alten 8051, / 1e6 ist der Divisor um auf Takte/us zu kommen
und /2, weil die Schleife 2 Takte/Durchlauf benötigt. Wenn man dann mit
dem Parameter us multipliziert, erhält man die Anzahl
Schleifendurchläufe, um eben diese Zeit in us zu warten.
Falk B. schrieb:> F_CPU ist die CPU Taktfrequenz, der Divisior 12.0 sind die Takte/ Befehl> bei guten, alten 8051, / 1e6 ist der Divisor um auf Takte/us zu kommen> und /2, weil die Schleife 2 Takte/Durchlauf benötigt. Wenn man dann mit> dem Parameter us multipliziert, erhält man die Anzahl> Schleifendurchläufe, um eben diese Zeit in us zu warten.
Habe ich wohl am Anfang überflogen ( nicht gesehen :( ).
Das heißt wenn ich das jetzt auf nem AVR ( ATtiny oder ATmega )
übertragen möchte, muss ich mir das Datenblatt zu rate ziehen und nach
schauen wie viele Takte ich pro Befehl brauche?!
Ist das überhaupt so einfach übertragbar?
Naj H. schrieb:> Habe ich wohl am Anfang überflogen ( nicht gesehen :( ).> Das heißt wenn ich das jetzt auf nem AVR ( ATtiny oder ATmega )> übertragen möchte, muss ich mir das Datenblatt zu rate ziehen und nach> schauen wie viele Takte ich pro Befehl brauche?!
Nein. Man benutzt die Funktion _delay_us(), die gibt es fertig im avr
gcc.
> Ist das überhaupt so einfach übertragbar?
Ja.
Es gibt aber auch schon fertige Umsetzungen auf dem AVR.
Beitrag "Onewire + DS18x20 Library"
Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.
Wichtige Regeln - erst lesen, dann posten!
Groß- und Kleinschreibung verwenden
Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang