Forum: Mikrocontroller und Digitale Elektronik CAN Nachrichten Puffer


von echolot (Gast)


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)


Lesenswert?

bekommst du nur eine Nachricht zum ein- oder auch eine zum Ausschalten?

von Sebastian (Gast)


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)


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)


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)


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)


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 (kosmos)


Lesenswert?

ja schreib doch mal was du genau vorhast.

von Thomas T. (runout)


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)


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)


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.
1
  if( CAN_Msg == Relais_ein && Relais == aus ) {
2
    schalte Relais ein
3
    Relais = ein;
4
  }
5
6
  else if( CAN_Msg == Relais_aus && Relais == ein ) {
7
    schalte Relais aus
8
    Relais = aus;
9
  }

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 User
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.