Go Down

Topic: CAN Befehl senden und antworten mit je 2 x Arduino UNO mit MCP 2515 (Read 133 times) previous topic - next topic

domil1984

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...

Code: [Select]

#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.)

Code: [Select]
#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");
        }
       
         
     }
}



noiasca

welche can lib verwendest du? Bitte auf Github verlinken was du da installierst hast.
Hättest noch einen 3. Arduino/Canshield bereit, den du als reinen Monitor mitlaufen lassen kannst?
how to react on postings:
- post helped: provide your final sketch, say thank you & give karma.
- post not understood: Ask as long as you understand the post
- post is off topic (or you think it is): Stay to your topic. Ask again.
- else: Ask again.

domil1984

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

https://github.com/Seeed-Studio/CAN_BUS_Shield

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

Grüße

noiasca

sehr gut. Dann lade da mal einen originalen Empfänger drauf (receive_check.ino???) und schau ob du von beiden deiner Sketche etwas empfängst.

Möglicherweise verschläfst du im Sketch1 die Antwort von Sketch2.Ist aber nur ein Verdacht kann ich ohne Hardware nicht prüfen.
how to react on postings:
- post helped: provide your final sketch, say thank you & give karma.
- post not understood: Ask as long as you understand the post
- post is off topic (or you think it is): Stay to your topic. Ask again.
- else: Ask again.

domil1984

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.

agmue

Bei mir funktioniert es so:

Code: [Select]
// 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);
}

Code: [Select]
// 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);
    }
  }
}
Die Vorstellungskraft ist wichtiger als Wissen, denn Wissen ist begrenzt. (Albert Einstein)

domil1984

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


agmue

Nicht nur, aber hauptsächlich.

Ausgabe Sender:
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   


Ausgabe Empfänger:
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

Die Vorstellungskraft ist wichtiger als Wissen, denn Wissen ist begrenzt. (Albert Einstein)

domil1984

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.


agmue

Die Vorstellungskraft ist wichtiger als Wissen, denn Wissen ist begrenzt. (Albert Einstein)

Go Up