Quantcast
Channel: Wardy's Projects
Viewing all articles
Browse latest Browse all 70

Adafruit Neopixel Ring - example assembly source code for Atmel ATTiny85

$
0
0
http://www.adafruit.com/products/1463

These new NeoPixel rings from adafruit are really very good.  A little strange to operate perhaps (they are like a shift register but they shift by re-transmitting downstream.  Or to put it another way you would send the pixels as if they were drawn out on a TV screen (which is not the way a shift register works if you think about it).

Initially, I wrote some PASM code for a Parallax Propeller (P8X32A) chip to make some interesting colour patterns appear on the ring.  This was quite easy with the aid of a Saleae Logic probe.

But the problem with the Propeller is that it's a very expensive chip and is COMPLETE overkill for making some fancy patterns on a bunch of LEDs.  No, instead I wanted to use a smaller chip to run the LEDs from.

Enter the ATTiny85 [PDF].

Long story short, I've written an very simple ATTiny85 demo assembly code program for showing a pattern on the NeoPixel Ring.  It shows a stationary pattern of 5 reds, 5 greens, and 5 blues, all of increasing brightness, and a single white LED showing an equal mix of the three colours.

Here's a pic of the code in action...

Please forgive the brightness of the LEDs in the picture.  In reality they are in fact displayed at a deliberately low intensity, because the LEDs themselves are very bright indeed when forced to maximum brightness.

The code shown below was written for the ATTiny85 and was compiled using Atmel Studio (version 6.1.2562) and I used a AVRISP MkII programmer device to install the software into the chip using the 6-pin programming connector.

VITAL INFO: You'll need to get the fuses right for this, I've highlighted the important bits...

SOURCE CODE Here's the (public domain) code: ring.asm

Load up Atmel Studio and start a new Assembly language project and select the ATTiny85 as your target chip.  Then replace the default assembly program with the code I have given here.

Hit F7 and it should hopefully compile without any errors.  Then open the programming menu and configure the Fuse options as you see above.  Then once you've set the fuses properly click the "Program" button to send the new fuse config to the chip.  Next click the "Memories" option from the list on the left side of the dialog and then program your chip with the "*.hex" file that was created.  You might have to use the "..." button next to the filename dropdown box in order to find the hex file.

All being well you should be able to hit the "Program" button on the Memories tab and the chip attached to your AVRISP MKII programmmer will now contain the firmware to generate the NeoPixel ring test pattern.

Connecting the ATTiny85 to the NeoPixel Ring:
  • ATTiny Pin 8 goes to 5Volts
  • ATTiny Pin 4 goes to GND
  • ATTiny Pin 5 (PB0) goes to the "Data IN" pin on the NeoPixel ring.  Also power the ring from 5V and the same GND rail.



If you have any problems, please let me know and I'll try to fix my hastily written instructions ASAP. :)


I hope this helps some of you wanting a fast and simple intro to using ATtiny85s to drive the Neopixels without having to rely on some awful heap of crummy arduino imitation libraries to get the job done.

IMPORTANT NOTE:

Please note that the WS2812 datasheet is WRONG!!! Please use the Adafruit timings table instead, my code uses the adafruit timings and they do work well...
Load this page and scroll down to the "Writing Your Own Library" section and notice the differences in the timings table.  This is important!



Good luck and happy hacking. :)






Afterthoughts:
You might find that other fuse settings work for you, the important thing to know is that the code I have provided is designed to work with an internally generated 16MHz system clock.  If you want to you can always just use an external 16MHz clock and choose your own fuses as you wish.  The code itself just deals with shovelling bits around.  The only time-sensitive part of the assembly code given here is the sub-routine labelled "send8bits". In fact you might want to simply convert the "send8bits" function into an Interrupt Service Routine and let it run every 60Hz or so. That would let the rest of your code run without any particular timing limitations - at a leisurely pace if you will :)











Viewing all articles
Browse latest Browse all 70

Trending Articles