Forum: Mikrocontroller und Digitale Elektronik canbus mit SN65HVD230D und FlexCan


von Ray M. (ray_m)


Lesenswert?

hi @all,

ich verwende SN65HVD230D und die FlexCan-Lib von
https://github.com/teachop/FlexCAN_Library

das funktioniert auch alles bis zu der stelle wo ich mehrere can-pakete
übertragen will

beim sender will ich ca. 30 messerwerte in can-messages verpacken
und wegschicken, also in einer dauer-scheife

  msg.id = 0x100;
  msg.len = sizeof(a);
  memcpy(msg.buf, &a, sizeof(a));
  CANbus.write(msg);

  msg.id = 0x101;
  msg.len = sizeof(b);
  memcpy(msg.buf, &b, sizeof(b));
  CANbus.write(msg);

  ... usw ...

leider funktioniert das so nicht,
beim empfänger kommen nur 6 messages an (0x100 bis 0x105)
alle anderen werden nicht empfangen bzw. versendet

auf empfänger seite mache ich

  while ( CANbus.read(rxmsg) ) {
    switch(rxmsg.id) {
      case 0x100: memcpy(&a, rxmsg.buf, rxmsg.len );; break;
      case 0x101: memcpy(&b, rxmsg.buf, rxmsg.len );; break;
      ... usw ...
  }

ich nehme mal an das mir irgendwo irgendein buffer
überläuft und er die restlichen messages einfach nicht verschickt

leider kann ich nix im netz finden und der code der flexcan-lib
bringt micht auch nicht weiter ...

hat jemand eine idee wo hier mein problem ist und wie ich es umgehen
kann ???

von hp-freund (Gast)


Lesenswert?

hello again ;-)

Ich dachte eigentlich das ....

Na ja, um das Problem zu lösen würde ich als erstes mal prüfen ob es am 
der msg.id liegt.
Sende/empfange also an Stelle von msg.id = 0x101 die 0x107 um zu sehen 
ob vielleicht nur die 6 id frei verfügbar sind.

von Ray M. (ray_m)


Lesenswert?

??? das versteh ich nicht, was soll das mit der id zu tun haben ???
ich hab 2 controller, 2 kabel, fertig ...

aber ich versuch das ...

von Richard (Gast)


Lesenswert?

Vielleicht ist einfach kein Buffer mehr verfuegbar.
Werte doch mal den Rueckgabewert von write() aus.

Github-Doku:
write(message) Send a frame of up to 8 bytes using the given identifier. 
write() will return 0 if no buffer was available for sending (see 
"Caller blocking" below).

von hp-freund (Gast)


Lesenswert?

Die Sendungen werden der Reihe nach übertragen und Du hast vermutlich 
weiter nummeriert.
Möglicherweise ist die 0x107 für irgend etwas reserviert. Um das 
auszuschliessen ist das ein einfacher Test.

Als nächstes prüfe ob Du mehr als 8 byte auf einmal zu senden versuchst.
msg.len > 8 abfragen

von Ray M. (ray_m)


Lesenswert?

Richard schrieb:
> Vielleicht ist einfach kein Buffer mehr verfuegbar.
> Werte doch mal den Rueckgabewert von write() aus.
>
> Github-Doku:
> write(message) Send a frame of up to 8 bytes using the given identifier.
> write() will return 0 if no buffer was available for sending (see
> "Caller blocking" below).

das hab ich gelesen, bringt mich aber auch nicht weiter
mit msg-timeout = irgendwas sendet er auch nicht mehr wie 6 messages

von Ray M. (ray_m)


Lesenswert?

hp-freund schrieb:
> Die Sendungen werden der Reihe nach übertragen und Du hast vermutlich
> weiter nummeriert.
> Möglicherweise ist die 0x107 für irgend etwas reserviert. Um das
> auszuschliessen ist das ein einfacher Test.

mach ich, sobald ich zurück am schreibtisch bin ;)

> Als nächstes prüfe ob Du mehr als 8 byte auf einmal zu senden versuchst.
> msg.len > 8 abfragen

ok, aber dass sollte nicht der fall sein, alle messwerte sind int oder 
float

von Ray M. (ray_m)


Lesenswert?

ich muss mich ma 2h ausklinken, danke für eure hilfe

ich meld mich später wenn ich getestet habe ...

von Ray M. (ray_m)


Lesenswert?

also an den id's liegt es nicht

wenn ich beim sender zum testen einen delay rein mache

  msg.id = 0x100;
  msg.len = sizeof(a);
  memcpy(msg.buf, &a, sizeof(a));
  CANbus.write(msg);
  delay(3);

  msg.id = 0x101;
  msg.len = sizeof(b);
  memcpy(msg.buf, &b, sizeof(b));
  CANbus.write(msg);
  delay(3);

  ... usw ...

funktioniert alles ...

also kriegt der can die daten nicht schnell genug raus

nur bei über 30 werten die ich verschicken will sind das über 100ms
bis ich einen satz verschickt hab ... das ist nicht zu gebrauchen ;(

geht das mint can auch richtig oder soll ich doch rs485 einbauen ;(

von Jens E. (surfjenser)


Lesenswert?

Mit welcher Datenrate betreibst du den CAN denn?

von Ray M. (ray_m)


Lesenswert?

1mbit

von hanswurst (Gast)


Lesenswert?

Wie sieht denn dein Buffer "a" und "b" aus?
Du kannst maximal 8 bytes uebertragen.

hanswurst

von Ray M. (ray_m)


Lesenswert?

test empfänger

#include <FlexCAN.h>

FlexCAN CANbus(1000000);
static CAN_message_t rxmsg;

void setup() {
  Serial.begin(115200);
  CANbus.begin();
  pinMode(13, OUTPUT);
  digitalWrite(13, 1);
  delay(1000);
}

void loop() {
  while ( CANbus.read(rxmsg) ) {
    Serial.print("0x"); Serial.println(rxmsg.id, HEX);
  }
}


der sender zum testen

#include <FlexCAN.h>

FlexCAN CANbus(1000000);
static CAN_message_t msg;

static struct DataSet {
    unsigned int a = 3526;
    signed int b   = -12;
    float c        = 14.2;
    byte d         = 1;
    unsigned int e = 13526;
    signed int f   = -112;
    float g        = 114.2;
    byte h         = 2;
} sysData;

void setup() {
  CANbus.begin();
  pinMode(13, OUTPUT);
  digitalWrite(13, 1);
}

void loop() {
  msg.id = 0x100;
  msg.len = sizeof(sysData.a);
  memcpy(msg.buf, &sysData.a, sizeof(sysData.a));
  CANbus.write(msg);
delay(3);
  msg.id = 0x101;
  msg.len = sizeof(sysData.b);
  memcpy(msg.buf, &sysData.b, sizeof(sysData.b));
  CANbus.write(msg);
delay(3);
  msg.id = 0x102;
  msg.len = sizeof(sysData.c);
  memcpy(msg.buf, &sysData.c, sizeof(sysData.c));
  CANbus.write(msg);
delay(3);
  msg.id = 0x103;
  msg.len = sizeof(sysData.d);
  memcpy(msg.buf, &sysData.d, sizeof(sysData.d));
  CANbus.write(msg);
delay(3);
  msg.id = 0x104;
  msg.len = sizeof(sysData.e);
  memcpy(msg.buf, &sysData.e, sizeof(sysData.e));
  CANbus.write(msg);
delay(3);
  msg.id = 0x105;
  msg.len = sizeof(sysData.f);
  memcpy(msg.buf, &sysData.f, sizeof(sysData.f));
  CANbus.write(msg);
delay(3);
  msg.id = 0x106;
  msg.len = sizeof(sysData.g);
  memcpy(msg.buf, &sysData.g, sizeof(sysData.g));
  CANbus.write(msg);
delay(3);
  msg.id = 0x107;
  msg.len = sizeof(sysData.h);
  memcpy(msg.buf, &sysData.h, sizeof(sysData.h));
  CANbus.write(msg);
delay(3);
}

von hp-freund (Gast)


Lesenswert?

hanswurst schrieb:
> Du kannst maximal 8 bytes uebertragen.

Das struct/packen Thema hatten wir in einem anderen Beitrag schon 
erläutert.
Vielleicht wird er es am Ende noch so machen :-)

Interessant ist im Moment warum die Übertragung so lahm ist.
Ich fürchte dazu brauchts einen CAN Experten.

Ray M. schrieb:
> msg.len = sizeof(sysData.h);
>   memcpy(msg.buf, &sysData.h, sizeof(sysData.h));

Ich weiss nicht was der compiler daraus macht, aber vermutlich dauert 
das ausführen der 2. sizeof Funktion länger (wenn nicht wegoptimiert 
wird) als wenn Du msg.len benutzen würdest.

Ausserdem ist bei deiner Methode wo die Daten mit fester Grösse 
vorliegen die Berechnung der msg.len zu Laufzeit gar nicht nötig.

von Pit (Gast)


Lesenswert?

Schicke die Nachrichten doch Blockweise weg. Schreib dir eine 
Sende-Funktion, die pro Block 5 Nachrichten verschickt. Diese Funktion 
kannst du dann zyklisch alle x Millisekunden aufrufen. So hast du eine 
gleichbleibende Buslast und dein Puffer ist auch nicht überfordert( du 
sagtest ja, dass du 6 Nachrichten direkt nacheinander versenden kannst )

von Ray M. (ray_m)


Lesenswert?

hp-freund schrieb:
> hanswurst schrieb:
>> Du kannst maximal 8 bytes uebertragen.
>
> Das struct/packen Thema hatten wir in einem anderen Beitrag schon
> erläutert.
> Vielleicht wird er es am Ende noch so machen :-)

joop, macht er ;)
nur bis hier kein durchsatz ist reicht das simple testgerüst ja aus ;)

> Interessant ist im Moment warum die Übertragung so lahm ist.
> Ich fürchte dazu brauchts einen CAN Experten.

das befürchte ich auch ... ;(

> Ray M. schrieb:
>> msg.len = sizeof(sysData.h);
>>   memcpy(msg.buf, &sysData.h, sizeof(sysData.h));
>
> Ich weiss nicht was der compiler daraus macht, aber vermutlich dauert
> das ausführen der 2. sizeof Funktion länger (wenn nicht wegoptimiert
> wird) als wenn Du msg.len benutzen würdest.
>
> Ausserdem ist bei deiner Methode wo die Daten mit fester Grösse
> vorliegen die Berechnung der msg.len zu Laufzeit gar nicht nötig.

mag sein, aber aktuell ist der teensy so schnell das der can-bus
aufgibt ... also speed-optimierung noch garnicht nötig ...


im übrigen reicht es aller 6 (mit CANbus.write(msg)) gesendeten messages
ein delay(3) rein zu machen und alles funktioniert ...

also scheint mir das doch irgendein buffer zu sein ... hmmm

im bsp. von den flexcan-jungs steht

    // send 6 at a time to force tx buffering
    txCount = 6;
    while ( txCount-- ) {
      CANbus.write(msg);
      msg.buf[0]++;
    }
    // time delay to force some rx data queue use
    rxTimer = 3;//milliseconds


nur ohne jegliche erklärung sagt nir das wenig ;(

: Bearbeitet durch User
von Ray M. (ray_m)


Lesenswert?

Pit schrieb:
> Schicke die Nachrichten doch Blockweise weg. Schreib dir eine
> Sende-Funktion, die pro Block 5 Nachrichten verschickt. Diese Funktion
> kannst du dann zyklisch alle x Millisekunden aufrufen. So hast du eine
> gleichbleibende Buslast und dein Puffer ist auch nicht überfordert( du
> sagtest ja, dass du 6 Nachrichten direkt nacheinander versenden kannst )

das löst das grundsätzliche problem nicht ...
das wäre nur ein workaround ...

es kann doch nicht sein das can so langsam und träge ist
6msg buffer dann warten ???
wenn im auto mein abs auch warten müsste ist der baum ganz
schnell ganz nah ... ;)

von Pit (Gast)


Lesenswert?

Ray M. schrieb:
> das löst das grundsätzliche problem nicht ...
> das wäre nur ein workaround ...
>
> es kann doch nicht sein das can so langsam und träge ist
> 6msg buffer dann warten ???
> wenn im auto mein abs auch warten müsste ist der baum ganz
> schnell ganz nah ... ;)

Das ist kein Workaorund sonder gängige Praxis in allen Bereichen, wo CAN 
eingesetzt wird.
Ich kenne weder deinen Chip noch die Software, von daher kann ich auch 
nur raten. Möglicherweise wird nur ein Message Object für das Senden und 
Empfangen angelegt. Schau dir mal an wieviele MOBs von der Hardware 
unterstützt werden und wieviele in der Software angelegt werden.

Genauso macht es wenig Sinn sizeof direkt 2 mal zu verwenden. Definiere 
deine Nachrichten doch direkt immer als 8 Byte Nachricht. Ob du jetzt 4 
oder 8 Byte als Nutzdaten schickst wird dir zeitlich nichts bringen, 
aber das ist nicht die Lösung für dein generelles Problem.

von Ray M. (ray_m)


Lesenswert?

Pit schrieb:
> Ray M. schrieb:
>> das löst das grundsätzliche problem nicht ...
>> das wäre nur ein workaround ...
>>
>> es kann doch nicht sein das can so langsam und träge ist
>> 6msg buffer dann warten ???
>> wenn im auto mein abs auch warten müsste ist der baum ganz
>> schnell ganz nah ... ;)
>
> Das ist kein Workaorund sonder gängige Praxis in allen Bereichen, wo CAN
> eingesetzt wird.

dann zieh ich ab heute mal die abs-sicherung und verlasse mich auf
mein gefühl im bremsfuss ...

> Ich kenne weder deinen Chip noch die Software, von daher kann ich auch
> nur raten. Möglicherweise wird nur ein Message Object für das Senden und
> Empfangen angelegt. Schau dir mal an wieviele MOBs von der Hardware
> unterstützt werden und wieviele in der Software angelegt werden.

... und da ich davon zu wenig ahnung hab, hab eich hier im forum gefragt 
;)

> Genauso macht es wenig Sinn sizeof direkt 2 mal zu verwenden. Definiere
> deine Nachrichten doch direkt immer als 8 Byte Nachricht. Ob du jetzt 4
> oder 8 Byte als Nutzdaten schickst wird dir zeitlich nichts bringen,
> aber das ist nicht die Lösung für dein generelles Problem.

genau ...

von Jens E. (surfjenser)


Lesenswert?

Wenn ich richtig gezählt habe, ist eine CAN-Message mit 11bit Identifier 
und 8 Byte Payload 111 Bit lang (inklusive Interframe Space).
Von der Übertragungsrate her solltest du also nicht in Schwierigkeiten 
kommen.
Normalerweise gibt es doch bei CAN Sende- und Empfangs-Mailboxes. Wie 
sind die denn bei dir bzw. der Lib implementiert? Was passiert wenn du 
schneller schreiben willst als es der CAN kann?
Und wie sieht es überhaupt auf der physikalischen Seite aus? Ist dein 
Bus richtig terminiert? Oder kommt es zu Fehlern, die eine Wiederholung 
der Übertragung erfordern?

von Ray M. (ray_m)


Lesenswert?

Jens E. schrieb:
> Wenn ich richtig gezählt habe, ist eine CAN-Message mit 11bit Identifier
> und 8 Byte Payload 111 Bit lang (inklusive Interframe Space).
> Von der Übertragungsrate her solltest du also nicht in Schwierigkeiten
> kommen.

das war auch meine annahme

> Normalerweise gibt es doch bei CAN Sende- und Empfangs-Mailboxes. Wie
> sind die denn bei dir bzw. der Lib implementiert? Was passiert wenn du
> schneller schreiben willst als es der CAN kann?

fragen die ich mangels wissen nicht beantworten kann un deshalb hier
gefragt habe ...

ich verstehe die ca. 220 zeilen code aus 
https://github.com/teachop/FlexCAN_Library/blob/master/FlexCAN.cpp 
leider nicht

> Und wie sieht es überhaupt auf der physikalischen Seite aus? Ist dein
> Bus richtig terminiert? Oder kommt es zu Fehlern, die eine Wiederholung
> der Übertragung erfordern?

2can-receiver
20cm draht dazwischen
2x120ohm an den enden

von Steffen R. (steffen_rose)


Lesenswert?

Kenne diese Lib nicht. Es klingt aber auf jeden Fall so, dass du 
schneller in den CAN schreibst, als dieser verschicken kann. Genau dies 
meldet Dir der Rückgabewert von

CANbus.write(msg);

Wenn Du eh blockieren willst (delay), kannst Du solange deine Nachricht 
zu schreiben versuchen bis du keinen Fehler merh zurückbekommst.
Und ja, die Prozessoren sind üblicherweise schneller mit reinschreiben, 
als die Nachrichten über den CAN gehen.

Wenn dann noch Sendewiederholungen und fremder Traffic hinzukommt, 
dauerts ein klein wenig länger. Wir sind ja hier nicht im Auto, wo vorab 
jede Nachricht genau kalkuliert wurde.

Kann natürlich auch gut sein, dass das Problem nicht auf Senderseite, 
sondern auf Empfängerseite zu suchen ist. Gut möglich, dass deine 
serielle Ausgabe länger dauert als die CAN übertragung. Dann laufen 
deine Empfangspuffer über. Auch hierfür (Overflow) gibt es sicherlich 
eine Funktion oder einen Rückgabewert in dem Paket.

Diese Details (Rückgabewerte, Flags, Status) sind wichtiger für eine 
genaue Analyse als ein helfender Workaround, der das Problem nur 
verbirgt und man nicht weiterkommt.

von Ray M. (ray_m)


Lesenswert?

Steffen R. schrieb:
> Kenne diese Lib nicht. Es klingt aber auf jeden Fall so, dass du
> schneller in den CAN schreibst, als dieser verschicken kann. Genau dies
> meldet Dir der Rückgabewert von
>
> CANbus.write(msg);

also der return von CANbus.write ist bei mir immer 0,
demnach dürfte er gar keine messages verschciken ??? häää

#include <FlexCAN.h>

FlexCAN CANbus(1000000);
static CAN_message_t msg;

static struct DataSet {
    unsigned int a = 3526;
    signed int b   = -12;
    float c        = 14.2;
    byte d         = 1;
    unsigned int e = 13526;
    signed int f   = -112;
    float g        = 114.2;
    byte h         = 2;
} sysData;

void setup() {
  CANbus.begin();
  pinMode(13, OUTPUT);
  digitalWrite(13, 1);
}

void loop() {
  msg.id = 0x100;
  msg.len = sizeof(sysData.a);
  memcpy(msg.buf, &sysData.a, msg.len);
  Serial.print("0x100 : "); Serial.println( CANbus.write(msg) );

  msg.id = 0x101;
  msg.len = sizeof(sysData.b);
  memcpy(msg.buf, &sysData.b, msg.len);
  Serial.print("0x101 : "); Serial.println( CANbus.write(msg) );

  msg.id = 0x102;
  msg.len = sizeof(sysData.c);
  memcpy(msg.buf, &sysData.c, msg.len);
  Serial.print("0x102 : "); Serial.println( CANbus.write(msg) );

  msg.id = 0x103;
  msg.len = sizeof(sysData.d);
  memcpy(msg.buf, &sysData.d, msg.len);
  Serial.print("0x103 : "); Serial.println( CANbus.write(msg) );

  msg.id = 0x104;
  msg.len = sizeof(sysData.e);
  memcpy(msg.buf, &sysData.e, msg.len);
  Serial.print("0x104 : "); Serial.println( CANbus.write(msg) );

  msg.id = 0x105;
  msg.len = sizeof(sysData.f);
  memcpy(msg.buf, &sysData.f, msg.len);
  Serial.print("0x105 : "); Serial.println( CANbus.write(msg) );

  msg.id = 0x106;
  msg.len = sizeof(sysData.g);
  memcpy(msg.buf, &sysData.g, msg.len);
  Serial.print("0x106 : "); Serial.println( CANbus.write(msg) );

  msg.id = 0x107;
  msg.len = sizeof(sysData.h);
  memcpy(msg.buf, &sysData.h, msg.len);
  Serial.print("0x107 : "); Serial.println( CANbus.write(msg) );

}

ergibt immer
0x100 : 0
0x101 : 0
0x102 : 0
0x103 : 0
0x104 : 0
0x105 : 0
0x106 : 0
0x107 : 0
0x100 : 0
0x101 : 0
0x102 : 0
0x103 : 0
0x104 : 0
0x105 : 0
0x106 : 0
0x107 : 0


> Wenn Du eh blockieren willst (delay), kannst Du solange deine Nachricht
> zu schreiben versuchen bis du keinen Fehler merh zurückbekommst.
> Und ja, die Prozessoren sind üblicherweise schneller mit reinschreiben,
> als die Nachrichten über den CAN gehen.
>
> Wenn dann noch Sendewiederholungen und fremder Traffic hinzukommt,
> dauerts ein klein wenig länger. Wir sind ja hier nicht im Auto, wo vorab
> jede Nachricht genau kalkuliert wurde.
>
> Kann natürlich auch gut sein, dass das Problem nicht auf Senderseite,
> sondern auf Empfängerseite zu suchen ist. Gut möglich, dass deine
> serielle Ausgabe länger dauert als die CAN übertragung. Dann laufen
> deine Empfangspuffer über. Auch hierfür (Overflow) gibt es sicherlich
> eine Funktion oder einen Rückgabewert in dem Paket.

seriell steht bei mir auf 115200 ... das reicht auf jeden fall
für die wenigen testdaten

#include <FlexCAN.h>

FlexCAN CANbus(1000000);
static CAN_message_t rxmsg;

void setup() {
  Serial.begin(115200);
  CANbus.begin();
  pinMode(13, OUTPUT);
  digitalWrite(13, 1);
}

void loop() {
  if ( CANbus.available() ) {
    while ( CANbus.read(rxmsg) ) {
      Serial.print("0x"); Serial.println(rxmsg.id, HEX);
    }
  }
}


> Diese Details (Rückgabewerte, Flags, Status) sind wichtiger für eine
> genaue Analyse als ein helfender Workaround, der das Problem nur
> verbirgt und man nicht weiterkommt.

ja, dass bringt mich aber alles nicht weiter wenn sich niemand findet
der hier schonmal ein ähnliches problem und eine lösung hatte ;)

von Ray M. (ray_m)


Lesenswert?

beim empfänger kommt ohne delay nach dem 6ten nur unsinn
an, je nach wetterlage ...

0x100
0x100
0x103
0x107
0x107
0x107
0x100
0x100
0x103
0x107
0x107
0x100
0x100
0x103
0x107
0x107
0x107
0x100
0x100
0x103
0x107
0x107

wenn ich beim sender so mach

#include <FlexCAN.h>

FlexCAN CANbus(1000000);
static CAN_message_t msg;

static struct DataSet {
    unsigned int a = 3526;
    signed int b   = -12;
    float c        = 14.2;
    byte d         = 1;
    unsigned int e = 13526;
    signed int f   = -112;
    float g        = 114.2;
    byte h         = 2;
} sysData;

void setup() {
  CANbus.begin();
  pinMode(13, OUTPUT);
  digitalWrite(13, 1);
}

void loop() {
  //  msg.timeout = 1;

  //int ret;

  msg.id = 0x100;
  msg.len = sizeof(sysData.a);
  memcpy(msg.buf, &sysData.a, msg.len);
  //ret = CANbus.write(msg);
  Serial.print("0x100 : "); Serial.println( CANbus.write(msg) );

  msg.id = 0x101;
  msg.len = sizeof(sysData.b);
  memcpy(msg.buf, &sysData.b, msg.len);
  //ret = CANbus.write(msg);
  Serial.print("0x101 : "); Serial.println( CANbus.write(msg) );

  msg.id = 0x102;
  msg.len = sizeof(sysData.c);
  memcpy(msg.buf, &sysData.c, msg.len);
  //ret = CANbus.write(msg);
  Serial.print("0x102 : "); Serial.println( CANbus.write(msg) );

  msg.id = 0x103;
  msg.len = sizeof(sysData.d);
  memcpy(msg.buf, &sysData.d, msg.len);
  //ret = CANbus.write(msg);
  Serial.print("0x103 : "); Serial.println( CANbus.write(msg) );
delay(3);
  msg.id = 0x104;
  msg.len = sizeof(sysData.e);
  memcpy(msg.buf, &sysData.e, msg.len);
  //ret = CANbus.write(msg);
  Serial.print("0x104 : "); Serial.println( CANbus.write(msg) );

  msg.id = 0x105;
  msg.len = sizeof(sysData.f);
  memcpy(msg.buf, &sysData.f, msg.len);
  //ret = CANbus.write(msg);
  Serial.print("0x105 : "); Serial.println( CANbus.write(msg) );

  msg.id = 0x106;
  msg.len = sizeof(sysData.g);
  memcpy(msg.buf, &sysData.g, msg.len);
  //ret = CANbus.write(msg);
  Serial.print("0x106 : "); Serial.println( CANbus.write(msg) );

  msg.id = 0x107;
  msg.len = sizeof(sysData.h);
  memcpy(msg.buf, &sysData.h, msg.len);
  //ret = CANbus.write(msg);
  Serial.print("0x107 : "); Serial.println( CANbus.write(msg) );
delay(3);
}


