Arduino Mega über CAN Shield mit PC steuern

Servus liebes Forum,

ich hab im Rahmen meiner Technikerarbeit begonnen mit dem Arduino zu programmieren.
Bei meiner Technikerarbeit soll ich über einen Mess-PC über USB2CAN-Converter und das Elecfreaks CAN Shield 1.2 meinem Arduino einen Startbefehl senden.
Der PC hat ja durch das Interface auch einen CAN-Bus oder?
Leider komme ich überhaupt nicht weiter, um eine CAN-Verbindung aufzubauen. Auch nicht mit dem Beispielcode der Hersteller-Lib.

Welche Software könnt ihr mir empfehlen, um meinem Arduino mit dem PC starten zu lassen.

Was verstehst Du unter "starten"?

Der Arduoino startet, sobald er Spannung hat. Evtl. solltest Du Dein Problem etwas genauer beschreiben.

Gruß Tommy

hi,

ich hab’s die ersten drei mal lesen nicht verstanden, aber ich glaube, jetzt hab’ ich’s:

Du willst vom PC aus das USB2CAN-modul dazu veranlassen, einen CAN-befehle über eine CAN-leitung an das CAN-shield zu schicken, und aufgrund dieses befehls soll dann vom arduino zb. eine LED ein- oder ausgeschaltet werden.

seh’ ich das richtig?

gruß stefan

Genau.
Ich möchte am PC auf einen Knopf drücken, der dann einen Startbefehl rausschickt.
Der Arduino soll die Message verarbeiten und dann einen Motor starten/LED leuchten lassen.

Hallo,

im Grunde sollte das nicht schwierig sein. Aber wie du sicher schon merkst, stehen die Leute mit CAN-Erfahrung hier nicht Schlange.

Ich verwende zwar auch etwas Arduino ähnliches (Teensy) als CAN-USB Interface für den PC, das kann man aber nicht 1:1 für deine Hardware übernehmen.

Gehen wir mal systematisch vor:

  • Du hast eine fertige Software für dieses PC-Interface, oder willst die auch noch schreiben ?

  • Hat dieses PC-Interface eine oder mehrere Schnittstellen ? Eventuell kann es dann zum Test erst mal an sich selber senden ?

-Wie sieht die CAN Verkabelung aus, da sollten GND, CAN-Low und CAN-High Signal vom PC-Interface und Shield verbunden sein ?

  • Hat die Verkabelung Abschlusswiderstände ? Oder wird dieser 60 Ohm Widerstand auf dem Shield benutzt ? (Ob der wirklich eine gute Idee ist, glaube ich eher nicht.)

  • Ist da irgendwo dokumentiert, dass das Shield für den Mega geeignet ist ? Ich bin nicht so in der AVR-Materie drin, dass ich sagen kann das passt mit den Pins 1:1 z.B. zum Uno.

Diese CAN-Shields verwenden übrigens alle das gleiche IC (MCP2515), weil es kein anderes CAN zu SPI Interface IC mehr zu kaufen gibt, CAN findet heute eher integriert in Microcontroller oder FPGA statt. Blöd ist nur, dass jeder Shieldhersteller andere Arduino Pins benutzt und jeder seine eigene Library hat, plus alterative Libraries von anderen Leuten.

Ich bleibe deswegen für CAN beim Teensy und könnte höchstens mal ein Beispiel zeigen, das sowas zwischen zwei Teensy zeigt. Ansonsten kann ich nur Tipps geben, wo es haken könnte.

  • Du hast eine fertige Software für dieses PC-Interface, oder willst die auch noch schreiben ?

Genau, ich habe das USB Interface und die passende Software CANOe 10 dafür.

  • Hat dieses PC-Interface eine oder mehrere Schnittstellen ? Eventuell kann es dann zum Test erst mal an sich selber senden ?

Dieses Hat 2 Kanäle

-Wie sieht die CAN Verkabelung aus, da sollten GND, CAN-Low und CAN-High Signal vom PC-Interface und Shield verbunden sein ?
Genau, das Shield + Interface werden mit einem 9-poligen Kabel miteinander verbunden

  • Hat die Verkabelung Abschlusswiderstände ? Oder wird dieser 60 Ohm Widerstand auf dem Shield benutzt ? (Ob der wirklich eine gute Idee ist, glaube ich eher nicht.)

