Hello, I am working on a project where I am grabbing CAN Bus data from an ECU. I am using an Arduino and a CAN Bus shield, to which I am grabbing the 2 pieces of data I need from the CAN Bus and then sending it over serial to Processing.
The two pieces of data I am grabbing are an CAN Address and the CAN Message. These are sent together, with my format (which I can easily change) in [Address]|[Message]#
i.e.
169|19 44 39 28 53 50#
122|63 10 28 16 87 56#
188|126 92 45 44 50 58#
The two symbols are to break the address and message and provide myself location points so that I could (hopefully), look at the serial data between those delimiters and easily grab the address or the message. Those symbols can be placed wherever in the string relative to the messages or the addresses, so changing the delimiters is a really easy fix that I assume I will have to do first.
My end goal is to be able to have a list of addresses, and next to each address is their most recent CAN Bus message. My challenge is that I don’t know how to read a segment of the Serial data stream and save that segment to a variable.
Hopeful end result is that I could have a string of numbers (and symbols)
1234#5678910|1234#5678910
And then be able to grab either 1234 or 5678910 and save that to a variable.
I’m not very experienced with Processing, but I have been on the official webpage, reading all about Serial and the related functions, but I just can’t piece together how I would achieve this.
EDIT: I have found out the answer to the question that I was asking, so I am editing the original post to update it with what I learned.
- Reading off serial can happen in a few ways, but you need to be sure of what type your data being transmitted is, otherwise you will run into error messages.
- String and String[] are not the same thing. The brackets (as far a I have determined) are for an array form of the datatype. Often times, it is as easy to fix as just adding brackets to the end of the datatype designation. I’ve run into this error often in working with strings from serial.
- When you can, don’t use strings. bytes or character arrays are way easier to work with, and I discovered that a little too late.
- split() was indeed the answer to getting my serial data divided up into an array. I used split() twice, designating the split tokens as two different characters. It was super simple to get the data broken down. With this, there was some additional things. I nested the split() function within an integer array, so that I had actually usable numbers that I could perform math on, not just strings or character arrays.
- I created a dictionary eventually in order to store data and recall it. It made the process really easy, but there was a definite issue that I still run in to. I am processing serial data into an array, and storing portions of the array to either the key or the value in my library. I need to be sure to sterilize my input heavily, and I still run into issues where I attempt to store data to a portion of an array that doesn’t yet exist, thus getting some array range issues.
The eventual code I developed (portions of it):
import processing.serial.*;
String lines;
String list;
StringDict canBus;
Serial myPort;
void setup(){
size(1080,800);
printArray(Serial.list());
myPort = new Serial(this, Serial.list()[4], 9600);
myPort.clear();
canBus = new StringDict();
String lines = myPort.readStringUntil('\n');
lines = null;
}
void draw(){
while (myPort.available() > 0){
String lines = myPort.readStringUntil('\n');
String[] list = split(lines, ':');
if (lines != null){
canBus.set(list[0], list[1]);
}
}
background(0);
//Full listing of CAN Bus Addresses and their messages
for (int i = 0; i < canBus.keyArray().length; i++){
String addresses = canBus.keyArray()[i];
String fullMessage = canBus.get(addresses);
int[] message = int(split(canBus.get(addresses), ','));
fill(0);
//This is an example of how I used the above code; got addresses, the full messages, and then a specific part
text("Bus " + addresses + " " + fullMessage + " Temperature: " + message[2] * 14.27, 100, 25+18*i);
}