Read continous bitstream and send to Matlab

Hi there,

for project I'm currently working on, I want to read a digital bitstream from a "Blackbox-ECU". The ECU is connected to 8 ultrasonic sensors and a display. I want to analyze the bitstream-communication from the ECU to the display in Matlab to get distance data from the sensors. The bitstream itself is a pattern, which reoccurs every 8 messages:

The messages themselves look like this:

They start with sort of a header with 3 bit-times "LOW" and the rest of the message is then manchester-encoded with a bitrate of 2.5kHz an thus a clockrate of 5kHz.
I connected my Arduino Uno in parallel to the display to read in the bitstream and per USB to send data via serial to Matlab with following code:

void setup() {
  pinMode(7, INPUT);
  Serial.begin(2000000);
}

void loop() {
  Serial.write(digitalRead(7));
}

Matlab then reads it with:

// Create Serial Port Object if not already available
if ~exist('SerPort', 'var')
    SerPort = serialport("COM3", 2000000);
end
while 1
  data = read(SerPort,100000,"uint8");
  plot(data);
end

However, in that case I get many defects in the messages, such as missing "headers" and random voltage changes below the clockrate:

What could be the cause of that? Is there a better way to analyze that kind of continuous datastream?

Any help appreciated.

First I am doubt that the Uno able to send serial messages in 2M baudrate
So I don't think it's a good idea to read and send each value at the same time. Perhaps It is more useful to accumulate at least 8 measurements, encode them in bits and send them in one byte. Or first read the entire pulse train, saving it in the memory buffer and than send it to PC.

And next - rather than just read the pin - it will be better check the level change in the interrupt.

I would do more processing on the Arduino. It looks like each message is about 24 bits. I'd use a 'CHANGE' interrupt and micros() to measure each pulse and decode them to binary. Then send each 24-bit message as an integer.

First, thanks for your suggestions. I can't read the entire pulse train (then buffer and send it), as I'm trying to compare every 8th message to the respective previous one of the last communication cycle and how it changes over time. 2M baudrate was just the maximum Matlab let me do, I don't know the max. the Uno will do and just went with it. I will look into change interrupts and see how far I get tomorrow. I also don't know how good it will work with micros() as I'm not quite sure how constant the bit-lenghts are over time. However, I will look into it.
Cheers

Is that you reading a Manchester encoded bitstream with an odd starting pukse using something that expects regular serial comms formatted input?

If so, I would expect your results to be unsatisfactory.

a7

The actual manchester-decoding is happening way later in Matlab, that bit of code is just to get the current bus level reading to the serial port

OIC, thx.

It might be better to time the reading on the pin, like a typical UART does, and sample at 16x or 4x the expected data rate.

Some software serial schemes get away with even less sampling - as few as once per bit relying on the timing not going off too much over one character. I've done 19.2 kbaud on that basis, maybe the Manchester signal woukd need a bit more sampling.

Timed readings rather than as fast as possible which seems like what you are doing.

Transmit a byte representing 1 or 0 every N us.

The Matlab code knows the samples are every N us, and uses them to recover the original signal with enough fidelity to be decoded.

I have no envelope the back of which upon to do the calculations, but I bet you would need a lower serial data rate.

Just my thoughts from under the umbrella.

a7

Makes sense, maybe that is a way too. The next standardized UART bitrate I can use considering my boys nyquist & shannon opinion would be 19,2kHz bitrate. Last time i tried that though, my signal looked completely messed up. Don't know why, I'll try tomorrow

OK the umbrella gang did this in our heads, so check the maths.

If the edges are coming at 5 kHz, that's 200 us between them (transition), or 400 us (2.5 kHz, no transition) In Manchester encoding.

Timing the edges, and reporting each edge as a single character representing the us time of the pulse or a scaled down lower resolution figure (1/2 or 1/4) woukd require one char every 200 us or a baud rate in excess of only 50000. We routinely use 115200,mbaud, a standard and high speed serial comms rate. No one right here now knows in practice what is actually achieved, it always just works.

The edge timing can be done with micros() or, what is I think equivalent, using a free running timer/counter.

If you recognize the start long pukse, and report that special case with a reserved byte code, then one char of time per edge can directly and minimally inform the receiver of the data stream progress.

The receiver coukd probably bin the edge times and use them directly in a Manchester decoder algorithm.

With reasonable bins, the exact data rate of the original signal could have a fair degree of tolerance around the theological spec.

a7

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.