Heizung über CAN belauschen mit nodeMCU und MCP2515

Moin,

ich möchte gerne meine Heizung über CAN Bus belauschen und die Daten anzeigen und in eine Datenbank schreiben.

Hardware ist schon zusammengebaut, nun fehlts noch an der Software.
Im Internet habe ich folgende Schaltung gefunden:


Quelle: http://forum.amperka.ru/attachments/cansan-jpg.16904/

Genauso hab ich's zusammengebaut.
Auf dem Oszi habe ich geschaut und es kommen auch CAN Daten am MCP2515 an.

Aber nun ist die große Frage: Wie kriege ich die Daten angezeigt?

Ich habe es schon mit "MCP2515-CAN-Sniffer" probiert. Fehlermeldung beim kompilieren, scheint nicht kompatibel zu sein.
"CAN_read" probiert. Funktioniert vermutlich nicht aufgrund anderer Verschaltung. Ich finde in der Bibliothek allerdings keine Stelle an der ich die Pin Belegung ändern könnte (ich will ja nicht für jede Bibliothek gleich wieder die Hardware umbauen).

Hat jemand sowas in Betrieb und kann mir einen Tipp geben?

Danke und lieben Gruß,
Chris

...kann man aus den HIGH / LOW Perioden die Busgeschwindigkeit ausrechnen?
Wenn ich mich nicht vermessen habe, sehe ich Perioden von

HIGH: 50µs / 100µs / 150µs / 200µs / 250µs
LOW: 50µs / 100µs / 200µs / 250µs

Vielleicht.

Schau mal im Wikipedia-Artikel den Frameaufbau an - das ginge einfach, wenn Du wiederkehrende Bitmuster erzeugen kannst (das macht die Heizung aber vermutlich nicht auf Zuruf). Es kommt dann noch dazu, das nach fünf gleichen Bits die Hardware automatisch ein umgekehrtes einfügt ("Stuffing").

Wenn Du aber die Länge der Frames einigermaßen exakt gemessen bekommst (und Glück hast, dass die Anzahl Datenbytes nicht allzu sehr variiert) hast Du eine Chance das rückzurechnen.

Gruß Walter

Ich will ja nur lauschen, d.h. ich erzeuge kein Bitmuster.
....okay, mussssss ja nicht sein, geht ja auch mit try&error

Momentan sehe ich aber mangels korrekter Zusammenarbeit von Hardware, Verdrahtung und Software leider noch gar nichts.

Daher nochmal die Frage:
Hat schonmal jemand einen nodeMCU mit MCP2515 zum laufen und lauschen gebracht und könnte mir dabei weiterhelfen?

Danke und lieben Gruß,
Chris

ich würde einen ESP32 (der hat CAN on board) und einen Can-Wandler nehmen.

Bei mir hats aber mit dem NodeMCU am Anfang auch funktioniert.
mit dieser Lib:
#include <mcp_can.h> // download the lib from GitHub - coryjfowler/MCP_CAN_lib: MCP_CAN Library

und offenbar an 10:

const int SPI_CS_PIN = 10; // PIN for Chip Select of CAN Module
MCP_CAN CAN(SPI_CS_PIN);

Mit der coryfowler lib bin ich gerade am versuchen.

Dort habe ich das CAN_receive Beispiel geladen und nach der oberen Verdrahtung
"MCP_CAN CAN0(5);"
definiert

Wieso denn 10? Ist es nicht 5 nach obiger Verdrahtung?

ich hab halt damals am SD3 / 10 auf der linken seiten angeschlossen, warum, kann ich dir nicht sagen, vermutlich war sonst alles belegt...

Hier mal mein angepasstes Sketch:

// CAN Receive Example
//

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

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

#define CAN0_INT 16                              // Set INT to pin 2
MCP_CAN CAN0(5);                               // Set CS to pin 10


void setup()
{
  Serial.begin(74880);
  
  // Initialize MCP2515 running at 16MHz with a baudrate of 500kb/s and the masks and filters disabled.
  if(CAN0.begin(MCP_ANY, CAN_200KBPS, MCP_8MHZ) == CAN_OK)
    Serial.println("MCP2515 Initialized Successfully!");
  else
    Serial.println("Error Initializing MCP2515...");
  
  CAN0.setMode(MCP_NORMAL);                     // Set operation mode to normal so the MCP2515 sends acks to received data.

  pinMode(CAN0_INT, INPUT);                            // Configuring pin for /INT input
  
  Serial.println("MCP2515 Library Receive Example...");
}

