PowerBroker2 / ELMduino

Arduino OBD-II Bluetooth Scanner Interface Library for Car Hacking Projects
MIT License
676 stars 125 forks source link

set a special pisd of ELMDUINO with header #219

Open Ciullox opened 10 months ago

Ciullox commented 10 months ago

I found this program on the net and I'm trying to modify it to receive from Arduino the clogging of the dpf of my car which is requested via a header "ATSH DA10F1" AND FROM A PIDS 2218E4 ONLY THAT THE program arrives " myELM327.sendCommand("AT SH DA10F1");" and it stops, it no longer goes forward and it doesn't print anything via serial

#include "SafeString.h"
#include <SoftwareSerial.h>
#include <ELMduino.h>

int BATTv;

SoftwareSerial mySerial(6 ,7); // RX, TX for BlueTooth HC-05
#define ELM_PORT mySerial
ELM327 myELM327;

//DICHIARAZIONE SAFE THE STRING
 createSafeString(dataFrame0, 14);   // will also add space for the terminating null =>15 sized array
 createSafeString(dataFrame1, 14);
 createSafeString(dataFrame2, 14);
 createSafeString(dataFrame3, 14);
 createSafeString(dataFrame4, 14);
 createSafeString(dataFrame5, 14);
 createSafeString(dataFrame6, 14);
 createSafeString(dataFrame7, 14);
 createSafeString(dataFrame8, 14);

// 

void setup() {
  // put your setup code here, to run once:
Serial.begin(9600); 
}
void clearData() {
                    dataFrame0.clear();
                    dataFrame1.clear();
                    dataFrame2.clear();
                    dataFrame3.clear();
                    dataFrame4.clear();
                    dataFrame5.clear();
                    dataFrame6.clear();
                    dataFrame7.clear();
                    dataFrame8.clear();

}

void addToFrame(int frame, char c) {
    switch(frame) {
        case 0:
            dataFrame0 += c;
            break;
        case 1:
            dataFrame1 += c;
            break;
        case 2:
            dataFrame2 += c;
            break;
        case 3:
            dataFrame3 += c;
            break;
        case 4:
            dataFrame4 += c;
            break;
        case 5:
            dataFrame5 += c;
            break;
        case 6:
            dataFrame6 += c;
            break;
        case 7:
            dataFrame7 += c;
            break;
        case 8:
            dataFrame8 += c;
            break;
    }
}

void frameSubstr(SafeString& frame, int m, int n, SafeString& subStr) {
    frame.substring(subStr,m,n);   // SafeString substring is inclusive m to n
}

//CONVERTITORE DA HEX TO INT
 int convertToInt(SafeString& dataFrame, size_t m, size_t n) {   
  // define a local SafeString on the stack for this method
    createSafeString(hexSubString, 14);  // allow for taking entire frame as a substring 
    frameSubstr(dataFrame, m, n, hexSubString);
    return (int)strtol(hexSubString.c_str(), NULL, 16);
 }

//ACQUISITORE FRASI OBD 
 void parse(char *raw) {
    int frame = -1;

    int len = strlen(raw);

    for(int i=0; i<len; i++) {

        if(raw[i+1] == ':') { //start frame
            frame = (int) raw[i] - '0';
            continue;
        }

        if(raw[i] == ':') {
            continue;
        }

        if(frame == -1) {
            continue;
        }

        if(raw[i] == '>') {
            frame = -1;
            continue;
        }

        addToFrame(frame, raw[i]);
    }

 }

//

void read_rawdata(){
                       // move data from OBD to Rawdata array
                       char rawData[myELM327.recBytes];
                       int n = 0;

                       Serial.print("Payload received: ");

                       for (int i=0; i<myELM327.recBytes; i++) {
                                                                  rawData[n++] = myELM327.payload[i];  
                                                                  Serial.print(myELM327.payload[i]); // Serial print OBD Rawdata
                                                               }
                       Serial.println(); 

                       parse(rawData);  // parse data received from OBD

  }

//

