Generic selectors
Exact matches only
Search in title
Search in content
Post Type Selectors

Home Forums Product Discussion & Questions BeoLab BL3500 and the MCL/PL connector Reply To: BL3500 and the MCL/PL connector

#125214
swo
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-Powerlink
  Minimal 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 frame
  once on GPIO1 – nothing else. No RX, no MK1 support, no other
  commands. Split out of Beolab3500-Standalone’s MclBusWriter (see
  wolfgangschneider/Beolab3500-Standalone ) – only sendInit() is
  needed here, so it’s inlined directly instead of pulling in the
  whole class/enum/MclData hierarchy.
  Per B&O MCL-2 Service Manual (“Datalink ’86”): the transmitting unit
  pulls the bus LOW for a fixed strobe width then releases it; the
  timing symbol (t1..t5) is the FULL period (LOW+HIGH), not the LOW
  width 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 t1
  pulse 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; // Stop
constexpr uint32_t T5_US = 15625; // Start
constexpr 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 low
  delayMicroseconds(STROBE_LOW_US);
  digitalWrite(TX_PIN, LOW);  // transistor off -> bus released, pull-up brings it back high
  delayMicroseconds(period – STROBE_LOW_US);
}
// which timing symbol encodes bit given 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” reference
  pulse(1); // AGC
  pulse(1); // AGC
  pulse(5); // Start
  for (size_t i = 0; INIT_BITS[i] != ‘\0’; i++) {
    int bit = INIT_BITS[i] – ‘0’;
    pulse(encodeBit(lastBit, bit));
    lastBit = bit;
  }
  pulse(4); // Stop
  pulse(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 released
  pinMode(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 high
  wasHigh = nowHigh;
}

 

  • This reply was modified 1 week, 6 days ago by swo.