kommt ganz sauber

0x100
0x101
0x102
0x103
0x104
0x105
0x106
0x107
0x100
0x101
0x102
0x103
0x104
0x105
0x106
0x107
...

an ...


ergebnis: can ist in der form zur einfachen übertragung von
          messdaten zwischen 2 oder mehr teensy's nicht zu gebrauchen 
...

ich werde mir was anderes überlegen müssen ...

hat jemand einen vorschlag ?

von Ray M. (ray_m)


Lesenswert?

das beste zum schluss ;(

wenn ich auf senderseite

  msg.timeout = 3;

setze oder irgendwas > 0 dann kommen die daten
alle richtig beim sender an ...

einige sekunden, dann hängt sich der sender komplett weg,
da hilft nur noch strom ab und wieder dran und dann geht es weiter,
wieder einige sekunden ...

also der teensy schickt weiter daten raus, aber beim empfänger
kommen keine mehr an ... can ist scheisse ;/

: Bearbeitet durch User
von Jens E. (surfjenser)


Lesenswert?

Ich glaube kaum, dass der CAN an sich etwas mit dem Problem zu tun hat. 
Vielmehr wird es wohl an dem Aufbau und der Benutzung dieser Library zu 
tun haben.
Und wie die bei 1Mbit CAN Datenrate und deiner Dauer-Loop mit 115k UART 
beim Empfänger auskommen willst, ist mir nicht klar

von Ray M. (ray_m)


Lesenswert?

Jens E. schrieb:
> Ich glaube kaum, dass der CAN an sich etwas mit dem Problem zu tun hat.
> Vielmehr wird es wohl an dem Aufbau und der Benutzung dieser Library zu
> tun haben.

kann gut sein ...

> Und wie die bei 1Mbit CAN Datenrate und deiner Dauer-Loop mit 115k UART
> beim Empfänger auskommen willst, ist mir nicht klar

wenn ich darüber nachdenke mir auch nicht, ich schreib das mal
zum testen um ...

von Ray M. (ray_m)


Lesenswert?

wenn ich die seriell raus nehme und canbus-geschwindigkeit runter
scheint es zu klappen

ok, also ich versteh hier was grundsätzliches nicht

ich will von einem teensy zum anderen meine messdaten
in nahzu echtzeit, also ohne irgendwelche delays übertragen,
der eine sammelt messdaten der andere soll die einfach möglichst
schnell, ohne merkliche verzögerung auf einem display anzeigen

hab ich hier eventuell die falsche technologie rausgesucht,
ist can dafür einfach nicht gemacht ?

wer zum geier funkt mir hier dazwischen, welcher buffer ist wo
von wem zu klein ? anderen can-receiver eventuell ?
ander lib eventuell ?

von Matze (Gast)


Lesenswert?

Echtzeit ist ne frage der Definition. Echtzeit bedeutet nur das eine 
Ereignis innerhalb eines vorgeschrieben Zeitfensters bearbeitet wird.

Weiterhin hat der Transceiver nichts damit zu tun, der wandelt nur die 
Pegel.

Der Treiber ist, naja, nicht besonders gut geschrieben, würde so nie in 
einem Professionellen Umfeld eingesetzt. Aber ist halt Arduino.

Machbar ist das schon mit CAN, nur nicht so wie du es machst.
Als Tipp:

Versuche die Nachrichten in einen Ring Buffer zu speichern (das geht 
schnell genug), der dich über Overflow usw informieren kann. Dann kannst 
du die Nachrichten nach einander aus dem Buffer holen, prüfen ob dieser 
leer ist usw...

CAN --> PushRingBuffer ... Main -> RingBufferDataAvaible : GetData

usw

von Ray M. (ray_m)


Lesenswert?

das kann ich machen, aber wieso sollte das mein problem mit
flexcan lösen ...

der ringbuffer erhöht ja nicht die geschwindigkeit auf dem canbus ...

eventuel muss einfach eine funktionierende can-lib her ...
kennt jemand eine alternative für den SN65HVD230D
wenn nicht hab ich viel zu tun oder ich nehme eine funktionierende lib
und kauf die passenden can-receiver dazu ...
eventuell vorschläge dazu ?

und mit arduino hat das wenig zu tun, ein teensy ist kein arduino,
ich kann das auch mit nem vi schreiben und zu fuß durch den gcc-avr
treten ... das wird das problem auch nicht lösen ...

von Matze (Gast)


Lesenswert?

Die lib hat nix mit dem Transceiver zu tun?!
Ich benutze den SN65 hier in einem professionellen Umfeld, zusammen mit 
zig STM32 (F4,F1,F3) zusammen.

Du solltest dir nochmal genau ansehen wie deine CAN-Peripherie auf deim 
Controller aufgebaut ist. Ich kann hier nur von ST reden, da ist es 
folgenermaßen (vereinfacht).

Jede CAN-Schnittstelle hat mehrere Mailboxen, die wiederrum einen FIFO 
vorgeschaltet. Der Treiber von ST versucht dann eine freie Mailbox zu 
finden, die sich dann (in Hardware) darum kümmert die Daten physikalisch 
auf den Bus zu schreiben. Ist keine Mailbox mehr frei (und fragt man das 
nicht ab) ist die Nachricht weg. Das gilt für Empfang und Senden. Was 
passiert also wenn du 10 Nachrichten nacheinander auf dem Bus empfängst, 
die ersten drei Mailboxen voll sind, und du es in der main nicht 
schaffst die Daten abzuholen? Richtig, sie sind weg. Deswegen 
CAN-Treiber auf Interrupt betrieb umstellen, die Daten in einen 
Ringbuffer schreiben (der ist schnell genug, ich arbeite hier mit knapp 
2000 Nachrichten pro sekunde (Buslast von 60%)) und in der main den 
Ringbuffer auslesen. Der muss dann halt groß genug sein.

Wenn man für gewöhnlich mehrere Daten verschicken will (also mehr als 
8Byte am Stück) hält man sich an ein Protokoll (Stichwort UDS oder 
KWP2000)

Wie gesagt, ist nur für den ST, sollte bei deinem aber wohl ähnlich 
sein. Anhaltspunkt für CAN:

https://vector.com/vi_controller_area_network_de.html vor allem das 
E-Learning.

Gruß,

von Jens E. (surfjenser)


Lesenswert?

Mit dem Beitrag hast du dir aber selbst ins Knie geschossen.
Wie Matze bereits geschrieben hat, hat der Transceiver nichts mit deinem 
Problem zu tun, da er nur die Pegel wandelt. Da kannst gern noch 100 
andere von NXP, Infineon und Co verwenden ohne das sich damit dein 
Problem löst.
Die eigentliche Arbeit für den CAN macht der CAN-Controller auf deinem 
Teensy. Genauer gesagt ist der in dem darauf befindlichen Kinetis-µC 
integriert. Entweder du schaust dir das Reference Manual zu dem µC 
genauer an und setzt dich damit auseinander, wie der CAN-Controller 
funktioniert, oder du nutzt doch nur die Library und verstehst nicht was 
im Hintergrund passiert - was ja durchaus dem Aurdino-Weg recht nahe 
kommt.

Und da du noch immer nicht geschrieben hast, wie schnell nun schnell 
genug ist für die Übertragung der Messwerte, ist es wohl etwas zu 
einfach, dem CAN-Bus ein Geschwindigkeitsproblem für deine Aufgabe zu 
unterstellen.

von Ray M. (ray_m)


Lesenswert?

Matze schrieb:
> Die lib hat nix mit dem Transceiver zu tun?!
> Ich benutze den SN65 hier in einem professionellen Umfeld, zusammen mit
> zig STM32 (F4,F1,F3) zusammen.
>
> Du solltest dir nochmal genau ansehen wie deine CAN-Peripherie auf deim
> Controller aufgebaut ist. Ich kann hier nur von ST reden, da ist es
> folgenermaßen (vereinfacht).

[...]

> sein. Anhaltspunkt für CAN:
>
> https://vector.com/vi_controller_area_network_de.html vor allem das
> E-Learning.

danke für die kurze und verständliche erklärung,
der link zum einarbeiten ist ein guter einstieg ...

von Ray M. (ray_m)


Lesenswert?

Jens E. schrieb:
> Mit dem Beitrag hast du dir aber selbst ins Knie geschossen.
> Wie Matze bereits geschrieben hat, hat der Transceiver nichts mit deinem
> Problem zu tun, da er nur die Pegel wandelt. Da kannst gern noch 100
> andere von NXP, Infineon und Co verwenden ohne das sich damit dein
> Problem löst.
>
> Die eigentliche Arbeit für den CAN macht der CAN-Controller auf deinem
> Teensy. Genauer gesagt ist der in dem darauf befindlichen Kinetis-µC
> integriert. Entweder du schaust dir das Reference Manual zu dem µC
> genauer an und setzt dich damit auseinander, wie der CAN-Controller
> funktioniert, oder du nutzt doch nur die Library und verstehst nicht was
> im Hintergrund passiert - was ja durchaus dem Aurdino-Weg recht nahe
> kommt.

du verstehst es nicht, es gibt mind. 2 wege nach rom
1. ich arbeite mich komplett ein und werde noch jemand der sich
   damit auskennt und alles auf die angeblich harte tour lernt,
   das kostet sinnlos zeit und bringt die lösung nicht voran
2. oder ich konzentriere mich auf meine kernkompetenz, aus soft-
   und hardware eine lösung bauen ... und genau da gehört es dazu
   vorhandene hardware über eine schnittstelle und libs einzubinden
   ohne genau zu wissen wie bit-bummsen im ic geht, erst wenn problem
   auftreten fragt man jemand der sich damit genauer auskennt,
   davon gibt es viele auf diesem planeten und die haben auch spass
   am bit-bummsen und bringen ihren teil der lösung ein, wenn das
   bit-bummsen fertig ist fängt mein part erst an ...

> Und da du noch immer nicht geschrieben hast, wie schnell nun schnell
> genug ist für die Übertragung der Messwerte, ist es wohl etwas zu
> einfach, dem CAN-Bus ein Geschwindigkeitsproblem für deine Aufgabe zu
> unterstellen.

unter 10ms ist schnell genug


ps: es tut mir echt leid das mich die innerein eines ic nicht
    interresieren ... ich will ihn benutzen und fertig ...
    viele leute fahren auto ohne zu verstehen wie ein motor 
funktioniert,
    und auch der designer hat keinen plan vom antrieb, also arbeiten
    alle zusammen und es wird gut ...


mein fazit:
  zu meiner kombination aus problem und SN65HVD230D/FlaxCan gibt
  es im forum niemanden der das auch schon einmal auf dem tisch hatte
  ok ... das ist pech für mich, also geh ich auf rs485 zurück,
  auch nur 2 kabel und 12mbit schnell und keine probleme mit
  irgendwelchen buffern, ic's, libs, buffern und was weis
  ich noch alles ...


danke an alle die sich hier mühe gegeben haben ich zu erhellen ...

: Bearbeitet durch User
von Nik (Gast)


Lesenswert?

Ray M. schrieb:
> mein fazit:
>   zu meiner kombination aus problem und SN65HVD230D/FlaxCan gibt
>   es im forum niemanden der das auch schon einmal auf dem tisch hatte
>   ok ... das ist pech für mich, also geh ich auf rs485 zurück,
>   auch nur 2 kabel und 12mbit schnell und keine probleme mit
>   irgendwelchen buffern, ic's, libs, buffern und was weis
>   ich noch alles ...

Du checkst ja noch net mal das der Transceiver nix, aber sowas von nix 
mit dem CAN zu tun hat... Also joa, geh weiter basteln.

von Stefan (Gast)


Lesenswert?

Wenn man mit Mikrocontroller arbeiten will, kommt man nicht drumherum 
sich mit dem IC auseinander zu setzen.
Ja es gibt Leute, die sich damit auskennen und ihr Geld damit verdienen.
Ich hab mir für den FlexCAN im imx6 einen "Treiber" geschrieben. Das 
sind zwei Wochen Arbeit und man hat was funktionirendes

von Ray M. (ray_m)


Lesenswert?

Nik schrieb:
> Ray M. schrieb:
>> mein fazit:
>>   zu meiner kombination aus problem und SN65HVD230D/FlaxCan gibt
>>   es im forum niemanden der das auch schon einmal auf dem tisch hatte
>>   ok ... das ist pech für mich, also geh ich auf rs485 zurück,
>>   auch nur 2 kabel und 12mbit schnell und keine probleme mit
>>   irgendwelchen buffern, ic's, libs, buffern und was weis
>>   ich noch alles ...
>
> Du checkst ja noch net mal das der Transceiver nix, aber sowas von nix
> mit dem CAN zu tun hat... Also joa, geh weiter basteln.

du bist schon ein super schlaumeier ... ein forum ist dafür da sich
aus zu tauschen und das deppen wie ich dumme fragen stellen dürfen
ohne von solchen proleten wie dir belästigt zu werden ...
geh in den keller und spiel mit dir selbst ...

==> plonk

von Ray M. (ray_m)


Lesenswert?

Stefan schrieb:
> Wenn man mit Mikrocontroller arbeiten will, kommt man nicht drumherum
> sich mit dem IC auseinander zu setzen.

das glaube ich nicht ... genau das halte ich für eine
überholte einstellung, wozu muss ich wissen wie der mixer funktioniert
wenn ich brot backe ?

> Ja es gibt Leute, die sich damit auskennen und ihr Geld damit verdienen.
> Ich hab mir für den FlexCAN im imx6 einen "Treiber" geschrieben. Das
> sind zwei Wochen Arbeit und man hat was funktionirendes

das ist sicher eine leistung und erfordert viel fachwissen,
du bist also jemand der sich mit bit-bummsen auskennt und daran
spass hat ... meine fähigkeiten liegen leider oberhalb des ic ...
wenn die lib die hw nicht sauber incl. docu abstrahiert bin ich halt
aufgeschmissen ...

: Bearbeitet durch User
von Stefan (Gast)


Lesenswert?

Ich schreib ebenso die Software die drauf aufsetzt. Und so viel 
Fachwissen ist das. Nur geduld und Docu lesen. Ob man jetzt die Docu des 
Prozessors oder des Treiber ließt, ist einerlei.
Und bei Mikrocontroller ist das ganze gar nicht überholt. Da diese für 
grundlegende Probleme eingesetzt werden.
Wenn man Libaries braucht, gibts eigentlich nur zwei Aeten dran zu 
kommen, wenn sie vernünftig sein sollen, selbst schreiben oder paar 
Tausend Euro in die Hand nehmen und schreiben lassen

von Ray M. (ray_m)


Lesenswert?

Stefan schrieb:
> Ich schreib ebenso die Software die drauf aufsetzt. Und so viel
> Fachwissen ist das. Nur geduld und Docu lesen. Ob man jetzt die Docu des
> Prozessors oder des Treiber ließt, ist einerlei.
> Und bei Mikrocontroller ist das ganze gar nicht überholt. Da diese für
> grundlegende Probleme eingesetzt werden.
> Wenn man Libaries braucht, gibts eigentlich nur zwei Aeten dran zu
> kommen, wenn sie vernünftig sein sollen, selbst schreiben oder paar
> Tausend Euro in die Hand nehmen und schreiben lassen

oder einfach was nehmen das einfach funktioniert und das ist
meine vorherige version mit rs485, dass ging alles ohne probleme,
einfach kurz protokol-spec gelesen, lib eingebunden und schon
war es benutzbar ... ohne das ich in die bits des ic schauen musste
can hab ich mir nur angeschaut weil es mir am
teensy eine serielle schnittstelle mehr beschert die ich sonst für
rs485 opfern muss ...

: Bearbeitet durch User
von Ray M. (ray_m)


Lesenswert?

und das mit dem "du must dich mit dem ic befassen" halte ich immer noch
für falsch, ich beschäftige mich ja auch nicht mit den interna der chips
wenn ich eine gyro, usb-host, accel, gps oder was auch immer in meine
schaltungen einbaue, ich lese die docu, nehme zum testen ein 
breakout-board
, binde die lib ein, benutze es und wenn es funktioniert mache ich mir 
mit
eagle einen plan und pack alles auf eine platine ... fertig ...
und nein, ich verdiene damit kein geld, für mich das reines hobby ...

von user (Gast)


Lesenswert?

Du möchtest die Daten auf einem Display ausgeben. Wieso müssen die Daten 
dann so schnell übertragen werden? Willst du die Daten in einer 
Animation mit 60 FPS darstellen?

von Ray M. (ray_m)


Angehängte Dateien:

Lesenswert?

user schrieb:
> Du möchtest die Daten auf einem Display ausgeben. Wieso müssen die Daten
> dann so schnell übertragen werden? Willst du die Daten in einer
> Animation mit 60 FPS darstellen?

eigentlich nicht, aber ohne merkliche verzögerung da
einige werte als gauge visualisiert werden und da schaut
ruckeln bei dynamischen änderungen einfach scheisse aus ...

da ich mich erst seit ca. 6-9monaten überhaupt mit
dem thema befasse fehlt mir sicher eine menge grundwissen
aber folgendes baue ich gerade zum spass und zum lernen

ich hab einen teensy mit dem ich ca. 100 werte einsammle, ca. 70
kommen über seriell (max232) rein, der rest ist gps, accel,
gyro, rtc und noch ca. 10 sensoren für temp, druck usw ...
die schreibe ich auf wunsch auf einen usb-stick und geb sie auf einem
display welches an einem ft800 hängt aus

soweit so gut, dass funktioniert auch alles ...

nun wollte ich das display und meinen schaltungsaufbau trennen,
schaltung in eine kiste und display in eine andere und kabel dazwischen,
auch das funktioniert ohne problem bei meinen 2 meter kabellänge wenn
ich einfach 8 kabel (+/- und 6 für die display-ansteuerung, SPI)
verwende und ja, ich hatte bis jetzt keine probleme mit 2metern und spi

aber 6 kabel nur um daten zu einem display zu schicken puhhh,
also hab ich geschaut was für schnittstellen ich am teensy noch frei hab
und das ist aktuell nur pin 3 und 4 also can, da alle 3 seriellen schon
belegt sind (max232, gps, usb-host) ...

also hab ich folgendes gedacht, nimm 2x SN65HVD230D mach 2 kabel
dazwischen und schick deine daten drüber ...

wenn ich auf beiden seiten eine serielle opfere, kann ich die beiden
teensys's ohne problme einfach zusammenhängen (rc/tx einfach kreuzen)
und meine daten fehlerfrei und schnell genug übertragen ...

das problem ist hier sicher nicht schnell oder langsam, auf beiden
teensys's läuft die main-schleife ohne delays immer runde rum und in der 
runde rum müssen halt die daten auch zur anderen seite und das geht mit
seriell ohne das ich daten verliere und der can ist mit in der fresse 
explodiert ;)

zum testen hab ich dann nochmal rs485 versucht, bis zu 12mbit schnell
und störunanfällig mit 2leitunge hat sich gut angehört auch wenn es
mich eine serielle schnittstelle kostet ... auch das geht ohne
probleme und datenverlust ... kostet mich aber 1 serielle die ich
eigentlich anderweitig gebrauchen könnte ...

da ich das problem hier mit can also so nicht gelöst bekomme,
werde ich also entweder wieder meine 8 leitungen nehmen und
mir ein schönes geschirmtes kabel besorgen
oder eine der seriellen für rs485 opfern ...

das kleine im bild ist der teensy mit can der am display hängt, dass
andere der versuchsaufbau mit breakouts auf lochraster ... rot/weis
die can-leitungen ...

: Bearbeitet durch User
von Pit (Gast)


Lesenswert?

Ray M. schrieb:
> das glaube ich nicht ... genau das halte ich für eine
> überholte einstellung, wozu muss ich wissen wie der mixer funktioniert
> wenn ich brot backe ?

Das ist keine überholte Einstellung. Du musst ja nicht wissen, wie die 
Pegelwandlung, das Bit-Stuffing, die CRC usw. funktioniert. Was du aber 
wissen musst sind generelle Grundlagen wie die Sache mit den Message 
Objects oder auch Mailboxen, wie andere das nennen.
Vom Prinzip her ist CAN ein ganz einfaches Bussystem. Man kann bis zu 8 
Bytes an Nutzdaten versenden und das ganze Drumherum übernimmt der CAN 
Controller bzw. der Tranceiver.
Wenn du jetzt aber die Puffer vollknallst ist das ein Fehler deiner 
Applikation und nicht des CAN.


Ray M. schrieb:
> ergebnis: can ist in der form zur einfachen übertragung von
>           messdaten zwischen 2 oder mehr teensy's nicht zu gebrauchen


Sorry aber das ist totaler Unsinn. Ich arbeite mit bis zu 10 CAN Knoten 
verteilt auf 3 CAN Stränge, darunter proprietäres CAN, CANopen, J1939 
und UDS. Das alles wird dein Teensy nicht schaffen aber ein einfacher 
Datenaustausch macht der ohne Probleme mit.

Von daher schaue dir noch einmal alle Rückgabewerte der Funktionen an, 
überprüfe die Puffer und lies die Docu noch einmal in Ruhe. Denn gerade 
bei solchen Sachen sitzt das Problem zu 99 % vor dem Bildschirm, ich 
kenne das aus eigener Erfahrung.....

von Ray M. (ray_m)


Lesenswert?

Pit schrieb:
> Ray M. schrieb:
>> das glaube ich nicht ... genau das halte ich für eine
>> überholte einstellung, wozu muss ich wissen wie der mixer funktioniert
>> wenn ich brot backe ?
>
> Das ist keine überholte Einstellung. Du musst ja nicht wissen, wie die
> Pegelwandlung, das Bit-Stuffing, die CRC usw. funktioniert. Was du aber
> wissen musst sind generelle Grundlagen wie die Sache mit den Message
> Objects oder auch Mailboxen, wie andere das nennen.
> Vom Prinzip her ist CAN ein ganz einfaches Bussystem. Man kann bis zu 8
> Bytes an Nutzdaten versenden und das ganze Drumherum übernimmt der CAN
> Controller bzw. der Tranceiver.
> Wenn du jetzt aber die Puffer vollknallst ist das ein Fehler deiner
> Applikation und nicht des CAN.

joop, dass hab ich dank der erklärung weiter oben verstanden

> Ray M. schrieb:
>> ergebnis: can ist in der form zur einfachen übertragung von
>>           messdaten zwischen 2 oder mehr teensy's nicht zu gebrauchen
>
>
> Sorry aber das ist totaler Unsinn. Ich arbeite mit bis zu 10 CAN Knoten
> verteilt auf 3 CAN Stränge, darunter proprietäres CAN, CANopen, J1939
> und UDS. Das alles wird dein Teensy nicht schaffen aber ein einfacher
> Datenaustausch macht der ohne Probleme mit.
>
> Von daher schaue dir noch einmal alle Rückgabewerte der Funktionen an,
> überprüfe die Puffer und lies die Docu noch einmal in Ruhe. Denn gerade
> bei solchen Sachen sitzt das Problem zu 99 % vor dem Bildschirm, ich
> kenne das aus eigener Erfahrung.....

ich hab heute ein wenig zeit, werde mich nochmal über die pdf's hängen,
ich hoffe ich bekomme eine erleuchtung beim schreiben eines kleinen
progs was mit rückgaberten und buffern usw. arbeit ... ;)

danke für eure gedult ...

von Steffen R. (steffen_rose)


Lesenswert?

Ray M. schrieb:
> Steffen R. schrieb:
>> Kenne diese Lib nicht. Es klingt aber auf jeden Fall so, dass du
>> schneller in den CAN schreibst, als dieser verschicken kann. Genau dies
>> meldet Dir der Rückgabewert von
>>
>> CANbus.write(msg);
>
> also der return von CANbus.write ist bei mir immer 0,
> demnach dürfte er gar keine messages verschciken ??? häää

int FlexCAN::write(const CAN_message_t &msg)
kehrt mit 0 zurück, wenn es nicht in die Hardware schreibt und mit 1 
nachdem es in die Hardware schreibt. So steht es im von Dir verlinkten 
Sourcecode.

Hier ist etwas sehr widersprüchlich.

Ray M. schrieb:
>> Diese Details (Rückgabewerte, Flags, Status) sind wichtiger für eine
>> genaue Analyse als ein helfender Workaround, der das Problem nur
>> verbirgt und man nicht weiterkommt.
>
> ja, dass bringt mich aber alles nicht weiter wenn sich niemand findet
> der hier schonmal ein ähnliches problem und eine lösung hatte ;)

Dies hilft aber uns, die nicht mit diesen Libraries arbeiten, Dir Hilfe 
zur Selbsthilfe zu geben.

Ray M. schrieb:
> beim empfänger kommt ohne delay nach dem 6ten nur unsinn
> an, je nach wetterlage ...
>
> 0x100
> 0x100
> 0x103
> 0x107
> 0x107
> 0x107

Im Sourcecode kann ich keine Overflow Prüfung erkennen. Einen CAN 
Adapter für den PC hast Du nicht zufällig, um genauer zu wissen, was 
über den CAN Bus geht?

Ray M. schrieb:
> einige sekunden, dann hängt sich der sender komplett weg,
> da hilft nur noch strom ab und wieder dran und dann geht es weiter,
> wieder einige sekunden ...

Busoff?

Ray M. schrieb:
> wer zum geier funkt mir hier dazwischen, welcher buffer ist wo
> von wem zu klein ? anderen can-receiver eventuell ?
> ander lib eventuell ?

Ist noch unklar, ob das Problem bei Sender oder Empfänger liegt. Hättest 
Du den Test - Uart raus - mit 1MB gemacht statt auch hier dran zu 
schrauben, wäre es etwas einfacher.

Ein größerer Puffer nützt nur zur Überbrückung von Bursts. Du möchtest 
aber nach meinem Verständnis Dauerlast.

Ray M. schrieb:
> 2. oder ich konzentriere mich auf meine kernkompetenz, aus soft-
>    und hardware eine lösung bauen ... und genau da gehört es dazu
>    vorhandene hardware über eine schnittstelle und libs einzubinden
>    ohne genau zu wissen wie bit-bummsen im ic geht, erst wenn problem
>    auftreten fragt man jemand der sich damit genauer auskennt,

Verständlich. Da Du aber auch das Design für dein Projekt machst, mußt 
Du zumindest den Durchsatz und die Latenz der von Dir gewählten 
Schnittstelle kennen.

Ray M. schrieb:
> unter 10ms ist schnell genug

Dann sind deine Simulationen mit den Delays doch gut und du schaffst den 
Durchsatz. Negativ an der von Dir gewählten Lib ist die fehlende 
Fehlererkennung (soweit ich es erkennen kann).
Ich würde auch das timeout setzen. Je nachdem, welche Blockierung deine 
Applikation verträgt.

Ray M. schrieb:
> wenn die lib die hw nicht sauber incl. docu abstrahiert bin ich halt
> aufgeschmissen ...

Ja, ich denke, das ist hier eines der Probleme.
Da aber Sourcecode und Testergebnis nicht so recht zusammenpassen, würde 
ich aber auch erstmal noch schauen, ob der Test korrekt durchgeführt 
wurde. Ich vermute, Du hast das Ergebnis verschiedener Testsszenarien in 
einen Topf geworfen. Und dieser Part liegt bei Dir als 
Anwendungs-Programmierer.

von Ray M. (ray_m)


Lesenswert?

also jetzt bin ich komplett verwirrt

>Jede CAN-Schnittstelle hat mehrere Mailboxen,
> die wiederrum einen FIFO vorgeschaltet.
> Der Treiber von ST versucht dann eine freie Mailbox zu
> finden, die sich dann (in Hardware) darum kümmert die Daten
> physikalisch auf den Bus zu schreiben.
> Ist keine Mailbox mehr frei (und fragt man das nicht ab)
> ist die Nachricht weg.

soweit so klar

sender seite:
CANbus.write gibt angeblich 1 zurück wenn es eine message
absetzen konnte und 0 wenn nicht, ich nehme mal an die docu
meint 1 wenn in mailbox abgelegt werden konnte und 0 wenn nicht

  msg.id = 0x100;
  msg.len = sizeof(sysData.a);
  memcpy(msg.buf, &sysData.a, msg.len);
  if ( CANbus.write(msg) ) {
    Serial.println("1: mailbox found, message send");
  } else {
    Serial.println("0: mailbox not found, message drop");
  }

nur was hat das mit dem empfänger zu tun ???

wenn ich den sender laufe lasse bekomme ich immer 0 zurück,
sobald ich einen empfänger auf dem bus anschalte kommt 1 zurück ...

hängen die mailboxen auf beiden seiten auf dem bus irgendwie zusammen 
???
hab ich in der can-einführung was überlesen ???

von Peter D. (peda)


Lesenswert?

Ray M. schrieb:
> hab ich in der can-einführung was überlesen ???

Ja.

Ein CAN-Sender sendet solange, bis er ein ACK empfängt, d.h. mindestens 
ein Teilnehmer hängt am Bus, der die Nachricht fehlerfrei empfangen hat.

von Ray M. (ray_m)


Lesenswert?

[...]

> Verständlich. Da Du aber auch das Design für dein Projekt machst, mußt
> Du zumindest den Durchsatz und die Latenz der von Dir gewählten
> Schnittstelle kennen.

das stimmt wohl, ich bin davon ausgegangen das can bei der latenz weit 
genug unten ist um einige wenige byte zu übertragen so das mein display
nicht ruckelt ...

> Ray M. schrieb:
>> unter 10ms ist schnell genug
>
> Dann sind deine Simulationen mit den Delays doch gut und du schaffst den
> Durchsatz. Negativ an der von Dir gewählten Lib ist die fehlende
> Fehlererkennung (soweit ich es erkennen kann).
> Ich würde auch das timeout setzen. Je nachdem, welche Blockierung deine
> Applikation verträgt.

na ja, wenn ich msg.timeout=3 setze geht das alles nur wird es zu 
langsam
ich glaube deshalb hier

"When caller blocking is selected for write() (non-zero timeout
specified), a single hardware transmit buffer is used."

> Ray M. schrieb:
>> wenn die lib die hw nicht sauber incl. docu abstrahiert bin ich halt
>> aufgeschmissen ...
>
> Ja, ich denke, das ist hier eines der Probleme.
> Da aber Sourcecode und Testergebnis nicht so recht zusammenpassen, würde
> ich aber auch erstmal noch schauen, ob der Test korrekt durchgeführt
> wurde. Ich vermute, Du hast das Ergebnis verschiedener Testsszenarien in
> einen Topf geworfen. Und dieser Part liegt bei Dir als
> Anwendungs-Programmierer.

ok, würde ich gern machen ...

sagst du mir wie und was in welcher reihenfolge ?

von Ray M. (ray_m)


Lesenswert?

Peter D. schrieb:
> Ray M. schrieb:
>> hab ich in der can-einführung was überlesen ???
>
> Ja.
>
> Ein CAN-Sender sendet solange, bis er ein ACK empfängt, d.h. mindestens
> ein Teilnehmer hängt am Bus, der die Nachricht fehlerfrei empfangen hat.

ahh ... ich hab was überlesen ... danke für den schubs ...

von Steffen R. (steffen_rose)


Lesenswert?

> In-order Transmission

> Caller blocking can be used to write() frames guaranteed in-order to the
> bus. When caller blocking is selected for write() (non-zero timeout
> specified), a single hardware transmit buffer is used.

Aus deiner verlinkten Doku!
D.h., wenn Du ohne Blockierung arbeitest, kann sich die Reihenfolge der 
Nachrichten ändern.
Ohne genauer hinzusehen, kann man aus deinen Daten somit nicht 
schließen, ob du einfach die Nachrichten in einer anderen Reihenfolge 
empfangen  hast oder ob wirklich Daten verloren gegangen sind.

Rein vom Algorithmus werden beim (zu schnellem) Reinschreiben neue 
Nachrichten zu erst übertragen. Erst in einer Lücke werden dann auch die 
älteren Nachrichten übertragen. Da Du das nicht willst mußt du somit 
auch die Doku beachten!

von Steffen R. (steffen_rose)


Lesenswert?

Ray M. schrieb:
> Peter D. schrieb:
>> Ray M. schrieb:
>>> hab ich in der can-einführung was überlesen ???
>>
>> Ja.
>>
>> Ein CAN-Sender sendet solange, bis er ein ACK empfängt, d.h. mindestens
>> ein Teilnehmer hängt am Bus, der die Nachricht fehlerfrei empfangen hat.
>
> ahh ... ich hab was überlesen ... danke für den schubs ...

Für die mitlesenden Experten:
Naja, begin() wartet auf den Error Active Wechsel.
Ohne timeout werden 8 Sendepuffer genutzt.

Insofern müßte ohne Gegenstelle und ohne Timeout 8x eine 1 zurückkommen. 
Erst dann sind die Puffer voll und es kommt dauerhaft eine 0.
Mit Timeout >0 wird nur ein Sendpuffer genutzt. Selbst dann müßte einmal 
eine 1 zurückkehren.

Ray hat schon korrekt geschrieben, dass der Rückgabewert das schreiben 
in den CAN und nicht den Senderfolg widergibt.

Ray M. schrieb:
> na ja, wenn ich msg.timeout=3 setze geht das alles nur wird es zu
> langsam

Dann brauchst Du eine eigene Zeitbasis und schreibst nur aller 10ms in 
den CAN. Bei der langen Zeit sind nur im Fehlerfall Probleme zu 
erwarten.

von Ray M. (ray_m)


Lesenswert?

Steffen R. schrieb:
>> In-order Transmission
>
>> Caller blocking can be used to write() frames guaranteed in-order to the
>> bus. When caller blocking is selected for write() (non-zero timeout
>> specified), a single hardware transmit buffer is used.
>
> Aus deiner verlinkten Doku!
> D.h., wenn Du ohne Blockierung arbeitest, kann sich die Reihenfolge der
> Nachrichten ändern.
> Ohne genauer hinzusehen, kann man aus deinen Daten somit nicht
> schließen, ob du einfach die Nachrichten in einer anderen Reihenfolge
> empfangen  hast oder ob wirklich Daten verloren gegangen sind.
>
> Rein vom Algorithmus werden beim (zu schnellem) Reinschreiben neue
> Nachrichten zu erst übertragen. Erst in einer Lücke werden dann auch die
> älteren Nachrichten übertragen. Da Du das nicht willst mußt du somit
> auch die Doku beachten!

ok, danke ... mein gehirn kommt der sache langsam auf die spur,
glaube ich ...

- ich kann nicht einfach reinschreiben, sondern muss warten bis
  eine mailbox frei ist

- eine nachricht gilt erst als versendet wenn mind. 1 empfänger
  sie bestätigt hat, solange kann ich wenn die mailboxes beim sender
  voll sind nix mehr reinschreiben weil dann natürlich einfach weg

- caller blocking ist keine gute idee

- ich hab ein problem in meiner main-schleife weil ich will ja so 
schnell
  wie möglich meine senoren abfragen muss aber langsamer daten über
  can verschicken, wenn ich jetzt threads hätte wär alles gut ;(

ich versuch mal meine erkenntnisse in pseudo-code zu fassen

while {
  sensoren auslesen und in buffer schreiben;
  if ( timedelta > 1sec) { gps auslesen und in buffer schreiben }
  buffer auf den usb-stick in datei schreiben
  // so jetzt komm ich ins schwimmen
  if ( can noch was frei ) {
    if ( daten aus buffer in can-message packen und wegschicken ) {
      merken was ich schon verschickt hab
    } else {
      nix machen, einfach weiter i mtext
    }
  } else {
    merken was ich noch nicht verschickt hab
    nix auf canbus rausschicken
  }
}

von Ray M. (ray_m)


Lesenswert?

Steffen R. schrieb:
> Ray M. schrieb:
>> Peter D. schrieb:
>>> Ray M. schrieb:
>>>> hab ich in der can-einführung was überlesen ???
>>>
>>> Ja.
>>>
>>> Ein CAN-Sender sendet solange, bis er ein ACK empfängt, d.h. mindestens
>>> ein Teilnehmer hängt am Bus, der die Nachricht fehlerfrei empfangen hat.
>>
>> ahh ... ich hab was überlesen ... danke für den schubs ...
>
> Für die mitlesenden Experten:
> Naja, begin() wartet auf den Error Active Wechsel.
> Ohne timeout werden 8 Sendepuffer genutzt.
>
> Insofern müßte ohne Gegenstelle und ohne Timeout 8x eine 1 zurückkommen.

genau so verhält sich das bei mir, kein client dran kommt 8x1 und dann
immer 0

> Erst dann sind die Puffer voll und es kommt dauerhaft eine 0.
> Mit Timeout >0 wird nur ein Sendpuffer genutzt. Selbst dann müßte einmal
> eine 1 zurückkehren.

auch das ist bei mir genau so ...

> Ray hat schon korrekt geschrieben, dass der Rückgabewert das schreiben
> in den CAN und nicht den Senderfolg widergibt.
>
> Ray M. schrieb:
>> na ja, wenn ich msg.timeout=3 setze geht das alles nur wird es zu
>> langsam
>
> Dann brauchst Du eine eigene Zeitbasis und schreibst nur aller 10ms in
> den CAN. Bei der langen Zeit sind nur im Fehlerfall Probleme zu
> erwarten.

aber dann kann ich auch nicht 30 messages auf einmal raushauen ;( ... ;)

von hp-freund (Gast)


Lesenswert?

Ray M. schrieb:
> aber dann kann ich auch nicht 30 messages auf einmal raushauen ;( ... ;)

Dann wird es Zeit zu packen.
Zeig doch mal deine komplette struct. Erst dann kann man sagen wie viele 
bytes tatsächlich übertragen werden müssen.

von Steffen R. (steffen_rose)


Lesenswert?

Ray M. schrieb:
> - ich hab ein problem in meiner main-schleife weil ich will ja so
> schnell
>   wie möglich meine senoren abfragen muss aber langsamer daten über
>   can verschicken, wenn ich jetzt threads hätte wär alles gut ;(

Wieso mußt Du die Sensoren häufiger abfragen also Du die Daten 
verschicken willst?

von Ray M. (ray_m)


Lesenswert?

was mich jetzt beim meinem laienhaften blick in die flexcan-lib 
verwundert
ist das die jungs da yield() drin machen, das startet doch soweit ich
das verstanden hab einen 2ten loop
nur wann kommt der zurück und arbeiten sie da die sendebuffer drin ab ?
wenn ja müsste ich ja nur in der lib die sendebuffer auf z.b. 200byte
setzen und würde keine daten verlieren wenn ich vor dem senden einfach
checke ob der buffer leer ist ? oder ist das in meinem hirn einfach
der falsche weg ???

von Steffen R. (steffen_rose)


Lesenswert?

Ray M. schrieb:
> auch das ist bei mir genau so ...

Lies noch mal, was du oben schreibst und welches davon abweichende 
Verhalten du hier bestätigst. Wie sollen wir da helfen?

Insofern: Die Lib arbeitet wie dokumentiert und du kannst den 
Rückgabewert für deine Entscheidungen heranziehen.

von Ray M. (ray_m)


Lesenswert?

Steffen R. schrieb:
> Ray M. schrieb:
>> - ich hab ein problem in meiner main-schleife weil ich will ja so
>> schnell
>>   wie möglich meine senoren abfragen muss aber langsamer daten über
>>   can verschicken, wenn ich jetzt threads hätte wär alles gut ;(
>
> Wieso mußt Du die Sensoren häufiger abfragen also Du die Daten
> verschicken willst?

weil ich sie so oft wie möglich uaf den usb-stick schreiben will,
je feiner die auflösung je besser zum auswerten für mich ... ;)

von Ray M. (ray_m)


Lesenswert?

hp-freund schrieb:
> Ray M. schrieb:
>> aber dann kann ich auch nicht 30 messages auf einmal raushauen ;( ... ;)
>
> Dann wird es Zeit zu packen.
> Zeig doch mal deine komplette struct. Erst dann kann man sagen wie viele
> bytes tatsächlich übertragen werden müssen.

aktuell sind 124byte im struct ... (int, float, byte gemixt)

von Ray M. (ray_m)


Lesenswert?

Steffen R. schrieb:
> Ray M. schrieb:
>> auch das ist bei mir genau so ...
>
> Lies noch mal, was du oben schreibst und welches davon abweichende
> Verhalten du hier bestätigst. Wie sollen wir da helfen?
>
> Insofern: Die Lib arbeitet wie dokumentiert und du kannst den
> Rückgabewert für deine Entscheidungen heranziehen.

ja, dass versuch ich gerade zu bauen ...

dann kann ich ja auch noch immer 2 int's aus dem struct in eine
message packen, dann hätte ich weniger messages zu verschicken ...
es bleiben auber auch dann noch mehr als in einem loop durchgehen ...

von hp-freund (Gast)


Lesenswert?

Ray M. schrieb:
> dann kann ich ja auch noch immer 2 int's aus dem struct in eine
> message packen, dann hätte ich weniger messages zu verschicken ...

Das meine ich. Richtig packen spart Platz. Und immer 8bytes ausnutzen.

__attribute__((packed)) für die struct und nicht die Werte einzeln 
senden.

Zeig mal die komplette struct, die es am Ende werden soll.

von Ray M. (ray_m)


Lesenswert?

hp-freund schrieb:
> Ray M. schrieb:
>> dann kann ich ja auch noch immer 2 int's aus dem struct in eine
>> message packen, dann hätte ich weniger messages zu verschicken ...
>
> Das meine ich. Richtig packen spart Platz. Und immer 8bytes ausnutzen.
>
> __attribute__((packed)) für die struct und nicht die Werte einzeln
> senden.
>
> Zeig mal die komplette struct, die es am Ende werden soll.

ich seh gerade das sind ja nur 102byte, die 124 waren noch vom 
vorgänger,
oops ;)


struct DataSet {
    int32_t count;
    unsigned int type;
    unsigned int rpm;
    unsigned int throttlePlate;
    signed int engineTemp;
    float batteryVoltage;
    signed int airTemp;
    unsigned int airPressureInt;
    float injectionTime;
    signed int injectionAngel;
    float lambda;
    float gasAirMass;
    float gasAirMassCorr;
    float gasBasicMap;
    float gasManVac;
    float gasBaseQuant;
    float gasAir;
    float gasIdleSpeedControl;
    float gasEngineTemp;
    float gasAcceleration;
    float gasSwitchingTime;
    float gasRaceInput;
    float gasLambda;
    signed int ignMap;
    signed int ignAirTemp;
    signed int ignAirPress;
    signed int ignEngineTemp;
    signed int ignAcceleration;
    float boostControl;
    float airPressureExt;
    float volThrottle;
    float volBattery;
    float volLambda;
    float volEngineTemp;
    float volAirTemp;
    float volExtAirPress;
    float volIntAirPress;
    float volLambda2;
    float volAirMass;
    float volEPasPoti1;
    float volEPasPoti2;
    float volTempA;
    float volTempB;
    float volTempC;
    float volTempD;
    float volIntTemp;
    float broadbandLambda1;
    float broadbandLambda2;
    float targetLambdaValue;
    signed int exhaustTemp1;
    signed int exhaustTemp2;
    float idleSpeedControl;
    unsigned int nozzlesUtilization;
    unsigned int rpmErrors;
    unsigned int probeTemp1;
    unsigned int probeTemp2;
    int16_t ax;
    int16_t ay;
    int16_t az;
    int16_t gx;
    int16_t gy;
    int16_t gz;
    int satellites;
    float flat;
    float flon;
    unsigned long fage;
    unsigned long age;
    int year;
    byte month;
    byte day;
    byte hour;
    byte minute;
    byte second;
    byte hundredths;
    float altitude;
    float speed;
    float rtcTemp;
    int gearboxTemp;
    int diffTemp;
    int oelTemp;
    int oelPress;
};

von Malte (Gast)


Lesenswert?

Überdenke nochmal ob es sinn macht alle Daten auf einmal zu übertragen, 
oder ob man hier vlt. einen anderen Ansatz fahren könnte. Des weiteren 
könnte man sich überlegen ob man einige von diesen hässlichen floats 
raus bekommt (Temperaturen usw kann man schön in ints packen...)

Gruß,
Malte

von Steffen R. (steffen_rose)


Lesenswert?

Ray M. schrieb:
> dann kann ich ja auch noch immer 2 int's aus dem struct in eine
> message packen, dann hätte ich weniger messages zu verschicken ...
> es bleiben auber auch dann noch mehr als in einem loop durchgehen ...

Da es nun dann doch auf Burst aller 10ms hinausläuft, wirst Du noch eine 
eigene Queue zum Zwischenpuffern benötigen.

Da Du 1MB nutzt, ist ein Timeout von mind. 1ms für Dich nicht attraktiv. 
Insofern solltest Du wohl eher schauen, dass dein Algorythmus mit einer 
vertauschten Reihenfolge auf dem CAN klarkommt.

hp-freund schrieb:
> Das meine ich. Richtig packen spart Platz. Und immer 8bytes ausnutzen.
>
> __attribute__((packed)) für die struct und nicht die Werte einzeln
> senden.

Dies ist effizient, aber im Fehlerfall problematisch.
Und wenn sich die Reihenfolge der Nachrichten ändert, braucht es einer 
Überwachung, wann die Struktur komplett übertragen wurde.
Mir geht es hier speziell um Werte, welche auf zwei CAN Telegramme 
aufgeteilt sind.

von Ray M. (ray_m)


Lesenswert?

Malte schrieb:
> Überdenke nochmal ob es sinn macht alle Daten auf einmal zu übertragen,
> oder ob man hier vlt. einen anderen Ansatz fahren könnte.

ich bin am überlegen ob ich immer nur die daten zum teensy/display
schicke die gerade angezeigt werden und wenn ich via touch eine
andere seite aufmache dem sende-teensy sage schick mir was anderes ...

oh jeeee, nun auch noch in beide richtungen can ... brrr ;)

das macht den code aber komplizierter und einfacher code ist halt
einfacher zu warten bzw. in einigen wochen auch einfacher zu erweitern 
;)

> Des weiteren
> könnte man sich überlegen ob man einige von diesen hässlichen floats
> raus bekommt (Temperaturen usw kann man schön in ints packen...)

das macht sinn, das werde ich machen ...

: Bearbeitet durch User
von Ray M. (ray_m)


Lesenswert?

Steffen R. schrieb:
> Ray M. schrieb:
>> dann kann ich ja auch noch immer 2 int's aus dem struct in eine
>> message packen, dann hätte ich weniger messages zu verschicken ...
>> es bleiben auber auch dann noch mehr als in einem loop durchgehen ...
>
> Da es nun dann doch auf Burst aller 10ms hinausläuft, wirst Du noch eine
> eigene Queue zum Zwischenpuffern benötigen.
>
> Da Du 1MB nutzt, ist ein Timeout von mind. 1ms für Dich nicht attraktiv.
> Insofern solltest Du wohl eher schauen, dass dein Algorythmus mit einer
> vertauschten Reihenfolge auf dem CAN klarkommt.

das ist dem algo eigentlich egal, alle can-messages werden empfange und
die werte werden auf dem empfänger wieder in einen struct geschrieben
über den dann die display-routine drüber rührt ...

> hp-freund schrieb:
>> Das meine ich. Richtig packen spart Platz. Und immer 8bytes ausnutzen.
>>
>> __attribute__((packed)) für die struct und nicht die Werte einzeln
>> senden.
>
> Dies ist effizient, aber im Fehlerfall problematisch.
> Und wenn sich die Reihenfolge der Nachrichten ändert, braucht es einer
> Überwachung, wann die Struktur komplett übertragen wurde.
> Mir geht es hier speziell um Werte, welche auf zwei CAN Telegramme
> aufgeteilt sind.

das sollte hier doch eigentlich nicht vorkommen ... oder hab ich was 
verpasst ?

von Malte (Gast)


Lesenswert?

Und dann, wie bei jeder Übertragung üblich, Werte nur dann Senden wenn 
sie sich geändert haben. Doppelt Senden macht ja keinen Sinn.

Ja, ja..Übertragung klingt leicht, zieht aber doch nen ganz schönen 
Rattenschwanz mit sich :)

von Ray M. (ray_m)


Lesenswert?

Malte schrieb:
> Und dann, wie bei jeder Übertragung üblich, Werte nur dann Senden wenn
> sie sich geändert haben. Doppelt Senden macht ja keinen Sinn.
>
> Ja, ja..Übertragung klingt leicht, zieht aber doch nen ganz schönen
> Rattenschwanz mit sich :)

joop ... puhhh ... ich hab am anfang auch gedacht das geht mit
can genauso wie serielll, einfach raus rotzen und fertig ...
aber is wohl nicht ;)

von Peter D. (peda)


Lesenswert?

Übertriebene Angst vorm Datenblatt schadet Dir nur selber.
Damit kann man einfach rauskriegen, wieviele MOBs (Hardwarepuffer) Dein 
CAN-Controller überhaupt hat.

