#include <Arduino.h>
#include <WiFi.h>
#include <AsyncTCP.h>
#include <ESPAsyncWebServer.h>
#include <mcp_can.h>
#include <SPI.h>
#include <String.h>
// Set INT to pin 2
#define CAN0_INT 33
// Set CS to pin 10 for the CAB-BUS sheild, will need to check you sheilds documentation for correct pin.
MCP_CAN CAN0(22);
//Default reply ECU ID
#define REPLY_ID 0x7E8
#define pin_dir 5
//=================================================================
//WEB page
//=================================================================
AsyncWebServer server(80);
// REPLACE WITH YOUR NETWORK CREDENTIALS
const char* ssid = "LabComu B202";
const char* password = "labcomu@2023";
const char* PARAM_INPUT_1 = "input1";
const char* PARAM_INPUT_2 = "input2";
const char* PARAM_INPUT_3 = "input3";
const String input_velocidade="0";
const String input_rpm="0";
const String input_temperatura="0";
// HTML web page to handle 3 input fields (input1, input2, input3)
const char index_html[] PROGMEM = R"rawliteral(
<!DOCTYPE HTML><html><head>
<title>Jiga teste Sismine</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
</head><body>
<h1>Jiga teste Sismine</h1>
<form action="/get">
input1: <input type="text" name="Velocidade">
<input type="submit" value="Submit">
</form><br>
<form action="/get">
input2: <input type="text" name="RPM">
<input type="submit" value="Submit">
</form><br>
<form action="/get">
input3: <input type="text" name="Temperatura">
<input type="submit" value="Submit">
</form>
</body></html>)rawliteral";
void notFound(AsyncWebServerRequest *request) {
request->send(404, "text/plain", "Not found");
}
//=================================================================
//Setup Needed Vars
//=================================================================
//Current Firmware Version
char FW_Version[] = "0.10";
// Incoming CAN-BUS message
long unsigned int canId = 0x000;
// This is the length of the incoming CAN-BUS message
unsigned char len = 0;
// This the eight byte buffer of the incoming message data payload
unsigned char buf[8];
//char str[20];
String canMessageRead = "";
// MIL on and DTC Present
bool MIL = true;
//Stored Vechicle VIN
unsigned char vehicle_Vin[18] = "1WK58FB1111111111";
//Stored Calibration ID
unsigned char calibration_ID[18] = "FW00116MHZ1111111";
//Stored ECU Name
unsigned char ecu_Name[19] = "OPENECUSIM";
//OBD standards https://en.wikipedia.org/wiki/OBD-II_PIDs#Service_01_PID_1C
int obd_Std = 11;
//Fuel Type Coding https://en.wikipedia.org/wiki/OBD-II_PIDs#Fuel_Type_Coding
int fuel_Type = 7;
//Default PID values
unsigned int engine_Coolant_Temperature = 80;
int engine_Rpm = 2000;
int vehicle_Speed = 0;
int timing_Advance = 10;
unsigned int intake_Temp = 25;
int maf_Air_Flow_Rate = 250;
String RX_SERIAL;
void setup() {
Serial.begin(115200);
delay(100);
Serial.println("OBD - WEB");
pinMode(pin_dir,OUTPUT);
WiFi.mode(WIFI_STA);
WiFi.begin(ssid, password);
if (WiFi.waitForConnectResult() != WL_CONNECTED) {
Serial.println("WiFi Failed!");
return;
}
Serial.println();
Serial.print("IP Address: ");
Serial.println(WiFi.localIP());
START_CAN_INIT:
//Try and init your CAN-BUS sheild.
//You will have to check your crystal oscillator on your CAN-BUS sheild and change 'MCP_16MHZ' accordingly.
if (CAN_OK == CAN0.begin(MCP_ANY, CAN_500KBPS, MCP_16MHZ)){
Serial.println("CAN BUS Shield init ok!");
CAN0.setMode(MCP_NORMAL);
pinMode(CAN0_INT, INPUT);
}else{
Serial.println("ERROR!!!! CAN-BUS Shield init fail");
Serial.println("ERROR!!!! Will try to init CAN-BUS shield again");
delay(100);
goto START_CAN_INIT;
}
// Send web page with input fields to client
server.on("/", HTTP_GET, [](AsyncWebServerRequest *request){
request->send_P(200, "text/html", index_html);
});
// Send a GET request to <ESP_IP>/get?input1=<inputMessage>
server.on("/get", HTTP_GET, [] (AsyncWebServerRequest *request) {
String inputMessage;
String inputParam;
// GET input1 value on <ESP_IP>/get?input1=<inputMessage>
if (request->hasParam(PARAM_INPUT_1)) {
input_velocidade = request->getParam(PARAM_INPUT_1)->value();
inputParam = PARAM_INPUT_1;
Serial.println(input_velocidade);
}
// GET input2 value on <ESP_IP>/get?input2=<inputMessage>
else if (request->hasParam(PARAM_INPUT_2)) {
input_rpm = request->getParam(PARAM_INPUT_2)->value();
inputParam = PARAM_INPUT_2;
Serial.println(input_rpm);
}
// GET input3 value on <ESP_IP>/get?input3=<inputMessage>
else if (request->hasParam(PARAM_INPUT_3)) {
input_temperatura = request->getParam(PARAM_INPUT_3)->value();
inputParam = PARAM_INPUT_3;
Serial.println(input_temperatura);
}
else {
inputMessage = "No message sent";
inputParam = "none";
}
//Serial.println(inputMessage);
// request->send(200, "text/html", "HTTP GET request sent to your ESP on input field ("
// + inputParam + ") with value: " + inputMessage +
// "<br><a href=\"/\">Return to Home Page</a>");
});
server.onNotFound(notFound);
server.begin();
}
void loop(){
//=================================================================
//Random PID Values - Used if want in stand alone mode... Testing
//=================================================================
digitalWrite(pin_dir,0);
engine_Coolant_Temperature = atof(input_temperatura);// random(0, 90);
engine_Rpm = atof(input_rpm);//random(500, 5000);
vehicle_Speed = atof(input_velocidade);//random(10, 120);
timing_Advance = random(-64, 63);
intake_Temp = random(-40, 215);
maf_Air_Flow_Rate = random(0, 655);
byte mode1Supported0x00PID[8] = {0x06, 0x41, 0x00, 0x88, 0x1F, 0x00, 0x00, 0x00};
byte mode1Supported0x20PID[8] = {0x06, 0x41, 0x20, 0x02, 0x00, 0x00, 0x00, 0x00};
byte mode1Supported0x40PID[8] = {0x06, 0x41, 0x40, 0x04, 0x00, 0x00, 0x00, 0x00};
byte mode9Supported0x00PID[8] = {0x06, 0x49, 0x00, 0x28, 0x28, 0x00, 0x00, 0x00};
byte obd_Std_Msg[8] = {4, 65, 0x1C, (byte)(obd_Std)};
byte fuel_Type_Msg[8] = {4, 65, 0x51, (byte)(fuel_Type)};
//Work out eng RPM
float rpm_Val = engine_Rpm * 4;
unsigned int rpm_A = (long)rpm_Val / 256;
unsigned int rpm_B = (long)rpm_Val % 256;
//Work out MAF values
float maf_Val = maf_Air_Flow_Rate * 100;
unsigned int maf_A = (long)maf_Air_Flow_Rate / 256;
unsigned int maf_B = (long)maf_Air_Flow_Rate;
//Build sensor return msg
byte engine_Coolant_Temperature_Msg[8] = {3, 65, 0x05, (byte)(engine_Coolant_Temperature + 40)};
byte engine_Rpm_Msg[8] = {4, 65, 0x0C, (byte)rpm_A, (byte)rpm_B};
byte vehicle_Speed_Msg[8] = {3, 65, 0x0D, (byte)(vehicle_Speed)};
byte timing_Advance_Msg[8] = {3, 65, 0x0E, (byte)((timing_Advance + 64) * 2)};
byte intake_Temp_Msg[8] = {3, 65, 0x0F, (byte)(intake_Temp + 40)};
byte maf_Air_Flow_Rate_Msg[8] = {4, 65, 0x10, (byte)maf_A, (byte)maf_B};
//Serial return message
String reply;
//=================================================================
//Handel Recived CAN-BUS frames from service tool
//=================================================================
//if(CAN_MSGAVAIL == CAN.checkReceive())
if (!digitalRead(CAN0_INT))
{
CAN0.readMsgBuf(&canId, &len, buf);
//https://en.wikipedia.org/wiki/OBD-II_PIDs#CAN_(11-bit)_bus_format
//Serial.print("Received: "); Serial.print(canId, HEX); Serial.print(",");
switch(Serial.read())
{
case 'q':
Serial.println("Velocidade 0 Km/h");
vehicle_Speed = 0;
break;
case 'w':
Serial.println("Velocidade 10 Km/h");
vehicle_Speed = 10;
break;
case 'e':
Serial.println("Velocidade 20 Km/h");
vehicle_Speed = 20;
break;
case 'r':
Serial.println("Velocidade 30 Km/h");
vehicle_Speed = 30;
break;
case 't':
Serial.println("Velocidade 40 Km/h");
vehicle_Speed = 40;
break;
case 'y':
Serial.println("Velocidade 50 Km/h");
vehicle_Speed = 50;
break;
case 'u':
Serial.println("Velocidade 60 Km/h");
vehicle_Speed = 60;
break;
case 'i':
Serial.println("Velocidade 70 Km/h");
vehicle_Speed = 70;
break;
case 'o':
Serial.println("Velocidade 80 Km/h");
vehicle_Speed = 80;
break;
case 'p':
Serial.println("Velocidade 90 Km/h");
vehicle_Speed = 90;
break;
case 'a':
Serial.println("Velocidade 100 Km/h");
vehicle_Speed = 100;
break;
case 'z':
Serial.println("0 RPM");
engine_Rpm = 0;
break;
case 'x':
Serial.println("1000 RPM");
engine_Rpm = 1000;
break;
case 'c':
Serial.println("2000 RPM");
engine_Rpm = 2000;
break;
case 'v':
Serial.println("3000 RPM");
engine_Rpm = 3000;
break;
case 'b':
Serial.println("4000 RPM");
engine_Rpm = 4000;
break;
case 'n':
Serial.println("5000 RPM");
engine_Rpm = 5000;
break;
}
for (int i = 0; i < 3; i++)
{
canMessageRead = canMessageRead + buf[i] + ",";
}
//Serial.println(canMessageRead);
//=================================================================
//Return CAN-BUS Messages - SUPPORTED PID's
//=================================================================
if (canMessageRead == "2,1,0,")
{
CAN0.sendMsgBuf(REPLY_ID, 0, 8, mode1Supported0x00PID);
reply = String(String(REPLY_ID, HEX) + ",0,8," + String((char*)mode1Supported0x00PID));
//Serial.println("Reply: " + reply);
reply = "";
}
if (canMessageRead == "2,1,32,")
{
CAN0.sendMsgBuf(REPLY_ID, 0, 8, mode1Supported0x20PID);
reply = String(String(REPLY_ID, HEX) + ",0,8," + String((char*)mode1Supported0x20PID));
//Serial.println("Reply: " + reply);
reply = "";
}
if (canMessageRead == "2,1,64,")
{
CAN0.sendMsgBuf(REPLY_ID, 0, 8, mode1Supported0x40PID);
reply = String(String(REPLY_ID, HEX) + ",0,8," + String((char*)mode1Supported0x40PID));
//Serial.println("Reply: " + reply);
reply = "";
}
if (canMessageRead == "2,9,0,")
{
CAN0.sendMsgBuf(REPLY_ID, 0, 8, mode9Supported0x00PID);
reply = String(String(REPLY_ID, HEX) + ",0,8," + String((char*)mode9Supported0x00PID));
//Serial.println("Reply: " + reply);
reply = "";
}
//=================================================================
//Return CAN-BUS Messages - RETURN PID VALUES - SENSORS
//=================================================================
//Engine Coolant
if (canMessageRead == "2,1,5,")
{
CAN0.sendMsgBuf(REPLY_ID, 0, 8, engine_Coolant_Temperature_Msg);
reply = String(String(REPLY_ID, HEX) + ",0,8," + String((char*)engine_Coolant_Temperature_Msg));
//Serial.println("Reply: " + reply);
reply = "";
}
//Rpm
if (canMessageRead == "2,1,12,")
{
CAN0.sendMsgBuf(REPLY_ID, 0, 8, engine_Rpm_Msg);
reply = String(String(REPLY_ID, HEX) + ",0,8," + String((char*)engine_Rpm_Msg));
//Serial.println("Reply: " + reply);
reply = "";
}
//Speed
if (canMessageRead == "2,1,13,")
{
CAN0.sendMsgBuf(REPLY_ID, 0, 8, vehicle_Speed_Msg);
reply = String(String(REPLY_ID, HEX) + ",0,8," + String((char*)vehicle_Speed_Msg));
//Serial.println("Reply: " + reply);
reply = "";
}
//Timing Adv
if (canMessageRead == "2,1,14,")
{
CAN0.sendMsgBuf(REPLY_ID, 0, 8, timing_Advance_Msg);
reply = String(String(REPLY_ID, HEX) + ",0,8," + String((char*)timing_Advance_Msg));
//Serial.println("Reply: " + reply);
reply = "";
}
//Intake Tempture
if (canMessageRead == "2,1,15,")
{
CAN0.sendMsgBuf(REPLY_ID, 0, 8, intake_Temp_Msg);
reply = String(String(REPLY_ID, HEX) + ",0,8," + String((char*)intake_Temp_Msg));
//Serial.println("Reply: " + reply);
reply = "";
}
//MAF
if (canMessageRead == "2,1,16,")
{
CAN0.sendMsgBuf(REPLY_ID, 0, 8, maf_Air_Flow_Rate_Msg);
reply = String(String(REPLY_ID, HEX) + ",0,8," + String((char*)maf_Air_Flow_Rate_Msg));
//Serial.println("Reply: " + reply);
reply = "";
}
//OBD standard
if (canMessageRead == "2,1,28,")
{
CAN0.sendMsgBuf(REPLY_ID, 0, 8, obd_Std_Msg);
reply = String(String(REPLY_ID, HEX) + ",0,8," + String((char*)obd_Std_Msg));
//Serial.println("Reply: " + reply);
reply = "";
}
//Fuel Type Coding
if (canMessageRead == "2,1,58,")
{
CAN0.sendMsgBuf(REPLY_ID, 0, 8, fuel_Type_Msg);
reply = String(String(REPLY_ID, HEX) + ",0,8," + String((char*)fuel_Type_Msg));
//Serial.println("Reply: " + reply);
reply = "";
}
//=================================================================
//Return CAN-BUS Messages - RETURN PID VALUES - DATA
//=================================================================
//VIN
if (canMessageRead == "2,9,2,")
{
unsigned char frame1[8] = {16, 20, 73, 2, 1, vehicle_Vin[0], vehicle_Vin[1], vehicle_Vin[2]};
unsigned char frame2[8] = {33, vehicle_Vin[3], vehicle_Vin[4], vehicle_Vin[5], vehicle_Vin[6], vehicle_Vin[7], vehicle_Vin[8], vehicle_Vin[9]};
unsigned char frame3[8] = {34, vehicle_Vin[10], vehicle_Vin[11], vehicle_Vin[12], vehicle_Vin[13], vehicle_Vin[14], vehicle_Vin[15], vehicle_Vin[16]};
CAN0.sendMsgBuf(REPLY_ID, 0, 8, frame1);
CAN0.sendMsgBuf(REPLY_ID, 0, 8, frame2);
CAN0.sendMsgBuf(REPLY_ID, 0, 8, frame3);
}
//CAL ID
if (canMessageRead == "2,9,4,")
{
unsigned char frame1[8] = {16, 20, 73, 4, 1, calibration_ID[0], calibration_ID[1], calibration_ID[2]};
unsigned char frame2[8] = {33, calibration_ID[3], calibration_ID[4], calibration_ID[5], calibration_ID[6], calibration_ID[7], calibration_ID[8], calibration_ID[9]};
unsigned char frame3[8] = {34, calibration_ID[10], calibration_ID[11], calibration_ID[12], calibration_ID[13], calibration_ID[14], calibration_ID[15], calibration_ID[16]};
CAN0.sendMsgBuf(REPLY_ID, 0, 8, frame1);
CAN0.sendMsgBuf(REPLY_ID, 0, 8, frame2);
CAN0.sendMsgBuf(REPLY_ID, 0, 8, frame3);
}
//ECU NAME
if (canMessageRead == "2,9,10,")
{
unsigned char frame1[8] = {10, 14, 49, 10, 01, ecu_Name[0], ecu_Name[1], ecu_Name[2]};
unsigned char frame2[8] = {21, ecu_Name[3], ecu_Name[4], ecu_Name[5], ecu_Name[6], ecu_Name[7], ecu_Name[8], ecu_Name[9]};
unsigned char frame3[8] = {22, ecu_Name[10], ecu_Name[11], ecu_Name[12], ecu_Name[13], ecu_Name[14], ecu_Name[15], ecu_Name[16]};
unsigned char frame4[8] = {23, ecu_Name[17], ecu_Name[18]};
CAN0.sendMsgBuf(REPLY_ID, 0, 8, frame1);
CAN0.sendMsgBuf(REPLY_ID, 0, 8, frame2);
CAN0.sendMsgBuf(REPLY_ID, 0, 8, frame3);
CAN0.sendMsgBuf(REPLY_ID, 0, 8, frame4);
}
//=================================================================
//Return CAN-BUS Messages - RETURN PID VALUES - DTC
//=================================================================
//DTC
if (canMessageRead == "1,3,0,")
{
if (MIL)
{
unsigned char DTC[] = {6, 67, 1, 2, 23, 0, 0, 0}; //P0217
CAN0.sendMsgBuf(REPLY_ID, 0, 8, DTC);
reply = String(String(REPLY_ID, HEX) + ",0,8, " + String((char*)DTC));
//Serial.println("Reply: " + reply);
reply = "";
}
else
{
unsigned char DTC[] = {6, 67, 0, 0, 0, 0, 0, 0}; //No Stored DTC
CAN0.sendMsgBuf(REPLY_ID, 0, 8, DTC);
reply = String(String(REPLY_ID, HEX) + ",0,8, " + String((char*)DTC));
//Serial.println("Reply: " + reply);
reply = "";
}
}
//DTC Clear
if (canMessageRead == "1,4,0,")
{
MIL = false;
}
canMessageRead = "";
}
}