Does anyone recognize this data protocol? - Page 1
Forum section: electronics / general

author: arend
author_rank: Newbie
timestamp: October 12, 2018, 09:37:11 am
content: Hello,I am working on modifying a sports-timer, that does nothing else than counting down from 30 to zero when I press start on the remote. However, it should countdown from a different interval.It consists of a controller box, and a huge led matrix. The matrix is connected to the controller using a 4-wired cable.Layout of the wires:Pin 1) VCC (+32 Volts)Pin 2) Data+ (5V)Pin 3) Data- (5V)Pin 4) GNDThe Data- is the inverted signal of Data+. I am dead sure about this, as the microcontroller in the controller spits out this signal and it then goes to a RS485 transceiver.The pins for the "returned" data are not used on this transceiver, so there is no communication back.The problem is, that I need to reprogram a new microcontroller with some software that spits out the correct data protocol. In the attachments are some screen captures of the data lines using my logic analyzer.In this capture, the counter is counting down from 30-25Maybe some useful information:Microcontroller of controllerbox is an Atmel TS87C52X2Microcontroller of led matrix is a PIC16F627A (Yes, it does the multiplexing as well)Photos of internals:Thanks

author: NivagSwerdna
author_rank: Super Contributor
timestamp: October 12, 2018, 09:41:54 am
content: As you have identified...https://en.wikipedia.org/wiki/RS-485Dump the bytes and post the stream

author: arend
author_rank: Newbie
timestamp: October 12, 2018, 09:57:36 am
content: I have already tried this one, but I did not manage to get a sensible decoding.For example, I tried decoding it as 485 with 15200 as BAUD, and this gives no errors. However, I don't see any useful information in this.See attachments for information.

author: AndyC_772
author_rank: Super Contributor
timestamp: October 12, 2018, 10:02:56 am
content: There's no meaningful data there to decode, just a burst of clock cycles every couple of milliseconds.Unless there are some additional data pins that aren't shown, it looks as though you've found a device that's acting as a timing reference only, and which doesn't actually contain the counter.

author: RobK_NL
author_rank: Frequent Contributor
timestamp: October 12, 2018, 10:12:56 am
content: Is there any observable difference in the 'data' between the start and end of that 5 second capture?

author: arend
author_rank: Newbie
timestamp: October 12, 2018, 10:16:49 am
content: @AndyC_772Could be possible, but then I'll need to understand that system instead.When I unplug the cable during countdown (at t=25 seconds), and replug it a couple of seconds later (at t=15 seconds), the matrix immediately shows the correct time again (t=10 seconds). There are litterly no more wires than four, and I am damn sure those other wires are a flat 32V line and a GND line.@RobK_NLMaybe there is, I am currently trying to figure this out using excel and some graphs. But it is hard to see any pattern.

author: mikeselectricstuff
author_rank: Super Contributor
timestamp: October 12, 2018, 10:20:39 am
content: Quote from: arend on October 12, 2018, 09:57:36 amWas 15200 the bit-rate you measured from the capture? - that data should decode as UART data to 0x55 ( or is it AA - can't remember) at the correct baudrate- measure the bit time as accurately as you can and set that as the baudrate for decodingIt may be that there are some other values only sent occasionally.

author: RobK_NL
author_rank: Frequent Contributor
timestamp: October 12, 2018, 10:26:45 am
content: Assuming it is some async protocol and assuming the first transition is a start-bit, I count (at least) 14 bits.

author: mikeselectricstuff
author_rank: Super Contributor
timestamp: October 12, 2018, 10:35:18 am
content: Or it could be strings of zero bytes at a higher baudrate

author: mikeselectricstuff
author_rank: Super Contributor
timestamp: October 12, 2018, 10:37:11 am
content: Might help to look at which pins its going in/out of on the two MCUs.if the PIC is working hard on display muxing, it may be the protocol is something wierd so it needs to take that into account - could it be encoding data as the gap lengths between bursts, for example ?

author: AndyC_772
author_rank: Super Contributor
timestamp: October 12, 2018, 10:38:07 am
content: Can you trigger a scope off the start of the data packet (use holdoff to ensure it's always triggering on the first edge of each one), then use persistence mode to see if the data content ever actually changes?It might also be worth measuring the time interval between consecutive clock bursts. Are they always regular, and the same time apart? Or could that be how the time is encoded? seems like Mike and I may have the same idea!

author: NivagSwerdna
author_rank: Super Contributor
timestamp: October 12, 2018, 10:43:41 am
content: Can we have a photo of both ends for context please? Any clues on make and model of display?The decoded stream of data doesn't seem unreasonable has 30 and 38s... those are numbers... 0 8?

author: arend
author_rank: Newbie
timestamp: October 12, 2018, 11:26:11 am
content: Wow, what an excellent help on this forum!It seems not that the interval changes, I have plotted this in excel and it seems quite consistent.@AndyC_772Thanks for the help, the data seems to change. See the video. (Persistance=Infinite, Holdoff=650uS)@NivagSwerdnaI have updated my first post with photos@GeorgeOfTheJungleThis gives only 0xFE's for all chunks, maybe my inexperience with Manchester makes it fail.For the PICs (for the matrix digits), the data comes in at pin RA1/AN1.

author: mikeselectricstuff
author_rank: Super Contributor
timestamp: October 12, 2018, 11:58:14 am
content: They're probably just encoding bits as time between edges.

author: AndyC_772
author_rank: Super Contributor
timestamp: October 12, 2018, 12:39:40 pm
content: Agreed. I see two bit durations, one long and one short. Definitely not a UART format.The next step for me would be to write some code which times and logs how long between each transition, starting at the first edge after a period of inactivity.I'd be willing to bet that the time intervals would be clustered around two discrete values, +/- some amount of random and quantisation noise. Call one of those intervals "0" and the other "1", and see what the data looks like then.

author: NivagSwerdna
author_rank: Super Contributor
timestamp: October 12, 2018, 01:51:55 pm
content: That has a PWM or more specifically Binary Code Modulation sort of feel to it?

author: RobK_NL
author_rank: Frequent Contributor
timestamp: October 12, 2018, 02:04:27 pm
content: PPM perhaps? Specifically D_PPM, since the duration of the burst varies.http://www.pcbheaven.com/wikipages/Pulse_Position_Modulation/

author: mikeselectricstuff
author_rank: Super Contributor
timestamp: October 12, 2018, 03:20:29 pm
content: This is where a scope with segmented memory is really useful, as you can capture each burst then walk through one at a time to decode manually

author: arend
author_rank: Newbie
timestamp: October 12, 2018, 07:30:25 pm
content: Indeed, now my scope is quite limited in capturing but I have captured the data for a couple of seconds using my USB logic analyzer. (5 seconds data is attached in first post).However, I think I might have something. The tips here gave me something to work with. What I did was writing a script that monitors the interval between each edge, and that performs the following steps:1) Ignore all "long" interval between bursts2) Calculate the average interval, and the standard deviation between all intervals (within the bursts)Now for only the parts that are low (0 Volt):3) For each interval x, apply following formula: (x-mean)/std4) All values >0 are considered as ones, all values <=0 are zeroes5) Since there are eight lower regions per burst, we can make a bytes of all burstsThis gives interesting insights, and there can be seen differences between seconds. For example, the difference between second 20 and 19 are shown below.Please notice they overlap perfectly, except for those bits in the top. This is true for all seconds, as they differ in that spot. For example, second 18 is somewhat "lower" than the others.

author: arend
author_rank: Newbie
timestamp: October 13, 2018, 10:33:45 am
content: Thanks a lot, I have been playing with this Manchester decoding in Salae but I cant get sensible values.Those settings give me at least something, but they all bytes give zero.There are a couple of options I'm thinking about:1) Break the secret, in my previous post I managed to see some differences between the seconds2) Dumping the Atmel firmware (if even possible, probably not) and disassemble the algorithm3) "Recording" the stream from t=30 downto t=0 and put this data stream in its completeness into a mcu. Then, depending on the time set play recording from given positionAt least there are still options.

author: AndyC_772
author_rank: Super Contributor
timestamp: October 13, 2018, 11:29:46 am
content: I'm not sure I really understand how you're doing the time interval analysis, or what the results would mean.In your video clip, it looks to me as though there are really only three discrete time intervals between consecutive edges:- one very long gap, which we're treating as a delimiter between consecutive words- one 'short' and one 'long' interval between consecutive edges within a word. ITry this... set your scope to a faster horizontal time base, so the width of the screen is a little wider than one bit time. Trigger off rising edges, and put the trigger point near the left edge of the screen. Set hold-off to zero, and persistence to infinite. You should see the trigger edge consistently at t=0, and the corresponding falling edge towards the right of the screen.With that set-up, you can see what the bit width really looks like. Where do the falling edges appear on screen? Are they clustered together in one or two places, which might be interpreted as a '1' and a '0', or is there a broad range of bit widths? What happens if you trigger on falling edges instead; is the 'low' time similar?

author: xavier60
author_rank: Super Contributor
timestamp: October 14, 2018, 01:50:39 am
content: It looks like something I did lately for PICs running on internal RC OSC.A long start pulse then each bit is represented by a transition. The value of the bit is represented by the time since the previous transition. Short for 0, long for 1.

author: arend
author_rank: Newbie
timestamp: October 16, 2018, 08:07:48 pm
content: Sorry for my late response, I didnt have time to work on this for the past days.Quote from: AndyC_772 on October 13, 2018, 11:29:46 amQuote from: xavier60 on October 14, 2018, 01:50:39 amI did this. If we call each "peak" and "valley" bits (14 in total) then I see that the interval indeed lays between 30uS and 40uS.What I did manage to do, is to export all edge-transitions (low to high, high to low) of my logic analyzer to a CSV file.Then, using a Python script I can convert those intervals to bits. Those burst are then converted to decimal numbers:t<35uS is 0t>35uS is 1.The cool thing is that there are no intervals that lay between 33-37uS).I paused the counter for each digit, and made 5 second captures of them. Those captures are then converted to an array of decimal numbers.I also made a capture of five seconds when the screen was clear.Now I have an array of decimal valued bursts for each 5 second capture, I can easily find distinct numbers by comparing each array with the "clear screen" capture.Look at this:This results in the following LUT:Code:lut = {"16127": "All clear","16383": "Higher digit clear","16255": "Lower digit alarm","16064": "lower decimal 0","16121": "lower decimal 1","16036": "lower decimal 2","16048": "lower decimal 3","16025": "lower decimal 4","16018": "lower decimal 5","16003": "lower decimal 6","16120": "lower decimal 7","16000": "lower decimal 8","16024": "lower decimal 9","16377": "higher decimal 1x","16292": "higher decimal 2x","16304": "higher decimal 3x"}That is in one word: perfect

author: AndyC_772
author_rank: Super Contributor
timestamp: October 16, 2018, 09:19:56 pm
content: ExcellentYou may struggle to combine "new" and "PLCC" in any meaningful way, but apart from that it sounds like you may be good to go!

author: arend
author_rank: Newbie
timestamp: October 19, 2018, 08:12:32 pm
content: Now I know how to decode, I know how to encode.For now, I made a little circuit with an RS485 transceiver (SN75176) and an Arduino. Just a proof of concept of course, later on I will put this in a state-of-the-art8051 MCU.The code is really dirty, however I do not have any choice.A simple for loop introduces too much delay, so I have to compute all delays before actually running a burst.But here it is, the one and only Naulink encoder:Code:short bit13,bit12 ,bit11 ,bit10 ,bit9 ,bit8,bit7,bit6 ,bit5,bit4,bit3,bit2,bit1,bit0 = 0;short low = 22;short high = 35;unsigned int low_digits[] = {16064, 16121, 16036, 16048, 16025, 16018, 16003, 16120, 16000, 16024};unsigned int high_digits[] = {16383, 16377, 16292, 16304};void set_bits(unsigned int x){bit13 = (x >> 13) & 1 == 1 ? high : low;bit12 = (x >> 12) & 1 == 1 ? high : low;bit11 = (x >> 11) & 1 == 1 ? high : low;bit10 = (x >> 10) & 1 == 1 ? high : low;bit9 = (x >> 9) & 1 == 1 ? high : low;bit8 = (x >> 8) & 1 == 1 ? high : low;bit7 = (x >> 7) & 1 == 1 ? high : low;bit6 = (x >> 6) & 1 == 1 ? high : low;bit5 = (x >> 5) & 1 == 1 ? high : low;bit4 = (x >> 4) & 1 == 1 ? high : low;bit3 = (x >> 3) & 1 == 1 ? high : low;bit2 = (x >> 2) & 1 == 1 ? high : low;bit1 = (x >> 1) & 1 == 1 ? high : low;bit0 = (x >> 0) & 1 == 1 ? high : low;}// the loop function runs over and over again forevervoid send_value(){digitalWrite(outP, HIGH);delay(1);//delayMicroseconds(500);digitalWrite(outP, LOW);delayMicroseconds(50);digitalWrite(outP, HIGH);delayMicroseconds(bit13);digitalWrite(outP, LOW);delayMicroseconds(bit12);digitalWrite(outP, HIGH);delayMicroseconds(bit11);digitalWrite(outP, LOW);delayMicroseconds(bit10);digitalWrite(outP, HIGH);delayMicroseconds(bit9);digitalWrite(outP, LOW);delayMicroseconds(bit8);digitalWrite(outP, HIGH);delayMicroseconds(bit7);digitalWrite(outP, LOW);delayMicroseconds(bit6);digitalWrite(outP, HIGH);delayMicroseconds(bit5);digitalWrite(outP, LOW);delayMicroseconds(bit4);digitalWrite(outP, HIGH);delayMicroseconds(bit3);digitalWrite(outP, LOW);delayMicroseconds(bit2);digitalWrite(outP, HIGH);delayMicroseconds(bit1);digitalWrite(outP, LOW);delayMicroseconds(bit0);digitalWrite(outP, HIGH);}The delays seem a little bit off, but a digitalWrite() call takes about 6 uS as well. On my scope, it is perfectly 30uS and 40uS for respectively 1 and 0.Thanks all a lot for the help, I really appreciate it.

author: mikeselectricstuff
author_rank: Super Contributor
timestamp: October 19, 2018, 09:48:06 pm
content: Quote from: arend on October 19, 2018, 08:12:32 pmUnless the compiler is quite clever, shifting the constant mask will be more efficient than shifting the value as it's done at compile time.i.e. bit13 = ( x & (1<<13)) ? high : low;