Z.B. der AT90CAN128 hat 15 MOBs (jeweils ID + 0..8 Datenbyte), die kann 
man z.B. als 7 fürs Senden und 8 fürs Empfangen aufteilen.
Das ist schonmal bedeutend mehr, als die UART (2..16 Byte) des RS-485 
hat.
Natürlich kann sich die CAN-Lib weitere Puffer im RAM anlegen, die dann 
per CAN-Interrupt gesendet bzw. gefüllt werden.

Die MOBs sind allerdings kein FIFO. Das Senden erfolgt mit dem 
niedrigsten ID zuerst und nicht, was zuerst geladen wurde.
Und beim Empfang erfolgt bei gleicher ID-Maske das Füllen von unten nach 
oben. Wird ein unteres MOB ausgelesen, kriegt das dann das nächste 
Paket.
Bei CAN kann es also zur Vertauschung der Reihenfolge kommen. Bei 
Paketen >8Byte nimmt man daher einen Teil des ID als Paketzähler.

Das schwierigste am CAN ist eigentlich nur das Einstellen der Timeslots 
(Baudrate).

von Steffen R. (steffen_rose)


Lesenswert?

Ray M. schrieb:
>> hp-freund schrieb:
>>> Das meine ich. Richtig packen spart Platz. Und immer 8bytes ausnutzen.
>>>
>>> __attribute__((packed)) für die struct und nicht die Werte einzeln
>>> senden.
>>
>> Dies ist effizient, aber im Fehlerfall problematisch.
>> Und wenn sich die Reihenfolge der Nachrichten ändert, braucht es einer
>> Überwachung, wann die Struktur komplett übertragen wurde.
>> Mir geht es hier speziell um Werte, welche auf zwei CAN Telegramme
>> aufgeteilt sind.
>
> das sollte hier doch eigentlich nicht vorkommen ... oder hab ich was
> verpasst ?

Dann hast Du den Vorschlag von hp-freund nicht verstanden.
Wenn du aber auch ohne seinem Vorschlag deine 8 Byte vollbekommst, umso 
besser.

von Steffen R. (steffen_rose)


Lesenswert?

Ray M. schrieb:
> joop ... puhhh ... ich hab am anfang auch gedacht das geht mit
> can genauso wie serielll, einfach raus rotzen und fertig ...
> aber is wohl nicht ;)

Wenn Du low level hinabsteigen willst ...

static const int txBuffers = 8;

könnte auch auf 24 erhöht werden können. Müßte man sich mal genauer 
ansehen. Aber da wärst Du jetzt der einzige hier, der das probieren 
kann.
Und bitte nicht Werte wahllos probieren.

Überlegung:
Die ersten Puffer werden für die RX Fifo genutzt. Ab dem 8.Puffer 
beginnen die TX Messageboxen. Insgesamt hat er wohl 32 Messageboxen.

von Ray M. (ray_m)


Lesenswert?

Steffen R. schrieb:
> Ray M. schrieb:
>>> hp-freund schrieb:
>>>> Das meine ich. Richtig packen spart Platz. Und immer 8bytes ausnutzen.
>>>>
>>>> __attribute__((packed)) für die struct und nicht die Werte einzeln
>>>> senden.
>>>
>>> Dies ist effizient, aber im Fehlerfall problematisch.
>>> Und wenn sich die Reihenfolge der Nachrichten ändert, braucht es einer
>>> Überwachung, wann die Struktur komplett übertragen wurde.
>>> Mir geht es hier speziell um Werte, welche auf zwei CAN Telegramme
>>> aufgeteilt sind.
>>
>> das sollte hier doch eigentlich nicht vorkommen ... oder hab ich was
>> verpasst ?
>
> Dann hast Du den Vorschlag von hp-freund nicht verstanden.

doch schon ...

> Wenn du aber auch ohne seinem Vorschlag deine 8 Byte vollbekommst, umso
> besser.

aber ich glaube ich bekomme die 8byte immer schön voll ;)

von Ray M. (ray_m)


Lesenswert?

Steffen R. schrieb:
> Ray M. schrieb:
>> joop ... puhhh ... ich hab am anfang auch gedacht das geht mit
>> can genauso wie serielll, einfach raus rotzen und fertig ...
>> aber is wohl nicht ;)
>
> Wenn Du low level hinabsteigen willst ...
>
> static const int txBuffers = 8;
>
> könnte auch auf 24 erhöht werden können. Müßte man sich mal genauer
> ansehen. Aber da wärst Du jetzt der einzige hier, der das probieren
> kann.
> Und bitte nicht Werte wahllos probieren.

warum nicht ;)

> Überlegung:
> Die ersten Puffer werden für die RX Fifo genutzt. Ab dem 8.Puffer
> beginnen die TX Messageboxen. Insgesamt hat er wohl 32 Messageboxen.

ok, dann kram ich jetzt mal das datenblatt raus und schau nach,
dann veruch ich mich mal am buffer anassen ... wenn das mein problem
vereinfacht ist das super ...

haha ... 2058 seiten docu zum chip ... huraaaa ich hab gleich fertig ...
so lange muss ich nie aufs klo ... ich glaube durchtesten geht schneller 
;)

: Bearbeitet durch User
von Y. W. (york_w34)


Lesenswert?

Hallo Ray,

hast Du schon mal überlegt Deine Struct in Gruppen aufzuteilen, die in 
die 8 Bytes einer CAN Nachricht passen, dann kann/muss man denen sogar 
noch verschiedene IDs geben und dadurch die Nachrichten der Wichtigkeit 
nach priorisieren.
Also wenn ein Wert sehr oft aktualisiert werden muss (ganz wichtig ist) 
dann eine niedrige CAN ID, wenn es eine Temp ist dann eine höhere.
Und dann solltest Du überlegen, immer nur Änderungen zu schicken, ok da 
Du hundertstel Sekunden übertragen willst wird die Nachricht wohl sehr 
oft kommen (über den Sinn der 1/100 Sek. will ich für ein Display jetzt 
mal nicht diskutieren).
Auf der Empfangs/Displayseite legst Du auch die Struktur an und 
aktualisierst sie immer, wenn eine entsprechende Nachricht reinkommt.

Wenn Du wirklich immer alles schicken willst, solltest Du Dir mal ISO TP 
anschauen, da kann man größere Datenblöcke mit einem/zwei CAN IDs 
übertragen.

Gruß
Y.W.

: Bearbeitet durch User
von Ray M. (ray_m)


Lesenswert?

Y. W. schrieb:
> Hallo Ray,
>
> hast Du schon mal überlegt Deine Struct in Gruppen aufzuteilen, die in
> die 8 Bytes einer CAN Nachricht passen, dann kann/muss man denen sogar
> noch verschiedene IDs geben und dadurch die Nachrichten der Wichtigkeit
> nach priorisieren.
> Also wenn ein Wert sehr oft aktualisiert werden muss (ganz wichtig ist)
> dann eine niedrige CAN ID, wenn es eine Temp ist dann eine höhere.
> Und dann solltest Du überlegen, immer nur Änderungen zu schicken, ok da
> Du hundertstel Sekunden übertragen willst wird die Nachricht wohl sehr
> oft kommen (über den Sinn der 1/100 Sek. will ich für ein Display jetzt
> mal nicht diskutieren).
> Auf der Empfangs/Displayseite legst Du auch die Struktur an und
> aktualisierst sie immer, wenn eine entsprechende Nachricht reinkommt.

ich hab mir folgendes überlegt

- ich zeige nicht immer alle werte gleichzeitig, warum also hinschicken

- wenn ich immer 8byte voll mache bekomme ich bei meinen daten
  im schlechtesten fall 2 werte in eine message und 6 messages ohne
  problme durch, also 12 werte, das sollte für eine display-seite
  locker reichen

- wenn ich am display via touch eine seite umschalte sag ich via can dem
  sender bescheid das er mit andere daten schicken soll

- dass sollte für meine anwendung funktionieren ... hoffe ich ...


> Wenn Du wirklich immer alles schicken willst, solltest Du Dir mal ISO TP
> anschauen, da kann man größere Datenblöcke mit einem/zwei CAN IDs
> übertragen.

das schau ich mir an, danke für das stichwort ...

von Ray M. (ray_m)


Lesenswert?

Ray M. schrieb:
> Y. W. schrieb:
>> Hallo Ray,
>>
>> hast Du schon mal überlegt Deine Struct in Gruppen aufzuteilen, die in
>> die 8 Bytes einer CAN Nachricht passen, dann kann/muss man denen sogar
>> noch verschiedene IDs geben und dadurch die Nachrichten der Wichtigkeit
>> nach priorisieren.
>> Also wenn ein Wert sehr oft aktualisiert werden muss (ganz wichtig ist)
>> dann eine niedrige CAN ID, wenn es eine Temp ist dann eine höhere.
>> Und dann solltest Du überlegen, immer nur Änderungen zu schicken, ok da
>> Du hundertstel Sekunden übertragen willst wird die Nachricht wohl sehr
>> oft kommen (über den Sinn der 1/100 Sek. will ich für ein Display jetzt
>> mal nicht diskutieren).
>> Auf der Empfangs/Displayseite legst Du auch die Struktur an und
>> aktualisierst sie immer, wenn eine entsprechende Nachricht reinkommt.
>
> ich hab mir folgendes überlegt
>
> - ich zeige nicht immer alle werte gleichzeitig, warum also hinschicken
>
> - wenn ich immer 8byte voll mache bekomme ich bei meinen daten
>   im schlechtesten fall 2 werte in eine message und 6 messages ohne
>   problme durch, also 12 werte, das sollte für eine display-seite
>   locker reichen
>
> - wenn ich am display via touch eine seite umschalte sag ich via can dem
>   sender bescheid das er mit andere daten schicken soll
>
> - dass sollte für meine anwendung funktionieren ... hoffe ich ...

mit der methode komme ich hin ohne im main-loop irgendwelche 
timeing-sachen
machen zu müssen da das auslesen der sensoren länger wie 3ms dauert und
die can-buffer somit bei jedem durchlauf immer leer sind ...

jetzt muss ich nur noch auf dem display schauen das ich immer mit einem
satz werten alles auf einer display-seite füllen kann und dann tut das 
erstmal so ...

: Bearbeitet durch User
von Pit (Gast)


Lesenswert?

Ray M. schrieb:
> - wenn ich am display via touch eine seite umschalte sag ich via can dem
>   sender bescheid das er mit andere daten schicken soll

Warum so "kompliziert"? Warum sträubst du dich so sehr gegen ein 
blockweises Senden? So hast du immer alle Werte auf dem Bus. Und ob ein 
neuer Wert nach 10 oder 30 ms kommt merkst du auf dem Display eh nicht.

Man sollte ein Display so dumm wie möglich halten, es ist halt ein 
reines Anzeigeinstrument. Die Sache mit dem Umschalten und dann die 
jeweilige Seite an den Controller zu schicken macht nur Sinn, wenn du 
massig Daten hast und das ist hier ja nicht der Fall.

Außerdem würde ich dir raten ein Analysetool für CAN zu besorgen, falls 
du weitere Projekte mit dem CAN machen möchtest. Nicht ganz billig aber 
ein faires Preis-/Leistungsverhältnis hast du mit dem Peak Dongle.

von Ray M. (ray_m)


Lesenswert?

Pit schrieb:
> Ray M. schrieb:
>> - wenn ich am display via touch eine seite umschalte sag ich via can dem
>>   sender bescheid das er mit andere daten schicken soll
>
> Warum so "kompliziert"? Warum sträubst du dich so sehr gegen ein
> blockweises Senden? So hast du immer alle Werte auf dem Bus.

weil mein konwhow dafür nicht ausreicht, ich hab noch zu wenig
mit microcontrollern gemacht und auf einer richtigen cpu macht das
eben das betriebssystem, da mach ich einfach einen fork oder thread
und fertig ;)

du kannst mir ja mal 10 zeilen pesoudo-code schicken damit ich
verstehe was ihr alle eigentlich meint,
umsetzen kann ich das dann schon ...

> Und ob ein neuer Wert nach 10 oder 30 ms kommt merkst du auf dem Display eh 
nicht.

das stimmt ...

> Man sollte ein Display so dumm wie möglich halten, es ist halt ein
> reines Anzeigeinstrument. Die Sache mit dem Umschalten und dann die
> jeweilige Seite an den Controller zu schicken macht nur Sinn, wenn du
> massig Daten hast und das ist hier ja nicht der Fall.

auch das stimmt, deshalb wollte ich ja auch einfach alles hinblasen
und nur das was ich brauche anzeigen ...
aber das war ja so einfach nix ;)

