Home › Forums › Product Discussion & Questions › BeoLab › BL3500 and the MCL/PL connector › Reply To: BL3500 and the MCL/PL connector
25 August 2026 at 14:53
#125214
GOLD Member
That could be usefull for some pepople. There have from time to time been questions on the forum on how to use the BL3500 as a center speaker for a TV where that solution could be used
Unfortunately the PL power lines (Pin 1 and Pin 4) don’t provide enough current. However, with an external 5 V supply it becomes feasible.
Of course the code must be adapted — but I streamlined it so it’s now under 100 lines.
/*BeoLab3500_MKII-PowerlinkMinimal trigger board for a Beolab 3500 MKII on the B&O PL bus:hold GPIO5 HIGH and it sends the captured MKII power-on/init frameonce on GPIO1 – nothing else. No RX, no MK1 support, no othercommands. Split out of Beolab3500-Standalone’s MclBusWriter (seewolfgangschneider/Beolab3500-Standalone ) – only sendInit() isneeded here, so it’s inlined directly instead of pulling in thewhole class/enum/MclData hierarchy.Per B&O MCL-2 Service Manual (“Datalink ’86”): the transmitting unitpulls the bus LOW for a fixed strobe width then releases it; thetiming symbol (t1..t5) is the FULL period (LOW+HIGH), not the LOWwidth alone. t1=3.125ms t2=6.250ms t3=9.375ms (data), t4=12.500ms(Stop), t5=15.625ms (Start). MKII traffic has one extra trailing t1pulse after Stop.*/#include <Arduino.h>constexpr gpio_num_t TX_PIN = GPIO_NUM_1;constexpr gpio_num_t TRIGGER_PIN = GPIO_NUM_5;constexpr uint32_t T1_US = 3125;constexpr uint32_t T2_US = 6250;constexpr uint32_t T3_US = 9375;constexpr uint32_t T4_US = 12500; // Stopconstexpr uint32_t T5_US = 15625; // Startconstexpr uint32_t STROBE_LOW_US = 1562;// Captured MKII power-on frame (Command=49, unrecognized/literal –// see Beolab3500-Standalone’s main.cpp file header for context).constexpr const char *INIT_BITS = “0011000111100111111100000000100”;void pulse(uint8_t tcode) {uint32_t period = tcode == 1 ? T1_US : tcode == 2 ? T2_US : tcode == 3 ? T3_US : tcode == 4 ? T4_US : T5_US;digitalWrite(TX_PIN, HIGH); // transistor on -> bus pulled lowdelayMicroseconds(STROBE_LOW_US);digitalWrite(TX_PIN, LOW); // transistor off -> bus released, pull-up brings it back highdelayMicroseconds(period – STROBE_LOW_US);}// which timing symbol encodesbitgiven the previous bit (differential code)uint8_t encodeBit(int lastBit, int bit) {if (lastBit == 0) return bit ? 3 : 2;return bit ? 2 : 1;}void sendInit() {Serial.println(“-> sending init”);int lastBit = 1; // Start acts as an implicit “1” referencepulse(1); // AGCpulse(1); // AGCpulse(5); // Startfor (size_t i = 0; INIT_BITS[i] != ‘\0’; i++) {int bit = INIT_BITS[i] – ‘0’;pulse(encodeBit(lastBit, bit));lastBit = bit;}pulse(4); // Stoppulse(1); // MKII trailing pulse}void setup() {Serial.begin(115200);delay(500);Serial.println(“BeoLab3500_MKII-Powerlink”);pinMode(TX_PIN, OUTPUT);digitalWrite(TX_PIN, LOW); // idle: transistor off, bus releasedpinMode(TRIGGER_PIN, INPUT_PULLDOWN);}void loop() {static bool wasHigh = false;bool nowHigh = digitalRead(TRIGGER_PIN) == HIGH;if (nowHigh && !wasHigh)sendInit(); // edge-triggered – one send per LOW->HIGH transition, not a flood while held highwasHigh = nowHigh;}
-
This reply was modified 1 week, 6 days ago by
swo.