LED über CAN-BUS schalten

OP #7503728
Lesenswert?

Hallo

Ich möchte gerne eine LED an einem ESP32 über eine Taste am anderen ESP32 und CAN-BUS schalten. Bin noch relativ neu beim ESP32 programmieren und hänge jetzt ein bisschen. Die CAN Verbindung läuft schon. Auch kann ich schon die gesendeten Daten mit einem Tastendruck ändern. Aber beim Auslesen des Datenstrings und dem Schalten der LED habe ich noch Probleme da ich noch nicht ganz verstehe was da eigentlich wie gesendet wird. Auch die Suche im Internet hat mich noch nicht unbedingt schlauer gemacht. Habe folgenden Code. Das ist das Example von der Library "MCP_CAN" https://github.com/coryjfowler/MCP_CAN_lib Habe nur beim Sender eine Variable "ggg" eingefügt die je nach Tastendruck entweder auf 0x00 oder 0x01 gesetzt wird. Eben dieses 0x00 oder 0x01 würde ich gerne mit dem CAN-Receiver abfragen und die LED dementsprechend schalten. Für Hilfe wie immer sehr dankbar. Gruß Uli

CAN-Sender:

1
#include <Arduino.h>
2

3
// CAN Send Example
4
//
5

6
#include <mcp_can.h>
7
#include <SPI.h>
8

9
MCP_CAN CAN0(5);     // Set CS to pin 5
10
int ggg=0x00;
11
int inPin=2;
12

13

14
void setup()
15
{
16
  pinMode(inPin, INPUT_PULLUP);
17
  Serial.begin(115200);
18

19
  // Initialize MCP2515 running at 16MHz with a baudrate of 500kb/s and the masks and filters disabled.
20
  if(CAN0.begin(MCP_ANY, CAN_500KBPS, MCP_16MHZ) == CAN_OK) Serial.println("MCP2515 Initialized Successfully!");
21
  else Serial.println("Error Initializing MCP2515...");
22

23
  CAN0.setMode(MCP_NORMAL);   // Change to normal mode to allow messages to be transmitted
24
}
25

26

27

28
void loop()
29
{
30
  
31
   if (digitalRead(inPin)==LOW){
32
    ggg = 0x01;
33
  } else {
34
    ggg = 0x00;
35
  }
36
  byte data[2] = {ggg, 0x01};
37
  // send data:  ID = 0x100, Standard CAN Frame, Data length = 8 bytes, 'data' = array of data bytes to send
38
  byte sndStat = CAN0.sendMsgBuf(0x100, 0, 2, data);
39
  if(sndStat == CAN_OK){
40
    Serial.println("Message Sent Successfully!");
41
  } else {
42
    Serial.println("Error Sending Message...");
43
  }
44
  delay(100);   // send data per 100ms
45
}
46

47
/*********************************************************************************************************
48
  END FILE
49
*********************************************************************************************************/
50

51
CAN-Receiver
52

53
#include <Arduino.h>
54

55
#include <mcp_can.h>
56
#include <SPI.h>
57

58
long unsigned int rxId;
59
unsigned char len = 0;
60
unsigned char rxBuf[8];
61
char msgString[128];                        // Array to store serial string
62

63
#define CAN0_INT 17                              // Set INT to pin 17
64
MCP_CAN CAN0(5);                               // Set CS to pin 5
65
int LED=2;
66

67

68
void setup()
69
{
70
  Serial.begin(115200);
71
  
72
  // Initialize MCP2515 running at 16MHz with a baudrate of 500kb/s and the masks and filters disabled.
73
  if(CAN0.begin(MCP_ANY, CAN_500KBPS, MCP_16MHZ) == CAN_OK)
74
    Serial.println("MCP2515 Initialized Successfully!");
75
  else
76
    Serial.println("Error Initializing MCP2515...");
77
  
78
  CAN0.setMode(MCP_NORMAL);                     // Set operation mode to normal so the MCP2515 sends acks to received data.
79

80
  pinMode(CAN0_INT, INPUT);                            // Configuring pin for /INT input
81
  
82
  Serial.println("MCP2515 Library Receive Example...");
83
  
84
}
85

