顯示具有 MCP2515 標籤的文章。 顯示所有文章
顯示具有 MCP2515 標籤的文章。 顯示所有文章

2023年11月20日 星期一

Catch your vehicle Data via cheap CAN bus Tool

Purpose:
這個專案是利用便宜的方案去抓取你的車子CANBUS的資料.
This project uses a cheap solution to capture your car’s actionable information of CANBUS data.

Architectures:
利用OBD2接頭延長線連接汽車, ELM327 and CAN Hacker module (ESP32+MCP2515).
再使用手機TORQUE APP 讀取車子的資訊並且利用PC的CANHACKER software接收資料並儲存以利後續分析PID資料.
Use the OBD2 connector extension cable to connect the car, ELM327 and CAN Hacker module (ESP32+MCP2515).
Then use the TORQUE APP on your mobile phone to read the car's information and use the PC's CANHACKER software to receive the data and store it for subsequent analysis of the PID data.

BOM(Bill of Material) Cost:  682NT

Fundamental:
CAN Hacker module (ESP32+MCP2515)
Reference the previous article link on blog:
ESP32 + MCP2515 use CanHacker on CAN Bus system 

OBD2(On-Board Diagnostics 2)
OBD-II systems provide access to health information and access to numerous parameters and sensors from the Electronic Control Units (ECUs). Thus, the OBDII system offers valuable information, including diagnostic trouble codes when troubleshooting problems.
if your car was manufactured after 1996, it features a Diagnostic Link Connector (DLC) or OBD2 port.

ELM327(Bluetooth interface)


ELM327 device acts as a bridge between the computer/mobile and the car. The OBD adapter is attached to the car's physical 16-pin OBD connector plug (OBD2 port), typically located near the dashboard below the steering wheel.
There are different types of interfaces that the ELM327 adapters can have, for example, Bluetooth, WiFi, USB, or serial port. For the best option for your needs.

Torque APP is for Android phones to use it with the ELM327 devices.
Reference https://wiki.torque-bhp.com/view/Main_Page

Torque is an OBD2 performance and diagnostic tool for any device that runs the Android operating system. It will allow you to access the many sensors within your vehicles Engine Management System, as well as allow you to view and clear trouble codes.


YouTube Demo:





2023年11月16日 星期四

ESP32+MCP2515 CAN Bus Scanner with ELM327 and ECU simulator

Purpose:
In this project it will be demonstrated that the ELM327 (Bluetooth interface), ECU emulator and ESP32 + MCP2515 module communicate with each other through the Controller Area Network (CAN) bus in the car's OBD-II (On-Board Diagnostics 2) connector.
在這個專案中將展示ELM327(藍牙介面)、ECU模擬器和ESP32 + MCP2515模組透過汽車的 OBD-II(車載診斷 2)連接器中的控制器區域網路 (CAN ) 匯流排相互通訊。

Fundamental:
ELM327 Bluetooth Automotive Code Readers
The ELM327 is a multi-protocol adapter that allows a pc or other device to communicate with a car's OBD-II engine management system through the Controller Area Network (CAN) bus. The ELM327 OBD2 interface is a great tool for any car owner, and it will help you keep on top of any issues that may arise with your vehicle.
reference https://en.wikipedia.org/wiki/ELM327

The previous article link on blog:
CAN BUS 通訊研究

Circuit:

YouTube Demo:



2023年9月14日 星期四

ECU Simulator CAN Bus Data with ESP32+MCP2515

Purpose:

依據之前的文章 ESP32 + MCP2515 use CanHacker on CAN Bus systemCAN BUS 通訊研究, 重新把ECU simulator跟 ESP32 Canhacker的CAN Bus通訊結果作整理. 

Based on the previous article ESP32 + MCP2515 use CanHacker on CAN Bus system and CAN BUS communication research, the CAN Bus communication results between ECU simulator and ESP32 Canhacker are reorganized.


模擬器提供下列模式:

系統狀態、即時資料:MODE 01
故障診斷:MODE 03,07,0A
故障清除:MODE 04
凍結資料:MODE 02
氧感測器測試:MODE 05
監測結果:MODE 06
車輛資訊:MODE 09 

模擬器提供六組模擬訊號調整旋鈕。由左至右編號為1~6。
預設模擬訊號源為:空氣流量、冷卻液溫度、轉速、車速、進氣溫度、節氣門位置

詢問汽車功能的CAN匯流排節點識別碼0x7DF , 接收汽車OBD資料要將Acceptance
Filter設為0x7E8,都是依據ISO 15765-4文件所定規範。
If ( CANIsTxReady ( ) )
{ TX_Data_Buf2[0] = 0x02 ;
TX_Data_Buf2[1] = 0x01 ;
TX_Data_Buf2[2] = PID_code;
TX_Data_Buf2[3] = 0x00 ;
TX_Data_Buf2[4] = 0x00 ;
TX_Data_Buf2[5] = 0x00 ;
TX_Data_Buf2[6] = 0x00 ;
TX_Data_Buf2[7] = 0x00 ;
CANSendMessage ( 0x7DF , TX_Data_Buf2 ,
8,CAN_TX_PRIORITY_1&
CAN_TX_STD_FRAME&
CAN_TX_NO_RTR_FRAME ) ;
}

if ( CANIsRxReady ( ) )
{
CANReceiveMessage( &RX_ID1 ,
RX_Data_Buf1 , &RX_Data_Len1 ,
&RX1_Message_Flag ) ;
if (RX_ID1==0x7E8)
{ Engine RPM = ((A*256)+B)/4 ; }
}

Reference https://en.wikipedia.org/wiki/OBD-II_PIDs





Circuit:
YouTube Demo:




2023年7月27日 星期四

Two ESP32 CAN Bus communication with MCP2515 module

Purpose:

Use the function of two articles (ESP32 one Wire Bus Application – DS18B20 section) and (ESP32 + MCP2515 use CanHacker on CAN Bus system) in my channel to integrate into a new topic.One ESP32 transfer the temperature on DS18B20 to the other ESP32 via can bus system.
CAN Bus communication with MCP2515 module to communicate between two ESP32

#1_ESP32+MCP2515+DS18B20 <--->#2_ESP32+MCP2515(ESP32 + MCP2515 use CanHacker on CAN Bus system)

#1_ESP32 PID is can.txId = 0x7D1;

Circuit:




Code Introduce:

//-----------------Mega2560 MCP2515 code --------------------------------------
mcp_can library mcp_can - Arduino Reference

#include <OneWire.h>
#include <DallasTemperature.h>
#include <BluetoothSerial.h>
#include <SPI.h>
#include "mcp_can.h"
//------CAN BUS setting ---------------------------------------------------------
#define CAN0_INT 21 // Set INT to pin 50
const int SPI_CS_PIN = 5;
MCP_CAN CAN0(SPI_CS_PIN);
//-----   DS18B20  ------------------
#define DQ_Pin 4

OneWire oneWire(DQ_Pin);
DallasTemperature sensors(&oneWire);

byte data[12]; // buffer for data
byte address[8]; // 64 bit device address

#define LED_BUILTIN 2
BluetoothSerial SerialBT;
//--------- Flag structure --------------------------------------
typedef struct _vFlag
{
  uint8_t BTFlag = 0;
  uint8_t DC_Flag = 0;
  uint8_t CANFlag = 0;
  uint8_t I2C_Flag = 0;
  uint8_t BMP180Flag = 0;
  uint8_t DS18B20Flag = 0;
  uint8_t JSONFlag = 0;
  uint8_t LEDFlag = 1;
  uint8_t sensor_Flag = 0;
  uint8_t sensor1_Flag = 0;
  uint8_t initial_Flag = 0;
  uint8_t Tone_Flag = -1;
  uint8_t IR_RECV_Flag=0;
  uint8_t IR_SEND_Flag=0;
  uint8_t FunctionFlag = 3;
  uint8_t SendFlag = 0;
  uint8_t BMPCnt = 0;
} vFlag;
vFlag *flag_Ptr;
vFlag flag;
//----------uart--------------
#define LINE_BUFFER_LENGTH 64
//--------- uart structure --------------------------------------
typedef struct _vUart
{
  char c;
  int lineIndex = 0;
  int line1Index = 0;
  int BTlineIndex = 0;
  bool lineIsComment;
  bool lineSemiColon;
  //char *line;
  char line[128];
  //char line1[128];
  char BTline[20];
  //char R_line[20];
  //char L_line[20];
  String inputString;
  String BTinputString;
  String S1inputString;
  int V[16];
  char ctemp[30];
  char I2C_Data[80];
  int DC_Spped = 50;
  float Voltage[16];
  int Buffer[128];
  int StartCnt = 0;
  int ReadCnt = 0;
  int sensorValue = 0;
} vUart;
vUart *Uart_Ptr;
vUart Uart;
//-------------CAN-------------------------------
typedef struct _vCAN_t
{
  long unsigned int rxId;
  long unsigned int txId;
  unsigned char rxlen = 8;
  unsigned char txlen = 8;
  unsigned char rxext = 0;
  unsigned char txext = 0;
  unsigned char rxBuf[20];
  byte data[8];
  unsigned char masknum = 0;
  unsigned char maskext = 0;
  long unsigned int maskId;
  unsigned char filternum = 0;
  unsigned char filterext = 0;
  long unsigned int filterId;
} vCAN_t;

vCAN_t *can_Ptr;
vCAN_t can;

//-------------------------------------------------
void setup()
{
  Serial.begin(9600);
  Serial.println(F("init"));
  pinMode(LED_BUILTIN, OUTPUT);
  SerialBT.begin("BT_BS18B20");// BTName

  if (oneWire.search(address))
  {
    Serial.println("Slave device found!");
    Serial.print("Device Address = ");
    Serial.println(address[0]);
  }
  else
  {
    Serial.println("Slave device not found!");
  }
  //-----DS-----------
  sensors.begin();
  //standard frame
  can.txId = 0x7D1;
  can.txext = 0;
  can.txlen = 8;
  can.data[0] = 0x8E;
  can.data[1] = 0x00;
  can.data[2] = 0x00;
  can.data[3] = 0x00;
  can.data[4] = 0x00;
  can.data[5] = 0x00;
  can.data[6] = 0x00;
  can.data[7] = 0x00;

}
//-----------------------------------------
void loop()
{
  Serial.print(F("Main at core:"));
  Serial.println(xPortGetCoreID());
  while(1)
  {
    if(flag.LEDFlag == 1)
    {
      digitalWrite(LED_BUILTIN, HIGH); // turn the LED on (HIGH is the voltage level)
      vTaskDelay(300);
      digitalWrite(LED_BUILTIN, LOW); // turn the LED off by making the voltage LOW
      vTaskDelay(300);
    }
    while (Serial.available() > 0)
    {
      Uart.c = Serial.read();

      if ((Uart.c == '\n') || (Uart.c == '\r'))
      { // End of line reached
        if (Uart.lineIndex > 0)
        { // Line is complete. Then execute!
          Uart.line[Uart.lineIndex] = '\0'; // Terminate string

          processCommand(Uart.line); // do something with the command
          SerialBT.println(Uart.line);

          Uart.lineIndex = 0;
          Uart.inputString = "";
        }
        else
        {
          // Empty or comment line. Skip block.
        }
        Uart.lineIsComment = false;
        Uart.lineSemiColon = false;
        Serial.println(F("ok>"));
      }
      else
      {
        //Serial.println( c );
        if ((Uart.lineIsComment) || (Uart.lineSemiColon))
        {
          if (Uart.c == ')')
            Uart.lineIsComment = false; // End of comment. Resume line.
        }
        else
        {
          if (Uart.c == '/')
          { // Block delete not supported. Ignore character.
          }
          else if (Uart.c == '~')
          { // Enable comments flag and ignore all characters until ')' or EOL.
            Uart.lineIsComment = true;
          }
          else if (Uart.c == ';')
          {
            Uart.lineSemiColon = true;
          }
          else if (Uart.lineIndex >= LINE_BUFFER_LENGTH - 1)
          {
            Serial.println("ERROR - lineBuffer overflow");
            Uart.lineIsComment = false;
            Uart.lineSemiColon = false;
          }
          else if (Uart.c >= 'a' && Uart.c <= 'z')
          { // Upcase lowercase
            Uart.line[Uart.lineIndex] = Uart.c - 'a' + 'A';
            Uart.lineIndex = Uart.lineIndex + 1;
            Uart.inputString += (char)(Uart.c - 'a' + 'A');
          }
          else
          {
            Uart.line[Uart.lineIndex] = Uart.c;
            Uart.lineIndex = Uart.lineIndex + 1;
            Uart.inputString += Uart.c;
          }
        }
      }
    } //while (Serial.available() > 0)
    while (SerialBT.available())
    {
      String BTdata = SerialBT.readString();

      Serial.println(BTdata);
      BTprocessCommand(BTdata);
    }//while (BT.available())
 
    if(flag.DS18B20Flag == 1)
    {
      vDS18B20Task();
      sensors.requestTemperatures();
      SerialBT.print("E");
      SerialBT.println(sensors.getTempCByIndex(0));
    }

    if (flag.CANFlag == 1)
    {
      Serial.print("Temperatures --> ");
      sensors.requestTemperatures();
      Serial.println(sensors.getTempCByIndex(0));
      //--------------------------------
      float f=sensors.getTempCByIndex(0);
      String mystring;
      mystring = String(f);
      byte float_data[mystring.length()+1];
      mystring.getBytes(float_data, mystring.length()+1);
      //---------------------------------------------
      int size = sizeof(float_data);
      for(int i=0;i<size;i++)
      {
        can.data[i] =float_data[i];
      }
     
      flag.CANFlag = 2;
      flag.LEDFlag = 0;
      delay(50);
      byte sndStat = CAN0.sendMsgBuf(can.txId, can.txext, can.txlen, can.data);
      if (sndStat == CAN_OK)
        Serial.println("CAN Message Sent Successfully!");
      else
        Serial.println("Error Sending CAN Message...");
      flag.CANFlag = 1;
    }
    /**
    else
    {
      Serial.println("Open CAN First...");
    }**/

  }
}
//-------------------------------------
void BTprocessCommand(String data)
{
 
}
//----------------------------------------
void processCommand(char *data)
{
  int len, xlen, ylen, zlen, alen;
  int tempDIO;
  String stemp;

  len = Uart.inputString.length();
  //---------------------------------------
  if (strstr(data, "VER") != NULL)
  {
    Serial.println(F("ESP32_20230727"));
    Serial.println(F("CAN_DS18B20"));
  }
  if (strstr(data, "DS18B20_ON") != NULL)
  {
    flag.DS18B20Flag = 1;
    flag.LEDFlag=0;
    Serial.println(F("DS18B20_ON"));

  }
  if (strstr(data, "DS18B20_OFF") != NULL)
  {
    flag.DS18B20Flag = 0;
    flag.LEDFlag=1;
    Serial.println(F("DS18B20_OFF"));
  }
  ///----------CAN function ----------------
  if (strstr(data, "CAN_ON_125") != NULL)
  {
    if (flag.CANFlag == 0)
    {
      if (CAN_OK != CAN0.begin(MCP_NORMAL, CAN_125KBPS, MCP_8MHZ))
      {
        Serial.println("CAN BUS Shield init fail");
        Serial.println("Init CAN BUS Shield again");
        flag.CANFlag = 0;
      }
      else
      {
        Serial.println("CAN BUS Shield init ok!");
        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
        flag.CANFlag = 1;
        Serial.println("init ok");
      }
    }
    else if (flag.CANFlag == 2)
    {
      flag.CANFlag = 1;
      Serial.println("CAN BUS message ON!");
    }
  }
  if (strstr(data, "CAN_ON_250") != NULL)
  {
    if (flag.CANFlag == 0)
    {
      if (CAN_OK != CAN0.begin(MCP_NORMAL, CAN_250KBPS, MCP_8MHZ))
      {
        Serial.println("CAN BUS Shield init fail");
        Serial.println("Init CAN BUS Shield again");
        flag.CANFlag = 0;
      }
      else
      {
        Serial.println("CAN BUS Shield init ok!");
        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
        flag.CANFlag = 1;
        Serial.println("init ok");
      }
    }
    else if (flag.CANFlag == 2)
    {
      flag.CANFlag = 1;
      Serial.println("CAN BUS message ON!");
    }
  }
  if (strstr(data, "CAN_ON_500") != NULL)
  {
    if (flag.CANFlag == 0)
    {
      if (CAN_OK != CAN0.begin(MCP_NORMAL, CAN_500KBPS, MCP_8MHZ))
      {
        Serial.println("CAN BUS Shield init fail");
        Serial.println("Init CAN BUS Shield again");
        flag.CANFlag = 0;
      }
      else
      {
        Serial.println("CAN BUS Shield init ok!");
        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
        flag.CANFlag = 1;
        Serial.println("init ok");
      }
    }
    else if (flag.CANFlag == 2)
    {
      flag.CANFlag = 1;
      Serial.println("CAN BUS message ON!");
    }
  }
  if (strstr(data, "CAN_OFF") != NULL)
  {
    flag.CANFlag = 2;
    flag.LEDFlag = 1;
    Serial.println("CAN BUS message OFF!");
  }
}
//-----------------------------------------

//-------------------------------------------
void vDS18B20Task()
{
  Serial.print("Temperatures --> ");
  sensors.requestTemperatures();
  Serial.println(sensors.getTempCByIndex(0));
}

YouTube Demonstration: