Forum: Mikrocontroller und Digitale Elektronik ds1820 + isr/Impulszähler


von grundschüler (Gast)


Lesenswert?

Ich möchte bei meinem neuen Durchlauferhitzer Durchfluss, Temperatur und 
Stromverbrauch erfassen.

Problem: der ow-bus-code schaltet während der Messung die isr mit 
cli()/sei() ab, d.h. Impulse des Flowsensors und des Stromzählers werden 
nicht gezählt.

Ich würde die Impulsmessung jetzt zeitlich auf 50sec beschränken und die 
Zahl der gemessenen Impulse dann hochrechnen. In einem Zeitfenster von 
10sec würden dann die Temperaturmessungen per ow durchgeführt.

Gibt es für dieses Problem andere Ansätze/bessere Lösungen?

von Praktiker (Gast)


Lesenswert?

grundschüler schrieb:
> Problem: der ow-bus-code schaltet während der Messung die isr mit
> cli()/sei() ab, d.h. Impulse des Flowsensors und des Stromzählers werden
> nicht gezählt.

Warum überläßt du das Zählen der Impulse nicht einem HW-Zähler/Timer? 
Der hälft weiter und das Auswerten des Overflow-Interrupts hat Zeit.

von Karl M. (Gast)


Lesenswert?

Hallo,

dann schreibe doch den Code ds1820 neu, die par µs warten für das 
Starten der Messung ist doch nicht das Problem.
Dann wird noch ein Timerevent verankert, der nach ca. 750µs den Messwert 
abholt.

von chris (Gast)


Lesenswert?

Je nachdem wie deine HW aussieht könnte man mehr sagen....

Hinweis der DS brauch mit allen drum dran ca 1s um Daten zu liefern d.h. 
man könnte ja für 1s die Impulszählungen stoppen(wie du es dir gedacht 
hast sperren) Temp auslesen und dann wieder für 50s sich auf die Impulse 
konzentrieren.....

optimaler:
2x8bitTimer für das Zählen der Impulse nutzen
1x16bitTimer um die 10s/50s zu erhalten
und dann kannst du in Ruhe alle 10s den Sensor auslesen aber der 
bräuchte nicht mal alle 10s gelesen werden vllt alle 60s 0.o

Aber von wie vielen Impulsen reden wir denn eigentlich hier???

von Karl H. (kbuchegg)


Lesenswert?

grundschüler schrieb:

> Problem: der ow-bus-code schaltet während der Messung die isr mit
> cli()/sei() ab,

Zeig mal den Code.

Das OW Timing ist eigentlich nur 'kritisch' (so kritisch ist es auch 
wieder nicht), während die eigentliche Übertragung läuft. Einen kleinen 
Spielraum hat man. D.h. wenn dieser Interrupt der einzigige ist, der dir 
da während der OW Übertragung dazwischenfunkt UND wenn die ISR 
Abarbeitung in ieser ISR nicht allzulang dauert UND wenn das auch nicht 
allzu häufig während der OW Übertragung passiert, DANN kannst du die 
Interrupts auch einfach eingeschaltet lassen.

Ein Beispiel:
Ich hab in einer Steuerung auch einen DS1820 hängen UND ich hab in 
dieser Steuerung eine interne Uhr, die auf der Auswertung der 50Hz 
Netzspannung durch externen Interrupt beruht. Ich hab also 50 Interrupts 
in der Sekunde, wobei in der ISR einfach nur eine Uhrzeit hochgezählt 
wird. Der DS1820 Code beruht auf dem PeDa Code. Die 50 ISR Aufrufe 
bringen die DS1820 Übertragung noch nicht aus dem Tritt, das Timing 
verkraftet diese Unterbrechungen noch bei 11Mhz Taktfrequenz.

: Bearbeitet durch User
von grundschüler (Gast)


Lesenswert?

danke für die wirklich guten hinweise. Ich werde heute Mittag mal 
ausprobieren, ob der ds-code die interrupts verkraftet. Wahrscheinlich 
muss ich nur den Timer zur Berechnung der Uhrzeit abstellen, weil der 
Impulszähler wirklich nur zählt.

Code werde ich heute Mittag einstellen.

von John (Gast)


Lesenswert?

Karl Heinz schrieb:
> Das OW Timing ist eigentlich nur 'kritisch' (so kritisch ist es auch
> wieder nicht), während die eigentliche Übertragung läuft.

Ich hab gerade mal die Übertragungszeit bei meinem DS18S20 gemessen:
 - Starten der Wandlung: 2,3ms
 - Auslesen der Daten:   8,2ms

Die Interrupts sind also maximal 8,2ms deaktiviert.
Wie viele Interrupts können bei Dir in der Zeit maximal auftreten?

Wenn es nicht mehr als einer ist, dann sollte es keine Probleme geben. 
Bei deaktivierten Interrupts wird zwar der Interrupt nicht ausgeführt, 
das Interrupt-Flag wird aber trotzdem gesetzt. Sobald die Interrupts 
wieder aktiviert werden, wird die Ausführung der ISR nachgeholt. Es 
gehen keine Interrupts verloren.

Gruß
John

von Wolfgang (Gast)


Lesenswert?

chris schrieb:
> Hinweis der DS brauch mit allen drum dran ca 1s um Daten zu liefern d.h.
> man könnte ja für 1s die Impulszählungen stoppen(wie du es dir gedacht
> hast sperren) Temp auslesen und dann wieder für 50s sich auf die Impulse
> konzentrieren.....

