[Carloop] Trying to get my electron to publish OBD data

I’m trying to get my Electron to publish OBD data to the Particle console.

Any ideas?

The error message says it clearly: You cannot use a uint32_t or uint8_t* parameter in a place where the functin expects a const char*.

You need to convert message.id and message.data into a string before you can use them in Particle.publish()

I’m very new to C++. Do you know how I can do that?

One way to do that would look like this

  char event[32];
  char data[32] = "";

  snprintf(even, sizeof(event), "%04x", message.id);
  for (int i=0; i < message.len; i++) 
    snprintf(data, sizeof(data), "%s%02x ", data, message.data[i]);

  Particle.publish(event, data, PRIVATE);

Thanks @ScruffR. That did exactly what I was looking for.

In my code above I arbitrarily picked a baud rate of 500,000. The above code sent some data to my Events feed that looks like this

but I’m not sure this is the same baud rate that my car’s bus is running at. Is there a way for an Electron to determine the baud rate? Or do I need to use an oscilloscope or something to figure out the correct baud rate?

I’d leave the final answer to that question to @jvanier but when you get valid CAN data you probably have the correct baudrate and that would also be the way to “search” for the correct baudrate: As long you don’t get valid data you need to try another baudrate :wink:

Typically there are only very few values to check.

Following up with your original response:

Do you know how I could update your code so that I can put both the message ID and data in the Event data, instead of putting the message ID in the Event name and the message data in the Event data? So instead of a feed that looks like:

the Events feed would look something like:


Edit: Figured it out. I changed the code to this

  char char_message[32] = "";

  snprintf(char_message, sizeof(char_message), "%04x", message.id);
  for (int i=0; i < message.len; i++) 
    snprintf(char_message, sizeof(char_message), "%s %02x", char_message, message.data[i]);

  Particle.publish("Received", char_message, PRIVATE);

Hey @ScruffR, I’m trying to move your code into a function, so instead of this:

I’m trying this:

image

but I’m getting this error when when I Verify:

image

Do you know what’s going on and/or how this could be rewritten to work? Can it even be put in a function?

Your function is only returning a single char but Particle.function() expects a const char* or a String.

The second error is caused by the invers problem. char_message is a pointer to the start of the character array but you try to force that into a single char.

To solve the problem (without using String which I try to avoid wherever possible) you could do this

const char* msg2Text(char* msgTxt, size_t len, CANMessage msg) {
  snprintf(msgTxt, len, "%04x:", msg.id);
  for(int i=0; i < msg.len; i++) 
    snprintf(msgTxt, len, "%s %02x", msgTxt, msg.data[i]);
  return msgTxt;
}
...
void loop() {
  char txt[32] = "";
  ...
  Particle.publish("Request sent...", msg2Text(txt, sizeof(txt), message), PRIVATE);
  // or somewhat clearer
  msg2Text(txt, sizeof(txt), message);
  Particle.publish("Request sent...", txt, PRIVATE);
  ...
}

Since you cannot (safely) return the address to a local variable you need a variable known to the calling procedure to catch the data (or use dynamic memory allocation - like String - which brings its own issues).

Thanks, that worked. But first I tried deriving the size in then function instead of passing it the size:

const char* msg2Text(char* msgTxt, CANMessage msg) {
  snprintf(msgTxt, sizeof(msgTxt), "%04x:", msg.id);
  for(int i=0; i < msg.len; i++) 
    snprintf(msgTxt, sizeof(msgTxt), "%s %02x", msgTxt, msg.data[i]);
  return msgTxt;
}

but my feed looked like this

image

What’s happening here?

sizeof(msgTxt) will always be 4 since msgTxt is a pointer to a string not the string itself.

I would not have gone throught the trouble of passing in the length if you could get it from the pointer :wink:
That’s also why other (properly written) C functions that take a pointer to a buffer also require the length to be passed in.

2 Likes