Light controller with arduino

29 replies

BeoLignage wrote:
So the beo library is prepared for both active low and active high signals.

Oh, I wasn't aware of that library. It seems to be implemented with remarkably little code. I didn't think this through, but it may be that the B&O command frame bit encoding is such that the polarity doesn't actually matter for the receiver, if it takes some shortcuts and doesn't care about complete start bit patterns, or something.

Anyway, well done so far! Keep us posted 🙂

[quote user="BeoLignage"]

but there is Mika

tournedos wrote:

BeoLignage wrote:
So the beo library is prepared for both active low and active high signals.

Oh, I wasn't aware of that library. It seems to be implemented with remarkably little code. I didn't think this through, but it may be that the B&O command frame bit encoding is such that the polarity doesn't actually matter for the receiver, if it takes some shortcuts and doesn't care about complete start bit patterns, or something.

Anyway, well done so far! Keep us posted 🙂

Well, the implementation isn't the most robust, and doesn't really handle errors. Also, two-way communication would probably confuse the hell out of it, as that is not considered at all. Anyway, it should work reasonably well as long as you don't push it to do things it can't.

Göran, how are you testing that it's working?
/  Johan

Johan wrote:

Göran, how are you testing that it's working?

/  Johan

It’s actually Goran, but I see why you guessed with dots on the o = ö  😎

Well I consider it as working since I get the right codes on the serial monitor when pressing different buttons. In addition I wrote a small program (sketch on arduino language (see below)) which checks for incoming signals and then compare them to the codes in the commands.h file, e.g if 7 is pressed in Light mode a “light #1 on” signal is sent to the 433MHz transmitter and if the 4 on beo4 is pressed in same mode the same lamp is turned off. And this works. So I haven’t stress tested the code (wouldn’t know how to either) but it seems to me that it works, so far every press on one button gives the same code, and no code is received as from noise.

Still a bit confused as to what the tick really is, I changed from 625 to 125 but 200 works as well. I would expect it to be more sensitive to changes if this is actually the counter that interprets the signal. Will read this link as soon as I press post.

What would you suggest as an alternative to this way of reading IR code, and what is the risk with this non robust way of doing it. Do I risk getting wrong codes or missing incoming or getting false signals… 

 

The code:

#include <Beomote.h>

#include <rf433.h>

 

int irPin = 10;

int clickCount = 0;

bool serialOut = true;

 

void setup() {

  Serial.begin(9600);

 

  Beo.initialize(irPin);

  set_out_pin(2);  // Set pin RF sender is connected to.

 

}

 

void loop() {

  BeoCommand cmd;

 

  if (Beo.receive(cmd)) {  

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

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

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

 

    if (cmd.address == 0x1B && cmd.command == 0x07){

      int light_id = 1;

      int on = 1;

 

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

        send(switches[light_id], on ? ON : OFF);

        delay(80);

      }

      }

    else if (cmd.address == 0x1B && cmd.command == 0x04){

      int light_id = 1;

      int on = 0;

 

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

        send(switches[light_id], on ? ON : OFF);

        delay(80);

      }

      }

  }

}

 

BeoLignage wrote:

It’s actually Goran, but I see why you guessed with dots on the o = ö  😎

Ok, sorry. Apparently I can't read. :-)

BeoLignage wrote:

Well I consider it as working since I get the right codes on the serial monitor when pressing different buttons. In addition I wrote a small program (sketch on arduino language (see below)) which checks for incoming signals and then compare them to the codes in the commands.h file, e.g if 7 is pressed in Light mode a “light #1 on” signal is sent to the 433MHz transmitter and if the 4 on beo4 is pressed in same mode the same lamp is turned off. And this works. So I haven’t stress tested the code (wouldn’t know how to either) but it seems to me that it works, so far every press on one button gives the same code, and no code is received as from noise.

Ok. Sounds sane.

BeoLignage wrote:

Still a bit confused as to what the tick really is, I changed from 625 to 125 but 200 works as well. I would expect it to be more sensitive to changes if this is actually the counter that interprets the signal. Will read this link as soon as I press post.

The lib works by polling the pin at a regular interval. As you surely have figured out the interval is dependent on the expression (F_CPU / 2000000) * TICK. F_CPU is the clock speed of the uC. This is why you had to change the value of TICK (because your clock is different than the lib implementer's). Clearly not a very portable implementation, especially since it doesn't even say what (F_CPU / 2000000) is expected to evaluate to. Anyway, if you have it working you're probably fine. I think as long as you're polling often enough it should work.

BeoLignage wrote:

What would you suggest as an alternative to this way of reading IR code, and what is the risk with this non robust way of doing it. Do I risk getting wrong codes or missing incoming or getting false signals… 

This was more in response to Mika's comment that it was implemented using very little code. The B&O format provides pretty rigid error checking which is described in the technical document, also the format is more complicated than what is supported by the lib (don't use a two-way remote for instance). I didn't say that you will have problems. I'm sure it will work fine. If it doesn't we can discuss how to make it better.
I would use interrupts to trigger upon the pin going low and then keep track of the time between the interrupts.. That way you don't have to poll all the time and waste energy.

Johan wrote:
I would use interrupts to trigger upon the pin going low and then keep track of the time between the interrupts.. That way you don't have to poll all the time and waste energy.

Exactly. But if it works now, do not worry - similarly for the error robustness, if the application is just there to receive button presses by a human, you can just press again if it doesn't go through. The library only seems to be prepared for 17 bit commands which is fine for the basic Beolink 1000 commands, but it won't work for example V.TAPE2 commands or LINK commands, which are longer.

I use interrupts in my own applications. With a bit of trickery, the resolution of the millis() system call is enough to keep track of the pulse intervals (which are 1 to 5 multiples of 3.125 milliseconds), which nicely allows you to not care about the actual CPU clock frequency. The interrupt routine stores the received pulse intervals into a circular buffer and also looks for a stop condition; when received, it sets a global flag so that the main program knows that there's (potentially) a command frame in the buffer. The actual pulse intervals are then decoded by the main program, outside of the interrupt routine.

So this tinkering project was put on hold (for some years :) )

But some time ago I brought it up again and continued the evolution as well. So, since I got so much help here on the forum, I thought I give you some pictures and write some lines on what I did.

Where I left it in 2014, I had a scope including controlling both RF and non-B&O stuff via IR. In the end the IR sending part was from a HW perspective trickier than what I could manage and the Beo IR at 455khz disturbed the ~38khz signal which I never got strong enough. I ended up buying a Lintronic box to fit the need in that room and left the Arduino to rest in a drawer.

Later on, I saw the potential to make a really simple IR to RF converter and got to it again.

Now I skipped the large proprietary B&O receiver and went for a TSOP7000 and also started looking in to using just the Atmega IC instead of an Arduino uno, but still with the Arduino bootloader on it. So now I can control Telldus and Nexa wall socket switches with the Light command on Beo4 and Beolink1000! And that by a pretty little box only 3x5cm in footprint.

link

This is very cool. Did you use a library for the ir decoding or did you code it from the ground up?

 

Hi CheapB,

I only did the high level coding on my own. I used the below librarys for decoding the IR codes.

https://github.com/christianlykke9/Beomote

the 433MHz library for the wall sockets is no longer available but many more exist, so should not be a problem finding one that works with your switches.

 

I also ended up making a custom box for it :)

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.