zeitkritisches System -> Projektarchitektur

Hallo,

ich bin der Neue.. :slight_smile:

Ich habe eine Frage bezüglich der groben Architektur eines Projekts.

Dabei handelt es sich um ein "AddOn" für die Bordelektronik eines alten VW T3.
Ich plane, in der Heckstoßstange einen Abstandsmesser einzubauen (bestehend aus drei US-Modulen).
Das Feedback soll primär akustisch über zwei Lautsprecher im Führerhaus ausgegeben werden.
Aber eventuell soll auch über ein kleines Display in der Mitte des Tacho-Moduls irgendwie visuell dargestellt werden wie es grob mit dem Abstand aussieht. (weitere Features wie RTC, Temperatur, evtl. kleines Menü etc. wären sind für das "Display-Update" angedacht.)
Letzteres ist bisher pure Spinnerei, das wird erstmal nicht umgesetzt, es geht ja vorerst um die Grundfunktionalität der (groben) Abstandsmessung.

Beim Durchlesen ist mir gerade aufgefallen dass es sich so anhören könnte als soll das ins bisherige Bordsystem integriert werden. Das soll es nicht. Alles was ich als Ressource abgreifen werde ist der Strom. (ja, ich habe mich über die Problematik von tlw. starken Schwankungen und Peaks der Spannungsversorgung grob informiert, das Problem soll hier erstmal außer Acht bleiben.)

Jetzt aber zurück zum Thema:
Zuerst wollte ich das alles auf einen Arduino UNO (liegt bereits seit geraumer Zeit daheim rum) laufen lassen. Mittlerweile habe ich allerdings Zweifel an der Echtzeit-Bedingung.
Der Arduino müsste die Ultraschall-Sensoren nacheinander abfragen, die Werte in Soundpegel umrechnen, das Ausgeben und dann alles von vorne. So weit sollte das ja noch halbwegs in Echtzeit ablaufen.
-> grobe Abschätzung anhand des Datenblattes: ein Durchlauf dauert im Fehlerfall circa 40ms, wenn alles klappt sollte es nicht länger als 1ms dauern.
-> ein gesamter Messzyklus mit dringend auszuwertenden Daten dauert max. ~81ms (2 Fails, einer schlägt auf ein Objekt an)

Die Umrechnung auf das akustische Signal dürfte relativ schnell gehen. Somit würde ich das System als "in Echtzeit" laufend bezeichnen. Stimmt Ihr da überein, oder ist das nach eurem Geschmack für den vorgesehenen Anwendungsfall keine Echtzeit mehr? (ja, Echtzeit = "Rechtzeit")

Was ist aber wenn danach weitere Funktionen hinzugefügt werden sollen deren Ansteuerung ein vielfaches der Zeit der US-Sensoren in Anspruch nimmt?
Ich habe drüber nachgedacht das gesamte System modular aufzubauen, also an jeden Sensor noch eine kleine Platine mit Arduino Mini/Micro/Nano / ATtiny oä dranzuhängen der dann die Werte erfasst und die dann auf einen Daten-Bus zur Übertragung an den UNO im Führerhaus zu geben. (->evtl. CAN?)
Da stellt sich aber wieder die Frage ob es nicht mehr Zeit in Anspruch nimmt die Kommunikation durchzuführen, oder die Werte zentral durch einen einzelnen uC direkt von den Sensoren abfragen zu lassen?

Wie würde man solch ein gemischtes System aus Echtzeitkomponenten und eher in Richtung "Unterhaltungselektronik" orientierte Features auslegen?

nochmal kurz die zwei Ansätze die mir in den Sinn kamen:

  1. für einzelne Sensoren/Sensor-Gruppen getrennte Slaves, die einem Master Bericht erstatten
  2. alles auf einem Zentralen uC zusammenlaufen lassen (zeit-kritische und unkritische Komponenten)

Mich interessiert bei der Wahl einer der beiden Versionen vor allem auch die Kommunikation zwischen uCs. Wie programmiert man das zeitoptimiert?

Generell: Wie kann ich "hard RTOS"-like Zeiten genau einhalten wenn ich mehr Zeitintervalle im Auge behalten will als Interrupt-fähige Timer verfügbar sind?
-> dazu hatte ich mir gestern Abend folgendes durchgelesen: Enginursday: Doing Away with Delay(); - News - SparkFun Electronics
Ich sehe dabei allerdings das Problem dass ich zwar mit der Auflösung des ausgewerteten Timers bestimmen kann ob die Zeit noch nicht erreicht ist, oder überschritten ist, aber GENAU die angestrebte Zeit einhalten ist eine Glückssache.
Gibt's da eine praktikable Alternative?

