Hallo liebe Forumgemeinde,
da ich im AVR Bereich noch am Anfang stehe, würde ich mich über "gute
Praxis" Kommentare freuen:
Chip: ATMEGA 8
Bsp:
Nehmen wir an, ich will 4 langsame Sensoren auslesen (z.B. dht 22)
Das Lesen dauert (weil man viel Warten muss) ca. 50ms
Wenn jeder Sensor 1x Sekunde ausgelesen wird, dann sind das 200ms
"warten", was dem Rest des Programms nicht gut tut.
Was sind gute Lösungen?
a) Über externe Interrups arbeiten - mit einem Multiplexer (weil nicht
genug Interrups)
b) Einen ATINY88 (etc.) dafür nutzen und z.B. via I2C einbinden
c) Das Warten irgendwie besser machen
Vielen Dank
Tom
Tom schrieb:> Wenn jeder Sensor 1x Sekunde ausgelesen wird, dann sind das 200ms> "warten", was dem Rest des Programms nicht gut tut.
Wozu willst du einen Feuchtesensor ein mal pro Sekunde auslesen. Schon
der gesunde Menschenverstand sollte einem sagen, dass das bei der
Zeitkonstante des Sensorelements extrem wenig Erkenntnisgewinn bringt.
Natürlich ist auch das zu schnelle zyklische Auslesen nicht gut, auch
weil sich die meisten Sensoren dabei selber erwärmen und das Ergebnis
verfälschen.
Es geht aber wohl eher um das delay das man sich einhandelt und damit
evtl. andere Aktionen blockiert.
Das liegt aber eher an den faulen Programmierern die eine einfache
sensor.read() Methode bauen die blockierend arbeitet. Wenn man sich
ansieht wie der Sensor arbeitet kann man in trigger / auslesen
auftrennen. Dann kann man alle Sensoren erstmal triggern, was anderes
machen, und nach x ms dann das Ergebnis abholen.
wie wäre es eigentlich, wenn wir statt des Bewertungssystems mal Preise
für die dümmsten Antworten vergeben würden, und die Zahl rechts im Post
dann immer anzeigt, wie viel dieser dummen Preise der USer bereits
ergattert hat?
Das gilt auch dann wenn man Fragen im Stil von Jeopady beantwortet
Derzeit eine brauchbare Antwort..auch wenn ich nicht gut im erklären
bin, versuche ich es auch mal.
Mit Timern zu Arbeiten ist hier ein guter Ansatz entweder mit Timer
Interrupt oder eben ohne.
Du zählst eine Variable hoch, bei jedem Programmdurchlauf erhöhst du
diese um 1
Stößt die Messung des Sensors an und gleich danach
Tom schrieb:> Nehmen wir an, ich will 4 langsame Sensoren auslesen (z.B. dht 22)> Das Lesen dauert (weil man viel Warten muss) ca. 50ms> Wenn jeder Sensor 1x Sekunde ausgelesen wird, dann sind das 200ms> "warten", was dem Rest des Programms nicht gut tut.
Warum? Was macht denn der Rest des Programms? Und wie kommst du auf
50ms? Ein Bit vom DHT22 braucht ~70µs (0) oder ~120µs (1). Für 32 Bits
also im Mittel um die 3ms. Noch ein bißchen was drumherum und großzügig
aufgerundet also vielleicht 5ms. Das sind dann 0.5% des 1-Sekunden
Zeitintervalls.
Also: was macht dein Programm so wichtiges, daß es keine 0.5% der
Rechenleistung pro Sensor erübrigen kann?
> Was sind gute Lösungen?
Man kann das Problem natürlich mit Hardware totwerfen. Die
unterschiedlichen Pulslängen vom DHT22 kann man mit einem Monoflop
unterscheiden und die 0en und 1en in ein externes Schieberegister
takten. Das muß der µC dann nur noch auslesen. Eine Variante davon ist
ein Slave-µC, der mit dem DHT22 redet und dem Master Klartext-Daten z.B.
via I²C liefert.
Man könnte das Telegramm des DHT22 im Timerinterrupt samplen. Die
kürzeste Zeit ist um die 20µs. Man müßte also mit wenigstens 20µs
abtasten, besser aber mit 10µs. Bei angenommenen 8MHz Takt wäre das ein
Interrupt alle 80 Takte. Knapp, aber machbar. Oder man verwendet die
Capture-Hardware zur Erfassung der Flanken. Dann wird die ISR nur noch
alle ~160 Takte aufgerufen. Beide Varianten sparen etwas Zeit gegenüber
stumpfem Warten. Aber nicht wahnsinnig viel. Vielleicht die Hälfte.
Oder man liest mal quer im Web und stellt fest, daß der DHT22 sowieso
nicht das Gelbe vom Ei ist. Und entscheidet sich für einen anderen
Sensor. Z.B. einen mit I²C Interface.
Tom schrieb:> Nehmen wir an, ich will 4 langsame Sensoren auslesen (z.B. dht 22)> Das Lesen dauert (weil man viel Warten muss) ca. 50ms
Nein. Das Lesen selbst dauert weniger als 5ms, selbst bei lauter einsen
(was ja nie der Fall sein kann).
Bei DHT11 dauert das Startsignal min.18ms., bei DHT22 weniger als 1ms,
ergibt 23ms bei DHT11 and 6ms bei DHT22.
> Wenn jeder Sensor 1x Sekunde ausgelesen wird, dann sind das 200ms> "warten", was dem Rest des Programms nicht gut tut.
Niemand liest die Sensoren 1 pro Sekunde, wozu auch?
Bei DHT22 ist die max. Auslesefrequenz sogar nur 0.5Hz, also max.
alle 2 Sekunden.
Aber egal:
Für 4 DHT22 Sensoren dauert das Ganze max.24ms.
Für 4 DHT11 Sensoren dauert das Ganze max. 44ms (wenn man weisst wie).
Wie du auf deine Zahlen gekommen bist, ist mir schleierhaft...
P.S.
Axel S. schrieb:> Oder man liest mal quer im Web und stellt fest, daß der DHT22 sowieso> nicht das Gelbe vom Ei ist. Und entscheidet sich für einen anderen> Sensor. Z.B. einen mit I²C Interface.
Oder man nimmt einen M88 und arbeitet mit PCINT und TIMER, kostet
(fast) keine CPU Zeit...
Tom schrieb:> c) Das Warten irgendwie besser machen
Richtig, mit Multitasking. Das gilt für fast alle langsamen
Sensoren, auch z.B. die Temperatursensoren DS18x20. Ist einfacher als es
klingt.
Multitasking??? - Ich lach mich kaputt!
Warum nicht gleich Kavallerie, Coast-Guard und Force de Frappe?
Hier braucht man einen freilaufenden Zähler mit passender Taktung
und einen Pin-Change-Interrupt. Kostet 1..5% der Prozessor-Zeit
und - JA LEIDER, GEHT NICHT OHNE: etwas Gehirnschmalz für die
Pin-Change-Interrupt-Routine.
wofür man für so eine Aktion immer einen Interrupt verwendet erschließt
sich mir hier nicht...
Ein freilaufender Zähler ist hier mehr als ausreichend.
Wer für bereits so einem Pillepalle einen Interrupt verwendet, murkst
sich vermutlich auch sonst ziemlich einen zusammen
Jakob schrieb:> Multitasking??? - Ich lach mich kaputt!> Warum nicht gleich Kavallerie, Coast-Guard und Force de Frappe?>> Hier braucht man einen freilaufenden Zähler mit passender Taktung> und einen Pin-Change-Interrupt. Kostet 1..5% der Prozessor-Zeit> und - JA LEIDER, GEHT NICHT OHNE: etwas Gehirnschmalz für die> Pin-Change-Interrupt-Routine.
Wenn man sowieso ein RTOS verwendet?!
Axel Shirakowski schrieb:> Ein freilaufender Zähler ist hier mehr als ausreichend.
Ein freilaufender Zähler alleine nützt überhaupt nichts. Irgendwie wird
der mit der Ablaufsteuerung im Programm kommunizieren müssen.
Wer Labormessungen macht, nimmt bessere Technik.
Wer ein Atiny + Arduino nutzt, macht das folgendermaßen. Man ruft eine
Sub-Routine auf, in der werden 10 Messungen in einer Schleife
durchgeführt. Die Ergebnisse zusammengezählt und durch 10 geteilt um den
Mittelwert zu ermitteln.
Dann zurück in die Hauptroutine und wenn man nix besseres zu tun hat,
legt man den Chip schlafen. Nach x Minuten (10 ist kein schlechter Wert
für Klimamessungen) ruft man den Sub erneut auf und das Spiel geht von
vorne los.
JEDE !!!! Wetterstadion für die Wohnung die ich kenne arbeitet so. Sonst
wäre die 2032 / bzw. 2 x AAA in 1 Tag leer.
Gruß
Pucki