DIY Philips Hue with RS-485

You know Philips Hue:
Movies
Music

And there is already a MediaPortal plugin:
AtmoOrb Video
AtmoOrb - A Hue like mood lamp based on Arduino

My first idea was to make every lamp a ethernet device - but the WizNETs have high power consumption and i would need one port for every lamp on my switch.
The idea is to use RS-485 since it is not a problem to run CAT cable from lamp to lamp.
50 meter cable should be 2 Mbit/s.

The question is if RS-485 is fast enough for 6-8 lamps that are 3-10 meters apart?
Hopefully without visible delay - Philips has a big delay.

See my schematic.

Nobody an idea if RS-485 is fast enough? :(

Yes, you can find RS485 drivers that will do 2 MBits/sec.

http://www.digikey.com/product-search/en/integrated-circuits-ics/interface-drivers-receivers-transceivers/2556324?k=rs485

You will need SPI with SPI clock divisor at 8 for 2 MHz clock to achieve that speed.

The question was more about if 2 Mbit/s is fast enough.

Why SPI and not MAX490?

You should let us “see the schematic” in your post, instead of making us download it. Here’s how.

3473266abcab86f081b6c0792267a80fa097206c.png

SPI and MAX490 are not alternatives; they are two different things. SPI is a communication protocol for 3 or 4 “logical” wires connecting a network of devices. It says nothing about the electrical characteristics of those wires, except that there is a way to send a 0 or 1 from one device to another. If more than two devices are connected, you would need a tri-state connection: 0, 1 or “nothing”.

RS-485 is just an electrical spec; it doesn’t say anything about what data goes over it. You can connect it to a UART (aka TTL-level RS-232), SPI, I2C or a morse-code key. It only says how a pair of wires are used for a tri-state connection.

Note that it takes a pair of wires to communicate from the sender to the receiver, and it is only in one direction. Two senders cannot exist at the same time on the pair of wires. This is called half-duplex communication.

You can take turns, like with a master/slave protocol or other “channel-sharing” technique.

Or you can use two pairs of wires, so that two systems can be connected to each other in a full-duplex configuration. This would be like the Arduino Serial object: the UART uses two pins, RX0 and TX0, to implement full-duplex comms with another module, cross-connected to its TX and RX pins. This does not extend to a network of more than 2 devices.

So when you ask if it’s “fast enough”, there are many factors to consider:

  • Fast enough for what? The time between pressing a button and seeing the change? Seeing all lights change? Depending on the task, visual perception can be between 10ms and 100ms.
  • The Arduino firmware and the way you send a command (i.e., the protocol) are the most important factors to being “fast enough”. If the wire is noisy, you will have to increase the reliability of sending commands by taking longer in some way: error-correcting codes, multiple transmissions, etc.
    The point is that 2Mb/sec is not the criterion. It can be “fast enough” for lots of things.

Cheers,
/dev

I know the difference between SPI, UART, full- and half-duplex.

I wonder why CrossRoads says: “You will need SPI with SPI clock divisor at 8 for 2 MHz clock to achieve that speed.”

I always connected the MAX chips to serial/UART but never thought about speed.
Is MAX <> serial/UART not fast enough to get 2 Mbit/s?

UART can only do 1 Mbit/s due to the way data is captured by timed sampling from the serial data stream, while SPI has a separate clock to let the receiver know when the signal is good (on rising or falling edge of the clock).

See:

20.3.1 Internal Clock Generation – The Baud Rate Generator
 Internal clock generation is used for the asynchronous and the synchronous master modes of operation. The
 description in this section refers to Figure 20-2.
The USART Baud Rate Register (UBRRn) and the down-counter connected to it function as a programmable
 prescaler or baud rate generator. The down-counter, running at system clock (fosc), is loaded with the UBRRn
value each time the counter has counted down to zero or when the UBRRnL Register is written. A clock is
 generated each time the counter reaches zero. This clock is the baud rate generator clock output (=
 fosc/(UBRRn+1)). The Transmitter divides the baud rate generator clock output by 2, 8 or 16 depending on
mode. The baud rate generator output is used directly by the Receiver’s clock and data recovery units.
 However, the recovery units use a state machine that uses 2, 8 or 16 states depending on mode set by the state
 of the UMSELn, U2Xn and DDR_XCKn bits.

Table 20-7 show a baud rate of 2 Mbps and settings to use for a 16 MHz system clock, so it could be doable.

I know the difference between SPI, UART, full- and half-duplex.

We don't know what you do know. And we still don't know the answer to "Fast enough for what?"

Even at a leisurely 9600 baud, 1 byte only takes 1ms to transmit. This is way below visual perception. Even if a command takes 10 bytes, that only takes 10ms. Why do you think you need 2,000,000 baud?

Cheers, /dev

I don't know if i need 2 Mbit/s and i don't know how to figure out how much i need.

But i guess it's allot of data to control hundreds of APA102 or WS2812B that change color every millisecond and need to do it fast?

Why do you think that color should change so much faster than an eye can recognize?

Sorry i have problems converting bits to human biology and i also don't know how much data it is that flows through the cable.

What i know is that the Philips Hue lamps have delay. If UART 1 Mbit/s would be enough, then why is a company like Philips having that problem?

One person reported a 3 second delay. That's a noticeable delay! It could have been caused by internet access times, too. You are doing a direct connection, so nothing (like a router) will be delaying with your transmissions.

I'd still suggest thinking about how you will "notice" a delay. What do you expect to happen, and how will you measure this delay? After you press a button (human speed), do you expect to see all 4 lights change within a fraction of a second? Let's set 100ms as the max delay.

At 9600 baud, you could send 100 characters in that time. Unless your command is really verbose, that should be no problem. If you send a different command to each light (i.e., they each have their own "name", or address), you could send 25 characters to each light.

Or, are you wanting to continuously change the lights' colors? With the above max 100ms response time, you could change the colors at least 10 times per second, at 10Hz.

If your commands are smaller than 25 characters, say 10 characters, then sending individual commands to each light would take 40 characters, or 40ms @ 9600. Then you could change colors at 25Hz. If the lights were blinking on and off, it would be noticeable. Annoying even. But we're talking about changing colors, so if it's a gradual change from one hue to another, 10Hz or 25Hz will probably not be noticeable.

You get to choose the commands. One of your Arduinos send them, the other receives them. It could be as simple as "FF0000," for all lights to turn RED. The comma delimits the RGB "tokens". If you notice weird colors flashing on, you might be getting data errors. Just add a checksum or CRC to detect bad commands and ignore them. Then your command might be "00FF00A9," a grand total of 9 bytes.

By the way, here's how you calculate the time it takes to send a command:

  time (seconds) = bytes * 11 / baud rate

For 9 bytes @ 9600 baud, it takes 0.0103s, or 10.3ms to send. Not very long. At 115200 baud, it only takes 0.00086s, or 860 microseconds, an absolutely imperceptible time!

However, if they're "near" to each other, it's easier to notice that they don't go ON or OFF at exactly the same time. If this is for Disco lighting, you could use a "broadcast" command (to all addresses) to make it happen nearly simultaneously (within 1ms or so).

With only 4 lights, I can't think of a reason that 9600 baud would be too slow. As long as you don't use delay(1000) in your program, you should be fine. :)

Cheers, /dev