CAN und MCP2515 - Kein Senden möglich

#7689588
Lesenswert?

Hallo zusammen, nach einigen Tagen weiß ich nicht mehr weiter und bitte um Hilfe.

Ich habe folgendes CAN-Bus-Minimalsystem aufgebaut:

Node A (Sender): Arduino Nano und MCP2515-Modul. Node B (Empfänger): ESP32 DevKitC und SN65HV230-Modul

Beide Seiten sind auf 125kHz initialisiert. Verbindung CANH, CANL und GND sind da. Ich habe diverse Bibliotheken ausprobiert, dann zur Eingrenzung des Problems nur Node A laufen lassen, an Stelle von Node B hängt ein weiteres MCP2515-Interface, welches nur mit Betriebsspannung versorgt wird.

Die Auswertung der Fehlercodes aus der Library (https://github.com/coryjfowler/MCP_CAN_lib) hat mir gezeigt, dass der MCP immer in einen TX-Timeout läuft (Fehlercode 7). Wenn ich nicht in "loop" initialisiere, ist irgandwann kein TX-Buffer mehr frei und der Fehlercode wechselt auf 6.

Das MCP-Interface ist dieses: https://42project.net/shop/module/kommunikationsmodule/spi-mcp2515-can-bus-modul-tja1050-transceiver-shield-5v-33v-fuer-arduino-und-pi/

Ich habe folgendes schon getestet/probiert:

  • "nacktes" MCP2515-Modul statt Node B
  • Spannungsversorgung über Labornetzteil statt über den USB
  • CANH/CANL vertauscht
  • verschiedene CAN-Bitraten ausprobiert
  • SPI_Clock mit 16MHz statt 8MHz ausprobiert

Alles hat keinen Erfolg gebracht. Jetzt weiß ich nicht mehr weiter :-(

Besten Dank im Voraus für jeden konstruktiven Tipp!

Hermann

Angehängte Dateien:
Beitrag #7689613 wurde von einem Moderator gelöscht.
#7689631
Lesenswert?

Wenn der Sender von niemandem ein ACK bekommt, dann probiert er ewig weiter, den ersten Frame zu senden.

Den MCP2515 nur mit Spannung zu versorgen ist glaube ich nicht ausreichend, um ihn zum Senden von ACKs zu bringen. Da müsste ich aber noch einmal ins Datenblatt schauen.

Zur Diagnose solltest du den LA an den RXD-Ausgang von einem der Transceiver (TJA1050 oder SN65HV230) hängen.

LG, Sebastian

#7689661
Lesenswert?

Ein Bus mit nur einem CAN-Node funktioniert nicht. Es brauch immer mindestens 2.

Wenn ein Node ein CAN-Frame raussendet und dieser nicht von einem anderen Node acknowledged (ACK) wird kommt es zu den von dir beschreibenden TX-Fehler.

Jeder andere CAN-Node acknowledged jedes Frame das er bekommt, auch wenn es nicht für sich bestimmt ist.

#7689670
Lesenswert?

Sebastian W. schrieb:

Den MCP2515 nur mit Spannung zu versorgen ist glaube ich nicht ausreichend, um ihn zum Senden von ACKs zu bringen. Da müsste ich aber noch einmal ins Datenblatt schauen.

Nur Spannung anzulegen st nicht ausreichend. Nach dem Power-On ist der MCP2515 im Configuration Mode, und nur im Normal Mode verschickt er ACKs. Ist irgendwie auch klar, woher soll er auch die Bitrate kennen ...

LG, Sebastian

(Firma: Gast) #7689821
Lesenswert?

Hermann G. schrieb:

Die Auswertung der Fehlercodes aus der Library (https://github.com/coryjfowler/MCP_CAN_lib) hat mir gezeigt, dass der MCP immer in einen TX-Timeout läuft (Fehlercode 7).

Die Beispiele arbeiten mit 500kbs Du nutzt 125kbps

Aus der Lib:

1
#define TIMEOUTVALUE    2500                                           /* In Microseconds, May need changed depending on application and baud rate */

alles ohne Gewähr

#7876585
Lesenswert?

Weiß jemand ob der Reset Pin floaten darf? Laut Datenblatt reicht ein Reset via SPI command, ich habe den Pin daher nicht beschaltet.

The MCP2515 differentiates between two kinds of Resets:

  1. Hardware Reset – Low on R̅E̅S̅E̅T̅ pin.
  2. SPI Reset – Reset via SPI command.

Both of these Resets are functionally equivalent. It is important to provide one of these two Resets after power-up to ensure that the logic and registers are in their default state. A hardware Reset can be achieved automatically by placing an RC on the R̅E̅S̅E̅T̅ pin (see Figure 9-1). The values must be such that the device is held in Reset for a minimum of 2 μs after Vdd reaches the operating voltage, as indicated in the electrical specification (t RL).

Ich hab diesen Fork gefunden aber der scheint älter zu sein. Läuft der ESP32 mit der Lib von autowp bei Dir?

https://github.com/dedalqq/esp32-mcp2515

Angehängte Dateien:
#7876639
Lesenswert?

Kleiner Tip. Das Softwarereset dauert DEUTLICH länger als die 2us im Datenblatt! Da hab ich mal fast 2 Tage dran gesucht! Das Projekt vom Krativen Chaos lief vor über 10 Jahren mal problemlos in einem Testaufbau mit 16 MHz und 10us. Vor ein paar Monaten mit 10 MHz nicht mehr! Lösung. Das Delay für das Softwarereset auf 1ms hochsetzen und gut. Vermutlich reichen auch 100us, hab ich nicht getestet.

1
bool mcp2515_init(void) {
2

3
    uint8_t tmp;
4

5
    // init IOs
6
  SET(MCP2515_CS);
7
  SET_OUTPUT(MCP2515_CS);
8
  
9
  RESET(P_SCK);
10
  RESET(P_MOSI);
11
  RESET(P_MISO);
12
  
13
  SET_OUTPUT(P_SCK);
14
  SET_OUTPUT(P_MOSI);
15
  SET_INPUT(P_MISO);
16
  
17
  SET_INPUT(MCP2515_INT);
18
  SET(MCP2515_INT);           // internal pull up, why?
19
  
20
  // init SPI master interface, SPI prescaler /4
21
  SPCR = (1<<SPE) | (1<<MSTR);
22
  SPSR = 0;
23
  
24
  // reset MCP2515 by software reset
25
  // After this it is in configuration mode
26
  RESET(MCP2515_CS);
27
  spi_io(SPI_RESET);
28
  SET(MCP2515_CS);
29
  
30
  // wait a little bit until the MCP2515 has restarted
31
    // attention! internal reset time is MUCH longer than 2us minimum pulse width of data sheet!
32
  _delay_ms(1);
33
  
34
  // load CNF1..3 register
35
    tmp = ((CFG_SJW & 0x3)<<6) | (CFG_BRP & 0x3F);
36
  mcp2515_write_register(CNF1, tmp);
37
  mcp2515_write_register(CNF2, ((1<<BTLMODE) | ((CFG_PHSEG1 & 0x7)<<3) | (CFG_PRSEG & 0x7)) );
38
  mcp2515_write_register(CNF3, (CFG_PHSEG2 & 0x7));
39

40
  // activate interrupts
41
  mcp2515_write_register(CANINTE, (1<<RX1IE)|(1<<RX0IE));
42

43
  // test if we could read back the value => is the chip accessible?
44
  if (mcp2515_read_register(CNF1) != tmp ) {
45
    return false;
46
  }
47
  
48
  // deactivate the RXnBF Pins (High Impedance State)
49
  mcp2515_write_register(BFPCTRL, 0);
50
  
51
  // set TXnRTS as normal inputs
52
  mcp2515_write_register(TXRTSCTRL, 0);
53
  
54
  // turn off filters => receive any message
55
  mcp2515_write_register(RXB0CTRL, (1<<RXM1)|(1<<RXM0));
56
  mcp2515_write_register(RXB1CTRL, (1<<RXM1)|(1<<RXM0));
57
  
58
  // reset device to normal mode
59
  mcp2515_write_register(CANCTRL, 0);
60
  
61
  return true;
62
}
Angehängte Dateien:
#7876658
Lesenswert?

Alexander schrieb:

Weiß jemand ob der Reset Pin floaten darf? Laut Datenblatt reicht ein Reset via SPI command, ich habe den Pin daher nicht beschaltet.

Laut Datenblatt wird bei Low am Reset-Pin ein Reset ausgelöst. Bei einem unbeschalteten Pin hast du KEINERLEI Kontrolle über den Pegel. Es wäre nicht einmal garantiert, dass sich der Pegel im erlaubten Bereich entsprechend Tabelle 13-1 befindet (entweder zwischen VSS und 0.15VDD ODER zwischen 0.85VDD und VDD).

Nicht ohne Grund ist im Datenblatt in der Beispielkonfiguration für den Reset-Pin (Fig. 9-1) der Widerstand R als Pull-Up geschaltet. https://ww1.microchip.com/downloads/en/DeviceDoc/MCP2515-Stand-Alone-CAN-Controller-with-SPI-20001801J.pdf

#7926480
Lesenswert?

Falk B. schrieb:

Falsch! Der Pin ist ein Push-Pull Ausgang, KEIN Open Drain!

Ist das wirklich so? Ich habe jedenfalls Probleme mit dem INT und weiß nicht ob es ein Hardware- oder Software Problem ist. Tagelang geht alles, dann flashe ich den ESP32 neu (ohne Änderungen am Code) und fang wieder mit der Fehlersuche von vorne an.

Jedes INT wird erfasst und gelöscht, wenn keine CAN Nachrichten mehr rein kommen sollte doch INT irgendwann Ruhe geben. LED geht aber nicht aus. Oder kann es sein dass der MCP2515 auch INT sendet ohne CAN Traffic?

Hier der Code

https://www.mikrocontroller.net/topic/goto_post/7878186

Falk B. schrieb:

Keine Ahnung was DIESE Funktion macht, aber es reicht ein _delay_ms(1), das ist 1ms.

Auch hier benötige ich mal qualifizierte Hilfe eines ESP32 Freaks

https://www.mikrocontroller.net/topic/goto_post/7926303

#7926557
Lesenswert?

Alexander schrieb:

Falk B. schrieb:

Falsch! Der Pin ist ein Push-Pull Ausgang, KEIN Open Drain!

Ist das wirklich so?

Komische Frage. Hast du im Datenblatt einmal bis zum Hardwareteil Kapitel 13 Electrical Characteristics durchgescrollt? Dort ist in Tabelle 13-1 für den INT-Pin doch ganz klar angegeben, welchen Pegel er bei High liefert (V_OH). Ein Open Drain Ausgang KANN naturgemäß keinen H-Pegel liefert.

: Bearbeitet durch User
#7926567
Lesenswert?

Er liefert ja aber einen Active Low Pegel, daher habe ich nicht so weit gescrollt. So oder so sollte doch aber ein Pull-up nicht schaden?

When an interrupt occurs, the I̅N̅T̅ pin is driven low by the MCP2515 and will remain low until the interrupt is cleared by the MCU.

Rahul D. schrieb:

Einfache Lösung: Oszi / (10€-)LogicAnalyzer an den Pin hängen und gucken, ob da was toggelt.

Das werde ich gleich mal testen, heut ist es nicht so warm im Auto.

: Bearbeitet durch User
#7926594
Lesenswert?

Lustigerweise geht es jetzt wieder. Ich hab nix verändert weder Hardware noch Software.

Habe zwar keine Ahnung mit welcher Frequenz, da ich nicht die richtige Einstellung finde, aber man sieht der INT wird zu unterschiedlichen Zeitpunkten abgeholt und ordnungsgemäß HIGH gesetzt. Bei fehlendem Traffic bleibt er HIGH und alles schaltet nach 10 Sekunden ab. Beim Abschalten geht INT mangels Stromversorgung wieder LOW.

Angehängte Dateien:
#7926825
Lesenswert?

Ich habe evtl. noch einen möglichen Fehler im Programm gefunden, ist zwar sehr unwahrscheinlich aber dennoch ein Restrisiko gewesen. Ein Timer wird von INT aller 100 ms zurückgesetzt. Unterbleibt das, wird nach 10 Sekunden Timeout der MCP2515 abgeschaltet. Es liefen der Timer für die 10 sek und der Timer für die 100 ms gegeneinander, könnte theoretisch immer wieder ungünstig aufeinander getroffen sein. Ich hab nun noch eine 100 ms Sperre drin in der kein INT reingrätschen kann, die 100 ms werden nun bei 10 sek Timeout ebenfalls noch mal zurückgesetzt. Dass es das tatsächlich war ist aber statistisch unwahrscheinlich.

Ansonsten bleibt eigentlich nur noch die Erklärung unerwünschte Kurzschlüsse des INT gegen Masse, die mein DSO138 nicht anzeigt, oder Kabelunterbrechung/ Wackelkontakt der Dupont Jumper Kabel (kein stabiles HIGH) die ich nicht gesehen habe weil ich mit dem Oszi direkt am CAN Modul dran war. Ein Pull-up direkt am ESP32 sollte das Problem beheben.

ChatGPT hatte übrigens ungefragt Open Drain in den Raum geworfen, der Irrtum muss ja irgendwo herkommen.

Zusätzliche Härtung möglich (optional, falls Du ganz sichergehen willst):

  • Interrupt vor Abschalten deaktivieren: detachInterrupt(INTx); direkt nach dem Commit im Shutdown-Pfad.

  • Pull-Up prüfen (MCP2515 INT ist Open-Drain, aktiv LOW): sauberer Pull-Up vermeidet Geklapper im Brown-Out.

Ganz so komisch scheint die Frage dann doch nicht zu sein, wenn jemand einen eigenen Thread dafür auf macht.

Beitrag "MCP2515 Interrupt-Pin"

: Bearbeitet durch User

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