Pages: [1]   Go Down
Author Topic: Reading Proprietary Serial Stream  (Read 749 times)
0 Members and 1 Guest are viewing this topic.
Offline Offline
Newbie
*
Karma: 0
Posts: 5
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Hi all, I'm doing a project where I'm reading a serial stream that's proprietary.

The data format is [16 bit header] [4 bits of data] [word0] [word2] ... [word12]
where each word is [start bit] [8 data bits] [2 stop bits]

First question:
I can't directly use the standard serial reader since the data doesn't really fit into a neat 8 bit format, or even consistent stop/start bits. One option is to read in the stream as if it were just 8 bit characters and then parse my data out of it in chunks, but not sure if it's worth the effort. Also, it's a non-standard data rate.. somewhere around 100baud. Will the hardware and/or serial port work reliably with a non-standard baud rate?

Second question:
I don't know the exact baud rate. My initial effort was to oversample the signal and just count the shortest time between a RE and FE. This MOSTLY worked and I was able to pull some data out, but there were random bits thrown in here and there. This means either a) the arduino wasn't nuts on with its 1kHz timing or b) the signal isn't exactly 100 baud. I attached the sketch at the bottom, but I basically just used timer1 to setup my 1kHz signal. Just for future reference, what's the accuracy of reading like this, roughly? Can I safely assume that it's actually reading at 1kHz for purposes like this?

Third question:
I just found the pulseIn() function... This would probably be a much better way to measure the signal for its baud rate, yes? Seems like there would be less phase problems.

If I end up doing my own "serial" reading, does this algorithm make sense?
- I know each packet starts with 16 bits of "1"'s. I would look for this and then the first falling edge (it's the same place every packet) and set the timer to take the first sample after 1/2 the frequency  (and at the actual frequency for the rest of the packet)

It seems like if I didn't have something like this, the signal might drift over time..


here's the code i used for the 1kHz sampling.

The post kinda got kinda long, thanks for reading guys, much appreciated! =)

Code:
const int analogInPin = A0;  // Analog input pin that the potentiometer is attached to

ByteBuffer buffer;

byte sensorValue = 0;        // value read from the pot

void setup() {
  //Setup our buffer
  buffer.init(256);
 
  // TIMER SETUP- the timer interrupt allows preceise timed measurements of the reed switch
  //for mor info about configuration of arduino timers see http://arduino.cc/playground/Code/Timer1
  cli();//stop interrupts

  //set timer1 interrupt at 1kHz
  TCCR1A = 0;// set entire TCCR1A register to 0
  TCCR1B = 0;// same for TCCR1B
  TCNT1  = 0;//initialize counter value to 0;
  // set timer count for 1khz increments
  OCR1A = 1999;// = (16*10^6) / (1000*8) - 1
  // turn on CTC mode
  TCCR1B |= (1 << WGM12);
  // Set CS11 bit for 8 prescaler
  TCCR1B |= (1 << CS11);   
  // enable timer compare interrupt
  TIMSK1 |= (1 << OCIE1A);
 
  sei();//allow interrupts
  //END TIMER SETUP
 
  // initialize serial communications at 9600 bps:
  Serial.begin(115200);
   
}

ISR(TIMER1_COMPA_vect) {//Interrupt at freq of 1kHz to measure reed switch
  // 8 butes is good enough for us
  sensorValue = analogRead(analogInPin) >> 2; //get val of A0
  buffer.put(sensorValue);
}

void loop() {
 
  //Our buffer should be getting filled in the background
  while (buffer.getSize() > 0)
    Serial.write(buffer.get());
}
Logged

Offline Offline
Edison Member
*
Karma: 9
Posts: 1016
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

How on earth did you get a device that transmits that kind of data ?
Can you tell us about the device.

A baudrate of 110 is a standard baudrate.
The 'words' use a standard protocol, with 2 stop bits, no parity.
But a 16 bit header and 4 bits of data without start and stop bit ?
That seems very odd or even impossible. How can a serial communication start without start bit ?
Even many very old equipment use hardware chips for serial communication. If such a chip is used, also a more or less normal serial protocol is used.
Perhaps the 16 bits and 4 bits are two bytes together.

Are the first 16 bits all 1's ?
But an idle line is default high, so how can you detect the 1's ?
Normally the start bit is a '0', and the stop bit is a '1'. The stop bit can be seen as the gap between two bytes.

You could analyse the protocol on your PC: http://wiki.nethome.nu/doku.php/analyzer/start
« Last Edit: February 01, 2013, 10:02:25 am by Krodal » Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 5
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

I didn't realize 110 was standard, I'll have to give that a shot and see if it matches the data. That might get it to fit nicely
The device is an OBD reader from a 1993 car. It's so old its not even OBD-II, it's OBD-1!
Also, thanks for that link to protocol analyzer, it might be useful. I've just been using python scripts and gnuplot =)
Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 5
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Well,I just looked into it a little more and it seems like its running at just shy of 122baud..
There are roughly 8 samples during a high or low phase, which would imply 8ms per bit which implies 125 baud. However, when I graph it with tic marks every 8.2ms, it seems to line up better... so 122 baud?! =X
see attached for plot


* Screen Shot 2013-02-01 at 6.11.00 AM.png (22.63 KB, 725x789 - viewed 28 times.)
Logged

Offline Offline
Edison Member
*
Karma: 9
Posts: 1016
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

I would use 122 baud.
Looking at the picture I guess the timing is (4674-4608.4)/8 = 8.2 and is 122 baud.
Suppose the timing is the magic number of 8.192 ms (2^13), the baudrate would be 122 baud.

Suppose we have a clock of 1MHz, and we would use a divider of 8192, the baudrate would be 122 baud.

Wikipedia about OBD1 : http://en.wikipedia.org/wiki/On-board_diagnostics#OBD-I
It seems that some use 160 baud, but no standard protocol is used for OBD1.
So you have to find the protocol used by your car.
I can find many examples of OBD1 and Arduino, like this one : http://en.wikipedia.org/wiki/OBDuino
That article has also many links.
« Last Edit: February 01, 2013, 10:48:57 am by Krodal » Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 5
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Thanks for the info and links! I'll play around with it a bit more when I get some time!
Logged

Offline Offline
Edison Member
*
Karma: 9
Posts: 1016
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

You replied while I was rewriting my previous post. Please look at it again.
Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 5
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

aw snap, that was awesome, thanks! I never would have thought of doing that.

Glad to know that 122baud has a basis in reality!
Logged

Global Moderator
Offline Offline
Brattain Member
*****
Karma: 495
Posts: 19026
Lua rocks!
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

For such a slow baud rate, an adaptation of SoftwareSerial should work fine. Even just to get the basic idea. At that rate you have heaps of time.
Logged


Pages: [1]   Go Up
Jump to: