Archive for the 'ACRIS' Category

Enabling the NRF24L01+ for ACRIS

Okay, it’s finally time for making a wireless version of ACRIS. I’m damn tired of stringing up CAT-5 cable everywhere.

So, I’m exploring possible wireless communications systems. My first choice is those based on the Nordic NRF24L01+ chip, which operates in the 2.4GHz spectrum. You can get a variety of turn-key modules from DealExtreme with PCB antennas or more powerful on-board amplifiers and external antennas for practically nothing.

I started by buying three PCB-antenna modules so that I could characterize them. Three weeks later, they finally showed up.

Designing a Reasonable Firmware Architecture

The next step was to write a library for ACRIS. Ultimately, the goal is to convert the whole system, bootloader and all, to be fully wireless. Of course, instead of just starting by writing some tests, I decided to redo the entire ACRIS firmware architecture. Originally, I was going to work on a separate branch, but then when I saw that Github doesn’t count non-master commits on your dashboard status, I got angry and merged it all into master. I also wrote a shitload of READMEs to describe what everything does (or rather, should do).

I finally learned how to make Makefiles from scratch instead of just going off of random other ones I found on the internet. I swear I’m going to start using make for everything ever now. But anyways, I wrote a framework for building and programming all projects in the [cci]avr/prj[/cci] directory. The new firmware architecture is described in this README.

Writing the NRF24L01+ Driver

After porting all the existing code to the new architecture, it was time to start writing a driver for the NRF24L01+. The NRF communicates with an MCU over SPI. Unfortunately, the ATmega168 only has one SPI module and I wanted to dedicate it only to the TLC5940 LED drivers since they use a non-standard way of latching the data (it’s possible to work around this and support everything on the one SPI bus but this would generate a lot of extra traffic on a bus I’m trying to keep quiet).

So, I decided to use the USART in SPI mode, as Atmel documents in their datasheet. In this mode, a third pin is used for the clock ([cci]XCK[/cci]) and [cci]TXD[/cci] and [cci]RXD[/cci] are used for [cci]MOSI[/cci] and [cci]MISO[/cci]. I was lucky enough to leave the [cci]XCK[/cci] pin unused in the LED controllers, so I can actually rework all of my existing LED controllers really easily.

At the same time, though, I need to make a device that translates commands from UART or USB to packets for the NRF. This means that I must use the USART for regular serial communication and SPI to communicate with the NRF.

So, I wrote a communication layer: a common set of commands for sending and receiving bytes and streams of data. The underlying driver can be selected as either SPI or USART depending on which file is compiled, but the API is the same.

On top of this layer, I wrote the actual driver for the NRF24L01+. Unfortunately, the code so far is pretty rigid. It doesn’t easily handle cases like being able to reconfigure the chip quickly. But it does expose functions for reading and writing registers, flushing buffers, transmitting a packet, set up reception, etc. I still have plenty of work to do on it, such as enabling double-buffering for received payloads, setting up ACK payloads (e.g. for communicating LED controller status information), etc. Maybe I’ll add support for their MultiCeiver architecture (automatic handling of multiple transmitters). Depending on how I intend to use it in the future, I may also modify the SPI architecture to be interrupt/event-based.

After a bunch of debugging, I finally got some test firmware working. Building the project [cci]test-nrf[/cci] with [cci]MODE=tx[/cci] will set the project up to be a transmitter and [cci]MODE=rx[/cci] will set it up as a receiver. When one of each is programmed onto two different boards, they’ll talk to each other and the receiver will spit data out via serial. The result?

The range of the modules is pretty decent. I can reach all the way to the other side of my apartment without any issues. But, the caveat is that the two must be in line-of-sight. Pretty much any wall will completely stop all communication. Now, this is using the 1Mbps data rate with Enhanced ShockBurst enabled. If I disable Enhanced ShockBurst and switch to 250Kbps, I might get better results.

OTOH, I also just bought a few of these modules. They use an external antenna and have onboard amplifiers which boost the gain by a whopping 30dB. So, I’m hoping that I’ll only need one of these and then can use the PCB-antenna modules in all of the lighting controllers for reception. The only possible problem with this is that the receivers may not be able to send back ACKs that the transmitter will hear. In this case, I’ll have to disable Enhanced ShockBurst and come up with some kind of isosynchronous transfer mode where the transmitter won’t care about ACKs. But then I won’t be able to enable auto-retransmission and reprogram the controllers wirelessly, which would really suck.

I’m waiting for some 3.3V LDO regulators to come in from Digikey so that I can rework the LED controllers. Right now, I’m using LM317s with a bunch of trimming resistors to make the supply voltage around 3V3.

ACRISifying an IKEA FADO Light

So we bought this FADO accent light from IKEA and frankly, it’s kind of… well… boring. I thought that maybe I could breathe new life into it by converting it into an ACRIS lighting instrument. For bonus points, I tried to do it in the least destructive way possible. Here’s what I did:

The first step was to rip out the old guts. I used a screwdriver to carefully open the tabs connecting the lightbulb assembly to the base.

Then I pulled out the wires that run through the base and into the lightbulb assembly.

Next, I used a dremel to grind down the side supports on the tabs to make a little shelf. I’m still letting this count as non-destructive because you can still assemble the original parts easily. Okay the assembly is ready to go.

Now came the fun part. Since it’s impossible to differentiate multiple LEDs in the light (I tried — looks like crap), it’s easiest to just solder all of the LED terminals together, and bring 4 wires out through the base.

It started with this:

And ended up like this (ugly, I know):

Then, I modified the controller a bit by wiring 3 pairs of channels together to handle the current from 3 LEDs. I screwed the board into the light base and carefully put the globe on.

The result isn’t half bad:

For hipster points, I took an instavine.

Unfortunately, there’s a few problems. First, I don’t have useful tools so I had to tape the damn thing together. Not good. Second, there’s no heatsink on the LEDs, so I’m not running them at full power. Third, I need to extend the feet on the base out a bit more so that the board is protected. Fourth, if I wanted to take it apart, I’d have to unplug all the LEDs and unscrew the board before I can reach the weird little springloaded thing that keeps the light bulb on the base.

But overall, it actually works quite nicely. I think when I bought them here in the bay area, they were like $15. I might buy some more!

ACRIS 2.0 Firmware

So close and yet so far… Long story short: after assembling everything and fixing a whole host of firmware problems, ACRIS boards are about 0.002″ away from being done. Yup, one of the hole sizes is wrong, but other than that, the boards are perfect!

Buuuuut ignoring that, I’m very happy with the results. Take a look:

So what you have there is, among other things, 12-bit resolution! That’s right; the new firmware finally supports the full 4096 levels of brightness of the LED drivers instead of 256.

The new firmware supports a couple of commands: low res setting (8-bit like before) and high res setting (12-bit). For each of these, there is a subcommand to set either all LEDs on the board to be the same color or each LED separately.

The protocol is not very complicated: [cci]SYNC CMD ARG0 ARG1 … ARGn[/cci]

[cci]SYNC[/cci] is now [cci]0x55[/cci] instead of [cci]0xAA[/cci]. I made this revision backwards compatible by making the command the old [cci]SYNC[/cci] command. That way, as long as you send the new [cci]SYNC[/cci] command before that (which would just get ignored by the old firmware), you can still control both firmwares at the same time. This is probably entirely unnecessary, but whatever. I thought it was cute.

I describe how the commands work in detail in the firmware README.

The high res commands pack 12-bit values into a series of bytes and then those values are unpacked in the firmware. The code is not super fast, but it’s not horrible either. I wish I could do some kind of hashing thing to speed up the unpacking process, but the memory requirements there would be ginormous.

The new command system isn’t the only thing that I added. One common failure mode in the past was that the voltage would sag causing the micro to stop running and then the LED drivers would go full brightness. The problem was that when you plugged the board back in, they would retain that state and it would happen all over again. I thought the fix was to just add a pull-up to the blank pin which is usually just controlled by the micro. This would prevent the pin from floating when the micro was browning out and would therefore shut the drivers off. However after I tested this fix out (BTW I forgot to solder one of the resistor pads down so I was very confused for a while why it wasn’t pulling up at all) the failure changed to just continually resetting the micro followed by a brief draw of high current and voltage sagging.

The problem turned out to be that I completely forgot to clear out the LED driver shift registers BEFORE starting them… just a totally stupid error on my part that’s been since fixed.

After I finished writing this new firmware, I used a little pre-processor magic to handle the hardware differences between the two board revisions. So, making with [cci]BRDREV=1[/cci] makes the project for the first revision and [cci]BRDREV=2[/cci] makes it for the second version. This allows me to have unified firmware.

I want to do a few more things with the firmware. E.g. I want to add some commands that would allow me to read the status of a board back on the bus. The hardware is now all there to do this and it would be good to know when the board is overheating. I could also add firmware-side brightness limiting when overheating occurs. I also need to finish the bootloader at some point — it still lacks a mechanism for verification.

After getting everything running, I finally was able to solve the question that had been bothering me the most: would my board be able to sustain 5.4A, the maximum current for all channels?

For this test, I hooked up separate 5V for the logic and started the LED power voltage out low. I then told the LED controllers to output full brightness and started ramping up the voltage. Small problem: the resistive loss on the wire was sizable as the current draw grew. I had to get up to around 11V output to hit the correct voltage drop for the LEDs on the other side. Things got a little melty but I sustained this for almost a minute before turning it back down as I wasn’t heatsinking the drivers at all. The point is that the board itself could handle that kind of current… I feel like I actually designed something correctly for once. 🙂

Here is a list of the things that the new board revision fixes:

  • screw terminal option for LED outputs
  • if you don’t want to do that, then you can twist and solder the wires to the board securely
  • data direction pins on the RS485 chips have pull-ups on them to prevent multiple devices from trying to drive the bus on system startup
  • blank pin on the LED drivers has a pull-up on it to prevent the drivers from trying to drive the LEDs before the system has started sending data to them
  • power connectors have the right pin ordering
  • power planes reduce noise and can handle the full current rating of the drivers
  • error pins of the tlc are brought back to the micro in order to read thermal errors
  • cleaner routing
  • board fits within iteadstudio’s 10cm x 10cm $35 color soldermask option

I’m planning on doing one minor revision to the board to address these problems:

  • power connector + slot is too small
  • soldermask accidentally applied over the back terminals
  • some silkscreening is illegible

I probably won’t ever order that revision unless I somehow need more LED controllers for something. Maybe an externally-funded project? Hopefully?

ACRIS boards are here!

Take a look:

Overall the quality looks pretty excellent, though there are a few spots that I want to test — I think some vias may have spilled over. Also, it seems like the bottom solder mask was screwed up — the LED connector pads are supposed to go to the board edge.

I’m probably going to put in a big digikey order soon. I will probably go for slightly smaller micros because the program I built only takes about 2.5k of flash. I think I’ll also buy the expensive components on Avnet instead of Digikey because it works out to be cheaper that way, even accounting for shipping. If I were to buy everything on Digikey, it would be about $246 for 10 boards worth of parts. That makes the total per-board cost about $30.

At larger quantities, that price goes down significantly. I think I may finally be closing in on a finished design.

ACRIS 2.0 Ordered

After a lot of re-routing and a bit of resizing, I’ve finished version 2.0 of the ACRIS boards. Hopefully this version will feature things like no more goddamn reworks. I think I’ve fixed everything.

I’ve added a few new features. For example, I brought all the XERR pins of the LED controllers back to the microcontroller so that the micro can perform analysis to see if there are any thermal errors from the chips.

The LED controllers have enough room around them such that it’s possible to put cute little DIP heatsinks on them. Screw terminal banks can be used, or you can just use the provided pads, which extend to the edge of the board, and solder to them.

I’ve also started a new version of the firmware that features improved commands and setting LED values using full 12-bit precision.

ACRIS Boards Rev 2.0 Routed!

I’ve finally redesigned the ACRIS boards… It’s only been like half a year. This new design has a ton of fixes, such as adding a pull-up to the blank signal on the LED drivers to prevent the LEDs from flashing when the power supply starts up. The power subsystem is roughly the same, though I removed the jumper to bypass the voltage regulator (it’s easy to just jumper the regulator instead). All of the ports are on one side, as are the status LEDs.

And, most importantly, there’s now a set of screw terminals on the other side for the LED outputs. This makes wiring LEDs up a lot simpler. I’m also planning to redo the footprint a bit so that they can also be easily used as board edge connectors.

My plan is to make another Myro order fairly soon. Now that my current LED drivers are all up and running in our living room, I want quite a few more for new projects!

ACRIS at the Cambridge Science Festival!

I demoed ACRIS at the Cambridge Science Festival’s Mini Maker Faire. Charles and Shane were also there demoing their spectacular skills.

One of the organizers, Chris Connors, took a few photos. Here’s me:

I got a few ideas from talking to people concerning color temperature adjustment. ACRIS might become a lightbulb replacement one day. 🙂

Ideas for Future ACRIS Firmware

I’m still procrastinating on the work I have to do by Friday, but whatever… I had more ideas for ACRIS. I just can’t seem to shut up about LEDs.

Anywayyyyyyyys… I had some ideas for future versions of the ACRIS board firmware. Right now, you do 0xAA followed by the instrument address followed by 5 (R,G,B) pairs. I want to retain this as a “simple control mode” and then add an “advanced control mode” that would look like 0x55 followed by the control command followed by its arguments.

Ideas for this mode include:

  • baud rate setting: You can set a different baud rate. Then, you need to send it some pre-defined pattern of bytes. If the system doesn’t receive what it expects within some time period, it’ll go back to the old mode (like screen resolution changes)
  • color correction mode: You can specify whether to do brightness/gamma correction. If so, then the system will try to make the input linear with what your eyes see. This requires some math and/or a lookup table.
  • resolution: Switch between 8-bit and 12-bit resolution.

Plus, I think it’s finally time to enable device-based transmission. That is, right now, all data flows one way: from my computer to the lights. However, I allowed for devices to switch to from receive to transmission mode. As long as no more than one device talks at once, then things will be okay. I want to do stuff like have the device tell the host its status if the host asks for it.

Power LED Matrix for ACRIS

I wanted to demo the ACRIS boards at MIT’s annual HKN Project Expo. This is a simple expo run in part by the EECS department at MIT. The idea is to provide a space for EECS students to show off cool stuff they’ve made. There were all sorts of projects: software, vehicles (Jordan showed off Segboard!), tesla coils, and, of course, blindingly-high-power LEDs. 🙂

My goal was to show off the ACRIS boards because I one day want to turn them into kits. But, the only completed lights I had were the wall sconces I made. So, I decided at the last minute to build a big LED matrix using a piece of sheet metal a friend found for me.

How last minute? I started at 2am the day of the expo and finished at about 10am. 8 hours. 20 LEDs (80 pads to solder to including 20 triple-point-to-point connections), 80 wires. Yeah. I’m tired.

But the result was this really derpy LED matrix held together with lots of Gorilla Tape.

It all began with the top of a rack server (at least that’s what I think it was).

I divided it up so that I would have a 5×4 array of LEDs. My original plan was to drill holes in the board and then screw the LEDs down like I usually do. Unfortunately, MITERS was closed by 3am, so 🙁

Next, I set to work modifying my ATX power supply. I added barrel plugs onto some wire and hooked those up to the 5V line on my power supply.

I had already built the rest of my LED controllers. I have a little army of them now. 🙂

Oh crap. Is that the sunrise?

Time to get serious. I started soldering the LEDs together by connecting all of the VCCs together. My plan was to have 4 columns of LEDs with 5 LEDs per column. Each column would be controlled by its own ACRIS LED controller.

Soldering the VCC lines were tricky because it was effectively a triple-point-to-point weld. And I was starting to get frantic.

Next, it was time to solder more wires on. All these wires I needed to connect to the LED board too… Eep what a mess!

All right, that looks a little better. Gorilla Tape to the rescue!

Lots of soldering, continuity testing, etc. later, I wired everything up. By this point, it was like 10:30 and I had literally a few minutes to run over to the expo.

Close call! But it worked beautifully on the first try. By some miracle, even despite the sleep deprivation, I didn’t screw up any of the LED connections. I had written a really quick visualization algorithm to show the power of the LED board. I wanted to add more plugins, but didn’t get a chance to.

I ended up getting second place and winning a little money. ACRIS is a little more funded now. 🙂

I’m really hoping to get back to working on the boards again soon. I have a lot of new ideas I want to test out. My friend Scott is working on a USB-based version.

Music Visualization Framework Started!

Check this out:

I’m using PyAudio to capture data from my sound card. Right now, I’m just using audioop’s RMS feature to make a loudness meter.