// loop 
void loop(){
             // insert timer/delay (ex. 1sec)

             myELM327.sendCommand("AT SH DA10F1");       // Set Header BMS 

             if (myELM327.queryPID("2218E4")) {      // intasamento dpf 
 /*- DPF clogging:
 -> PID = 2218E4
 -> equation = ((A*256)+B)*(1000/65535)
 -> OBD Header = DA10F1*/

                           read_rawdata(); 
                           //BATTv = ((convertToInt(dataFrame2, 4, 5)<<8) + convertToInt(dataFrame2, 6, 7))/10;
                           int A=convertToInt(dataFrame2, 4, 5);
                           int B=convertToInt(dataFrame2, 6, 7);
                           BATTv =((A*256)+B)*(1000/65535);
                           Serial.print("intasamento: ");
                           Serial.println(BATTv);
                           Serial.print(" % ");
                           delay(1000);
                           clearData();
                        }                                                                                   
    }        
jimwhitelaw commented 10 months ago

The loop above is not using the library correctly, it should be like this:

void loop()
{
  myELM327.queryPID("2218E4");
  if (myELM327.nb_rx_state == ELM_SUCCESS)
  {
    read_rawdata(); 
    //BATTv = ((convertToInt(dataFrame2, 4, 5)<<8) + convertToInt(dataFrame2, 6, 7))/10;
    int A=convertToInt(dataFrame2, 4, 5);
    int B=convertToInt(dataFrame2, 6, 7);
    BATTv =((A*256)+B)*(1000/65535);
    Serial.print("intasamento: ");
    Serial.println(BATTv);
    Serial.print(" % ");
    delay(1000);
    clearData();
  }
  else if (myELM327.nb_rx_state != ELM_GETTING_MSG)
  {
    myELM327.printError();
  }
}

And this code should go into setup():

myELM327.sendCommand("AT SH DA10F1");       // Set Header BMS 
Ciullox commented 10 months ago

thanks for the advice, I updated as you said and after sending the command in the setup I put a Serial.print but nothing is printed in the serial monitor, in my opinion it stops in that function

jimwhitelaw commented 10 months ago

OK, I didn't look closely at that code before, but I don't see anywhere that myELM327.begin() is called. It should probably be in the setup() method. Can you link to the original code?

Ciullox commented 10 months ago

what I wrote is exactly the same as the original, I just changed the pids and the header pids giulia.zip

jimwhitelaw commented 10 months ago

Hmm, I can't see how that could have ever worked.... Try adding this code in setup() before the sendCommand() instruction:

if (!myELM327.begin(mySerial, true))
  {
    Serial.println(F("Couldn't connect to OBD scanner - Phase 2"));
    while (1)
      ;
  }

Also, have you verified that the pin numbers specified for mySerial() are correct for your hardware?

Ciullox commented 9 months ago

I added this line of code but the program stops at that if you made me add and I don't understand why. the OBD I use has a reception LED that lights up when it receives a command and lights up when I ask for the pin, however in the doubt it gives me the sending message and then clears the buffer without even entering the if that confirms reception

Ciullox commented 9 months ago

I saw that someone solved the querypids infinite click bug with processpid so is this correct?

myELM327.processPID("ATSH DA10F1","2218E4",8);

why does it give this error Compilation error: no matching function for call to 'ELM327::processPID(const char [12], const char [7], int)'

PowerBroker2 commented 9 months ago

You can't submit commands using processPID(), only real PID queries. For this, you need the service, pid, and other pieces of context data:

https://github.com/PowerBroker2/ELMduino/blob/35760840152b29106b599b036648280fff49c288/src/ELMduino.h#L321

You can use these functions to send commands:

https://github.com/PowerBroker2/ELMduino/blob/35760840152b29106b599b036648280fff49c288/src/ELMduino.h#L322-L323

Evgeniy-18 commented 8 months ago

And this code should go into setup(): myELM327.sendCommand("AT SH DA10F1"); // Set Header BMS

Hello. How to include headers in a loop (myELM327.sendCommand)