Ist jetzt doch ein bisschen mehr ausgeartet als erwartet, irgendwie muss ich solche Sachen manchmal erst in Worte fassen bevor da ein großer Entwicklungsfortschritt bei rumkommt. Sorry.. :smiley:

Falls ich den Timer-Teil besser in ein gesondertes Thema auslagern soll, sagt bitte bescheid.

EDIT: habe vergessen das Datenblatt des US-Sensors anzuhängen..
es handelt sich um den HC-SR04:

Vielen Dank für die Hilfe :slight_smile:
SimMue

Du denkst viel zu kompliziert.

Das macht ein Atmel 328 und langweilt sich noch dabei.

Interrupts im Programm (außer denen in der Lib) sind hier nicht notwendig, nur eine durchdachte, blockierungsfreie Programmierung mit kurzen Timeout Zeiten bei den US-Sensoren

"Echtzeit" ist relativ.

Wenn du in Echtzeit eine Heizung regeln willst, reichen Minuten als Reaktionszeit.
Wenn du in Echtzeit einen dynamischen Roboterlageregler hast, brauchst du wenige Millisekunden.

Im Falle eines Rückfahrassistenten ist der Mensch eindeutig das langsamste in der Kette.
Ich würde mal sagen, wenn du 100ms Reaktionszeit schaffst, dann ist das völlig ausreichend.

das hat aber nichts mit der Rechenleistung zu tun.
Der Arduino wird sich langweilen. Die meiste Zeit wartet er auf die Rückmeldung der US-Sensoren.
Das könntest du beschleunigen, in dem du nicht die NewPing.h verwendest, sonder direkt über die Capture Einheit des ATMega gehst. Aber das ist zum einen unnötig, erfordert zum anderen sehr hohes Programmierwissen.

Was ist aber wenn danach weitere Funktionen hinzugefügt werden sollen deren Ansteuerung ein vielfaches der Zeit der US-Sensoren in Anspruch nimmt?

Dann hast du was falsch gemacht.
Du mußt deine Software so aufbauen, dass keine der Funktionen, die du aufrufst, länger als einige ms braucht. Wenn du konsequent ohne delays arbeitest, ist das meist auch möglich.

danke erstmal für die Antworten!

Dass der uC die meiste Zeit nichts zu tun hat ist klar.

Zu dem Programmierwissen sollte ich vlt. erwähnen dass ich jetzt im dritten Semester E-Technik studiere und in den ersten beiden Semestern C/C++ Vorlesungen hatte.
Meinst du mit "sehr hohem Programmierwissen" die Fähigkeit Timer-Interrupts zu setzen, oder bezieht sich das auf was anderes?
Das kann ich nämlich durchaus. (soll jetzt nicht angeberisch klingen, nur damit halt klar ist auf welchem Niveau ich mich circa bewege :slight_smile: )
Das Setzen von Interrupts und Timer-Interrupts habe ich bisher bloß direkt übers AVR Studio gemacht, also ohne die Arduino-spezifischen Funktionen etc.

Geht das auch über die Arduino IDE und muss man da die avr-libs extra einbinden, oder werden die sowieso vorne dran gehängt?

Gibt's im uC vom Arduino "verbotene" Ressourcen, die man nicht manuell selbst verändern sollte, weil mir sonst die Arduino-Funktionen wieder die Konfiguration zerfetzen könnten, oder kann ich wie bei einem normalen ATmega frei nach Lust und Laune konfigurieren?

guntherb:
sonder direkt über die Capture Einheit des ATMega gehst. Aber das ist zum einen unnötig

warum, wenn ich fragen darf? (bezogen auf das "unnötig")

Der AVR Kram ist in der Arduino Software automatisch mit drin. Das wird durch die Arduino Funktionen und Klassen ja auch intern verwendet.

Das ganze Arduino Zeug ist lediglich ein Wrapper für die AVR libs. Aber du bist nicht gezwungen die Komfort Funktionen auch zu verwenden. Oft bietet es sich an da zu mischen.

Gibt's im uC vom Arduino "verbotene" Ressourcen, die man nicht manuell selbst verändern sollte

Von Timer0 solltest du die Finger lassen wenn es nicht unbedingt nötig ist. Der wird von millis() und delay() verwendet, welche wiederum von anderen Funktion verwendet werden. Wenn man genau weiß was man da macht kann man ihn aber auch abschalten, bzw. anders verwenden.

Außerdem wird PWM durch Timer erledigt. Wenn man also PWM macht kann man nicht gleichzeitig den Timer der entsprechenden Pins für was anderes verwenden. Man kann natürlich die PWM Pins so wählen, dass sie von einem bestimmten Timer gesteuert werden. z.B. PWM auf Timer0 (was millis() und delay() nicht beeinflusst). Oder PWM auf Timer2 und Timer1 für irgendwas nehmen.

SimMue:
Der Arduino müsste die Ultraschall-Sensoren nacheinander abfragen, die Werte in Soundpegel umrechnen, das Ausgeben und dann alles von vorne.

Nur mal ganz grob: Bereits dieser eine Satz von Dir klingt für mich komplett falsch.

Zunächst mal scheinst Du von einem völlig falschen Messprinzip auszugehen: Offenbar glaubst Du, es würde Ultraschall mit einer bestimmten Lautstärke ausgesendet, und gemessen wird dann, mit welcher Lautstärke das Echo zurückkommt: Je leiser, desto weiter weg.

So funktioniert aber kein Ultraschall-Entfernungssensor. Stattdessen funktionieren die Sensoren mit Trigger-Echo so: Ausgesendet werden beispielsweise 8 Impulse, und es wird die Laufzeit des Schalls gemessen, bis diese 8 Impulse als Echo zurückkommen. Aus der Laufzeit des Schalls ergibt sich die Entfernung: Je länger das Signal in der Luft unterwegs ist, desto größer der Abstand.

Und für das was Du möchtest, brauchst Du daher auch nicht "alle Sensoren nacheinander" abzufragen. Du möchtest doch wahrscheinlich nur wissen:

  • welches ist der geringste Abstand von einem Sensor zu einem Gegenstand?
  • und welcher von mehreren Sensoren hat diesen geringsten Abstand gemessen?

In dem Fall wäre die Programmlogik - ganz grob:
Du triggerst alle Deiner Sensoren gleichzeitig (Trigger-Pins zusammenschließen und mit einem Arduino-OUTPUT gemeinsam triggern), und danach stellst Du einfach fest, welcher Sensor das Echo als erstes zurück bekommt. Das ist dann der Sensor mit dem geringsten Abstand zu einem Gegenstand.

Und mein Gefühl sagt mir, mehr als das möchtest Du auch gar nicht feststellen.

Im übrigen ist ein HC-SR04 kein wetterfester Sensor, sondern einer, der nur indoor in geschützten Innenräumen eingesetzt werden darf. Diesen Sensor kannst Du keinesfalls außen am Fahrzeug einsetzen. Außer vielleicht bei Schönwetter zu Testzwecken bei trockener Witterung.

jurs:
Im übrigen ist ein HC-SR04 kein wetterfester Sensor, sondern einer, der nur indoor in geschützten Innenräumen eingesetzt werden darf. Diesen Sensor kannst Du keinesfalls außen am Fahrzeug einsetzen. Außer vielleicht bei Schönwetter zu Testzwecken bei trockener Witterung.

Da bin ich auch schon länger am schauen. Momentan setze ich den SR04 etwas geschützt aussen ein, jedoch hält er nie länger als 8-9 Monate, dann ist er oxidiert.
Gibt es da was bezahlbares, was sich ebenso einfach mit dem Arduino verwurschten lässt?

Hallo,

es gibt welche bei Conrad im Alugehäuse. Gib mal Ultraschallsensor ein.

Doc_Arduino:
es gibt welche bei Conrad im Alugehäuse. Gib mal Ultraschallsensor ein.

Da gibt es allerdings meistens eher nur nackte Ultraschall-Wandlerkapseln ohne Leistungselektronik und ohne Ansteuerelektronik, d.h. um die für irgendwas sinnvoll zu gebrauchen, mußt Du Dir erstmal eine entsprechende Schaltung entwickeln, wie sie beim HC-SR04 bereits auf dem Modul dabei ist.

Genau deswegen. Da lass ich lieber noch ein paar SR04 verrotten, bevor ich sowas mach. Im Prinzip könnte man auch KFZ Abstandssensoren nehmen vom Schrottplatz. Das ist aber das gleiche in Grün.

ElEspanol:
Da lass ich lieber noch ein paar SR04 verrotten, bevor ich sowas mach. Im Prinzip könnte man auch KFZ Abstandssensoren nehmen vom Schrottplatz. Das ist aber das gleiche in Grün.