void loop()
{
  if(!digitalRead(CAN0_INT))                         // If CAN0_INT pin is low, read receive buffer
  {
    CAN0.readMsgBuf(&rxId, &len, rxBuf);      // Read data: len = data length, buf = data byte(s)
    
    if((rxId & 0x80000000) == 0x80000000)     // Determine if ID is standard (11 bits) or extended (29 bits)
      sprintf(msgString, "Extended ID: 0x%.8lX  DLC: %1d  Data:", (rxId & 0x1FFFFFFF), len);
    else
      sprintf(msgString, "Standard ID: 0x%.3lX       DLC: %1d  Data:", rxId, len);
  
    Serial.print(msgString);
  
    if((rxId & 0x40000000) == 0x40000000){    // Determine if message is a remote request frame.
      sprintf(msgString, " REMOTE REQUEST FRAME");
      Serial.print(msgString);
    } else {
      for(byte i = 0; i<len; i++){
        sprintf(msgString, " 0x%.2X", rxBuf[i]);
        Serial.print(msgString);
      }
    }
        
    Serial.println();
  }
}

/*********************************************************************************************************
  END FILE
*********************************************************************************************************/

Hier der serielle Monitor:

 ets Jan  8 2013,rst cause:2, boot mode:(3,6)

load 0x4010f000, len 3584, room 16 
tail 0
chksum 0xb0
csum 0xb0
v2843a5ac
~ld
Entering Configuration Mode Successful!
Setting Baudrate Successful!
MCP2515 Initialized Successfully!
MCP2515 Library Receive Example...

Ich hab alle Bitraten durchprobiert, bei keinem kommen Daten :frowning:
Aber bei allen schreibt er "Entering Configuration Mode Successful! Setting Baudrate Successful! MCP2515 Initialized Successfully! MCP2515 Library Receive Example..." ?!?!?!

Hier mal die reale Welt:




Ich habe noch einen USB CAN-Analyzer gefunden.
Damit konnte ich herausfinden, dass die Bitrate 20 kBit/s ist, und ich konnte Daten vom CAN Bus auslesen :slight_smile:
Nun muss das ganze 'nur' noch auf dem nodeMCU und MCP2515 laufen.
Hat jemand eine Idee?

Vlt hilft das weiter.
War gleich der erste Eintrag bei Google, weiter habe ich nicht gesucht.

themanfrommoon:
Hat jemand eine Idee?

Es gibt zwei SPI-Schnittstellen, beim ESP32 nutze ich VSPI, beim ESP8266 könnten das lt. AZ-Delivery Pinout die Pins zwischen SD1 und CLK sein.

Nur eine Idee :slight_smile:

hmm, leider geht immer noch nichts.

NodeMCU V3 + MCP2515 + Daten auf Webseite | CANhack.de
Vlt hilft das weiter.
War gleich der erste Eintrag bei Google, weiter habe ich nicht gesucht.

Da habe ich leider nicht gefunden wie der nodeMCU v2 und der MCP2515 verbunden werden (welcher PIN an welchen PIN)

Es gibt zwei SPI-Schnittstellen, beim ESP32 nutze ich VSPI, beim ESP8266 könnten das lt. AZ-Delivery Pinout die Pins zwischen SD1 und CLK sein.

Ich hab ja nicht den nodeMCU V3, sondern den nodeMCU v2.
Da sieht das pinout etwas anders aus:

Aber auch da habe ich die SPI Schnittstelle mal getauscht, ohne Erfolg. Genau genommen sogar mit fatalem Misserfolg.
Der Kompiler meldete plötzlich "MD5 of file does not match data in flash".
Ich konnte gar kein neues Sketch mehr hochladen.
Erst nachdem ich die PINs wieder abgezogen habe lief der ESP wieder. Sehr merkwürdigt!?

Ich habe jetzt versucht mal den Entwickler der Library zu kontaktieren
https://forum.arduino.cc/index.php?topic=703856.0

Lieben Gruß,
Chris

Ist dieses Thema noch aktuell oder bereits gelöst?

Wenn man ein Problem mit vielen Unbekannten hat, kann man versuchen, ein paar Unbekannte loszuwerden. Daher ist mein Vorschlag, die Heizung durch einen UNO zu ersetzen. Dazu habe ich auf mein Thema UNO - Mega - Teensy mittels CAN-Bus verbinden zurückgegriffen und den Mega durch einen ESP32 ersetzt. Außer MCP_CAN CAN0(5); war keine Anpassung notwendig:

// MCP2515 - ESP32
//    SCK  - IO18
//    SI   - IO23
//    SO   - IO19
//    CS   - IO5
//    Vcc  - 5V ! Der ESP32 hat 5V-feste Eingänge
//    GND  - GND
//
// http://henrysbench.capnfatz.com/henrys-bench/arduino-projects-tips-and-more/arduino-can-bus-module-1st-network-tutorial/
// CAN Receive Example der Bibliothek https://github.com/coryjfowler/MCP_CAN_lib
#include <mcp_can.h>
#include <SPI.h>

MCP_CAN CAN0(5);                // Set CS pin

char msgString[128];            // Serial Output String Buffer
const int LEDpin = 13;

void setup()
{
  Serial.begin(115200);
  delay(3000);
  pinMode(LEDpin, OUTPUT);

  while (CAN_OK != CAN0.begin(MCP_ANY, CAN_500KBPS, MCP_8MHZ))  // init can bus : masks and filters disabled, baudrate, Quarz vom MCP2551
  {
    Serial.println("CAN BUS Shield init fail");
    Serial.println(" Init CAN BUS Shield again");
    delay(100);
  }
  Serial.println("CAN BUS Shield init ok!");
  CAN0.setMode(MCP_NORMAL);   // Change to normal mode to allow messages to be transmitted
}

void loop()
{
  unsigned long rxId = 0;
  byte len = 0;
  byte rxBuf[8];

  if (CAN_MSGAVAIL == CAN0.checkReceive())           // check if data coming
  {
    CAN0.readMsgBuf(&rxId, &len, rxBuf);      // Read data: len = data length, buf = data byte(s)
    Serial.println("-----------------------------");
    if ((rxId & 0x80000000) == 0x80000000)            // Determine if ID is standard (11 bits) or extended (29 bits)
      sprintf(msgString, "Extended ID: 0x%.8lX  DLC: %1d  Data:", (rxId & 0x1FFFFFFF), len);
    else
      sprintf(msgString, "Standard ID: 0x%.3lX       DLC: %1d  Data:", rxId, len);

    Serial.print(msgString);

    if ((rxId & 0x40000000) == 0x40000000) {          // Determine if message is a remote request frame.
      sprintf(msgString, " REMOTE REQUEST FRAME");
      Serial.print(msgString);
    } else {
      for (byte i = 0; i < len; i++) {
        sprintf(msgString, " 0x%.2X", rxBuf[i]);
        Serial.print(msgString);
        if (i == 2)
        {
          digitalWrite(LEDpin, rxBuf[i] % 2);
        }
      }
    }
    Serial.println();
  }
}

Der ESP32 zeigt die selbe Ausgabe wie der Mega2560 an.

Versuche mal, ob Du es auch für den ESP8266 zum Laufen bekommst.

Moin,

ja klaro ist das noch aktuell.
Habe leider keinen UNO, sondern quasi nur jede Menge ESP8266.....und irgendwo noch vergraben ein oder zwei Nanos

Bei mir dauerts leider meistens sehr lange weil ich viel zu wenig Zeit für solche Basteleien habe.

Liebe Grüße,
Chris

themanfrommoon:
....und irgendwo noch vergraben ein oder zwei Nanos

Ist doch der selbe µC, also los geht's!

themanfrommoon:
... weil ich viel zu wenig Zeit für solche Basteleien habe.

Oder andere Dinge sind Dir wichtiger :wink:

Wenn man ein Problem mit vielen Unbekannten hat, kann man versuchen, ein paar Unbekannte loszuwerden. Daher ist mein Vorschlag, die Heizung durch einen UNO zu ersetzen.

Die Idee versteh ich nicht.
Wieso ist die Heizung jetzt plötzlich Teil des Problems?
Was die macht ist doch bekannt.
Und das Sie was macht ist auch bekannt.
Das hab ich doch mit meinem CANalyzer beobachtet.
Ich könnte auch mit dem CANalyzer auf den CAN Bus senden. Aber wozu? Die Heizung macht das doch schon?!

themanfrommoon:
Die Idee versteh ich nicht.

Das Problem versteckt sich immer da, wo Du es nicht vermutest. Daher tut ein Perspektivwechsel manchmal ganz gut.

Weil ich gerade dabei war, habe ich den ESP32 mit MCP2515 an SPI und SJA1000 mit den internen Registern kurz erfolgreich in Kommunikation mit UNO und Mega2560, beide mit MCP2515, getestet.