Forum: Mikrocontroller und Digitale Elektronik CAN Nachrichten Puffer


Announcement: there is an English version of this forum on EmbDev.net. Posts you create there will be displayed on Mikrocontroller.net and EmbDev.net.
von echolot (Gast)


Bewertung
0 lesenswert
nicht lesenswert
Moin,

ich betreibe einen Mega8 und einen MCP2515 um Nachrichten vom CanBus zu 
Empfangen. Der Empfang der Nachrichten funktioniert auch soweit.
Programmiert wird mit AVR-GCC.

Der µC soll nun bei bestimmten Nachrichten, die er vom Bus empfängt 
Ausgänge (Relais) schalten. Bisher lese ich in meiner Hauptschleife 
sämtliche Can Nachrichten aus und schalte dann über Switch/Case die 
entsprechenden Ausgänge. Nun habe ich aber ein kleines Problem. Manche 
Nachrichten auf dem Bus kommen bis zu 100 mal hintereinander (habe 
leider keinen Einfluss darauf), immer mit dem selben Inhalt. Dadurch 
kommt es natürlich dazu, dass das Relais nicht dauerhaft durchschaltet, 
sondern "oszilliert" im Takt der Nachrichten. Ich bräuchte nun also eine 
Art "Pufferfunktion" um dies zu verhindern. Mein bisheriger Ansatz war 
einfach ein Zähler, der bis 100 zählt und dann erst das Relais schaltet. 
Leider funktioniert dies nicht wie gewünscht, da jetzt die Verzögerung 
zwischen der ersten empfangenen Nachricht und dem Schalten des Relais zu 
groß wird.

Hat vllt. jemand einen Ansatz oder eine Idee, wie ich das Problem lösen 
könnte?


Gruß, echolot

von nga (Gast)


Bewertung
0 lesenswert
nicht lesenswert
bekommst du nur eine Nachricht zum ein- oder auch eine zum Ausschalten?

von Sebastian (Gast)


Bewertung
0 lesenswert
nicht lesenswert
Hi Echolot,

schalte doch direkt ein, aber nur nach einer gewissen Hysterese wieder 
aus.

Ist die Nachricht zum Ein- und Ausschalten die gleiche?

Gruß
Sebastian

von echolot (Gast)


Bewertung
0 lesenswert
nicht lesenswert
Hallo,

habe mich vllt. etwas unklug ausgedrückt, das Relais muss nicht 
dauerhaft geschaltet bleiben, es wird nur ein mal getriggert (200ms)
Die Nachricht ist immer die selbe.

Gruß, echolot

von sonar (Gast)


Bewertung
0 lesenswert
nicht lesenswert
echolot schrieb:
> habe mich vllt. etwas unklug ausgedrückt, das Relais muss nicht
> dauerhaft geschaltet bleiben, es wird nur ein mal getriggert (200ms)

Ein Relais wird normalerweise nicht getriggert, sondern es wird 
durchgeschaltet oder eben nicht. Wann es anschalten soll und wann es 
ausschalten soll, musst du in deinem Programm festlegen und zwar 
entsprechend deine CAN-Nachrichten.

Was sollen die 200ms sein und wer legt die fest?

von Rudolph (Gast)


Bewertung
0 lesenswert
nicht lesenswert
echolot schrieb:
> Manche
> Nachrichten auf dem Bus kommen bis zu 100 mal hintereinander (habe
> leider keinen Einfluss darauf), immer mit dem selben Inhalt.

Das ist völlig normal.

> Dadurch kommt es natürlich dazu, dass das Relais nicht dauerhaft
> durchschaltet, sondern "oszilliert" im Takt der Nachrichten.

Das ist  nicht "natürlich" und hat auch nichts mit dem CAN zu tun. :-)

Hysterese ist wie erwähnt eine Lösung.

Alternativ, reagier doch einfach auf den Inhalt der Botschaft?

von Sebastian (Gast)


Bewertung
0 lesenswert
nicht lesenswert
Hi,

wie soll sich denn das Relais verhalten, wenn viele dieser Nachrichten 
in kurzer Zeit ankommen?
Wenn du weißt, was du willst, kannst du es dann sicher auch in der SW 
umsetzen.

Gruß
Sebastian

von Thomas O. (kosmos)


Bewertung
0 lesenswert
nicht lesenswert
ja schreib doch mal was du genau vorhast.

von Thomas T. (runout)


Bewertung
0 lesenswert
nicht lesenswert
das Stichwort ist: Inhibit-Time
Ansonsten hat der TO nicht richtig formuliert
wo sein Problem liegt.

Grüße Runout

von Chris K. (christopher_k25)


Bewertung
0 lesenswert
nicht lesenswert
Ich interpretiere jetzt mal aus deiner Beschreibung heraus:
du hast irgendwo ein auslösendes Event - ein Taster, eine Lichtschranke 
oder so - welches die Nachricht auf dem Bus erzeugt.
Diese Nachricht soll bewirken dass irgendwo anders ein Aktor (Licht, 
Motor, Hupe) für eine bestimmte Zeit arbeitet.

Ich würde dann mit der ersten Nachricht das Relais einschalten und einen 
Timer starten, der 200ms lang abläuft, und bei Ablauf des Timers das 
Relais wieder ausschalten. Wenn der Timer läuft (Abfrage im Programm), 
kannst du entweder nichts tun - das Relais ist ja bereits geschaltet - 
oder den Timer zurücksetzen. Dadurch bleibt das Relais geschaltet bis 
200ms nach Empfang der letzten Nachricht.

Wenn es sein kann dass die Nachrichten über einen längeren Zeitraum als 
200ms empfangen werden, du aber das Relais nur genau 200ms schalten 
willst, löst du bei jeder Nachricht einen weiteren Timer aus und 
resettest diesen auf einen Zählwert größer als der Abstand zwischen Zwei 
Nachrichten. Erreicht der dann seinen Ablaufwert, setzt er eine Variable 
die signalisiert dass das Relais wieder bereit ist. Und natürlich 
schaltest du das Relais auch nur ein wenn die Flag gesetzt ist.

So ganz im Zustandsautomaten-Style.

von Karl H. (kbuchegg) (Moderator)


Bewertung
0 lesenswert
nicht lesenswert
echolot schrieb:
> Hallo,
>
> habe mich vllt. etwas unklug ausgedrückt, das Relais muss nicht
> dauerhaft geschaltet bleiben, es wird nur ein mal getriggert (200ms)
> Die Nachricht ist immer die selbe.

Dann mach dir doch eine Variable, in der du den Schaltzustand des Relais 
vermerkst.

  if( CAN_Msg == Relais_ein && Relais == aus ) {
    schalte Relais ein
    Relais = ein;
  }

  else if( CAN_Msg == Relais_aus && Relais == ein ) {
    schalte Relais aus
    Relais = aus;
  }

Die erste Nachricht triggert den Schaltvorgang, alle weiteren jeweiligen 
Nachrichten werden ignoriert, weil das Relais ja schon geschaltet wurde.

Edit: falls ich dein Problem richtig verstanden habe.
Wenn der Sender natürlich 100 mal hintereinander 
ein/aus/ein/aus/ein/aus/... schickt, dann flattert das Relais natürlich.

: Bearbeitet durch Moderator

Antwort schreiben

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

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.