CAN Befehl senden und antworten mit je 2 x Arduino UNO mit MCP 2515

Hallo Forum,

ich arbeite mich gerade für ein Projekt bei Arduino ein. Diverse Tutorials habe ich durchgearbeitet.

Aktuell hab ich mich mit dem CAN Bus befasst.
Ich möchte mit Arduino 1 + MCP 2515 Daten zu Arduino 2 + MCP2515 übertragen.

Das klappt soweit super. An Arduino 1 drücke ich einen Taster --> Signal wird auf den CAN Bus gesendet, Arduino 2 holt den Befehl ab und schaltet eine LED ein bzw. aus.

Nun wollte ich das Programm erweitern. Wenn bei Arduino 2 das Signal für LED Ein ankommt, sollte kurz gewartet werden und Arduino 2 sendet auf den CAN Bus eine Nachricht das die LED eingeschaltet wurde.

Dies sollte von Arduino 1 empfangen werden.

Allerdings erscheint hier immer eine falsche CAN ID bzw. nicht die von der gesendet wurde.
Auch die Daten werden nicht übertragen.

Im Anhang sind Screenshots von der seriellen Schnittstelle der beiden Arduinos.

Schnittstelle an COM 9 (Arduino 2) Empfang der Daten in Ordnung. LED wird eingeschaltet.

Schnittstelle an COM 8 (Arduino 1) Empfang von Daten, allerdings nicht mit gesendeter ID und ohne Daten.

Code von Arduino 1 funktioniert und sendet...

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



const int spiCSPin = 10;
int ButtonON = 3;
int ButtonOFF = 2;
int LED = 8;
int Buttonstate = 0;

OneButton buttonON(ButtonON,true);
OneButton buttonOFF(ButtonOFF,true);

MCP_CAN CAN(spiCSPin);

void setup()
{
    pinMode (LED, OUTPUT);     
    Serial.begin(9600);  
    while (CAN_OK != CAN.begin(CAN_500KBPS))
    {
        Serial.println("CAN BUS init Failed");
        delay(100);
    }
    Serial.println("CAN BUS Shield Init OK!");
    buttonON.attachPress(pressedON);
    buttonON.setPressTicks(30);
    buttonOFF.attachPress(pressedOFF);
    buttonOFF.setPressTicks(30);
}

unsigned char stmp[8] = {0,0,0,0,0,0,0,0};
    
void loop()
{   
unsigned char len = 0;
unsigned char buf[8];
buttonON.tick();
buttonOFF.tick();
delay(10);

 if(CAN_MSGAVAIL == CAN.checkReceive())
    {
        CAN.readMsgBuf(&len, buf);
        unsigned long canId = CAN.getCanId();
        Serial.println("++++++++++++++++++");
        Serial.print("Data from ID: 0x");
        Serial.println(canId, HEX);
        for (int i = 0; i < len; i++) { // print the data
        Serial.print(buf[i]);
        Serial.print("\t");
        

    }
    }
}
void pressedON()
{
  digitalWrite(LED, HIGH);  
  Serial.println("LED auf HIGH");
  stmp[0]=1;
  CAN.sendMsgBuf(0x43, 0, 8, stmp);
}

void pressedOFF()
{
  digitalWrite(LED, LOW);
  Serial.println("LED auf LOW");
  stmp[0]=0;
  CAN.sendMsgBuf(0x43, 0, 8, stmp);
}

Code von Arduino 2 (im if CAN Massage available Teil wird die LED eingeschaltet und anschließend eine Nachricht auf den Bus gesendet. Dies funktioniert allerdings nicht.)

#include "SPI.h"
#include "mcp_can.h"

const int spiCSPin = 10;
const int ledPin = 2;
boolean ledON = 1;

MCP_CAN CAN(spiCSPin);

void setup()
{
    Serial.begin(9600);
    pinMode(ledPin,OUTPUT);

    while (CAN_OK != CAN.begin(CAN_500KBPS))
    {
        Serial.println("CAN BUS Init Failed");
        delay(100);
    }
    Serial.println("CAN BUS  Init OK!");
}

unsigned char stmp[8] = {0,1,0,1,0,1,0,1};

void loop()
{
    unsigned char len = 0;
    unsigned char buf[8];
    
    //CAN.sendMsgBuf(0x43, 0, 8, stmp);

    if(CAN_MSGAVAIL == CAN.checkReceive())
    {
        CAN.readMsgBuf(&len, buf);

        unsigned long canId = CAN.getCanId();

        Serial.println("-----------------------------");
        Serial.print("Data from ID: 0x");
        Serial.println(canId, HEX);
        for (int i = 0; i < len; i++) 
        {
        Serial.print(buf[i]);
        Serial.print("   |   ");
        }
        Serial.println("\t");
    
        if (buf[0] == 1)
        {
          digitalWrite(ledPin,HIGH); 
          Serial.println("LED EIN");
          delay(500);
          CAN.sendMsgBuf(0x44, 0, 8, stmp);
        }
        
        if (buf[0] == 0)
        {
          digitalWrite(ledPin,LOW);
          Serial.println("LED AUS");
        }
        
          
     }
}

Hi, ich verwende diese Lib fürs CAN Shield.

Habe auch noch einen dritten Arduino mit MCP2515 zur Verfügung...

Grüße

Dein Verdacht hat sich bestätigt. Der 3. Arduino bekommt vom Bus beide Nachrichten.

Mir ist nur nicht klar, wie ich die Daten im Sketch 1 sicher empfangen kann...

Das Sketch ist ja relativ klein.

Arduino 3.JPG

Bei mir funktioniert es so:

// Sender 
#include <OneButton.h>
#include <SPI.h>
#include <mcp_can.h>

