/*+++ACAN2515/PSE++++++++++++++++++++++++++++++++++++++++++++++++++++++++++* Script : CAN_BUS_ANALYSE_ESP R32_xV0.4 ACAN2515: Version 2.1.0 vom 16.02.2022 Programmspeicherbedarf: 215478 Byte* Board : Wemos D1 R32, ESP32 Boardeinstellung: !!ESP32 DEV Modul!! Shield : Watterott Can-Bus V2.x Quarz 16MHz Baudrate[sw] 10kb/s Ub: 3,3V /5,0V Rs: !120 Ohm Standart Pinning SPI Bemerkung: SPI ICSP auf Can_Pin über Kabel inArbeit: x Plan: ID zu Text; Quelle; Status; Wert ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/ #ifndef ARDUINO_ARCH_ESP32 #error "Select an ESP32 board" #endif /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/ #include "ACAN2515.h" static const byte MCP2515_SCK = 18 ; // SCK input of MCP2515 static const byte MCP2515_MOSI = 23 ; // SDI input of MCP2515 static const byte MCP2515_MISO = 19 ; // SDO output of MCP2515 static const byte MCP2515_CS = 5 ; // CS input of MCP2515 static const byte MCP2515_INT = 26 ; // INT (2) output of MCP2515 static const uint8_t LED_BUILTIN =2; String Ver="CAN_BUS_ANALYSE_ESP R32_xV0.4"; ACAN2515 can (MCP2515_CS, SPI,MCP2515_INT ) ; // Einstellung ACAN 2515 static const uint32_t QUARTZ_FREQUENCY = 16UL * 1000UL * 1000UL ; // Quarz Frequenz Can-Bus 16MHz /*+++Zyklus_Zeit und Daten ermitteln++++++++++++++++++++++++++++++++++++++++*/ #define INT_ZYKLUS ((unsigned long)(INT_TIMER_NEW - INT_TIMER_OLD)) unsigned long INT_TIMER_OLD; unsigned long INT_TIMER_NEW; uint8_t Tx = 12; // Sende_LED_D03 uint8_t Rx = 14; // Empfangs_LED_D02 int _mn_max=0; int m_OLD=0; // int m; // unsigned long SCAN_ID =0x00000000; // gescante_Identifikation unsigned long CAN_ID[40]; // 27 BMW CVM 605 altes projekt unsigned char len = 0; // Datenlänge unsigned long SCAN_TIME; // unsigned long S_TIME; bool scan=true; // 1. Scan erlaubt bool Zyklus_T=true; // 1. Zykluszeiten und Daten ermittel 8 Byte /*+++SCAN_BUS+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/ void SCAN_BUS(long S_TIME) { m=1; // Anzahl telegramme unsigned long SCAN_TIME =(unsigned long)S_TIME * 1000; // Vorgabe Scan_Zeit in Sekunden 120s INT_TIMER_OLD= millis(); // Start Scan_Zeitraum do // CAN-Bus Daten empfangen, Schleife { CANMessage frame ; // CAN_Message ermöglichen if (can.receive (frame)) // CAN-Bus daten empfangen True { digitalWrite(Rx, HIGH); // LED Rx Indikator CAN_ID[m]=(frame.id); // lese Can-Bus ID in CAN_ID[m] // Test ob Can_ID schon mal aufgezeichnet wurde for(int n = 1; n<=m; n++) // Schleife [m] abhängig { if(CAN_ID[n]==CAN_ID[m]&& m!=n) // CAN_ID vorhanden { --m; // [m] letzter Eintrag löschen break; // Scan_abbruch } } ++m; if (m==m_OLD) // evtl. geänderter Abbruch ohne Zeit { ++_mn_max;} // max. Anzahl der gleichen Speicherstelle else {_mn_max=0; Serial.print("*"); // Scan_Vorschritt * } m_OLD=m; // digitalWrite(Rx, LOW); // Empfang beendet } INT_TIMER_NEW= millis(); // } while (INT_ZYKLUS < SCAN_TIME); // Schleifen_Ende scan= true; Serial.printf("*<-|\n:Scan_Zeit[ms] :%d *\n",INT_ZYKLUS); // Abschluss Scan_ID sort_H(m_OLD); // ID'S werden sortiert } /*++Zyklus_Zeit und Daten ermitteln+++++++++++++++++++++++++++++++++++++++++*/ void SCAN_Zyklus_Time() { bool M_ZT=false; bool ran= false; for(int n = 1; n<=m_OLD-1; n++) // m_OLD-1: letzter Scan nie abgeschlossen { ran=false; M_ZT=false; while(ran==false) { CANMessage frame ; if(can.receive (frame)) { digitalWrite(Rx, HIGH); // Telegramm erhalten an SCAN_ID=frame.id; if (CAN_ID[n]== SCAN_ID && M_ZT==false) { INT_TIMER_OLD= millis(); M_ZT=true; } else if(CAN_ID[n]== SCAN_ID && M_ZT==true) { INT_TIMER_NEW= millis(); Serial.printf("Msg: %d ",n); Serial.printf("ID: 0x%X ",(frame.id)); // ID /* Serial.printf("ext: 0x%X ",(frame.ext)); // ext. Serial.printf("rtr: 0x%X ",(frame.rtr)); // rtr */ Serial.printf("len: 0x%X ",(frame.len)); // len digitalWrite(Rx,LOW); // Telegramm erhalten LED aus for(int i = 0; i<(frame.len); i++) // data { Serial.printf(" 0x%X, ",frame.data[i]); // Daten } if (len<8) { for(int i = frame.len; i<8; i++) // Auffüllung auf 8 Byte { Serial.print("0x00, "); // Ausgleich 8 byte } } Serial.printf("\tZyklus[ms]: %d*\n",INT_ZYKLUS); ran=true; } } } } } /*++Sortier Routine+++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/ void sort_H(const unsigned int laenge ) { for(unsigned int i = 0; i < laenge-1; i++) { unsigned int min_pos = i; for(unsigned int j = i+1; j < laenge; j++) if(CAN_ID[j] < CAN_ID[min_pos] ) { min_pos = j;} int temp = CAN_ID[i]; CAN_ID[i] = CAN_ID[min_pos]; CAN_ID[min_pos] = temp; } } /*+++Setup++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/ void setup () { pinMode (LED_BUILTIN, OUTPUT) ; pinMode(Tx, OUTPUT); digitalWrite(Tx, HIGH); // Ausgang; Tx_Led out, kurz aktiv pinMode(Rx, OUTPUT); digitalWrite(Rx, HIGH); // Ausgang; Rx_Led out, kurz aktiv digitalWrite (LED_BUILTIN, HIGH) ; Serial.begin (115200) ; // Serial_Schnittstelle bitrate 115200 b/s while (!Serial) { delay (100); digitalWrite (LED_BUILTIN, !digitalRead (LED_BUILTIN)) ; // toggelt Board_LED } delay (100); digitalWrite (LED_BUILTIN, LOW) ; // Serial ok SPI.begin (MCP2515_SCK, MCP2515_MISO, MCP2515_MOSI) ; // SPI ini Standart Serial.println ("ACAN2515 Ini") ; // ACAN2515 ini delay(200); ACAN2515Settings settings (QUARTZ_FREQUENCY, 10UL * 1000UL) ; // CAN bit rate 10 kb/s settings.mRequestedMode = ACAN2515Settings::NormalMode; // NormalMode const uint16_t errorCode = can.begin (settings, [] { can.isr () ; }) ; /* Serial.println("Setting"); Serial.printf ("Bit Rate prescaler: %d\t\n",settings.mBitRatePrescaler) ; Serial.printf ("Propagation Segment: %d\t\n",settings.mPropagationSegment) ; Serial.printf ("Phase segment 1: %d\t\n",settings.mPhaseSegment1) ; Serial.printf ("Phase segment 2: %d\t\n",settings.mPhaseSegment2) ; Serial.printf ("SJW: %d\t\n",settings.mSJW) ; Serial.printf ("Triple Sampling: %s\t\n",(settings.mTripleSampling ? "yes" : "no")) ; Serial.printf ("Actual bit rate: %d bit/s\t\n",settings.actualBitRate ()) ; Serial.printf ("Exact bit rate ? %s\t\n",(settings.exactBitRate () ? "yes" : "no")) ; Serial.printf ("Sample point: %d%%\t\n\n",settings.samplePointFromBitStart ()) ; */ if (errorCode == 0) // { digitalWrite(Tx, LOW); // No ERROR LED LOW digitalWrite(Rx, LOW); // No ERROR LED LOW Serial.printf ("Configuration error: 0x%X\nRUN\n",errorCode) ; } else { digitalWrite(Tx, HIGH); // Error LED High digitalWrite(Rx, HIGH); // Error LED High Serial.printf ("Configuration error: 0x%X\nSTOP!\n",errorCode) ; } Serial.println (Ver) ; // Script Verswion delay (2000); } /*+++Loop+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/ void loop () { if (scan) { Serial.println("***Bus Scan läuft***"); SCAN_BUS(180); // Scannt den Bus für ..120 Sekunden for(int m = 1; m<=m_OLD-1; m++) // Schleife m_OLD-1: letzter Scan nie abgeschlossen { Serial.printf("CAN_Bus-->Msg:%d \tid:0x%X *\n",m,(CAN_ID[m])); scan=false; // weiterer Scan unterbunden } Serial.println("***Bus Scan abgeschlossen & sortiert***"); } if (Zyklus_T) { Serial.println("***Zykluszeiten und Daten_Ermittlung läuft***"); SCAN_Zyklus_Time(); Zyklus_T=false; Serial.println("***Daten ermittelt***"); } } /*+++Ende+++PSE+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/ // END FILE