16 channel PWM Dimmer code

Managed to find some time over the weekend to get some coding done for the dimmer (was called “controller” but I thought this would be confusing in the end so now it is “dimmer”, more theatery).

The Dimmer .ino and library now works and can do:

  • Independently control 16 LED channels of high res (0-4095) PWM
  • Fade multiple channels simultaneously
  • Delay a fade when queued
  • Lock/unlock channel from change
  • Multiple dimmers with security
  • Accept html parameter like serial data

Independently control 16 LED channels

All sixteen channels coming out of the Adafruit PWM driver can be controlled independently. Current value of channel is stored in a struct array (CHANNEL), as well as “locked” value, and is updated every time Dimmer::write is called.

Fade multiple channels simultaneously

Every channel can be faded, on-off changes also are a fade but have a span (fade duration) of 0. To make a channel fade, you call Dimmer::addFade with pin number and target value at minimum to produce a simple on or off change. If you want a fade, add the “span” variable; if you want a delay before the fade starts, add the “delay” variable.

Calling Dimmer::addFade adds the fade to the fade buffer; this is set in the library (currently at 2 but I will ramp this up once I get it working properly with an Arduino Nano and use most of the memory left over) and in an array of FADE struct’s that contains the information necessary for the fade: channel, start value, end value, start time, span and delay. There are other ways to do this of course but I used this way so eventually I can change the fading style from just linear to sine or mapped to LED down light fade profiles.

The fade buffer is run through every Loop (by calling Dimmer::updateFades) and sends the appropriate value to the Adafruit PWM driver until the fade is complete. Then it frees the frame (place in the FADE buffer) but setting channel to -1 for the next fade.

Delay a fade when queued

You can delay a fade from starting, this is good for when you can to fade multiple channels in a sequence but want one fame to finished before the next starts. I have this happening in one room with 5 lighting channels and it looks super cool.

Lock/unlock channel from change

Locking a channel idea came to me because, at the moment at least, there is a stack of inducted interference in the input line (switches). This is for several reasons: I have a temporary power run that is too close to my 12V loom, the power supply is not filtered and the switch setup I have, normally grounded but switch high when pressed, lets noise be interpreted as a “I have been pushed” signal. Anyhoo, because of this, I have some great things happen to my lighting when high inductive loads are used, like the dryer or blender or electric blankets and especially the one fluro tube in the house…all these makes the lighting go crazy. So locking a channel isolates to from being changed, I thought this would be good in the future for keeping a channel off if you are changing a light to something as the switch may no longer be in the room for you to keep an eye on. Also could be good for stopping switches being played with by kids.

Multiple dimmers with security

Each dimmer has its own address (ID) and token password that needs to be sent with the serial string for each fade comment. As I eventually want these dimmers on WiFi, I though some security, even if it is pretty weal, would be better than nothing. I would also like to be able to change these values without having to update code. The address is easy enough as using a DIP switch address setup like DMX will be good, there are plenty of pins left over on the Nano board when you run I2C. Token is a little harder, I have no ideas yet.

Accept html parameter like serial data

My plan here is to eventually hook these dimmers up to a network for the communication back to the main controller. This network could be a serial loop (much like DMX except with more overheads in data), BlueTooth mesh or wi-fi/Ethernet. I have breifly played with getting two Arduinos talking to each other via plain wire and this worked well, especially with the Mega as you can use SoftwareSerial. I then played with some HT-05 and HT06 BlueTooth modules but quickly found that this is not where I want to go with this; it’s just too slow to connect and really limits how many dimmers I can use.

As I want it on Wifi, and I see that people are starting to make very cheap I2C WiFi to serial modules, I went with pretty standard html like parameter string for sending data. Sending:


over serial will:

  • target the dimmer with ID (i) if 1
  • pass the token/password (t) of fg5gpo3D, Arduino will compare with what it has
  • select the pin (p) to change
  • select the action (a) to do (read, write, lock, unlock); in this case write (w)
  • give it the value (v) or 4095 (fully on)
  • and span (s) or fade duration of 1000ms
  • delay (d) the fade by 1000ms before starting

This request (I am calling it “frame”) is then added to the fade buffer for processing. Dimmer 1 will then pickup the request, authenticate the token and fade pin 2 (providing it is not locked) up to 4095 (full) over 1 second after waiting for 1 second…neat hey!

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s