Beolink active + Beo4 + Arduino to control home lights...

24 replies

I successfully integrated a little arduino micro board in the Beolink case, i use it to decode some IR code from the BEO4 to turn on or off my lights, keeping the rest of the commands compatible with my Beosound 3200.

Is someone is interested to know 'how to', just drop me a message...

 

Hi,

 

this sounds very interesting to me. What type of Arduino board did you use? Is the source code available?

 

Location: Near Munich

My B&O Icons:

Beoremote-Beo4.png Beoremote-Beo4.png
Beosound.png Beosound.png
Beosound-9000.png Beosound-9000.png
Beosound-5.png Beosound-5.png
Beoplay-P2.png Beoplay-P2.png
Beoplay-M3.png Beoplay-M3.png
Beoplay-Earset.png Beoplay-Earset.png
Beogram-400x.png Beogram-400x.png

hello,

this is quit simple for the moment, simply wiring the ir eye pin 7 to the arduino (for test i use an arduino mega 2560, and use the bromate library to decode ir signal.

Next step now, i will disconnect b&o processor from the board, and connect completely the arduino in place, i already know how to handle the i2c lines related to the audio processor and the ir eye I/O.

I keep you informed as soon as i have time to sketch some diagrams and show some code. My arduino is linked to and RGB Led driver module so i control the lights with my beo4 remote control

 

hello,

this is quit simple for the moment, simply wiring the ir eye pin 7 to the arduino (for test i use an arduino mega 2560, and use the bromate library to decode ir signal.

Next step now, i will disconnect b&o processor from the board, and connect completely the arduino in place, i already know how to handle the i2c lines related to the audio processor and the ir eye I/O.

I keep you informed as soon as i have time to sketch some diagrams and show some code. My arduino is linked to and RGB Led driver module so i control the lights with my beo4 remote control

 

read beomote library, not bromate...

ok, i have some code to share, but is it possible to share that on this forum ? how can i do that ?

 

Seems to be a very nice project. What kind of lights do you control and how?

in fact, this is the part of the project that is already working, i have an arduino mega 2560, connected to a little rgb led driver board, a ethernet card, a temperature/pressure jauge and and IR moment detector. This is the basis setup for a home automation system with sound control, light control, temperature/pressure and presence control. This is already working by the remote control of a beo4 remote control. I don't see where i can dowload the code on the forum, so i will send it like messages, you will have to regale the code to have it complete...

 

 

 

in fact, this is the part of the project that is already working, i have an arduino mega 2560, connected to a little rgb led driver board, a ethernet card, a temperature/pressure jauge and and IR moment detector. This is the basis setup for a home automation system with sound control, light control, temperature/pressure and presence control. This is already working by the remote control of a beo4 remote control. I don't see where i can dowload the code on the forum, so i will send it like messages, you will have to regale the code to have it complete...

 

 

 

PART1: Main code

#include <Beomote.h>

#include <Ethernet.h>

#include <Wire.h>

#include <SPI.h>

#include <Adafruit_Sensor.h>

#include <Adafruit_BMP280.h>

#include "RGBdriver.h"

 

//Clocked In RGB LED Strip interface -- 

#define LED_CLK 24  //Led strip driver

#define LED_DIO 26  //Led strip driver

 

//Beoremote IR Code table -------------

#include "BeoRemote_Lookup_Table.h"

 

 

//Declare the RGB LED Driver

RGBdriver LEDDriver(LED_CLK,LED_DIO);

 

 

// assign a MAC address for the Ethernet controller.---

byte mac[] = {

  0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED

};

 

// assign an IP address for the controller: ---

IPAddress ip(192, 168, 123, 101);

 

// Initialize the Ethernet server library

// with the IP address and port

// (port 80 is default for HTTP):

EthernetServer server(80);

 

Adafruit_BMP280 bmp;    //BMP280 I2C connection

 

//For I2C Temperature sensor, I2C line are pin 20:SDA and pin 21:SCL

 

//pin definition

static const int IRBOPin = 22;    //IR Detector Bang&Olufsen

//static const int IRSTDPin = 4;

static const int audioPin = 28;   //Relay command output for audio power on/off

static const int blowerPin = 30;  //Relay command output for blower power on/off 

static const int PIRPin = 6;      //PIR movment detector pin

//status

boolean audioStatus = false;

boolean blowerStatus = false;

int currentLedStripColor = 0;

boolean lightChannelSelect = false;

int PIRCalibrationTime = 30;  //time needed for PIR to calibrate and stabilize

 

//the time when the PIR sensor outputs a low impulse

long unsigned int lowIn;

 

//the amount of milliseconds the PIR sensor has to be low 

//before we assume all motion has stopped

long unsigned int pause = 5000; 

 

boolean lockLow = true;

boolean takeLowTime;  

 

 

 

boolean BTGO = false;      //This is used to toggle a wait for next key for selection of relay to toggle

boolean DOOR = false;      //This is used on remote to wait for a four digit code to toggle alarm ON/OFF

String ALARMCODE = "";     //This variable is used to hold the code ticked in by remotecontrol

 

static const int RELAY_ON = 0;

static const int RELAY_OFF = 1;

static const int ON = 1;

static const int OFF = 0;

 

static const int YellowColor = 1;

static const int RedColor = 2;

static const int BlueColor = 3;

static const int GreenColor = 4;

static const int WhiteColor = 5;

 

float temperature = 0;

float humidity = 0;

float pressure = 0;

 

String URLCommandString = String(100); //string for fetching data from address  //fetch the header part of the URL

String WorkMode;  //Isolate the GET command to see if we are in ALARM mode

 

boolean getAlarm = false;   //false: normal mode   true: alarm mode activated

boolean intrusionDetection = false; //false:no intrusion detected, true: intrusion detected transmitted to central unit

boolean setAlarm = false;  //if set to true, command is send to Central Unit to switch house in alarm mode

 

 

void setup() {

 

  pinMode(IRBOPin,INPUT);

  pinMode(PIRPin,INPUT);

 // pinMode(IRSTDPin,INPUT);

  pinMode(audioPin,OUTPUT);

  pinMode(blowerPin,OUTPUT);

 

 

  getAlarm = false;

  setAlarm = false;

  intrusionDetection = false;

 

  BTGO=false;

  DOOR=false;

 

  LEDDriver.begin();

  LEDDriver.SetColor(0,0,0);

  LEDDriver.end();

 

 

  //at power up, audio relay and blower relay are also shutdown 

  digitalWrite(audioPin,RELAY_OFF);

  digitalWrite(blowerPin,RELAY_OFF);

 

  Serial.begin(9600);

  lightChannelSelect = false;

  currentLedStripColor = 0;

 

  Serial.println(F("BMP280 test"));

 

  if (!bmp.begin()) {  

    Serial.println(F("Could not find a valid BMP280 sensor, check wiring!"));

    while (1);

  }

 

 

 

  //Initialize B&O IR eye

  Beo.initialize(IRBOPin);

 

  //Start the Ethernet connection and the server:

  Ethernet.begin(mac, ip);

  server.begin();

  Serial.print("server is at ");

  Serial.println(Ethernet.localIP());

 

  // give the IR sensor and Ethernet shield time to set up:

  //delay(1000);

 

  //give all the interfaces some time to calibrate

  Serial.print("calibrating sensor & ethernet ");

    for(int i = 0; i < PIRCalibrationTime; i++){

      Serial.print(".");

      delay(300);

      }

    Serial.println(" done");

    Serial.println("SENSOR & ETHERNET ACTIVE");

    delay(50);

 

 

 

 

 

}

 

void loop() {

  checkIREye();

  //checkBMP280();  //only for serial monitoring purpose...

  checkEthernet();

  checkPIRSensor();

 

}

 

void checkPIRSensor() {

  if (getAlarm == true) {

    if(digitalRead(PIRPin) == HIGH){

       if(lockLow){  

         //makes sure we wait for a transition to LOW before any further output is made:

         lockLow = false;            

         intrusionDetection = true;

         }         

         takeLowTime = true;

       }

 

     if(digitalRead(PIRPin) == LOW){       

       if(takeLowTime){

        lowIn = millis();          //save the time of the transition from high to LOW

        takeLowTime = false;       //make sure this is only done at the start of a LOW phase

        }

       //if the sensor is low for more than the given pause, 

       //we assume that no more motion is going to happen

       if(!lockLow && millis() - lowIn > pause){  

           //makes sure this block of code is only executed again after 

           //a new motion sequence has been detected

           lockLow = true;                        

           }

       }

  }

}

 

 

 

 

void checkBMP280() {

 

 

    Serial.print(F("Temperature = "));

    Serial.print(bmp.readTemperature()-5);

    Serial.println(" *C");

 

     Serial.print(F("Pressure = "));

    Serial.print(bmp.readPressure()/100);

    Serial.println(" hPa");

 

    Serial.print(F("Approx altitude = "));

    Serial.print(bmp.readAltitude(1021.60)); // this should be adjusted to your local forcase

    Serial.println(" m");

 

    Serial.println();

 

  //delay(2000);

}

 

 

 

 

void checkIREye() {

  BeoCommand cmd;

  if (Beo.receive(cmd)) {

    //Serial.print(cmd.link, HEX);

    //Serial.print(":");

    //Serial.print(cmd.address, HEX);

    //Serial.print("!");

    //Serial.println(cmd.command, HEX);

    checkRemoteCmd(cmd);

  }

}

 

void checkEthernet() {

 

  // listen for incoming clients

  EthernetClient client = server.available();

  if (client) {

    Serial.println("new client");

    // an http request ends with a blank line

    boolean currentLineIsBlank = true;

    while (client.connected()) {

      if (client.available()) {

        char c = client.read();

 

       //read char by char HTTP request

       if (URLCommandString.length() < 100) {

       //store characters to string 

       URLCommandString = URLCommandString += c; 

       } 

 

        // if you've gotten to the end of the line (received a newline

        // character) and the line is blank, the http request has ended,

        // so you can send a reply

        if (c == '\n' && currentLineIsBlank) {

          // send a standard http response header

          client.println("HTTP/1.1 200 OK");

          client.println("Content-Type: text/html");

          client.println("Connection: close");  // the connection will be closed after completion of the response

          client.println("Refresh: 5");  // refresh the page automatically every 5 sec

          client.println();

          client.println("<!DOCTYPE HTML>");

          client.println("<html>");

          // output the value of each analog input pin

 

          client.print("temperature ");

          client.print(bmp.readTemperature()-5);

          client.print("</br>");

          client.print("pression ");

          client.print(bmp.readPressure()/100);

          client.print("</br>");

          client.print("CURRENT UNIT ALARM MODE: ");

          if (getAlarm == true) {

            client.print("ACTIVE");

          } else {

            client.print("INACTIVE");

          }

          client.print("</br>");

          client.print("CURRENT HOUSE ALARM MODE: ");

          if (setAlarm == true) {

            client.print("ACTIVE");

          } else {

            client.print("INACTIVE");

          }

          client.print("</br>");

 

          client.print("INTRUSION DETECTION: ");

          if (intrusionDetection == true) {

            client.print("INTRUSION DETECTED!");

          } else {

            client.print("NO INTRUSION...");

          }

 

          client.println("</html>");

          break;

        }

        if (c == '\n') {

 

          // you're starting a new line

          currentLineIsBlank = true;

        } else if (c != '\r') {

          // you've gotten a character on the current line

          //Serial.write(c);

          currentLineIsBlank = false;

        }

      }

    }

    // give the web browser time to receive the data

    delay(1);

 

    //Check if we are in ALARM mode...

    WorkMode = URLCommandString.substring(3,10); 

    if(WorkMode.indexOf("/alarm") > 0) {  

      getAlarm = true;

    } else {

      getAlarm = false;

    }

 

    //Check if we are in ALARM RESET mode...

    WorkMode = URLCommandString.substring(3,10); 

    if(WorkMode.indexOf("/reset") > 0) {  

      intrusionDetection = false;

    }

 

    // close the connection:

    client.stop();

    Serial.println("client disconnected");

    URLCommandString="";

  }

}

 

 

 

void toggleLedStripColor(int color) {

  if (currentLedStripColor == color) {

    setLedStripColor(OFF);

    currentLedStripColor = 0;

  } else {

    currentLedStripColor = color;

    setLedStripColor(color);

  }

}

 

void setLedStripColor(int color) {

 

  switch(color) {

 

    case OFF:           LEDDriver.begin();

                        LEDDriver.SetColor(0,0,0);

                        LEDDriver.end();

                        break;

 

    case WhiteColor:    LEDDriver.begin();

                        LEDDriver.SetColor(255,255,255);

                        LEDDriver.end();

                        break;

 

    case YellowColor:   LEDDriver.begin();

                        LEDDriver.SetColor(255,100,20);

                        LEDDriver.end();

                        break;

 

    case RedColor:      LEDDriver.begin();

                        LEDDriver.SetColor(255,0,0);

                        LEDDriver.end();

                        break;

 

    case GreenColor:    LEDDriver.begin();

                        LEDDriver.SetColor(0,255,0);

                        LEDDriver.end();

                        break;

 

    case BlueColor:     LEDDriver.begin();

                        LEDDriver.SetColor(0,0,255);

                        LEDDriver.end();

                        break;

 

    default:            LEDDriver.begin();

                        LEDDriver.SetColor(0,0,0);

                        LEDDriver.end();

                        break;

 

  }

}

 

void composeCode(String code) {

  ALARMCODE = ALARMCODE + code;

  if (ALARMCODE.length() == 4) {

    if (ALARMCODE == "3521") {

      setAlarm = !setAlarm;

 

      if(setAlarm == true) {

        delay(300);

        setLedStripColor(RedColor);

        delay(300);

        setLedStripColor(OFF);

        delay(300);

         setLedStripColor(RedColor);

        delay(300);

        setLedStripColor(OFF);

        delay(300);

      } else {

        delay(300);

        setLedStripColor(GreenColor);

        delay(300);

        setLedStripColor(OFF);

        delay(300);

         setLedStripColor(GreenColor);

        delay(300);

        setLedStripColor(OFF);

        delay(300);

      }

      setLedStripColor(currentLedStripColor);

 

 

 

    }

    ALARMCODE="";

    DOOR=false;

  }

}

 

 

void checkRemoteCmd(BeoCommand cmd ) {

 

  switch (cmd.command) {

 

    case SPEC_RED:            Serial.print("Red LED");

                              if (lightChannelSelect) {

                                toggleLedStripColor(RedColor);

                              }

                              break;

 

    case SPEC_GREEN:          Serial.print("Green LED");

                              if (lightChannelSelect) {

                                toggleLedStripColor(GreenColor);

                              }

                              break;

 

    case SPEC_BLUE:           Serial.print("Blue LED");

                              if (lightChannelSelect) {

                                toggleLedStripColor(BlueColor);

                              }

                              break;

 

    case SPEC_YELLOW:         Serial.print("Orange LED");

                              if (lightChannelSelect) {

                                toggleLedStripColor(YellowColor);

                              }

                              break;

 

    case BEO1_PAD_GO:         Serial.print("Pad GO");

                              BTGO = true;

                              break;

    case BEO4_PAD_GO:         Serial.print("Pad GO");

                              BTGO = true;

                              break;

 

    case NUM_0:               Serial.print("0");

                              if (BTGO) {

                                digitalWrite(audioPin,RELAY_OFF);

                                digitalWrite(blowerPin,RELAY_OFF);

                                audioStatus=false;

                                blowerStatus=false;

                                BTGO=false;

                              }

 

                              if(DOOR) {

                                composeCode("0");

                              }

                              break;

 

    case NUM_1:               Serial.print("1");

                              if (BTGO) {

                                if(audioStatus) {

                                  digitalWrite(audioPin,RELAY_OFF);

                                  audioStatus=false;

                                  BTGO=false;

                                  break;

                                }else {

                                  digitalWrite(audioPin,RELAY_ON);

                                  audioStatus=true;

                                  BTGO=false;

                                  break;

                                }                               

                              }

                              if(DOOR) {

                                composeCode("1");

                              }

                              break;

 

 

    case NUM_2:               Serial.print("2");

                              if (BTGO) {

                                if(blowerStatus) {

                                  digitalWrite(blowerPin,RELAY_OFF);

                                  blowerStatus=false;

                                  BTGO=false;

                                  break;

                                }else {

                                  digitalWrite(blowerPin,RELAY_ON);

                                  blowerStatus=true;

                                  BTGO=false;

                                  break; 

                                }

                              }

                              if(DOOR) {

                                composeCode("2");

                              }

                              break;

 

    case NUM_3:               if(DOOR) {

                                composeCode("3");

                              }

                              break;

 

    case NUM_4:               if(DOOR) {

                                composeCode("4");

                              }

                              break;

 

    case NUM_5:               if(DOOR) {

                                composeCode("5");

                              }

                              break;

 

    case NUM_6:               if(DOOR) {

                                composeCode("6");

                              }

                              break;

 

    case NUM_7:               if(DOOR) {

                                composeCode("7");

                              }

                              break;

 

    case NUM_8:               if(DOOR) {

                                composeCode("8");

                              }

                              break;

 

    case NUM_9:               if(DOOR) {

                                composeCode("9");

                              }

                              break;

 

 

 

    case CMD_LIGHT:           Serial.print("LIGHTCHANNELSELECT TOGGLE:");

                              lightChannelSelect = true;

                              if (currentLedStripColor == 0) {

                                setLedStripColor(WhiteColor);

                                currentLedStripColor = WhiteColor;

                              } else {

                                toggleLedStripColor(currentLedStripColor);

                              }

                              break;

 

    case ACT_MENU:            DOOR=!DOOR;  //just toggle the DOOR boolean on /off

                              ALARMCODE="";

                              Serial.print("DOOR: " + DOOR);

                              break;

 

    case CMD_TV:              lightChannelSelect = false;

                              break;

 

    case CMD_RADIO:           lightChannelSelect = false;

                              break;

 

    case CMD_CD:              lightChannelSelect = false;

                              break;

 

    case CMD_DVD:             lightChannelSelect = false;

                              break;

 

    case CMD_SAT:             lightChannelSelect = false;

                              break;

 

    case CMD_VTAPE:           lightChannelSelect = false;

                              break;

 

    case CMD_MYVIDEO:         lightChannelSelect = false;

                              break;

 

    case CMD_MYPC:            lightChannelSelect = false;

                              break;

 

    case CMD_MYMUSIC:         lightChannelSelect = false;

                              break;

 

    case CMD_TEXT:            lightChannelSelect = false;

                              break;

 

    case CMD_AUX:             lightChannelSelect = false;

                              break;

 

    case CMD_NETRADIO:        lightChannelSelect = false;

                              break;

 

    case CMD_NMUSIC:          lightChannelSelect = false;

                              break;

 

    case CMD_CINEMA:          lightChannelSelect = false;

                              break;                          

  }

 

}

 

 

or
BeoWorld Gold Membership card
Join BeoWorld

Register to access the forums, reference material, and exclusive member benefits — including our monthly prize draw.

Become a Member

December 2026 Prize Draw

Gold Members Only

As a Gold member you're automatically entered into our exclusive prize draw — your chance to win iconic Bang & Olufsen products. A unique benefit of BeoWorld Gold membership, every draw brings a new opportunity to win something special.