const int spiCSPin = 10;
int ButtonON = 3;
int ButtonOFF = 2;
int LED = 8;

OneButton buttonON(ButtonON, true);
OneButton buttonOFF(ButtonOFF, true);

MCP_CAN CAN(spiCSPin);

void setup()
{
  pinMode (LED, OUTPUT);
  Serial.begin(9600);
  while (CAN_OK != CAN.begin(CAN_500KBPS))
  {
    Serial.println("CAN BUS init Failed");
    delay(100);
  }
  Serial.println("CAN BUS Shield Init OK!");
  buttonON.attachPress(pressedON);
  buttonON.setPressTicks(30);
  buttonOFF.attachPress(pressedOFF);
  buttonOFF.setPressTicks(30);
}

unsigned char stmp[8] = {0, 0, 0, 0, 0, 0, 0, 0};

void loop()
{
  unsigned char len = 0;
  unsigned char buf[8];
  buttonON.tick();
  buttonOFF.tick();

  if (CAN_MSGAVAIL == CAN.checkReceive())
  {
    CAN.readMsgBuf(&len, buf);
    unsigned long canId = CAN.getCanId();
    Serial.println("++++++++++++++++++");
    Serial.print("Data from ID: 0x");
    Serial.println(canId, HEX);
    for (int i = 0; i < len; i++) { // print the data
      Serial.print(buf[i]);
      Serial.print("\t");
    }
    Serial.println();
  }
}
void pressedON()
{
  digitalWrite(LED, HIGH);
  Serial.println("LED auf HIGH");
  stmp[0] = 1;
  CAN.sendMsgBuf(0x43, 0, 8, stmp);
}

void pressedOFF()
{
  digitalWrite(LED, LOW);
  Serial.println("LED auf LOW");
  stmp[0] = 0;
  CAN.sendMsgBuf(0x43, 0, 8, stmp);
}
// Enpfänger
#include "SPI.h"
#include "mcp_can.h"

const int spiCSPin = 10;
const int ledPin = 8;
boolean ledON = 1;

MCP_CAN CAN(spiCSPin);

void setup()
{
  Serial.begin(9600);
  pinMode(ledPin, OUTPUT);

  while (CAN_OK != CAN.begin(CAN_500KBPS))
  {
    Serial.println("CAN BUS Init Failed");
    delay(100);
  }
  Serial.println("CAN BUS  Init OK!");
}

unsigned char stmp[8] = {0, 1, 0, 1, 0, 1, 0, 1};

void loop()
{
  unsigned char len = 0;
  unsigned char buf[8];

  //CAN.sendMsgBuf(0x43, 0, 8, stmp);

  if (CAN_MSGAVAIL == CAN.checkReceive())
  {
    CAN.readMsgBuf(&len, buf);

    unsigned long canId = CAN.getCanId();

    Serial.println("-----------------------------");
    Serial.print("Data from ID: 0x");
    Serial.println(canId, HEX);
    for (int i = 0; i < len; i++)
    {
      Serial.print(buf[i]);
      Serial.print("   |   ");
    }
    Serial.println("\t");

    if (buf[0] == 1)
    {
      digitalWrite(ledPin, HIGH);
      Serial.println("LED EIN");
      CAN.sendMsgBuf(0x44, 0, 8, stmp);
    }

    if (buf[0] == 0)
    {
      digitalWrite(ledPin, LOW);
      Serial.println("LED AUS");
      CAN.sendMsgBuf(0x44, 0, 8, stmp);
    }
  }
}

Sehe ich das richtig, dass du nur das Delay bei der Button Funktion rausgenommen hast?

buttonON.tick();
buttonOFF.tick();

delay(10); <-- ???

Hab es getestet... Bei mir geht es nicht. Wenn ich auf die serielle Schnittstelle von Arduino 1 ( //Sender bei deinem Code) wechsle wird die serielle Schnittstelle komplett zugemüllt...

Grüße

Nicht nur, aber hauptsächlich.

Ausgabe Sender:

[sup]Enter setting mode success 
set rate success!!
Enter Normal Mode Success!!
CAN BUS Shield Init OK!
LED auf HIGH
++++++++++++++++++
Data from ID: 0x44
0	1	0	1	0	1	0	1	
LED auf LOW
++++++++++++++++++
Data from ID: 0x44
0	1	0	1	0	1	0	1	
LED auf HIGH
++++++++++++++++++
Data from ID: 0x44
0	1	0	1	0	1	0	1	
LED auf LOW
++++++++++++++++++
Data from ID: 0x44
0	1	0	1	0	1	0	1	
[/sup]

Ausgabe Empfänger:

[sup]Enter setting mode success 
set rate success!!
Enter Normal Mode Success!!
CAN BUS  Init OK!
-----------------------------
Data from ID: 0x43
1   |   0   |   0   |   0   |   0   |   0   |   0   |   0   |   	
LED EIN
-----------------------------
Data from ID: 0x43
0   |   0   |   0   |   0   |   0   |   0   |   0   |   0   |   	
LED AUS
-----------------------------
Data from ID: 0x43
1   |   0   |   0   |   0   |   0   |   0   |   0   |   0   |   	
LED EIN
-----------------------------
Data from ID: 0x43
0   |   0   |   0   |   0   |   0   |   0   |   0   |   0   |   	
LED AUS
[/sup]

Der "Müll" auf dem CAN Bus kommt von einer mangelnden Spannung am MCP2515. Ein Draht hatte einen minimalen Kabelbruch und die Spannung war nicht hoch genug.

Kabel getauscht und jetzt läuft der Scatch!

Vielen Dank für die Hilfe und Unterstützung.

domil1984:
... Kabelbruch ...

Blöd zu finden!

Danke für die Rückmeldung :slight_smile: