interfaceing sensor that sends a 26 bit data frame

Hi all,

I am trying to read and manipulate data coming from a moisture/temperature sensor on a piece of grain drying equipment. When I look at the data coming from the sensor with a logic analyzer, I see 26 bit bursts of data as shown in the screen shot below-

The top signal is a data request signal coming from the dryer controller. The bottom signal is the reply from the moisture sensor.

Looking at the reply closer, you can see that the smallest bit width is about 109uS. If I divide this into the total length of the replies I get 26 bits.

Here are a few of the captured frames-

10100000001110011111100111
10100000010110110100101101
10100000011001110010101101

I started out using the cursors on the logic analyzer to identify every bit in the frame, but this is very tedious. Looking over the Atmel data sheet it appears that I will not be able to use the UART because this data does not fit a standard 5,6,7,8, or 9 bit frame length.

What would be the best way to capture this data with an Arduino?

Thanks in advance!

How do you identify the start and end of the data frame?

It should not be too difficult to write some code that works like regular serial detection code but which expects more bits. The code in Yet Another Software Serial might give you some ideas.

Note, however, that regular serial data relies on strict timing between the data bits.

...R

The serial standard is what ever the equipment was designed for. The usual is one start bit, 8 data bits and one or two stop bits. That is 10 or 11 total protocol bits. IF you measure the transmit pin with a volt meter when noting is being sent, you will see the quiescent voltage. When that changes, it will be the beginning of the "start bit". What is the quiescent voltage?

Paul

Jeepers peepers people, it's not that complicated.

1 / 9600 bits per second is 104.17us. Three 9 bit words of 8 data bits, 1 stop and no parity adds ups to 27 bits. I think you'll find that to be what you've got there, not some super wacky, non-standard custom device.

avr_fred:
Jeepers peepers people, it's not that complicated.

1 / 9600 bits per second is 104.17us. Three 9 bit words of 8 data bits, 1 stop and no parity adds ups to 27 bits. I think you'll find that to be what you've got there, not some super wacky, non-standard custom device.

Fred, there HAS to be a start bit to begin the clock sync. Always = zero. Then possible 7 bits of data.

Paul

The top signal is a data request signal coming from the dryer controller. The bottom signal is the reply from the moisture sensor.

Note the two traces are inverted from each other. Is the data being sent back as an RS232 signal, if so it needs level shifting and inverting before you can read it on an Arduino.

Those curser measurements are not one cycle but one and a half cycles. To measure one cycle always measure from one rising edge to the next, or one falling edge to the next.

Thanks for the replies everyone. I will try and answer all the questions that were raised.

Robin2:
How do you identify the start and end of the data frame?

There is a start and stop bit. If you look at the second screen shot, the first and the last pulse shown are the start and stop bits (from what I can tell).

Paul_KD7HB:
IF you measure the transmit pin with a volt meter when noting is being sent, you will see the quiescent voltage. When that changes, it will be the beginning of the "start bit". What is the quiescent voltage?

Paul

When I measure voltage on the sensor reply line at idle, I get 0 volts, when a bit is being sent it is at 5 volts.

Grumpy_Mike:
Note the two traces are inverted from each other. Is the data being sent back as an RS232 signal, if so it needs level shifting and inverting before you can read it on an Arduino.

Those curser measurements are not one cycle but one and a half cycles. To measure one cycle always measure from one rising edge to the next, or one falling edge to the next.

The signal is not RS232 or RS485, it is TTL levels. I should have been more clear on the traces shown on the screen shot. The top trace is showing a different line than the sensor transmit line. It is showing an input to the sensor that acts as a request for the sensor to send a reply frame. I am zoomed way out on the first screen shot. So you can see that there is a request made by the controller (made by a pulse that lasts for about 7uS), then the sensor sends a reply frame (shown by the bottom trace). There are three requests in a group, the sensor replies to these requests at different speeds. The first two requests take a fair amount longer to reply to than the third one.

Yes, the cursors on the second screen shot actually have three bits between them. You may not be able to read it, but in the bottom right of the screen the time between the three bits is 325uS. I did this because the first bit on this frame measured a little less than most. This gives a bit width of about 108.3uS. But if I measure the full length of many frames, I get an average total length of 2.846mS. Dividing this by 26 (I have looked at enough frames to know with certainty that there are 26 bits) I get 109.46uS.

I believe it is a non standard type of frame because there is never consistently bits on in the same place except at the beginning and end of the 26 bit frame. If I ground out the sensing plate on the sensor, one of the replies will actually go to all zeroes except for the two bits on at the beginning (with one off in between) and one on at the end. Like this-

10100000000000000000000001

I have been able to figure out that the second and third bits have to do with the type of reply (moisture or temperature) and that every frame ends with a one. Also there are always 6 zeros after the start bit and the frame type. That leaves 16 bits for data. I think.

Robin2:
It should not be too difficult to write some code that works like regular serial detection code but which expects more bits. The code in Yet Another Software Serial might give you some ideas.

Note, however, that regular serial data relies on strict timing between the data bits.

...R

Thanks for the link Robin2, I will check it out.

A single 26 bit asynchronous frame length would be pretty unusual - you'd need only a tiny clock speed difference between tx and rx to render the last few bits unreadable.
(Google "receiver margin")

Robin2:
The code in Yet Another Software Serial might give you some ideas.

I looked over the code a little and also saw that there is another software serial library available, AltSoftSerial. I am wondering if I would be best to start new.

Would it be possible to use a pin interrupt to detect a when the pin level changes from idle to signal the start of a frame. Then in the ISR turn off the pin interrupt and set a timer to go off in 1/2 of a bit width of time. When this timer is up then check the line level and record as the first bit in the frame (it should be the start bit). After this set the timer to check the line level every bit width for 25 more times. Read the line level each time.

I have used a pin interrupt before, but not any of the timer settings. I will not be needing any analog input on this project. I understand that timer1 is a sixteen bit timer. Can I use this timer to time in between bits? How would I set it up? With a 16Mhz clock 1/2 of a bit width is about 876 cycles. Will it work to detect 876 cycles the first time and then 1752 cycles there after or is there a better way? If I get off a little the error will accumulate doing it this way. Over the course of twenty six times, could it get large enough to be a problem?

Also would I be able to use digitalRead() or is this going to be to slow? Is there a quicker way to read the status of an input?

I will also need to be able to send out this type of a frame, potentially at the same time that I am receiving one. If timers and interrupts are a limiting factor, I can use a Mega if necessary.

I would appreciate any thoughts or advice on this.

Thank you!

AWOL:
A single 26 bit asynchronous frame length would be pretty unusual - you'd need only a tiny clock speed difference between tx and rx to render the last few bits unreadable.
(Google "receiver margin")

Thanks for the reply AWOL.

Yes I agree, but I cant see how it can be any other way.

Here is a screen shot of the logic analyzer zoomed out to the three replies that I receive from the sensor.

Here is a screen shot zoomed in more on the very right frame which is a temp frame.

And here is zoomed in more yet.

This particular reply is when I took the temperature sensor to below zero degrees. The reply is showing all zeros except for the first two bits that are on (the first one a start bit and the second bit meaning it is the temp frame) and the last bit (being the stop bit).

Now here is the temp frame when the temp on the sensor is above zero.

You can see the same bit pattern at the very beginning and the stop bit at the end but in the data part of the frame more bits are on to show the temp above zero.

The first frame shows 2.846ms in between the cursors and the second shows 2.843ms. If these time periods were multiple frames wouldn't there have to be additional start and stop bits?

Please tell me if I am missing something because it does seem very unusual.

minnfarm:
Would it be possible to use a pin interrupt to detect a when the pin level changes from idle to signal the start of a frame. Then in the ISR turn off the pin interrupt and set a timer to go off in 1/2 of a bit width of time. When this timer is up then check the line level and record as the first bit in the frame (it should be the start bit). After this set the timer to check the line level every bit width for 25 more times. Read the line level each time.

I believe that is what my code does.

...R

Please tell me if I am missing something because it does seem very unusual.

I think you are ignoring the fact that the bottom trace of the original picture is at least upside down.
The normal state of a serial signal is a "Mark", the undriven state of the line. For TTL signals this is a logic 1 but your trace shows this being a logic zero. The top trace is what you expect from a asynchronous serial signal. So at the very least that signal needs inverting, either in hardware or software.

Robin2:
I believe that is what my code does.

…R

Thank you, I will take a closer look at it.

Grumpy_Mike:
I think you are ignoring the fact that the bottom trace of the original picture is at least upside down.
The normal state of a serial signal is a “Mark”, the undriven state of the line. For TTL signals this is a logic 1 but your trace shows this being a logic zero. The top trace is what you expect from a asynchronous serial signal. So at the very least that signal needs inverting, either in hardware or software.

Here is part of the sensor schematic.

I have been connecting the logic analyzer on connector three of the terminal strip. There is about 50 feet of cable connecting this terminal strip and a terminal strip on the dryer controller. There is a 100 ohm pull up resistor on the dryer controller circuit board connected to this line and to 5 VDC. When I measure the voltage on connector three at idle (mark) though it is at 0, so apparently the micro controller output pin on the sensor is high at idle (as you mention is normal) and then it is inverted through the NPN transistor.

I planned on inverting the signal with a NPN transistor, similar to what the Data Request line shows on terminal three on the sensor schematic.

These frames do not appear to be what one would expect from an asynchronous serial signal. After the start bit there are two bits identifying the frame type then it is padded with six zeroes. Following that are sixteen data bits and then a stop bit that is the same logic level as space (not mark).

Thank you for the replies.