Übersicht

In dieser Ingenieurspraxis geht es darum eine sinnvolle Kommunikationsstruktur für das Luftschiff zu finden und diese zu realisieren.

Das ganze soll über den uns verfügbaren Arduino ATMega 328P Mikrocontroller laufen.

{autotoc}

 

1. Begriffserklärung :

 

 

2. Dokumentation :

Montag-17.09(Tag 1):

  • Einarbeitung in die Programmierung des Arduino-Microcontrollers: Wie werden Signale ausgegeben und eingelesen (Analog-Digital/IN-OUT), einfache Beschaltungen.



Diestag-18.09(Tag 2):

  • Erste Entwurfe Arduino-Controller-area-network-CAN.("Canduino")
  • Auswahl des CAN Controllers(MCP 2515) und des CAN Transceiver(MCP2551)
  • Einarbeiten in die Datenblätter des CAN
  • Lotübungen an realistischen Schaltungen


Mittwoch-19.09(Tag 3):

  • Feststehender Schaltplan des CAN-Interface .

Zu verwendende Bauteile:

-MCP 2515 CAN Controller und MCP2551 CAN Transceiver

-2x 15pF Kapazitäten

-1x 16MHz Quarzoszillator (ACHTUNG: auf jeden Fall 16 MHz verwenden und nicht wie im Schaltplan vermerkt 20 MHz)

-3x100nf(Einen für die Reset-Schaltung//im Nachhinein hinzugefügt)

-LEDs

-Für die LEDs: 330 Ohm Wiederstände

-1x4,7K Ohm Widerstand

-2x10K Ohm Widerstände für die Reset Schaltung(Im Nachhinein hinzugefügt)

 

Beginn mit der Fertigung eines CAN Interface -Prototyps. Nach Anfertigung => Nächster Schritt: Verbindung über SPI (=>Canduino) und erste Tests.

Donnerstag-20.09(Tag 4):

  • Fertigstellung des ersten Prototyps.
  • Korrektur des Programms.
  • Erste Tests.


Freitag-21.09(Tag 5):

  • Fotos des Prototyps:
  • Bau eines weiteren Prototyps wird angesetzt

Prototyp

 


Prototyp CAN-Interface



Interaktion zwischen Arduino und CAN via SPI:





Was nicht im Schaltplan skizziert ist, ist die im Datenblatt des MCP2515 aufgelistete Verschaltung an dem Reset-Pin. Hierzu ein kurzer Blick auf das Datenblatt des MCP2515 im Absatz  RESET.

Desweiteren ist zu nennen wie die PINs des Arduino und die des CAN Controllers miteinander verbunden werden müssen.
CAN-Controller ->Arduino:
(CLK)13->PIN 13
(MOSI)14->PIN 11
(MISO)15->PIN 12
(SS)16-> PIN 10

Montag-24.09(Tag 8):

  • Bau des zweiten Prototyps abgeschlossen
  • Tests erfolgen ohne Fehler

=> CAN BUS muss jetzt getestet werden.

 

Für den CAN BUS werden folgende Materialien verwendet:

-2x 120 Ohm Widerstände

-Kabel (eine genaue Verschaltung entnehme den nächsten Bildern)


Dienstag-25.09(Tag 9):

  • Programm für den Test die CAN-CAN Kommunikation wurde verbessert
  • Funktionstücktigkeit wurde bestätigt


CAN-CAN
 

Programm welches ein Interface eine zufällig gespeicherte Zahl im anderen Interface erratet.


Programm bei dem ein Interface eine zufällig gespeicherte Zahl im anderen Interface errät.
 
Testprogram
#include <LiquidCrystal.h>

#include <SPI.h>
#include <SoftwareSerial.h>
#include <CAN.h>

#define BUS_SPEED 1000
#define RX 1
#define TX 0

int state;

#define GUESS_MIN		0b00000001
#define GUESS_MAX		0b00001111

CANClass CAN;

void setup() {           
  Serial.begin(9600);
  CAN.begin();
  CAN.baudConfig(BUS_SPEED);	
  CAN.resetFiltersAndMasks();
  CAN.setMaskOrFilter(MASK_0,   0b11111111, 0b11100000, 0b00000000, 0b00000000);
  CAN.setMaskOrFilter(MASK_1,   0b11111111, 0b11100000, 0b00000000, 0b00000000); 
  CAN.setMaskOrFilter(FILTER_2, 0b10101010, 0b10100000, 0b00000000, 0b00000000);


  state = TX; //TX = raten
  //state= RX; //RX = Ich suche eine Zahl aus. Dementsprechend ändern(Empfänger(RX) oder Sender(TX))

  delay(1000);

  randomSeed(analogRead(0)); //random input from a non-connected pin.
}

byte guess = -1;
byte guess_count = 0;

byte length,rx_status,i;
uint32_t frame_id;
byte frame_data[8]; 
byte filter,ext;

void loop() {
  switch(state) {
  case TX: //Ich rate.
    guess = random(GUESS_MIN, GUESS_MAX);
    guess_count++;

    frame_data[0] = guess;
    frame_data[1] = guess_count;
    frame_id = guess << 3;  
    length = 1;

    CAN.load_ff_0(length,&frame_id,frame_data,false);

    Serial.print(guess);
    Serial.print(",");
    delay(500);


    if (CAN.buffer1DataWaiting()) {
      CAN.readDATA_ff_1(&length,frame_data,&frame_id,&ext,&filter);
      Serial.print("I glaub ich habs!:");
      Serial.println(frame_data[0]);
      state = RX;
      guess_count = 0;
    } 
    else {
      frame_data[0] = guess;
      frame_data[1] = guess_count;  
      frame_id = 0x555;
      length = 2;
      CAN.load_ff_0(length,&frame_id,frame_data,false);
      delay(1000);
    }
    break;
  case RX: //Maske setzen und anderen raten lassen.
    guess = random(GUESS_MIN, GUESS_MAX);
    CAN.setMaskOrFilter(FILTER_0, guess,      0b00000000, 0b00000000, 0b00000000);
    Serial.print("Zu ratende Zahl: ");
    Serial.println(guess);

    while (state == RX) {
      rx_status = CAN.readStatus();
      if (CAN.buffer0DataWaiting()) {
        CAN.readDATA_ff_0(&length,frame_data,&frame_id,&ext,&filter);
        Serial.print("{#");
        Serial.print(frame_data[1]);
        Serial.print("}:");
        Serial.print(frame_data[0]);
        Serial.println("!");
        Serial.print("Other party got it on filter: ");
        Serial.println(filter);

        frame_data[0] = 1;
        frame_id = 0x555;
        length = 1;
        CAN.load_ff_0(length,&frame_id,frame_data,false);

        state = TX;
        delay(2000);
        Serial.println("\nSender:");

      }

      if (CAN.buffer1DataWaiting()) {
        CAN.readDATA_ff_1(&length,frame_data,&frame_id,&ext,&filter);
        Serial.print("[#");
        Serial.print(frame_data[1]);
        Serial.print("]:");
        Serial.print(frame_data[0]);
        Serial.print(", ");
      }
    }
    break;
  }
}



Mittwoch-26.09(Tag 10):

  • Nach erfolgreichen Test wird der Bau von mehreren CAN Interfaces angesetzt



Donnerstag-27.09(Tag 11):

  • Vier stehen am heutigen Tag zur Verfügung. Voll funktionstüchtig.(Getest mit "Rate-Spiel"Programm).



Freitag-28.09(Tag 12):

  • Die Zusammenstellung der nötigen Hardware für die Kommunikationsstruktur wurde mit dem heutigen Tag vervollständigt

 


CAN-BUS

 

4. CAN-BUS libraries und einfaches Programm zum testen der Interfaces

Um die CAN-Interfaces besser zu testen, habe ich dafür ein Programm geschrieben, welches

Daten von einem zum anderen sendet und diese ausgegeben werden.

Für den Test hab ich ein einfachen Text verwendet.

 

5. CAN-Protokoll festlegen:

Im nächsten Teil der Praxis geht es um die Festlegung eines geeigneten Protokolls.
Das Ziel wird in folgender Animation dargestellt:
 



Nun ist aber das Problem, dass die bisher genutzten Libraries keinen Extended Identifier unterstützen.( Näheres zu den Identifier entnehme diesem Link.)
Nun ist es meine Aufgabe eine passende Library zu finden bzw. schreiben.


Nach einigen Versuchen ist ein Einsatz zu erkennen. An diesem wird versucht weiter zu arbeiten.

(Neuzusammengestellte Library entnehme dem Anhang(MCP_CAN))

 

Erste Ansätze eines Basic Programms für das Empfangsmanagement via Filter und Masken.

#include <LiquidCrystal.h>
#include <SPI.h>
#include <SoftwareSerial.h>
#include <mcp_can.h>


void setup() {           
  Serial.begin(9600);
  if(CAN.begin(CAN_500KBPS) ==CAN_OK) Serial.print("can init ok!!\r\n");
  else Serial.print("Can init fail!!\r\n");
 // CAN.reset_Mask();                                            
  //CAN.reset_Filt(); 
CAN.init_Mask(0, 0,  0b11111111);// in dezimal 255
CAN.init_Mask(1, 0,  0b11111111); 
CAN.init_Filt(3, 0,  0b10101011); 


  delay(1000);

  randomSeed(analogRead(0)); //random input from a non-connected pin.
}


byte len;
byte frame_data[8]; 
//byte filter;

void loop() {
 
   //Nachricht verschicken
    frame_data[0] = 'H';
    frame_data[1] = 'i';
    len = 2;

    CAN.sendMsgBuf(0x555, 0, 2, frame_data);
    Serial.println("Nachricht gesendet!");
    delay(5000);
    
    



      
      
     
      
    } 
  


 
#include <mcp_can.h>
#include <SPI.h>
#include <stdio.h>

byte Flag_Recv = 0;
byte len = 0;
byte frame_data[8];
char str[20];
uint32_t frame_id;
 

void setup(){

 CAN.begin(CAN_500KBPS);   //Initialisiere CAN BUS: Bitrate 500kbps
 attachInterrupt(0, MCP2515_ISR, FALLING); // start interrupt
 Serial.begin(9600);
 CAN.init_Mask(1,0,0b11111111);
 CAN.init_Filt(2,0,0b10101010);//in hexadezimal 0x555, dezimal 1365
}

void MCP2515_ISR()
{
     Flag_Recv = 1;
}



void loop(){
  


        if(Flag_Recv)                   // Check ob Daten angekommen
    {
      Flag_Recv = 0;                // flag leeren
      CAN.readMsgBuf(&len, frame_data); 
      Serial.println("CAN_BUS BEKOMMT DATEN!");
      Serial.print("DatenLaenge = ");Serial.println(len);
       for(int i = 0; i<len; i++) 
        {
        Serial.println(frame_data[i]);Serial.print("\t");
      }
        
      //  CAN.sendMsgBuf(0xAB, 1, 2, frame_data);
        
       

        delay(2000);
       

      }

    
    }

6. Externe Links:

 

CAN<->Arduino Libraries und Testprogramme.

http://de.wikipedia.org/wiki/Controller_Area_Network
http://arduino.cc/
http://www.datasheetcatalog.org/datasheet2/0/0027dto5zhyf4i01qo7dqexxwhcy.pdf
http://code.google.com/p/canduino/
http://www.ladyada.net/learn/arduino/
http://www.can-cia.org/index.php?id=systemdesign-can-protocol
http://www.can-cia.org/index.php?id=systemdesign-can-protocol

Anhänge:
Diese Datei herunterladen (mcp_can.zip)MCP_CAN-Library[Neue Library, die Extended Identifier unterstützt]%2012-%10-%09 %1:%Okt%+02:00