Also auf dem Board finde ich keinen 60 Ohm Widerstand.

  • Ist da irgendwo dokumentiert, dass das Shield für den Mega geeignet ist ? Ich bin nicht so in der AVR-Materie drin, dass ich sagen kann das passt mit den Pins 1:1 z.B. zum Uno.

Ich verwende inzwischen einen Uno, das CanShield wird inzwischen auch initalisiert nur iwie Empfang ich nichts auf meinem CANOe mit dem Bsp. Programm

Das sollte gehen, ich hatte einen Teensy schon mal mit an der Arbeit und mit einem Vector VN8970 und CANoe am laufen.

Ziemlich sicher ist deine Verkabelung falsch.

Also ich habe gemerkt das ich bei meinem Shield eine Andere Pinbelegung ist als beim USB Interface.
Daher habe ich ein Adapterkabel gebastelt und inzwischen kann ich mit der Example Datei “send” auf meinem PC Daten empfangen die ich vom Shield los sende.
Leider bekomme ich das Senden über CanOE bzw. empfangen mit dem Arduino nicht hin.
Denke auch das die Example Datei für mich nicht optimal ist.

// demo: CAN-BUS Shield, receive data
#include <mcp_can.h>
#include <SPI.h>

unsigned char Flag_Recv = 0;
unsigned char len = 0;
unsigned char buf[8];
char str[20];

void setup()
{
CAN.begin(CAN_500KBPS); // init can bus : baudrate = 500k
attachInterrupt(0, MCP2515_ISR, FALLING); // start interrupt
Serial.begin(115200);
}

void MCP2515_ISR()
{
Flag_Recv = 1;
}

void loop()
{
if(Flag_Recv) // check if get data
{
Flag_Recv = 0; // clear flag
CAN.readMsgBuf(&len, buf); // read data, len: data length, buf: data buf
Serial.println(“CAN_BUS GET DATA!”);
Serial.print("data len = ");
Serial.println(len);

for(int i = 0; i<len; i++) // print the data
{
Serial.print(buf*);Serial.print("\t");*

  • }*
  • Serial.println();*
  • }*
    }[/quote]

In dem Schaltplan zum oben verlinkten Shield sieht man, dass da in den Datenleitungen zwischen dem MCP2515 und dem MCP2551 zwei LEDs verbaut sind.

Siehst du da irgendeine Aktivität an den LEDs ? Wenn da genügend Daten unterwegs sind, sollte man da ein ähnliches Flackern sehen, wie an den LEDs in der seriellen Übertragung vom Arduino. Das sollte auch unabhängig vom Programm im Arduino passieren.

Nein. die flackern nur beim Bsp.prg "send" bzw. RX und TX blinken
Beim Programm "receive" leuchtet nur die POWER LED

Eigentlich sollte die RX flackern, selbst wenn gar kein Programm im Arduino läuft, das was empfangen will.

Kannst du den Arduino mit seinem Shield an einen CAN-Bus hängen, von dem du weißt, dass da Daten drauf sind ? Also z.B. CANoe mit den beiden Schnittstellen mit sich selbst reden lassen und das Shield als dritten Teilnehmer dran hängen.

Habe es nun geschafft mit einer anderen CANOe Config mir was auf den Arduino zu schicken.
Jetzt muss ich nur noch den Startbefehl rausfiltern und dann meinen Motor anlaufen lassen.

Oder stell ich mir das zu einfach vor?

Würde mir jetzt über ein Panel im CANOe basteln und dann dem Button zuweisen das der Generatorblock mit losschicken für eine gewisse Zeit beginnt.

rosch92:
Oder stell ich mir das zu einfach vor?

Nö, das ist im Prinzip schon recht einfach.

Ein Problem hast du aber durch die Hardwareauswahl:

Der MCP2515 hat nur interne Puffer für zwei CAN-Messages. Wenn der Arduino die nicht schnell genug abholt, gehen Daten verloren.

Du musst also darauf achten, dass sich das Programm immer um eingehende Daten kümmert, auch wenn es noch was anderes macht.

Der MCP hat eine eingebaute Filtermöglichkeit. Wenn da mehr Verkehr auf dem Bus ist, sollte man ihn so konfigurieren, dass er alles wegfiltert was er nicht braucht.