86

87

88
void loop()
89
{
90
  if(!digitalRead(CAN0_INT))                         // If CAN0_INT pin is low, read receive buffer
91
  {
92
    CAN0.readMsgBuf(&rxId, &len, rxBuf);      // Read data: len = data length, buf = data byte(s)
93
    
94
    if((rxId & 0x80000000) == 0x80000000)     // Determine if ID is standard (11 bits) or extended (29 bits)
95
      sprintf(msgString, "Extended ID: 0x%.8lX  DLC: %1d  Data:", (rxId & 0x1FFFFFFF), len);
96
    else
97
      sprintf(msgString, "Standard ID: 0x%.3lX       DLC: %1d  Data:", rxId, len);
98
  
99
    Serial.print(msgString);
100
    if (rxId == 100){
101
      digitalWrite(LED, HIGH);
102
    } else{
103
      digitalWrite(LED, LOW);
104
    }
105
  
106
    if((rxId & 0x40000000) == 0x40000000){    // Determine if message is a remote request frame.
107
      sprintf(msgString, " REMOTE REQUEST FRAME");
108
      Serial.print(msgString);
109
    } else {
110
      for(byte i = 0; i<len; i++){
111
        sprintf(msgString, " 0x%.2X", rxBuf[i]);
112
        Serial.print(msgString);
113
      }
114
    }
115
        
116
    Serial.println();
117
  }
118
}
119

120
/*********************************************************************************************************
121
  END FILE
122
*********************************************************************************************************/
#7503797
Lesenswert?

An der Stelle, wo Du die ID auf 100 abfragst, musst Du die Daten in rxBuf prüfen, denn dort wird abgelegt, was Du gesendet hast. Dort wird also an den ersten beiden Bytes „ggg“ (rxBuf[0]) und 0x01 (rxBuf[1]) abgelegt. Könnte übrigens sein, dass Du gleich angepflaumt wirst, weil Du den Code in den Text eingefügt hast - sei tapfer!

Übrigens (und dafür werde ich vlt. gleich angemacht werden): Lade mal genau die Programmschnipsel getrennt nacheinander bei ChatGPT hoch (einfach in den Chat Copy und Paste) und stelle deine spezifischen Fragen. Du wirst überrascht sein, was da geht und was Du lernen kannst.

Was ich Dir auch wärmstens empfehlen würde, wäre ein Logic Analyzer, einer für 10€ reicht. Damit kannst Du schön beobachten, was per SPI gesendet wird und was auf dem CAN los ist. Beim SPI kann man bei den langsamen LA zwar keine 10MBit machen, aber für den Anfang reichen ja auch mal 1MBit. Weiß nicht, was die Lib da voreinstellt.

Edit: Habe es gerade mal in ChatGPT reingestellt, er schlägt folgenden Code vor:

void loop() { if (!digitalRead(CAN0_INT)) // Wenn CAN0_INT-Pin niedrig ist, Nachricht empfangen { CAN0.readMsgBuf(&rxId, &len, rxBuf); // Nachricht lesen

1
// Prüfen, ob die empfangene Nachricht die erwartete ID hat (hier 0x100)
2
if (rxId == 0x100)
3
{
4
  // Extrahieren Sie den Wert von ggg aus den empfangenen Daten
5
  if (len >= 2) // Stellen Sie sicher, dass genug Daten empfangen wurden
6
  {
7
    ggg = rxBuf[0]; // Die erste Byte in rxBuf enthält ggg
8

9
    // Jetzt können Sie ggg verwenden, um die LED zu steuern
10
    if (ggg == 0x01)
11
    {
12
      digitalWrite(LED, HIGH); // LED einschalten
13
    }
14
    else
15
    {
16
      digitalWrite(LED, LOW); // LED ausschalten
17
    }
18
  }
19
  else
20
  {
21
    Serial.println("Nicht genug Daten empfangen.");
22
  }
23
}

} }

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren