2
\$\begingroup\$

I have a drummachine (Roland TR505, but all of this would be true with any other device) sending a byte 11111000 (Timing Clock MIDI message), 48 times per second, to a MIDI OUT port. It works well.

I'm reading MIDI signal on my electronic device via software with classical serial port reading techniques (at 31500 baud, etc., I totally respected the MIDI standard in my electronic schematic).

[ROLAND TR505]  =====MIDI cable=====> [MY ELECTRONIC DEVICE]

I have a tricky situation:

  1. If I power on my electronic device and I let the serial port reading software start, and then I power the TR505 on, it works : the flow of bits coming to serial port is correctly interpreted. It works perfectly.

  2. If I power the TR505 (i.e. the bits are already flowing to serial port), and then I power on my electronic device, there is a problem : probably my device starts reading serial data in the middle of a byte, i.e. data is wrongly interpreted.

Question: when you connect a device already powered on, already sending data to another device which listens serial port, how to ensure that the listening device won't start in the middle of a byte?

i.e. if the bits flow is:

...0111100001111000011110000...

how will my device know it's byte1=11110000 and not byte1=01111000 ?


Here is the software code in Python:

import serial

ser = serial.Serial('/dev/ttyAMA0', baudrate=38400) # Note: there's a well known hack in /boot/config.txt to make this work at 31500 baud, which is normally not supported on Raspberry; in short baudrate is not the problem

while True:
    data = ord(ser.read(1)) # read a byte
\$\endgroup\$
  • \$\begingroup\$ you dont, this is expected, it can take a while depending on the data mix to get the right number of framing errors to sync onto the stream. \$\endgroup\$ – old_timer May 16 '17 at 20:29
  • \$\begingroup\$ @old_timer Let's imagine my software sees : 0111100001111000011110000111100001111000011110000.... The bytes will be read forever as 01111000 instead of 11110000. It will never change. Do you see what I mean? \$\endgroup\$ – Basj May 16 '17 at 20:34
  • \$\begingroup\$ Does that spec handle the RTS DSR protocols? Or other handshakeing? \$\endgroup\$ – Trevor_G May 16 '17 at 20:36
  • \$\begingroup\$ @Trevor It seems that no (see the table). \$\endgroup\$ – Basj May 16 '17 at 20:38
  • \$\begingroup\$ @Basj yes, that is how uart serial works unfortunately, if/when the pattern changes well then it may sort itself out. If you know this is the only pattern it will send you can re-init the uart until you see the right pattern then there you go. \$\endgroup\$ – old_timer May 16 '17 at 20:43
2
\$\begingroup\$

if the bits flow is:

...0111100001111000011110000...

how will my device know it's byte1=11110000 and not byte1=01111000 ?

That's not the full picture. Each Byte is 'framed' with a Start bit (0) and a Stop bit (1). The UART syncs by looking for the 1 to 0 transition when going from Stop to Start.

Most devices do not send data continuously, and any gap longer than 9 bits should be enough to get into sync. MIDI baud rate is 31250 bps, so if the timing clock is a single Byte repeated 48 times per second there should be a large gap between Bytes. The actual bit flow should look like this:-

...011110000111111111111111111111111...1111111111111111110111100001....
    ^Byte-1^                                              ^Byte-2^
\$\endgroup\$
  • \$\begingroup\$ The last lines helped me much to understand, it is now very clear, thanks! \$\endgroup\$ – Basj May 17 '17 at 8:52
  • \$\begingroup\$ About the problem I encountered, it was probably a small issue in the latest implementation of UART in the RaspberryPi (enable_uart=1, dtoverlay=midi-uart0 in /boot/config.txt) / or maybe small kernel bug. When booting the Raspberry with data already spitting to UART Rx, then it won't synchronize, never. When booting without any incoming data, then everything is fine. \$\endgroup\$ – Basj May 17 '17 at 8:55
3
\$\begingroup\$

Let's consider a continual serial stream coming out of a TxUART into an RxUART. No intervals between bytes and only 1 stop bit. TxUART is already running and mid-byte when RxUART goes ready to receive.

There's a temptation to think that RxUART will never synchronise itself to the transmitted bytes from TxUART. That it will take the next 0 as a start bit and then finish receiving in the middle of the next byte and so on.

In actuality, it synchronises fairly quickly, worst case within a couple of hundred bytes.

RxUART is looking for a start bit...actually a stop bit followed by a start bit, so a falling edge. 9 bits later it needs a stop bit. So it's looking for:

10dddddddd1

If it doesn't find a 1, and it often won't, it's a framing error and that byte will be discarded anyway. It will then search along for the next 10 stop-start bit pattern. So it's 'sliding' along the TxUART serial stream, getting closer to the real start bit every time. Once on a start bit, stop bits are in the right place and it stays sync'd.

For the record, I did the analysis once on a system with an RxUART starting up randomly when a TxUART was already sending continuous incrementing bytes. My guess was that it wouldn't ever sync'. My study quickly showed that the number of incoming incrementing bytes before RxUART syncs' is 2 minimum and 128 maximum. Here, your data is more random but the principles still stand.

\$\endgroup\$
  • \$\begingroup\$ But in your analysis did you ever see the UART receive half a byte? Did the second byte ever not equal the first byte + 1? \$\endgroup\$ – Misunderstood May 17 '17 at 1:56
  • \$\begingroup\$ @Misunderstood, sorry, don't understand your point... \$\endgroup\$ – TonyM May 17 '17 at 6:15
  • \$\begingroup\$ Thanks for your answer @TonyM, but I'm not sure to understand 100% of it. Can you do your explanation with a real example of bit flow like ...011110001111111111...1111111111111111110111100001.... to make it easier to understand (sorry, maybe I'm slow these days :p) \$\endgroup\$ – Basj May 17 '17 at 14:27
  • \$\begingroup\$ Sorry @Basj, the explanation's there but I can't play out lots of examples to demonstrate it :-) It's straightforward enough for you to go over with a text editor in front of you. \$\endgroup\$ – TonyM May 17 '17 at 14:33
1
\$\begingroup\$

UARTs use the falling edge at the start of the start bit to synchronize between sender and receiver. So it is possible to catch a wrong edge.

There are (comparatively) long pauses between the clock messages, so it's unlikely that you will start in the middle of a byte.

But even even you started at the wrong time, you still needed a data 0 bit that is interpreted as the start bit, so the possible 'wrong' values are:

  • 00111111: 3F = data
  • 01111111: 7F = data
  • 11111111: FF = System Reset

(If the receiver does not wait for the line to become low, but actually checks for a falling edge, only 3F is possible.)

The 3F/7F data bytes would be ignored because there is no preceding status byte. The System Reset command is theoretically valid, but most devices ignore it, and it would be harmless as the very first command received.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.