Bei einem Bus mit 500 kBit/s wird die Rechnenleistung eines 8-Bit Arduino nicht reichen, um den ganzen Busverkehr zu verarbeiten. Falls du das wirklich willst, hier schon mal Links auf die Alternativen, die das könnten (ohne Shield):

ArduFE:
Nö, das ist im Prinzip schon recht einfach.

Ein Problem hast du aber durch die Hardwareauswahl:

Der MCP2515 hat nur interne Puffer für zwei CAN-Messages. Wenn der Arduino die nicht schnell genug abholt, gehen Daten verloren.

Du musst also darauf achten, dass sich das Programm immer um eingehende Daten kümmert, auch wenn es noch was anderes macht.

Der MCP hat eine eingebaute Filtermöglichkeit. Wenn da mehr Verkehr auf dem Bus ist, sollte man ihn so konfigurieren, dass er alles wegfiltert was er nicht braucht.

Bei einem Bus mit 500 kBit/s wird die Rechnenleistung eines 8-Bit Arduino nicht reichen, um den ganzen Busverkehr zu verarbeiten. Falls du das wirklich willst, hier schon mal Links auf die Alternativen, die das könnten (ohne Shield):
GitHub - collin80/due_can: Object oriented canbus library for Arduino Due compatible boards
GitHub - collin80/FlexCAN_Library: Arduino library for CAN on Teensy 3.1, 3.2, 3.5, and 3.6

Ich will über den Bus nur ein Datenpaket losschicken, welches der Arduino dann als Startbedingung detektieren soll, danach wird ein Motor angesteuert welcher einen Taster betätigt und dann Rückmeldung über den CAN-Bus an mein Panel im CANOe gibt

Also ich bekomme inzwischen von CanOe ein Datenpaket geschickt.
Wie bekomme ich nun diesen "Impuls" in einen festen Zustand?

Würde Ja wie ein Taster funktionieren der zum Schalter wird.
Oder habe ich da was falsch verstanden.

Na das ist Aufgabe der Software.

Entweder es gibt unterschiedliche CAN-Daten für Aus und Ein, oder im Arduino Sketch wird bei Empfang abwecheslnd etwas (bool -Variable, Ausgangspin, ...) ein- oder ausgeschaltet.

Ja und das ist mein Problem.
Ich will einen Befehl rausschicken und dann
habe eine if-Bedingung wo ich auf 0xFF vergleiche und will dann beim eintreten eine LED anschalte.
Leider geht die LED immer nur kurz an.
Mir fällt mein Denkfehler nicht auf :smiley:

Na dann guck halt nicht (nur), wo du die LED anschaltest, sondern auch wann du sie ausschaltest 8)

Ohne erneutes digitalWrite bleiben Ausgänge so wie sie waren.

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

unsigned char Flag_Recv = 0;
unsigned char len = 0;
unsigned char buf[1];
char str[20];

void setup()
{
pinMode(13, OUTPUT);
CAN.begin(CAN_500KBPS); // init can bus : baudrate = 500k
attachInterrupt(0, MCP2515_ISR, FALLING); // start interrupt
Serial.begin(115200);
Serial.println(“Seriell OK”);
}

void MCP2515_ISR()
{
Flag_Recv = 1;
}

void loop()
{
if (Flag_Recv) // check if get data
{
Flag_Recv = 0; // clear flag
CAN.readMsgBuf(&len, buf); // read data, len: data length, buf: data buf

Serial.println(“CAN_BUS GET DATA!”);
Serial.print("data length: ");
Serial.println(len);
Serial.print("id: ");
Serial.println(CAN.getCanId());

for (int i = 0; i < len; i++) // print the data
{
Serial.print(buf*); Serial.println("\t");*

  • }*
  • }*
    _ if (buf[0] == 0xEE) {_
    ** digitalWrite(13, HIGH);**
    ** }**
    }
    [/quote]
    Ich finde meinen Denkfehler nicht :smiley:

unsigned char buf[1];

CAN.readMsgBuf(&len, buf); // read data, len: data length, buf: data buf

Würde mich wundern, wenn das ok ist.

for (int i = 0; i < len; i++) // print the data
{
Serial.print(buf); Serial.println("\t");

}

das ist dann nur Unsinn, aber sollte nicht weh tun. ( Ist da ein [ i ] verloren gegangen ? )