> Außerdem würde ich dir raten ein Analysetool für CAN zu besorgen, falls
> du weitere Projekte mit dem CAN machen möchtest. Nicht ganz billig aber
> ein faires Preis-/Leistungsverhältnis hast du mit dem Peak Dongle.

meinst du das hier ?
  http://www.peak-system.com/PCAN-USB-FD.365.0.html

285€ ist aber für reine spielerei schon eine echte ansage ...

meinst du nicht das so was hier
  http://www.wayengineer.com/usbcan-debug-adapter-can-bus-analyzer-p-6065.html
  http://www.ebay.de/itm/CAN-Protocol-Analyser-Development-System-USB-Windows-/261934081574?pt=LH_DefaultDomain_3&hash=item3cfc7ce626
für meine hobby-spieler reicht ?

blos wenn ich die windowssoftware sehe wird mir schon wieder gruselig,
dann muss ich mir auch erstmal noch einen alten windows-laptop besorgen 
;(

: Bearbeitet durch User
von Steffen R. (steffen_rose)


Lesenswert?

CAN FD brauchst Du nicht. Er wird dieses meinen.

http://www.peak-system.com/PCAN-USB.199.0.html

Vorsicht, Du willst 1MB nutzen. Alle Adapter können die Bitrate. 
Unterschiedlich ist der Burst, den die Adapter können.
Deine zweite Hardware kenne ich nicht.

http://www.systec-electronic.com/de/produkte/industrielle-kommunikation/schnittstellen-und-gateways/can-usb-adapter-usb-canmodul1

finde ich ganz gut.

Denk dran, dass du noch PC Software brauchst. Die Adapter haben häufig 
nur sehr rudimentäre Software dabei. Und nicht jede Software unterstützt 
jede Hardware. An der Stelle hat Peak die Nase vorn.

von Steffen R. (steffen_rose)


Lesenswert?

Ray M. schrieb:
> blos wenn ich die windowssoftware sehe wird mir schon wieder gruselig,
> dann muss ich mir auch erstmal noch einen alten windows-laptop besorgen
> ;(

Darauf habe ich jetzt nicht geachtet.

Welches System hast Du? Linux?
Dann ja, der Peak Adapter unterstützt socketCAN. Wenn dein Kernel 
halbwegs aktuell ist, ist dieser Treiber bereits enthalten.
Zu socketCAN gibt es auch Kommandozeilentools, welche Dir die 
Nachrichten anzeigen (und vieles mehr).

Und ja, Basiswissen zu socketCAN mußt Du dir aneignen. Du mußt die 
Schnittstelle einbinden und öffnen.

von Ray M. (ray_m)


Lesenswert?

Steffen R. schrieb:
> Ray M. schrieb:
>> blos wenn ich die windowssoftware sehe wird mir schon wieder gruselig,
>> dann muss ich mir auch erstmal noch einen alten windows-laptop besorgen
>> ;(
>
> Darauf habe ich jetzt nicht geachtet.
>
> Welches System hast Du? Linux?

joop

> Dann ja, der Peak Adapter unterstützt socketCAN. Wenn dein Kernel
> halbwegs aktuell ist, ist dieser Treiber bereits enthalten.

ist drin, gerade nachgeschaut, die can-utils bauen auch ohne probleme

> Zu socketCAN gibt es auch Kommandozeilentools, welche Dir die
> Nachrichten anzeigen (und vieles mehr).
>
> Und ja, Basiswissen zu socketCAN mußt Du dir aneignen. Du mußt die
> Schnittstelle einbinden und öffnen.

das wird machbar sein, dann kann ich mit wireshark aufs interface
und alles wird gut ...

von Ray M. (ray_m)


Lesenswert?

Steffen R. schrieb:
> CAN FD brauchst Du nicht. Er wird dieses meinen.
>
> http://www.peak-system.com/PCAN-USB.199.0.html

na ja, sind immernoch 195€ für spielerei ;)


> Vorsicht, Du willst 1MB nutzen. Alle Adapter können die Bitrate.
> Unterschiedlich ist der Burst, den die Adapter können.
> Deine zweite Hardware kenne ich nicht.
>
> 
http://www.systec-electronic.com/de/produkte/industrielle-kommunikation/schnittstellen-und-gateways/can-usb-adapter-usb-canmodul1
>
> finde ich ganz gut.
>
> Denk dran, dass du noch PC Software brauchst. Die Adapter haben häufig
> nur sehr rudimentäre Software dabei. Und nicht jede Software unterstützt
> jede Hardware. An der Stelle hat Peak die Nase vorn.

na ja, solange socketCAN geht kann ich es an mein notebook stecken
und alles wir gut ...

hat dein vorschlag auch einen preis ???
auf der website finde ich nix

: Bearbeitet durch User
von Steffen R. (steffen_rose)


Lesenswert?

z.B.:
sysWORXX USB-CANmodul1

eBay-Artikelnummer:
261957599142

Ray M. schrieb:
> na ja, sind immernoch 195€ für spielerei ;)

Willst Du es wirklich wissen?
Nach meiner Meinung ist 1MB nicht für Spielerei geeignet. Max. 125k oder 
250k. Und da halte ich deinen angegebenen zweiten Adapter für 
möglicherweise wenig problematisch.

Das ist aber nur meine persönlich Meinung um auch aufzuzeigen, dass ich 
der Meinung bin, dass du bei deinem Weg dann auch entsprechend besseres 
Werkzeug benötigst. Und Du musst auch besser auf deine CAN Verkabelung 
und Abschlusswiderstände achten usw.

von Pit (Gast)


Lesenswert?

Ray M. schrieb:
> weil mein konwhow dafür nicht ausreicht, ich hab noch zu wenig
> mit microcontrollern gemacht und auf einer richtigen cpu macht das
> eben das betriebssystem, da mach ich einfach einen fork oder thread
> und fertig ;)
>
> du kannst mir ja mal 10 zeilen pesoudo-code schicken damit ich
> verstehe was ihr alle eigentlich meint,
> umsetzen kann ich das dann schon ...

1
void v_SendMessage()
2
{
3
   static uint8 u8_Block = 0;
4
5
   switch( u8_Block)
6
   {
7
8
   case 0:
9
   default:
10
      // hier 1 bis 5 nachrichten platzieren
11
      u8_Block = 1;
12
   break;
13
14
   case 1:
15
      // hier 1 bis 5 nachrichten platzieren
16
      u8_Block = 2;
17
   break;
18
19
   case 2:
20
      // hier 1 bis 5 nachrichten platzieren
21
      u8_Block = 0;
22
   break;
23
   }
24
25
}

von Ray M. (ray_m)


Lesenswert?

Pit schrieb:
> Ray M. schrieb:
>> weil mein konwhow dafür nicht ausreicht, ich hab noch zu wenig
>> mit microcontrollern gemacht und auf einer richtigen cpu macht das
>> eben das betriebssystem, da mach ich einfach einen fork oder thread
>> und fertig ;)
>>
>> du kannst mir ja mal 10 zeilen pesoudo-code schicken damit ich
>> verstehe was ihr alle eigentlich meint,
>> umsetzen kann ich das dann schon ...
>
>
>
1
> void v_SendMessage()
2
[...]
3
>

so mahc ich das, danke ...

ich packe meine daten aktuell so ein,
wobei a und e hier unsigned int sind ...

  msg.id = 0x100;
  msg.len = 8;
  memcpy(msg.buf, &a, sizeof(a));
  memcpy(&msg.buf[4], &e, sizeof(e));

ist das ok oder hab ich wieder dünnes im hirn ?

von Ray M. (ray_m)


Lesenswert?

Steffen R. schrieb:
> z.B.:
> sysWORXX USB-CANmodul1
>
> eBay-Artikelnummer:
> 261957599142
>
> Ray M. schrieb:
>> na ja, sind immernoch 195€ für spielerei ;)
>
> Willst Du es wirklich wissen?

nee ;)

> Nach meiner Meinung ist 1MB nicht für Spielerei geeignet. Max. 125k oder
> 250k. Und da halte ich deinen angegebenen zweiten Adapter für
> möglicherweise wenig problematisch.
>
> Das ist aber nur meine persönlich Meinung um auch aufzuzeigen, dass ich
> der Meinung bin, dass du bei deinem Weg dann auch entsprechend besseres
> Werkzeug benötigst. Und Du musst auch besser auf deine CAN Verkabelung
> und Abschlusswiderstände achten usw.

ok, dann werd ich wohl 200 ausgeben müssen, dass dürfte wie mit
anderem werkzeug auch sein, kauf gleich das richtige sonst zahlst
du am ende eh drauf ...

von Ray M. (ray_m)


Lesenswert?

Ray M. schrieb:
> Pit schrieb:
>> Ray M. schrieb:
>>> weil mein konwhow dafür nicht ausreicht, ich hab noch zu wenig
>>> mit microcontrollern gemacht und auf einer richtigen cpu macht das
>>> eben das betriebssystem, da mach ich einfach einen fork oder thread
>>> und fertig ;)
>>>
>>> du kannst mir ja mal 10 zeilen pesoudo-code schicken damit ich
>>> verstehe was ihr alle eigentlich meint,
>>> umsetzen kann ich das dann schon ...
>>
>>
>>
1
>> void v_SendMessage()
2
> [...]
3
>>

oh man ... c ist schon eine tolle sprache,
arrays nur mit werten gleichen types,
über structs kann man nicht iterieren
... na hauptsache der compiler macht es dann schön ;) ;) ;)

: Bearbeitet durch User
von Steffen R. (steffen_rose)


Lesenswert?

Ray M. schrieb:
> oh man ... c ist schon eine tolle sprache,
> arrays nur mit werten gleichen types,
> über structs kann man nicht iterieren

Beides zusammen ergibt ein union...

Aber ich hatte angenommen, du hast dich für einen feste Zuordnung von 
CAN Nachricht und enthaltenen Daten entschieden?
Bei einer Iteration über deine Struktur würden sich hier die 
Datenzuordnung bei Änderung der Struktur auch verändern und du mußt 
immer beide /alle Geräte anfassen.

von Ray M. (ray_m)


Lesenswert?

Steffen R. schrieb:
> Ray M. schrieb:
>> oh man ... c ist schon eine tolle sprache,
>> arrays nur mit werten gleichen types,
>> über structs kann man nicht iterieren
>
> Beides zusammen ergibt ein union...

ja ja genau, aber ich hab schon kopfweh vom canbus,
da muss jetzt auch nicht noch union sein ...

> Aber ich hatte angenommen, du hast dich für einen feste Zuordnung von
> CAN Nachricht und enthaltenen Daten entschieden?

hab ich ... wegen des kopfweh ;)

> Bei einer Iteration über deine Struktur würden sich hier die
> Datenzuordnung bei Änderung der Struktur auch verändern und du mußt
> immer beide /alle Geräte anfassen.

ich benutz bei allen teilnehmern einfach die gleich strutcs.h,
das finde ich ok und gut wartbar, die hängt einfach via "ln -s ..."
in jedem project-dir und gut is ...

von hp-freund (Gast)


Lesenswert?

Ist doch schön das dich CAN zwingt effizient programmieren zu lernen, 
oder :-)

von Ray M. (ray_m)


Lesenswert?

hp-freund schrieb:
> Ist doch schön das dich CAN zwingt effizient programmieren zu lernen,
> oder :-)

oh ja super ... vor allem wenn man c vor 15 jahren das letzte mal
benutzt hat ... brrr ;)

von Steffen R. (steffen_rose)


Lesenswert?

Ray M. schrieb:
> ich benutz bei allen teilnehmern einfach die gleich strutcs.h,
> das finde ich ok und gut wartbar,

Klar, wenn man immer den Spass hat auf allen Hochzeiten gleichzeitig zu 
tanzen.

von Hans M. (Gast)


Lesenswert?

Hab jetzt mal nicht das ganze Thread-"Monster" gelesen.
Den Bus auf beiden Seiten terminiert hast aber schon?!
Hatte mal auf einer Seite nicht gemacht ( bei 15cm Kabel geht das schon 
;-) )
aber ging nicht. Widerstand dran und schon ging's

Hans

von Ray M. (ray_m)


Lesenswert?

Hans M. schrieb:
> Hab jetzt mal nicht das ganze Thread-"Monster" gelesen.
> Den Bus auf beiden Seiten terminiert hast aber schon?!

joop ... 2x120 ;)

> Hatte mal auf einer Seite nicht gemacht ( bei 15cm Kabel geht das schon
> ;-) )
> aber ging nicht. Widerstand dran und schon ging's
>
> Hans

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.