Home › Forums › Product Discussion & Questions › BeoMaster › Understanding Datalink 86
Tagged: Datalink, datalink 86, IR codes, MCL, mcl2, smart device
- This topic has 5 replies, 2 voices, and was last updated 3 weeks, 1 day ago by
TK.
-
AuthorPosts
-
3 February 2026 at 18:03 #73175
Storck
BRONZE MemberOk, I need some help understanding the datalink 86 protocol!
I will try and update this post with my findings, so it can work as a reference for future hobbyists!
I want to build a device for Home Assistant so I can take control of my Beomaster 6500. I want to be able to automatically turn it on and off when the TV goes on and off, and use my phone or the TV remote to control the volume etc. Nothing fancy. I’ve read about some similar projects here on the forum, but not exactly what I want.
I’ve hooked up a esp32 to a logic level shifter and wrote some software that sends the data I input, so far so good.
I’ve followed the documentation here: https://www.mikrocontroller.net/attachment/33137/datalink.pdf
Start: 3 bits
In the documentation it says “four pulses”, but in the example diagram (2045-4) I only see three, this is also what the datalink sends out when I use the remote.t1 t1 t5
Format (local/2adresses): 4 bits
This Is a bit of a mystery for me. From the signals I gathered I get 0000 for “short” remote signals, and 0011 for the much longer messages. Is there any documentation about this?Address (to): 5 bits
I suppose this is the device/source you want to control, so “0 0000” for TV, “0 0001” for Radio etc?
Address (from): 5 bits
I haven’t sent this part, from what I read on other posts this isn’t included in the “short” message system.
Data: 8 bits
The actual message, this is pretty well documented as well:
https://github.com/toresbe/datalink/blob/main/datalink86-captures-new.txthttps://github.com/christianlykke9/Beomote/blob/master/Commands.h
for example I get “1010 1100” when pressing standby. “1000 0000” when pressing the “TV” source button.
Stop: 1bit
T4 + tailing pulse.
With this logic a message like this should work.
Start | Format | Address (to) | Data | StopSTX | 0000 | 00000 | 1010 1100 | ETX
I can’t get this code to work, even though it’s the same as I’m receiving when I press the remote.
On the other hand some codes work. This code for example works, and changes the radio to channel 2.STX | 0000 | 00001 | 0000 0010 | ETX
The full/long messages
For a lot of button presses on the remote I get the long message type. These seem to consist of 40 bits, much longer than the datalink 86 documentation I linked above.
Example from Toresbe github:
STX 0011 1011 1100 0001 0100 0000 0000 0010 0000 0000 ETX # Power off
How are these codes structured? Format, Address (to), Address (from), Data? How many bits for each?
From right to left the data seems to be 8bits data, 16 bits display settings (?), 5 bits source(Adress(to)). I cant figure out the first 11 bits, I suppose that the four first is the mysterious “Format”. I read somewhere that 0011 is “Local format”.
Start | Format | ????? | Address(to) | data (display) | data (command) | Stop
STX 0011 | 1011 110 | 1 0010 | 0100 0000 0000 0000 | 0000 0000 ETX # CD
STX 0011 | 1011 110 | 0 0001 | 0100 0000 0000 0000 | 0000 0000 ETX # RADIO
Are you supposed to include all the display data when you send commands? Or is this just used to broadcast information to other units about which track your listening to etc?
Does this have anything to do with the different “Beolink options” you can choose in settings? 1 for same room, 2 for TV in another room, 3-4 for different MCL2 units. Or does this only impact the remote?
All input will be much appreciated.
-
This topic was modified 3 weeks, 3 days ago by
Storck.
4 February 2026 at 07:21 #73190TK
BRONZE MemberSounds like a great project. Datalink ’86 is a very extendable protocol for its time, that is intended to handle multi-component 2-way communications. If all you are looking to accomplish is emulate the function of a Beo4 (sending one-way commands using MCL2 over the Aux port), then you need not worry too much about the various message formats and permutations of MCL2.
A standard Beo4 command is implemented via an MCL2 ‘AAC’ command (Address-To, Address-From, Command) through the MCL network. [EDIT: whoops, no it’s not, but the illustrated command structure will still work. See next post for a clarification] This is accomplished by sending a fixed-length command of 22 bits, and looks as follows:
:STX:00:10:ToADR:FrADR:DATA_CMD:ETX:
In this message, the preceding ’00’ is what you will usually send to start message for what you are doing, and the ’10’ tells the listening component the structure of the message. Namely, that the following message contains a 5-bit destination address, a 5-bit sender address, and an 8-bit single instruction. There are many other message formats and combinations, which allow for messages of different structures and lengths. However, since you are not doing anything overly complicated, you’ll likely only need to use the AAC format of ’10’ and most of your commands will look like this:
:STX:00:10:00001:00001:DATA_CMD:ETX:
This is basically sending an 8-bit command from the “Radio” (00001) to itself “Radio” (00001). DATA_CMD is a number from 0 to 255, and is a singular function, such as “STANDBY” ( 00001100 ) or “UNMUTE” ( 00011100), for example. You can use the already published list of commands, which has many of the most commonly-used ones, to have the 6500 do your bidding.
Here are some commands you will likely need:
:STX:00:10:00001:00001:10000011:ETX: -> Set source to A-Aux (Powers on)
:STX:00:10:00001:00001:00011100:ETX: -> UnMute (needed when sending MCL)
:STX:00:10:00001:00001:00001100:ETX: -> Standby
Some of the data you are looking at from your example from Toresbe is Beomaster OUTPUT – i.e. what the Beomaster is updating the other components on the system on. These longer messages contain things like system volume, track number, RDS data, etc. Once you are ready to start listening for status updates, you can begin to process and act on Beomaster messages as well. I’ll refrain from posting more about that protocol so as not to confuse you. The entire protocol is very rich, and has many quirks. Much of the protocol basics are defined in the TJE 1985 document, but the entire protocol syntax has advanced well beyond that point until its final iteration in the mid 90’s.
Feel free to ask any follow-up questions you may have.
-
This reply was modified 3 weeks, 2 days ago by
TK.
4 February 2026 at 09:28 #73193TK
BRONZE MemberWhoops, I just realized that a Beo4 command is an ‘AC’ command (Address-To, Command), and is formatted like this:
:STX:00:00:ToADR:DATA_CMD:ETX:
Examples of both styles of command —
:STX:00:00:00001:00001100:ETX -> ‘AC’ “Send the Radio a Standby command”
:STX:00:10:00001:00001:00001100:ETX -> ‘AAC’ “Send the Radio from the Radio a Standby command”
Both AC and AAC commands will work for your implementation, and should yield the same result. But there’s no need to complicate matters, so you might as well stick with the slightly simpler ‘AC’ protocol. But since I made the error, now is a good time to point out some of the nuances. An AC command is ’00’, which tells the receiver that a 5-bit address and an 8-bit command follow. if the receiver sees ’10’, it knows to expect a 5-bit address, followed by another 5-bit address, followed by an 8-bit command.
4 February 2026 at 16:30 #73214Storck
BRONZE MemberThank you for taking the time TK. It’s your answers to other forum posts that have helped me to get this far 🙂
I figured out the logic with AC and ACC commands. I only have a stand alone Beosystem, no other linked devices, so the AC commands works plenty. I was able to figure out all commands except turning off the device. The code you provided above works though, thank you. I’m using TV 0x80 as source instead of A.Aux 0x83, but it seems to work the same. This is just because i usually use the “TV” button on the Beolink 1000 that sends 0x80.
I do have a question about the ToADR. The Beomote github I linked to references these adresses:
SOURCE_VIDEO = 0x00,
SOURCE_AUDIO = 0x01,
SOURCE_VIDEOTAPE = 0x05,
SOURCE_ALL = 0x0F,
SOURCE_SPDEMO = 0x1D,
SOURCE_LIGHT = 0x1BThey seem to match better than the code for the selected source (radio, tape, cd etc.). It seems like the commands only works if I use 0x01 (Audio) or 0x0F (All) as ToADR. If I use 0x00 which is referenced as TV by Toresbos github it doesn’t work. Does this matter, or can I just stick with 0x01?
I don’t need to fully understand the OUTPUT data, but I would like my device to be able to read the Volume level and selected Source. I have set up RX functionality in my software, but I don’t know which bits to listen for. Would much appreciate some help 🙂
That way I can add a volume slider that takes the current setting into account instead of having to repeatedly press the “volume up” command. Also, I can set the software not to change to the TV source if I start the tv while playing music from the Beogram or something.
4 February 2026 at 20:16 #73224TK
BRONZE MemberJust an FYI, some of my lexicon and definitions is based on my own MCL code I call BeoBabble, so if the nomenclature doesn’t match what you read elsewhere, then it’s because I made it up, lol. My plan has always been to release it in Github, and it will convert maybe 95% of all MCL2 traffic into english, but I realized that I need to stabilize the output protocol a bit prior to releasing it, if only for pride.
Source:
The “Source” you refer to are the 5-bit component addresses, which I refer to as simply “Address”. So there are 31 of them, plus 1 (‘11111’) for future expansion. They play an important role in 2-way communication, because the code tells the listening ToADR the component-type that the FrADR is. This way, the ToADR can cater a message response based on the FrADR’s capabilities. (This will be important to understand in the next post, which is why I’m discussing it first) Every component B&O made was assigned a unique address type to identify what it was. Further, B&O also foresaw the need to be able to communicate with multiple components with the same address type (for example, 2 CD players on one MCL). This gave rise to the ‘AUC’ command set, where you are required to send a Unit number 0-6 as well as the ToADR:
:STX:S:T:01:ToADR:UNI:DATA_CMD:ETX: -> ‘AUC’ designated by the format ’01’
:STX:00:00:10010:00110101:ETX -> ‘AC’: “Send the CD a ‘Play’ command”
:STX:00:01:10010:000:00110101:ETX -> ‘AUC’: “Send the CD:Unit ‘0’ a ‘Play’ command”
Based on my limited testing, these two calls are essentially equivalent on a single-CD MCL. I have not tried all the permutations of commands, but I suspect based on my limited experience that an ‘AC’ command can be viewed as a shorthand for an ‘AUC’ command where the unit ‘U’ defaults to ‘000’. It’s been a while since I experimented with this, so I may be way off base. This is how I remember it being, though.
-
This reply was modified 3 weeks, 1 day ago by
TK.
4 February 2026 at 21:18 #73225TK
BRONZE MemberGetting volume status:
There are several methods to do this. Indeed, the system will typically send out a MCL2 status message broadcast when the state of the system is changed via either a Beo4 command, or someone hitting a button on the component, or a status update provided to the Beomaster over Datalink ’80 from one of the components. Some examples of these are the bitstreams you see in the Github output you referenced. There is a wide variety of status messages, but the ones I’ve found to be the most useful are the ones that are sent as responses to commands that are sent by an MCP (Master Control Panel), which has a FrADR address of ‘11110’. This makes sense, because the MCP is charged with updating the user of the full system status, so the messages it receives will have the most information on system status.
This is where it’s nice to send commands using the ‘AAC’ format instead of the ‘AC’ format, in order to make the Beomaster believe it is talking to an MCP. I pretty-much only send commands using AAC (which is why I messed up my original post to you, confusing ‘AAC’ with ‘AC’). While AC is effectively sending messages “in the blind”, AAC is the basis for 2-way communication, where an FrADR sends a command, and typically expects a response or confirmation directed specifically to it. Incidentally, If an MCP gets no response in a timely manner, it displays the dreaded “NO CONTACT” message that many of us are familiar with, even if the command was received but not responded to.
Here is an example handshake between an MCP and a BM:
:STX:00:10:00001:11110:01011101:ETX: -> ‘AAC’ Send Radio from MCP: “ShowStatus”
BM responds that it is playing Radio P3 out of 6 programs, volume 20, unmuted, loudness on, stereo, 97.3FM. All of this is encoded in the messages below:
00.1100.11110.0010.0001.0001.0100 -> ‘AND’, 3 nibbles of data
00.1100.11110.0010.0000.0001.0011 -> ‘AND’, 3 nibbles
00.1110.11110.00001.0100.1000.0110.1000.0001.0100 -> ‘AAND’, 5
00.1100.11110.0101.1111.1100.0000.0000.0000.0011 -> ‘AND’, 6
00.1100.11110.0111.0000.0000.1111.1111.1001.0111.0011.0001 -> ‘AND’, 8
Here you can see now digits 3-6 have changed from the more simple ‘AC’ and ‘AAC’ formats. These new messages comprise of ‘AND’ and ‘AAND’ formats, which can vary in length, depending on the ‘N’ (N-count – more on that at a later date). There are now 4 digits instead of 2 that make up the message format. We can also see that the AND format has a single ToADR of ‘MCP’ (11110) , and the other AAND format contains a ToADR and a FrADR. I can go into more detail on all the possible permutations in a bit, but this can serve to help you better understand how you will need to setup your receiver to collect incoming messages. total message lengths will vary based on format and ‘N-count’, as will message structure. Some bit patterns within the message you are looking for will probably be unique, and you can probably just seek those patterns when you are hunting for data. In this case, the volume data you are looking for appears in 2 messages – the very first AND message, and the single AAND message. Looking at the AAND message, if you just parse for “0011101111000001010010” at the start of the message, you’ll likely get what you need for volume. The remaining part of the message: 00.0110.1000.0001.0100 has volume information stored as a number between 0-70, in the last 8 bits. in this example the stored number is ’20’.
Fair warning, this AAND message format is also used to send track count, in which case the message will begin with “0011101111000001010000” *next to last digit is now ‘0’. Also fair warning, it’s been a while since I reviewed this, so I may be totally wrong in my recollection.
-
This topic was modified 3 weeks, 3 days ago by
-
AuthorPosts
- You must be logged in to reply to this topic.