CANdalus

Anwendung

Um das Problem mit der CAN-BUS Library zu vereinfachen haben wir neue Befehle zur ursprünglichen CANduino-Library hinzugefügt und diese CANdalus genannt. Zunächst einmal möchte ich diese erklären und darstellen und anschließend möchte ich noch die ursprünglichen Befehle der CANduino-Bibliothek erklären, welche zwar einiges umständlicher sind, aber dafür auch sehr viel flexibler einsetzbar.

 

Die drei neuen Befehle die es nun gibt sind:

init_adres(int adr);

send(byte datenfeld[], int adresse, byte laenge);

receive(byte *datenfeld, int *laenge);

 

init_adres verleiht einem Gerät eine eindeutige Adresse im BUS-System. Hierbei muss sich der Nutzer um nichts kümmern als um eine zweistelliger Hexadezimale Adresse. Das setzen von Filtern und Masken übernimmt die Funktion dabei automatisch. Zu beachten ist das auch automatisch eine Übertragungsgeschwindigkeit von 1MBit/s gewählt wird was eine maximale Kabellänge von 40m bedeutet, dies dürfte aber für unsere Anwendungsfälle genügen.


Beispiel:

void setup() {          
  Serial.begin(9600);                                
  int adresse=0xAA;                                  
  CAN.init_adres(adresse);                           
 }

 

send hat drei Variablen, die übergeben werden müssen:

  • das Datenfeld: gibt an welche Daten gesendet werden sollen
  • die Adresse: gibt die Adresse des Empfängers an (natürlich wieder zweistellig hexadezimal angeben.
  • die Länge: gibt an wie lang das Datenfeld in Byte ist

 

Ganz wichtig, alle 3 Variablen müssen übergeben werden!

 

receive hat zwei Variablen die übergeben werden müssen:

  • Einmal den Pointer auf das Datenfeld in welchem die neu angekommenen Daten gespeichert werden sollen
  • Und ein Pointer auf eine Integer Variable in denen der Wert der Länge gespeichert werden soll

 

Ich möchte noch ein paar Sachen für das bessere Verständnis hinzufügen:

Zunächst einmal sollte man wissen das man mit diesen Befehlen nur von einem Gerät auch nur an genau an EIN anderes Daten schicken kann, wenn man nun aber etwas flexibler sein möchte und beispielsweise eine Nachricht an mehrere Geräte schicken möchte muss man man die Ursprünglichen CANduino-Befehle benutzen. Diese sind im übrigen auch alle in der CANdalus-Bibliothek eingebunden und anwendbar.

Zum zweiten sollte man als Entwickler wissen dass der send-Befehl die Daten in 8 Byte Pakete aufsplitet und diese dann nacheinander sendet und wieder zusammensetzt, wenn man nun aber die Daten im Programm zu schnell bearbeitet kann es vorkommen das er noch nicht alle Pakete bekommen hat. (Paketsendedauer bei maximaler Sendegeschwindigkeit ca 10 MS)

 

Funktionsweise

 

Um Datenmengen zu schicken, welche größer als 8 Byte sind, müssen diese in Einzelne Pakte welche 8 Byte groß sind unterteilt werden. Damit die Datenpakete wieder in der richtigen Reihenfolge am Empfänger zusammengesetzt werden, werden in der Frame-ID die letzten 3 Bit als Paket_ID zweckentfremdet (in der Grafik Bit 1-3). Hierbei bedeutet:

  • 000: Symbolisiert das erste Datenpaket
  • 101: Symbolisiert ein beliebiges Datenpaket zwischem erstem und letztem Datenpaket
  • 111: Symbolisiert das letzte Datenpaket

Zusätzlich wird über die Bit 9-21 die Länge der zu schickenden Daten übertragen.

Bit 22-29 übertragen die Geräte-ID, diese wird dazu genutzt das Paket einem bestimmten Gerät zu zuweisen. Um dementsprechend nur die vorderen 8 Bit als eindeutige ID zu benutzen werden in der Maske auch nur die forderen 8 Bit auf 1 gesetzt.

 

Im Send-Befehl werden dann durch Bitverschiebung und bitweise Veroderung die Geräte-ID, Paket-ID und Länge zur Frame-ID zusammengesetzt.

 

 Hierzu ein Beispiel aus der Bibliothek zur Veranschaulichung:

 

  for(paket_zaehler=0; paket_zaehler<iterationen;paket_zaehler++)         //Iteriere die Pakete durch
  {
    for(i=0; i<8; i++)                                               //Iteriere die einzelnen Bytefelder in einem Paket durch
    {
      frame_data[i]=datenfeld[paket_zaehler*8+i];    //Die entsprechenden Felder den 8 Bytelangen Framedatenfeld zuweisen
    }
	 if(paket_zaehler==0)
    {
     paket_id=0;                                                    //Beim ersten Paket die Paket-ID auf 0b000 setzen
    }
    else if(paket_zaehler==iterationen-1)
    {
      paket_id=7;                                                 //Beim letzten Paket die Paket-ID auf 0b111 setzen
    }
    else
    {
      paket_id=5;                                                //Ansonsten die Paket-ID auf 0b101 setzen
    }
   frame_id=(paket_id |adress_id |laengen_id);    //Alle IDs verodern
   CAN.load_ff_0(length,&frame_id,frame_data,true); //Paket senden
   
  }

 

 

Anhänge:
Diese Datei herunterladen (candalus.zip)candalus.zip[CANdalus Bibliothek mit Beispiel]%2013-%04-%03 %1:%Apr%+02:00