Eventuell wäre eBay-Artikelnummer 121627882136 eine Alternative.
Mit Versand vom Chinaversender knappe 10 EUR pro Stück.

Von der Beschreibung her sowohl waterproof als auch von der Ansteuerung vergleichbar zu den HC-SR04, dabei mit größerer maximaler Reichweite, aber einem blinden Bereich von 25cm Mindestabstand und mit größerem Abstrahlwinkel von bis zu 50 Grad.

Aber im Automobilbereich im Winter auch nicht wirklich betriebssicher einsetzbar, denn der Hersteller gibt an, dass die niedrigste Betriebstemperatur -10°C sein darf, was in Deutschland im Winter ja auch mal unterschritten werden kann.

Genau sowas. Habs gerade schon bestellt. Minusgrade gibt es bei unserem Pool zum Glück nicht

Offenbar glaubst Du, es würde Ultraschall mit einer bestimmten Lautstärke ausgesendet, und gemessen wird dann, mit welcher Lautstärke das Echo zurückkommt: Je leiser, desto weiter weg.

nein, ich bin mir durchaus im Klaren darüber dass US-Sensoren mit der Laufzeit des Schalls arbeiten.
Problematisch stelle ich mir nur vor, dass ich dreimal ein baugleiches Modul verwende.
Damit die sich sicher nicht gegenseitig beeinflussen trigger ich sie einfach nacheinander.
Außerdem verbaue ich wie gesagt im Führerhaus zwei kleine Lautsprecher über die ich dann die Richtung des Hindernisses ganz grob ausmachen möchte.

Einfach nur die insgesamt geringste Distanz wird nicht ausreichen. Ich möchte wissen bei welchem Sensor welcher Abstand ausgewertet wurde.

Im übrigen ist ein HC-SR04 kein wetterfester Sensor

Das ist unglücklich, zum Testen wirds hoffentlich erstmal reichen...
Zum Praxiseinsatz muss ich mich dann wohl über ne Alternative schlau machen.
Danke für den Hinweis!

Einfach nur die insgesamt geringste Distanz wird nicht ausreichen. Ich möchte wissen bei welchem Sensor welcher Abstand ausgewertet wurde.

Jurs' Vorschlag (2015-11-13, 20:36:10), alle 3 synchron triggern, kann auch erweitert werden, wenn unbedingt erforderlich. Aber wie willst du das anzeigen?

Ich würde übrigens die "Richtung" über 3 LED und den Minimal-Abstand wie üblich über Pieps-Pulsfrequenz signalisieren.

SimMue:
Zu dem Programmierwissen sollte ich vlt. erwähnen dass ich jetzt im dritten Semester E-Technik studiere und in den ersten beiden Semestern C/C++ Vorlesungen hatte.
Meinst du mit "sehr hohem Programmierwissen" die Fähigkeit Timer-Interrupts zu setzen, oder bezieht sich das auf was anderes?
Das kann ich nämlich durchaus. (soll jetzt nicht angeberisch klingen, nur damit halt klar ist auf welchem Niveau ich mich circa bewege :slight_smile: )

Das ist gut zu wissen!
Oft weiß man einfach nicht, auf welchem Niveau sich der Fragesteller bewegt.

SimMue:

guntherb:
sondern direkt über die Capture Einheit des ATMega gehst. Aber das ist zum einen unnötig

warum, wenn ich fragen darf? (bezogen auf das "unnötig")

Das unnötig bezog sich auf die Echtzeitanforderungen.
Wenn du newping.h Lib verwendest, hast du bei jedem Sensor maximal die Wartezeit bis zum Timeout.
Das ist bei Einstellung auf 5m ca. 30ms pro Sensor, bei 4 Sensoren also 120ms + Rechenzeit und Anzeige. Lass uns mal annehmen, für Rechenzeit und Anzeige würden 80ms gebraucht werden (und das ist richtig, richtig lang!) dann bist zu bei 200ms Loopwiederholzeit.

Das ist bei einem System, bei dem nachher ein Mensch reagieren muss, immer noch sehr kurz.

Daher meine Ausage: "unnötig". Das langsamste im System ist der Mensch. Da lohnt es sich nicht, aus dem Controller noch ein paar ms rauszuquetschen.

Mein Vorschlag:
Fang einfach mal an, nutze die newping Library, damit kannst du sehr schnell ein System zum testen darstellen.
Dann kannst du immer noch entscheiden, ob es zu langsam ist.