Dieses rumgedoktere an den Sympthomen löst das Problem nicht, sondern 
wäre nur ein übler work around, um eine schlechten Programmierung zu 
vertuschen.

> ... und dann kannst du in Ruhe alle 10s den Sensor auslesen aber der
> bräuchte nicht mal alle 10s gelesen werden vllt alle 60s 0.o

Der µC ist immer fix genug, um alle 10s eine Temperaturmessung auf die 
Reihe zu kriegen. Ob 10s oder 60s Messintervall macht da keinen 
Unterschied. Und wenn es bei 10s mit der parallelen Pulserfassung nicht 
funktioniert, wird es auch bei 60s schief gehen.

von Peter D. (peda)


Lesenswert?

John schrieb:
> Die Interrupts sind also maximal 8,2ms deaktiviert.

Sollte nicht sein.
Die Sperre ist nur für eine Bitzeit, also 60µs nötig.
Die 480..960µs Resetpuls benötigen keine Sperre, wenn die Interrupts 
kurz genug gehalten werden (480µs = 3840 Zyklen beim AVR@8MHz).

Damit das Main nicht zu lange verzögert wird, mach man das 1-Wire am 
besten als Statemaschine, die jeweils immer nur 1 Bit je Aufruf 
bearbeitet.
Eine weitere Lösung wäre ein 500µs Timerinterrupt je Bit.

: Bearbeitet durch User
von eProfi (Gast)


Lesenswert?

Du kannst das kritische Bit-Timing der seriellen Schnittstelle 
überlassen.
Du sendest ein bestimmtes Byte über einen Widerstand und empfängst es 
gleichzeitig (und je nach Zustand des zu empfangenen OW-Bits verändert).

  Tx ---- R ----- Rx
              |
              --- DS -- Gnd

D.h. Du musst pro OW-Bit ein Byte senden und empfangen.

von chris (Gast)


Lesenswert?

Wolfgang schrieb:
> chris schrieb:
>> Hinweis der DS brauch mit allen drum dran ca 1s um Daten zu liefern d.h.
>> man könnte ja für 1s die Impulszählungen stoppen(wie du es dir gedacht
>> hast sperren) Temp auslesen und dann wieder für 50s sich auf die Impulse
>> konzentrieren.....

> Dieses rumgedoktere an den Sympthomen löst das Problem nicht, sondern
> wäre nur ein übler work around, um eine schlechten Programmierung zu
> vertuschen.

>> ... und dann kannst du in Ruhe alle 10s den Sensor auslesen aber der
>> bräuchte nicht mal alle 10s gelesen werden vllt alle 60s 0.o

> Der µC ist immer fix genug, um alle 10s eine Temperaturmessung auf die
> Reihe zu kriegen. Ob 10s oder 60s Messintervall macht da keinen
> Unterschied. Und wenn es bei 10s mit der parallelen Pulserfassung nicht
> funktioniert, wird es auch bei 60s schief gehen.

hey hey erstmal lesen und verstehen das war die Intension des 
Fragestellers und meine Lösung dazu wird komplett weggelassen also 
aufpassen...

von grundschüler (Gast)


Angehängte Dateien:

Lesenswert?

chris schrieb:
> meine Lösung dazu wird komplett übergangen


die Lösung mit dem Timer als Impulszähler ist für mich neu, erfordert 
Umdenken und braucht daher noch eine Weile. Hört sich aber gut an und 
wird ausprobiert.

Aufgrund der Beiträge habe ich meinen Uhrzeit-timer überarbeitet und die 
Berechnung ins Hauptprogramm verlegt. Eine ganz wesentliche Änderung 
meines Programms, welches ich bereits für sehr ausgereift gehalten 
hatte.

Ich habe jetzt sehr kurze ISRs. die ds1820-Auslesung scheint auch ohne 
cli zu funktionieren. Im Hauptprogramm sieht die Auswertung so aus:
1
if(sec%4==1){//dle++
2
dle_l_min=(dle_isr_imp-dle_isr_imp_alt)*100/126;
3
dle_isr_imp_alt=dle_isr_imp;
4
lgw(3,1,"imps:");li(dle_isr_imp);
5
lw(" l/min:");li(dle_l_min/10);lw(",");li(dle_l_min%10);
6
lw(" l");li(dle_isr_imp/760);lw(" ");
7
}//dle--
8
9
if(sec%4==2){//dsz++
10
dsz_kW_h=(dsz_isr_imp-dsz_isr_imp_alt)*10000/55;
11
dsz_isr_imp_alt=dsz_isr_imp;
12
lgw(4,1,"imps:");li(dsz_isr_imp);
13
lw(" kW/h:");li(dsz_kW_h);lw(" ");
14
//lw(" l");li(dsz_isr_imp/760);lw(" ");
15
}//dsz--
16
17
if(sec%4==3){//ds++
18
ds1820_auslesen_to_global_TR();
19
}//ds--
20
21
22
if(sec%4==0){//ds++
23
ds1820_start_meas();
24
}//ds--

von C-user (Gast)


Lesenswert?

grundschüler schrieb:
> Im Hauptprogramm sieht die Auswertung so aus:

Das sieht so aus, als ob das Programm für eine switch-case Struktur 
prädestiniert ist. Das spart z.B. den Mehrfachaufruf der Modulo-Funktion 
mit dem selben Argument und schafft Übersicht, wenn man sich zusätzlich 
noch an ein paar Formatierungskonventionen hält ;-)

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