<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>WS2812b &#8211; ABNielsen.com</title>
	<atom:link href="https://abnielsen.com/tag/ws2812b/feed/" rel="self" type="application/rss+xml" />
	<link>https://abnielsen.com</link>
	<description>Anders Braüner Nielsen</description>
	<lastBuildDate>Fri, 24 Dec 2021 04:45:29 +0000</lastBuildDate>
	<language>en-US</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	<generator>https://wordpress.org/?v=6.9.1</generator>
	<item>
		<title>WS2812B RGB lights on a 6502!</title>
		<link>https://abnielsen.com/2021/12/23/ws2812b-rgb-lights-on-a-6502/</link>
					<comments>https://abnielsen.com/2021/12/23/ws2812b-rgb-lights-on-a-6502/#comments</comments>
		
		<dc:creator><![CDATA[Anders]]></dc:creator>
		<pubDate>Thu, 23 Dec 2021 08:19:48 +0000</pubDate>
				<category><![CDATA[Projects]]></category>
		<category><![CDATA[6502]]></category>
		<category><![CDATA[WS2812b]]></category>
		<guid isPermaLink="false">https://abnielsen.com/?p=229</guid>

					<description><![CDATA[The problem with WS2812B&#8217;s on a slow CPU When even the co-author of the FastLED library, Mark Kriegsmann, says it&#8217;s can&#8217;t be done, you know it&#8217;s not going to be [&#8230;]]]></description>
										<content:encoded><![CDATA[
<h2 class="wp-block-heading">The problem with WS2812B&#8217;s on a slow CPU</h2>



<p>When even the co-author of the FastLED library, Mark Kriegsmann, says<a href="https://blog.kriegsman.org/2015/02/16/fastled-for-the-apple-ii/"> it&#8217;s can&#8217;t be done</a>, you know it&#8217;s not going to be easy.  &#8220;The CPU would need to be at least&nbsp;20X faster to support them[WS2811 based LED&#8217;s], and it isn’t. &nbsp;For that you want an Arduino or Teensy[&#8230;]&#8221;, as he puts it. </p>



<p>The WS2812B protocol is very simple. Basically it&#8217;s a binary PWM signal. Said another way: A long high pulse followed by a short low period for a 1 and a short high pulse followed by a long low period for a 0, and just a long period of nothing to latch the data and turn on the LED.  </p>



<div class="wp-block-image"><figure class="aligncenter size-full"><img fetchpriority="high" decoding="async" width="621" height="352" src="https://abnielsen.com/wp-content/uploads/2021/12/image-1.png" alt="" class="wp-image-234" srcset="https://abnielsen.com/wp-content/uploads/2021/12/image-1.png 621w, https://abnielsen.com/wp-content/uploads/2021/12/image-1-300x170.png 300w" sizes="(max-width: 621px) 100vw, 621px" /><figcaption>From the <a href="http://www.world-semi.com/solution/list-4-1.html" data-type="URL" data-id="http://www.world-semi.com/solution/list-4-1.html" target="_blank" rel="noreferrer noopener">WorldSemi datasheet</a>.</figcaption></figure></div>



<p>That looks easy right? Just toggle a pin at the right interval and it works, right? Well &#8211; it is, if you&#8217;ve got a fast enough processor. Looking at the numbers though, there isn&#8217;t enough time to do much toggling when running at 1 or 2Mhz &#8211; let alone varying the periods.</p>



<figure class="wp-block-image size-large"><img decoding="async" width="1024" height="333" src="https://abnielsen.com/wp-content/uploads/2021/12/image-2-1024x333.png" alt="" class="wp-image-235" srcset="https://abnielsen.com/wp-content/uploads/2021/12/image-2-1024x333.png 1024w, https://abnielsen.com/wp-content/uploads/2021/12/image-2-300x98.png 300w, https://abnielsen.com/wp-content/uploads/2021/12/image-2-768x250.png 768w, https://abnielsen.com/wp-content/uploads/2021/12/image-2.png 1086w" sizes="(max-width: 1024px) 100vw, 1024px" /><figcaption>WS2812B timings from the <a href="http://www.world-semi.com/solution/list-4-1.html" target="_blank" rel="noreferrer noopener">WorldSemi datasheet</a>. </figcaption></figure>



<p>At the very &#8220;slowest&#8221; the high+low period must be 1.825 microseconds, or just about 500khz minimum. Maybe it&#8217;s possible to toggle a 6502 pin at 500khz, but it certainly isn&#8217;t possible to squeeze NOP&#8217;s in there to vary the period or do any kind of processing to change colors. So maybe Mark is right and you actually do need a faster processor? </p>



<p>Luckily it turns out, this isn&#8217;t the case. The 6502 is perfectly capable of controlling a string of WS2812B&#8217;s, a.k.a. Neopixels. Just like everything else you might want to interface the 6502 to though &#8212; the RGB LED&#8217;s need a little bit of help. </p>



<p>In this case all we need is a 6522 VIA, which is part of most 6502 computers anyway, a 74hc14 inverter, and a 74hc165 parallel-in serial-out shift register, along with an 8 Mhz clock and some passives. </p>



<p>To be fair, this does mean running the 6502 at 2Mhz(Note: Not 8 Mhz), which would be slightly problematic for the Apple II, but perfectly doable for many or most other 6502 based computers.</p>



<p>As luck would have it, my own <a href="https://youtu.be/y5PQ7kBH29A" target="_blank" rel="noreferrer noopener">6502 single board computer</a> has an 8 Mhz clock output available and is already running happily at 2 Mhz, which takes the hard work out interfacing with the LED&#8217;s &#8211; only two extra IC&#8217;s needed. </p>



<figure class="wp-block-image size-large"><img decoding="async" width="1024" height="683" src="https://abnielsen.com/wp-content/uploads/2021/12/IMG_2675-1024x683.jpeg" alt="" class="wp-image-237" srcset="https://abnielsen.com/wp-content/uploads/2021/12/IMG_2675-1024x683.jpeg 1024w, https://abnielsen.com/wp-content/uploads/2021/12/IMG_2675-300x200.jpeg 300w, https://abnielsen.com/wp-content/uploads/2021/12/IMG_2675-768x512.jpeg 768w, https://abnielsen.com/wp-content/uploads/2021/12/IMG_2675-1536x1024.jpeg 1536w, https://abnielsen.com/wp-content/uploads/2021/12/IMG_2675-2048x1365.jpeg 2048w" sizes="(max-width: 1024px) 100vw, 1024px" /><figcaption>My 6502 Single Board Computer happily driving a strip of WS2812B LED&#8217;s</figcaption></figure>



<p></p>



<h2 class="wp-block-heading">The schematic</h2>



<p> </p>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="1024" height="713" src="https://abnielsen.com/wp-content/uploads/2021/12/image-1024x713.png" alt="" class="wp-image-233" srcset="https://abnielsen.com/wp-content/uploads/2021/12/image-1024x713.png 1024w, https://abnielsen.com/wp-content/uploads/2021/12/image-300x209.png 300w, https://abnielsen.com/wp-content/uploads/2021/12/image-768x535.png 768w, https://abnielsen.com/wp-content/uploads/2021/12/image.png 1293w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /><figcaption>Two IC&#8217;s and a few passive components is all it takes. </figcaption></figure>



<p>The circuit takes a shift clock and serial data from the 6522 shift register. CB1 is the clock and CB2 is the shifted data. CB1 is normally high until it starts clocking out data, which keeps the ~CE(chip enable, active low) pin high through R2. When CB1 goes low the first time, C2 immediately discharges through D1 (I used a 4148) and ~CE is activated. This arrangement keeps the shift register active while data is shifted.</p>



<p>At the same time the signal from CB1 is also fed through the U1A inverter, a simple RC filter, and another inverter, giving the ~PL(load register pin) the short negative pulse needed to latch the data being clocked out from the 6522 shift register. If the pulse is too long, we miss the first bit. </p>



<p>Now we get to where the magic happens &#8211; the serial binary data is converted to WS2812-style PWM data. Since D7 is always high and D0-D4 is always low, this varies the high period of the signal by putting the data on pins D5 and D6.  </p>



<p>The latched data is then clocked out to Q7 at the rate of 8 Mhz, fed to the CP pin and this is then fed directly to the WS2812B data pin. This means the 6522 supplies data at a comfortable rate of 1 Mhz and the 74HC165 shifts out the converted data at 8 Mhz, which means the bit rate is right around 1bit per microsecond. As you can see this is well within the 1.25us+-600ns in the datasheet. </p>



<p>We&#8217;re actually closer to going too fast than too slow, but halving the clocks to 500KHz and 4 Mhz would make it 2 microseconds pr bit &#8211; out of spec that says max 1.825 microseconds. <br>Maybe &#8211; just maybe &#8211; this could actually work on an Apple II since it has a slightly higher clock than 1Mhz @ 1.023Mhz, but you would then need to make a 4x frequency multiplier for the shift register CP to match input and output.  </p>



<p>But wait&#8230; 3/8 is only 375ns, right? That would be a 0 signal, right? And 1/8 is only 125ns? Well &#8211; in my case I seem to have either stray capacitance on Q7 or something else messing with the timing &#8211; somehow using more than two pins for the data gives me a T1H period way longer  than what we&#8217;re aiming for here &#8211; essentially making every bit a 1. Maybe a pulldown resistor on Q7 would make things more consistent &#8211; either way I chose to leave things the way they are simply because they work. </p>



<h2 class="wp-block-heading">The code</h2>



<p>The code below is a simplified modification to the current state of my 6502 firmware &#8211; my favorite compiler for the 6502 is <a href="https://cc65.github.io/" target="_blank" rel="noreferrer noopener">cc65</a>. Since I&#8217;m not sure I&#8217;ll merge the change, I&#8217;m leaving it here for now &#8211; untested, but contains everything needed to get it working. Assume a <a href="https://creativecommons.org/licenses/by-nc/4.0/">CC BY-NC license</a> for now. </p>



<p>Sending a color to an LED on the string is as simple as just sending them in the right order with a delay that&#8217;s long enough to make sure the 6522 shift register finished shifting before sending another byte &#8211; the WS2812B expects colors in GRB order. 24 bits in total per LED.</p>



<p>When we&#8217;re done putting colors on the LED string, all that&#8217;s left to do is just to wait 50 microseconds, so the string latches the data (updates). </p>



<p>Essentially this means we have 100 clock cycles (at 2 Mhz) available to manipulate LED data even while we&#8217;re sending pixels. As long as we&#8217;re sending the next 24 bit LED data before the 50 microseconds have passed, we can keep using time between LED&#8217;s for as many LED&#8217;s as we need. </p>



<p>100 clock cycles is more than enough to rainbow the LED&#8217;s and most other simple processing. </p>



<pre class="wp-block-code"><code>;Variables used besides 6522 registers, ACR &amp; SR affected here
; WS2812B variables
GREEN = $20
RED = $21
BLUE = $22
PIXELS = $27

main:
          LDA #%01011000
          STA ACR             ; 6522 ACR register T1 continuous, PB7 disabled, Shift Out Ø2
          lda #40 ; This is how many pixels I'm using.
          sta PIXELS
          jsr sendpixels ; This should clear LEDs on reset if RAM has been 0'd out - random color otherwise. 

    sendpixels:
      ldx PIXELS
    sending:
      sei ; Getting interrupted breaks the timing
      jsr sendpixel
      cli
      dex
      bne sending
      jmp halt ; Done

    sendpixel:
      lda GREEN
      sta SR1
      jsr eznop
      lda RED
      sta SR1
      jsr eznop
      lda BLUE
      sta SR1
      jsr eznop
       rts

      eznop:
         rts

      halt:
      jmp halt ; Loop forever here</code></pre>



<h2 class="wp-block-heading">Conclusion</h2>



<p>As you can see, the 6502 is perfectly capable of rainbowing a string of individually addressable RGB LED&#8217;s &#8211; it even has time to spare. Previously I&#8217;ve managed to run one of these LED strips at 4 Mhz(out of spec though), but I&#8217;m happy to report it&#8217;s possible to go even lower with this approach. <br>In a pinch you could use the same trick with an Arduino at lower clock speeds &#8211; all you would need is a second &#8216;165 shift register to have the Arduino output a whole port at the same time ( PORTA = RED; NOP x 7 etc.) </p>



<p>What do you think? Cool experiment or waste of time? I&#8217;d appreciate a comment here or on Youtube.</p>



<figure class="wp-block-embed is-type-video is-provider-youtube wp-block-embed-youtube wp-embed-aspect-16-9 wp-has-aspect-ratio"><div class="wp-block-embed__wrapper">
<iframe loading="lazy" title="WS2812B RGB LEDs on a 6502!" width="640" height="360" src="https://www.youtube.com/embed/sWaI3kpXslY?feature=oembed" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe>
</div></figure>
]]></content:encoded>
					
					<wfw:commentRss>https://abnielsen.com/2021/12/23/ws2812b-rgb-lights-on-a-6502/feed/</wfw:commentRss>
			<slash:comments>11</slash:comments>
		
		
			</item>
		<item>
		<title>3 cent PMS150C MCU driving 300 WS2812B LED&#8217;s</title>
		<link>https://abnielsen.com/2019/04/24/driving-300-ws2812b-rgb-leds-with-a-3-cent-microcontroller-pms150c/</link>
					<comments>https://abnielsen.com/2019/04/24/driving-300-ws2812b-rgb-leds-with-a-3-cent-microcontroller-pms150c/#comments</comments>
		
		<dc:creator><![CDATA[Anders]]></dc:creator>
		<pubDate>Wed, 24 Apr 2019 21:40:05 +0000</pubDate>
				<category><![CDATA[Padauk PMS150C]]></category>
		<category><![CDATA[Projects]]></category>
		<category><![CDATA[3 cent mcu]]></category>
		<category><![CDATA[neopixel]]></category>
		<category><![CDATA[Padauk]]></category>
		<category><![CDATA[pms150c]]></category>
		<category><![CDATA[WS2812b]]></category>
		<guid isPermaLink="false">https://abnielsen.com/?p=195</guid>

					<description><![CDATA[The 3 cent Padauk PMS150C is.. Interesting to say the least. First of all there&#8217;s a lot this little MCU doesn&#8217;t do. It doesn&#8217;t have a lot of code space [&#8230;]]]></description>
										<content:encoded><![CDATA[
<p>The 3 cent Padauk PMS150C is.. Interesting to say the least. First of all there&#8217;s a lot this little MCU doesn&#8217;t do. It doesn&#8217;t have a lot of code space (1K Word), it doesn&#8217;t have a lot of RAM (64 bytes) and it doesn&#8217;t even do hardware multiplication. It doesn&#8217;t have an instruction for loading data from ROM either(Though there are ways of getting around this &#8211; but that&#8217;s a subject for another post). And of course &#8211; you can only program it ONCE.</p>



<div class="wp-block-image"><figure class="alignleft is-resized"><img loading="lazy" decoding="async" src="https://abnielsen.com/wp-content/uploads/2019/04/20190422_0071-1024x683.jpg" alt="" class="wp-image-190" width="514" height="344" srcset="https://abnielsen.com/wp-content/uploads/2019/04/20190422_0071-1024x683.jpg 1024w, https://abnielsen.com/wp-content/uploads/2019/04/20190422_0071-300x200.jpg 300w, https://abnielsen.com/wp-content/uploads/2019/04/20190422_0071-768x512.jpg 768w" sizes="auto, (max-width: 514px) 100vw, 514px" /><figcaption>PMS150C U06 on an ill suited SOIC8 breakout</figcaption></figure></div>



<div class="wp-block-image"><figure class="alignleft is-resized"><img loading="lazy" decoding="async" src="https://abnielsen.com/wp-content/uploads/2019/04/20190422_0089-1024x683.jpg" alt="" class="wp-image-194" width="512" height="342" srcset="https://abnielsen.com/wp-content/uploads/2019/04/20190422_0089-1024x683.jpg 1024w, https://abnielsen.com/wp-content/uploads/2019/04/20190422_0089-300x200.jpg 300w, https://abnielsen.com/wp-content/uploads/2019/04/20190422_0089-768x512.jpg 768w" sizes="auto, (max-width: 512px) 100vw, 512px" /></figure></div>



<p></p>



<p>Hint: Gallery the bottom of this post!</p>



<h2 class="wp-block-heading">So.. What can it do? Blink lights? Well yes.. and so much more. </h2>



<p>Even though it has it&#8217;s limitations, there&#8217;s actually a lot you can do just by bitbanging with an 8Mhz microcontroller. As you can see in the screenshot from the IDE below, it&#8217;s actually meant to work with a bunch of peripherals &#8211; even though there is no hardware support for any of it. </p>



<div class="wp-block-image"><figure class="alignleft is-resized"><a href="https://abnielsen.com/wp-content/uploads/2019/04/image.png"><img loading="lazy" decoding="async" src="https://abnielsen.com/wp-content/uploads/2019/04/image.png" alt="" class="wp-image-197" width="244" height="226" srcset="https://abnielsen.com/wp-content/uploads/2019/04/image.png 976w, https://abnielsen.com/wp-content/uploads/2019/04/image-300x278.png 300w, https://abnielsen.com/wp-content/uploads/2019/04/image-768x711.png 768w" sizes="auto, (max-width: 244px) 100vw, 244px" /></a><figcaption>The Padauk IDE &#8220;code generator&#8221;</figcaption></figure></div>



<p>Of course there&#8217;s a couple of very smart people over on the EEVBlog forum working hard at <a href="http://www.eevblog.com/forum/blog/eevblog-1144-padauk-programmer-reverse-engineering/">making an open toolchain for these chips,</a> but I decided I couldn&#8217;t wait to get started and stuck with the manufacturer IDE, ICE and programmer.</p>



<p>To get the most out of the tools at hand, the IDE seems to expect you to use a mix of plain C, macros and assembly instructions, all mushed together in some pretty interestingly looking code.  I&#8217;m probably not going to be popular for saying this but it actually feels very intuitive when you get used to it. It&#8217;s weird, but it&#8217;s &#8220;fun&#8221;.</p>



<p>After my initial mandatory &#8220;blinky tests&#8221; I decided to try something slightly more useful &#8211; controlling a WS2812B LED. Since the protocol itself relies on bitbanging with pretty tight timings, I figured this was a good test.</p>



<p>Before we move on, here&#8217;s the spoiler! Success:</p>



<figure class="wp-block-embed-youtube wp-block-embed is-type-video is-provider-youtube wp-embed-aspect-16-9 wp-has-aspect-ratio"><div class="wp-block-embed__wrapper">
<iframe loading="lazy" title="3 cent MCU PMS150C driving 300 WS2812B&#039;s (aka NeoPixels)" width="640" height="360" src="https://www.youtube.com/embed/zdhI0kNYR_c?feature=oembed" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe>
</div></figure>



<h3 class="wp-block-heading">But how? Adafruit&#8217;s Arduino-library uses 3 bytes of RAM for every LED so how do you run 300 with just 64 bytes of RAM?</h3>



<p>Turns out there&#8217;s a simple solution to this problem: Don&#8217;t put every LED in RAM. <br>Since the timings of the WS2812B&#8217;s aren&#8217;t that tight, there&#8217;s actually room for a lot of spare cycles between sending the 24bit value for each LED. Basically just do the logic on the fly, instead of storing each LED in RAM. The only downside is you can&#8217;t just change a single LED value and leave the rest. <br><br>The logic for controlling the LED&#8217;s is pretty simple once you wrap your head around it. Send 24 bits for each LED and end with a delay long enough to make the data latch. In this case, keep each bit around 1.25uS, a &#8220;0&#8221; is a short high, followed by a &#8220;long&#8221; low and a &#8220;1&#8221; is a long high followed by a short low. So simply: High-&gt;Low 24 times. Long high for 1, short high for 0.<br>Here&#8217;s a snippet from the datasheet:<br></p>



<figure class="wp-block-image"><img loading="lazy" decoding="async" width="1024" height="342" src="https://abnielsen.com/wp-content/uploads/2019/04/image-1-1024x342.png" alt="" class="wp-image-211" srcset="https://abnielsen.com/wp-content/uploads/2019/04/image-1-1024x342.png 1024w, https://abnielsen.com/wp-content/uploads/2019/04/image-1-300x100.png 300w, https://abnielsen.com/wp-content/uploads/2019/04/image-1-768x257.png 768w, https://abnielsen.com/wp-content/uploads/2019/04/image-1.png 1280w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /><figcaption><br></figcaption></figure>



<p>The +/- 150ns was plenty of headroom in my case, with the PMS150C running at 8mhz. Same is the case with the +/- 600ns for each bit. I expect I could&#8217;ve easily run 3000 LED&#8217;s instead of 300 &#8211; but I didn&#8217;t have the power supply for that much heat lying around <img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f642.png" alt="🙂" class="wp-smiley" style="height: 1em; max-height: 1em;" /></p>



<p>Tim &#8220;cpldcpu&#8221; wrote <a href="https://cpldcpu.wordpress.com/2014/01/14/light_ws2812-library-v2-0-part-i-understanding-the-ws2812/">a detailed post about it</a> back in 2014 but either things changed since or he got the details wrong, because in my tests a RES signal needed to be at least 50uS and when experiencing glitches, the longer the reset signal, the better. <br>I have a feeling I would&#8217;ve never done this project if I hadn&#8217;t seen <a href="https://wp.josh.com/2014/05/13/ws2812-neopixels-are-not-so-finicky-once-you-get-to-know-them/">Big Josh&#8217;s post about how simple the protocol actually is</a> but sadly his code needed some serious manipulation to port to the Padauk IDE, so I ended up rewriting it completely from scratch with the WorldSemi datasheet in hand and a vague memory of what BigJosh did with it.<br>A big thank you for the inspiration to both Tim and BigJosh!</p>



<figure class="wp-block-image"><a href="https://abnielsen.com/wp-content/uploads/2019/04/20190422_0010.jpg" target="_blank" rel="noreferrer noopener"><img loading="lazy" decoding="async" width="1024" height="576" src="https://abnielsen.com/wp-content/uploads/2019/04/20190422_0010-1024x576.jpg" alt="" class="wp-image-180" srcset="https://abnielsen.com/wp-content/uploads/2019/04/20190422_0010-1024x576.jpg 1024w, https://abnielsen.com/wp-content/uploads/2019/04/20190422_0010-300x169.jpg 300w, https://abnielsen.com/wp-content/uploads/2019/04/20190422_0010-768x432.jpg 768w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></a><figcaption><br>Padauk PMS150C successfully driving 300 WS2812B LED&#8217;s<br></figcaption></figure>



<h3 class="wp-block-heading">So.. What about the code?</h3>



<p>Below is the minimum code I use to talk to the string of LED&#8217;s. There&#8217;s room for optimisation and I&#8217;m sure a bunch of it looks funny, if you&#8217;re used to seeing a plain C project on an AVR. First of all, the Padauk IDE is a little bit fuzzy when it comes to data types. There&#8217;s no such thing as a &#8220;long&#8221; and it seems to me all types are unsigned by default &#8211; though I haven&#8217;t researched this thoroughly. <br>The only data types available in the Padauk IDE are:</p>



<ul class="wp-block-list"><li>Bit (1 bit) </li><li>Byte (8 bit)</li><li>Int (8 bit(!))</li><li>Word (16 bit)</li><li>EWORD (24 bit)</li><li>DWORD (32 bit)</li></ul>



<p>The handy thing about the types though, is that the individual bits and bytes can be accessed by macros, without any fuzzing about with shifting them around. </p>



<p>For instance: <br>mybyte.4 = 0; //Clears bit 4 of mybyte<br>myEWORD$1 = mybyte; //Sets the middle byte of the 24 bit EWORD</p>



<p>Also, the builtin macros come very handy. See the below code. All the code needed to control the WS2812B&#8217;s are contained in the macros &#8220;send1&#8221;, &#8220;send0&#8221; and the function SendRGB();</p>



<p>The SendRGB() function is a prime example of Padauk IDE weirdness, containing both assembly instructions, macros and plain old C. But what can I say: It works. I probably could&#8217;ve shifted the rgb EWORD x in a while loop(more efficiently than the 24 macro if&#8217;s) but I decided to try out the macro and it was more than efficient enough for this purpose. The rest of the code(which I haven&#8217;t included here) is basic manipulation of the r,g &amp; b values followed by a show(); to set the right colors.<del> Leave a comment if you want to see, and I&#8217;ll throw the complete project on github.</del></p>



<p>After popular demand, the complete source is available here:  <br><a href="https://github.com/AndersBNielsen/pms150c-projects">https://github.com/AndersBNielsen/pms150c-projects</a> </p>



<blockquote class="wp-block-quote is-layout-flow wp-block-quote-is-layout-flow"><p>byte        red, green, blue; //Could save these three RAM bytes by using the rgb EWORD directly ( rgb$0, rgb$1, rgb$2)</p><p>EWORD        rgb;</p><p>word        pixels; //Only has to be a word if number of pixels &gt; 255<br> define definedPIXELS 300;</p><p>send1 MACRO<br>         SET1 LED;<br>         .DELAY 5; //Around 0.85uS<br>         $ LED low; //Same as SET0 LED;<br>     //  .DELAY 1; //Going around is enough delay 1.25uS in total<br> ENDM</p><p><br> send0 MACRO<br>         SET1 LED;<br>         .DELAY 2; //Around 0.40uS<br>         $ LED low;<br>         .DELAY 2; //With the loop around 0.85uS<br> ENDM</p><p><br> void SendRGB (void) {<br>     DISGINT; //Let&#8217;s not get interrupted</p><p><br> <code>.FOR bitno, &lt;23,22,21,20,19,18,17,16,15,14,13,12,11,10,9,8,7,6,5,4,3,2,1,0&gt; //Regular for() loop doesn't work, but at least the compiler can do the hard work </code></p><p></p><p><code>if (rgb.bitno == 0) {</code></p><p><code>         send0;</code></p><p><code>     } else {</code></p><p><code>         send1;</code></p><p><code>     } </code></p><p><code>.ENDM </code></p><p><code>ENGINT;</code><br> }</p><p><br> void show (void) {<br>     rgb$0 = blue; //I lost track of MSB, LSB and endians.. This is what works. <br>     rgb$1 = red;<br>     rgb$2 = green;<br>     SendRGB();<br> }</p><p><br> void clearLED (void) {<br> rgb = 0;<br> pixels = definedPIXELS;<br>  do {<br> SendRGB();<br> } while (&#8211;pixels);<br> .delay 2000; //If you want to make sure the LED-reset is caught, use a longer one. <br> }        </p></blockquote>



<h3 class="wp-block-heading">So.. Why would I choose this instead of a major brand MCU?</h3>



<p>Obviously, the major selling point of this microcontroller is the price. At 3 cents each it&#8217;s ten times cheaper than the Pic equivalent(at 3000 MOQ) &#8211; the pic10f200(34 cents) or the ATTiny10(28 cents @ 4500 MOQ). //Digikey<br>Also, the customer service is far from bad &#8211; I got an email reply from Padauk within 12 hours. <br>The downside for the PMS150c is the OTP nature, the limited instruction set, and the sometimes curious and seemingly random IDE documentation &#8211; only partially translated into English. (Getting better with every release though from 0.84 to 0.86)<br>If you&#8217;re thinking about making a toy with an ATTiny10 in it and it doesn&#8217;t need to do a lot of heavy math &#8211; this might be able to do the same job for a tenth of the cost. That doesn&#8217;t mean I would be happy to see it in a pacemaker.</p>



<h3 class="wp-block-heading"> What else can it do?</h3>



<p>My guess is: More than you&#8217;d think. I have a feeling my next project might involve controlling the <del>nrf24L01+ </del> SI24R01 2.4Ghz radio module or maybe a budget Raspberry Pi module.<br><br>Either way, please tell me what you think, point out my mistakes and let me know in a comment what you&#8217;d like to see me do with this thing in the future. </p>



<ul class="wp-block-gallery columns-3 is-cropped wp-block-gallery-1 is-layout-flex wp-block-gallery-is-layout-flex"><li class="blocks-gallery-item"><figure><img loading="lazy" decoding="async" width="1024" height="683" src="https://abnielsen.com/wp-content/uploads/2019/04/20190422_0095-1024x683.jpg" alt="" data-id="193" data-link="https://abnielsen.com/20190422_0095/" class="wp-image-193" srcset="https://abnielsen.com/wp-content/uploads/2019/04/20190422_0095-1024x683.jpg 1024w, https://abnielsen.com/wp-content/uploads/2019/04/20190422_0095-300x200.jpg 300w, https://abnielsen.com/wp-content/uploads/2019/04/20190422_0095-768x512.jpg 768w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /><figcaption>PMS150C &#8211; top view<br></figcaption></figure></li><li class="blocks-gallery-item"><figure><img loading="lazy" decoding="async" width="1024" height="576" src="https://abnielsen.com/wp-content/uploads/2019/04/20190422_0083-1024x576.jpg" alt="" data-id="192" data-link="https://abnielsen.com/20190422_0083/" class="wp-image-192" srcset="https://abnielsen.com/wp-content/uploads/2019/04/20190422_0083-1024x576.jpg 1024w, https://abnielsen.com/wp-content/uploads/2019/04/20190422_0083-300x169.jpg 300w, https://abnielsen.com/wp-content/uploads/2019/04/20190422_0083-768x432.jpg 768w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /><figcaption>PMS150C</figcaption></figure></li><li class="blocks-gallery-item"><figure><img loading="lazy" decoding="async" width="1024" height="683" src="https://abnielsen.com/wp-content/uploads/2019/04/20190422_0089-1024x683.jpg" alt="" data-id="194" data-link="https://abnielsen.com/20190422_0089/" class="wp-image-194" srcset="https://abnielsen.com/wp-content/uploads/2019/04/20190422_0089-1024x683.jpg 1024w, https://abnielsen.com/wp-content/uploads/2019/04/20190422_0089-300x200.jpg 300w, https://abnielsen.com/wp-content/uploads/2019/04/20190422_0089-768x512.jpg 768w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></figure></li><li class="blocks-gallery-item"><figure><img loading="lazy" decoding="async" width="1024" height="683" src="https://abnielsen.com/wp-content/uploads/2019/04/20190422_0073-1024x683.jpg" alt="" data-id="191" data-link="https://abnielsen.com/20190422_0073/" class="wp-image-191" srcset="https://abnielsen.com/wp-content/uploads/2019/04/20190422_0073-1024x683.jpg 1024w, https://abnielsen.com/wp-content/uploads/2019/04/20190422_0073-300x200.jpg 300w, https://abnielsen.com/wp-content/uploads/2019/04/20190422_0073-768x512.jpg 768w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /><figcaption>PMS150C<br>Don&#8217;t I have a nice table?<br></figcaption></figure></li><li class="blocks-gallery-item"><figure><img loading="lazy" decoding="async" width="1024" height="683" src="https://abnielsen.com/wp-content/uploads/2019/04/20190422_0037-1024x683.jpg" alt="" data-id="185" data-link="https://abnielsen.com/20190422_0037/" class="wp-image-185" srcset="https://abnielsen.com/wp-content/uploads/2019/04/20190422_0037-1024x683.jpg 1024w, https://abnielsen.com/wp-content/uploads/2019/04/20190422_0037-300x200.jpg 300w, https://abnielsen.com/wp-content/uploads/2019/04/20190422_0037-768x512.jpg 768w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></figure></li><li class="blocks-gallery-item"><figure><img loading="lazy" decoding="async" width="1024" height="576" src="https://abnielsen.com/wp-content/uploads/2019/04/20190422_0043-1024x576.jpg" alt="" data-id="186" data-link="https://abnielsen.com/20190422_0043/" class="wp-image-186" srcset="https://abnielsen.com/wp-content/uploads/2019/04/20190422_0043-1024x576.jpg 1024w, https://abnielsen.com/wp-content/uploads/2019/04/20190422_0043-300x169.jpg 300w, https://abnielsen.com/wp-content/uploads/2019/04/20190422_0043-768x432.jpg 768w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /><figcaption>PMS150C<br>Pretty lights eh?</figcaption></figure></li><li class="blocks-gallery-item"><figure><img loading="lazy" decoding="async" width="1024" height="576" src="https://abnielsen.com/wp-content/uploads/2019/04/20190422_0048-1024x576.jpg" alt="" data-id="187" data-link="https://abnielsen.com/20190422_0048/" class="wp-image-187" srcset="https://abnielsen.com/wp-content/uploads/2019/04/20190422_0048-1024x576.jpg 1024w, https://abnielsen.com/wp-content/uploads/2019/04/20190422_0048-300x169.jpg 300w, https://abnielsen.com/wp-content/uploads/2019/04/20190422_0048-768x432.jpg 768w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /><figcaption>PMS150C breadboard layout</figcaption></figure></li><li class="blocks-gallery-item"><figure><img loading="lazy" decoding="async" width="1024" height="683" src="https://abnielsen.com/wp-content/uploads/2019/04/20190422_0051-1024x683.jpg" alt="" data-id="188" data-link="https://abnielsen.com/20190422_0051/" class="wp-image-188" srcset="https://abnielsen.com/wp-content/uploads/2019/04/20190422_0051-1024x683.jpg 1024w, https://abnielsen.com/wp-content/uploads/2019/04/20190422_0051-300x200.jpg 300w, https://abnielsen.com/wp-content/uploads/2019/04/20190422_0051-768x512.jpg 768w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></figure></li><li class="blocks-gallery-item"><figure><img loading="lazy" decoding="async" width="1024" height="683" src="https://abnielsen.com/wp-content/uploads/2019/04/20190422_0063-1024x683.jpg" alt="" data-id="189" data-link="https://abnielsen.com/20190422_0063/" class="wp-image-189" srcset="https://abnielsen.com/wp-content/uploads/2019/04/20190422_0063-1024x683.jpg 1024w, https://abnielsen.com/wp-content/uploads/2019/04/20190422_0063-300x200.jpg 300w, https://abnielsen.com/wp-content/uploads/2019/04/20190422_0063-768x512.jpg 768w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></figure></li><li class="blocks-gallery-item"><figure><img loading="lazy" decoding="async" width="1024" height="683" src="https://abnielsen.com/wp-content/uploads/2019/04/20190422_0071-1024x683.jpg" alt="" data-id="190" data-link="https://abnielsen.com/20190422_0071/" class="wp-image-190" srcset="https://abnielsen.com/wp-content/uploads/2019/04/20190422_0071-1024x683.jpg 1024w, https://abnielsen.com/wp-content/uploads/2019/04/20190422_0071-300x200.jpg 300w, https://abnielsen.com/wp-content/uploads/2019/04/20190422_0071-768x512.jpg 768w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></figure></li><li class="blocks-gallery-item"><figure><img loading="lazy" decoding="async" width="1024" height="683" src="https://abnielsen.com/wp-content/uploads/2019/04/20190422_0034-1024x683.jpg" alt="" data-id="184" data-link="https://abnielsen.com/20190422_0034/" class="wp-image-184" srcset="https://abnielsen.com/wp-content/uploads/2019/04/20190422_0034-1024x683.jpg 1024w, https://abnielsen.com/wp-content/uploads/2019/04/20190422_0034-300x200.jpg 300w, https://abnielsen.com/wp-content/uploads/2019/04/20190422_0034-768x512.jpg 768w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></figure></li><li class="blocks-gallery-item"><figure><img loading="lazy" decoding="async" width="1024" height="683" src="https://abnielsen.com/wp-content/uploads/2019/04/20190422_0027-1024x683.jpg" alt="" data-id="183" data-link="https://abnielsen.com/20190422_0027/" class="wp-image-183" srcset="https://abnielsen.com/wp-content/uploads/2019/04/20190422_0027-1024x683.jpg 1024w, https://abnielsen.com/wp-content/uploads/2019/04/20190422_0027-300x200.jpg 300w, https://abnielsen.com/wp-content/uploads/2019/04/20190422_0027-768x512.jpg 768w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></figure></li><li class="blocks-gallery-item"><figure><img loading="lazy" decoding="async" width="1024" height="576" src="https://abnielsen.com/wp-content/uploads/2019/04/20190422_0020-1024x576.jpg" alt="" data-id="182" data-link="https://abnielsen.com/20190422_0020/" class="wp-image-182" srcset="https://abnielsen.com/wp-content/uploads/2019/04/20190422_0020-1024x576.jpg 1024w, https://abnielsen.com/wp-content/uploads/2019/04/20190422_0020-300x169.jpg 300w, https://abnielsen.com/wp-content/uploads/2019/04/20190422_0020-768x432.jpg 768w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></figure></li><li class="blocks-gallery-item"><figure><img loading="lazy" decoding="async" width="1024" height="576" src="https://abnielsen.com/wp-content/uploads/2019/04/20190422_0017-1024x576.jpg" alt="" data-id="181" data-link="https://abnielsen.com/20190422_0017/" class="wp-image-181" srcset="https://abnielsen.com/wp-content/uploads/2019/04/20190422_0017-1024x576.jpg 1024w, https://abnielsen.com/wp-content/uploads/2019/04/20190422_0017-300x169.jpg 300w, https://abnielsen.com/wp-content/uploads/2019/04/20190422_0017-768x432.jpg 768w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></figure></li><li class="blocks-gallery-item"><figure><img loading="lazy" decoding="async" width="1024" height="576" src="https://abnielsen.com/wp-content/uploads/2019/04/20190422_0010-1024x576.jpg" alt="" data-id="180" data-link="https://abnielsen.com/20190422_0010/" class="wp-image-180" srcset="https://abnielsen.com/wp-content/uploads/2019/04/20190422_0010-1024x576.jpg 1024w, https://abnielsen.com/wp-content/uploads/2019/04/20190422_0010-300x169.jpg 300w, https://abnielsen.com/wp-content/uploads/2019/04/20190422_0010-768x432.jpg 768w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></figure></li><li class="blocks-gallery-item"><figure><img loading="lazy" decoding="async" width="1024" height="576" src="https://abnielsen.com/wp-content/uploads/2019/04/20190422_0008-1024x576.jpg" alt="" data-id="179" data-link="https://abnielsen.com/20190422_0008/" class="wp-image-179" srcset="https://abnielsen.com/wp-content/uploads/2019/04/20190422_0008-1024x576.jpg 1024w, https://abnielsen.com/wp-content/uploads/2019/04/20190422_0008-300x169.jpg 300w, https://abnielsen.com/wp-content/uploads/2019/04/20190422_0008-768x432.jpg 768w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /><figcaption>PMS150C<br>Much shiny!<br></figcaption></figure></li></ul>
]]></content:encoded>
					
					<wfw:commentRss>https://abnielsen.com/2019/04/24/driving-300-ws2812b-rgb-leds-with-a-3-cent-microcontroller-pms150c/feed/</wfw:commentRss>
			<slash:comments>25</slash:comments>
		
		
			</item>
		<item>
		<title>PCB&#8217;s: CNC DIY or China express?</title>
		<link>https://abnielsen.com/2018/10/06/pcbs-cnc-diy-or-china-express/</link>
					<comments>https://abnielsen.com/2018/10/06/pcbs-cnc-diy-or-china-express/#respond</comments>
		
		<dc:creator><![CDATA[Anders]]></dc:creator>
		<pubDate>Sat, 06 Oct 2018 12:50:03 +0000</pubDate>
				<category><![CDATA[Projects]]></category>
		<category><![CDATA[pcb design]]></category>
		<category><![CDATA[WS2812b]]></category>
		<guid isPermaLink="false">https://abnielsen.com/?p=83</guid>

					<description><![CDATA[Around three years ago I made a couple of these WS2812b &#8220;bulbs&#8221; for my hallway. I had a CNC and thought it couldn&#8217;t be that hard to etch out some [&#8230;]]]></description>
										<content:encoded><![CDATA[<p>Around three years ago I made a couple of these WS2812b &#8220;bulbs&#8221; for my hallway. I had a CNC and thought it couldn&#8217;t be that hard to etch out some traces. It could. I had so many failures because of leveling issues and pieces of copper getting stuck where they shouldn&#8217;t. On the positive side though &#8211; they all worked flawlessly for three years. I think they took about an hour to make on average.</p>
<p>What I meant to say was: Don&#8217;t waste your time. I could&#8217;ve had these made for 50 cents each but instead I wasted my time. Lesson learned <img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f642.png" alt="🙂" class="wp-smiley" style="height: 1em; max-height: 1em;" /><a href="https://abnielsen.com/wp-content/uploads/2018/10/20181001_0140.jpg"><img loading="lazy" decoding="async" class="alignleft size-large wp-image-13" src="https://abnielsen.com/wp-content/uploads/2018/10/20181001_0140-1024x576.jpg" alt="" width="640" height="360" srcset="https://abnielsen.com/wp-content/uploads/2018/10/20181001_0140-1024x576.jpg 1024w, https://abnielsen.com/wp-content/uploads/2018/10/20181001_0140-300x169.jpg 300w, https://abnielsen.com/wp-content/uploads/2018/10/20181001_0140-768x432.jpg 768w" sizes="auto, (max-width: 640px) 100vw, 640px" /></a></p>
]]></content:encoded>
					
					<wfw:commentRss>https://abnielsen.com/2018/10/06/pcbs-cnc-diy-or-china-express/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>ATTiny84 USB-capable business card featuring 2.4Ghz wireless and WS2812B&#8217;s</title>
		<link>https://abnielsen.com/2018/10/02/business-card-rf24-ws2812b-attiny84-usb/</link>
					<comments>https://abnielsen.com/2018/10/02/business-card-rf24-ws2812b-attiny84-usb/#comments</comments>
		
		<dc:creator><![CDATA[Anders]]></dc:creator>
		<pubDate>Tue, 02 Oct 2018 14:04:15 +0000</pubDate>
				<category><![CDATA[ATTiny]]></category>
		<category><![CDATA[Projects]]></category>
		<category><![CDATA[Arduino]]></category>
		<category><![CDATA[ATTiny84]]></category>
		<category><![CDATA[nRF24L01+]]></category>
		<category><![CDATA[V-USB]]></category>
		<category><![CDATA[WS2812b]]></category>
		<guid isPermaLink="false">https://abnielsen.com/?p=52</guid>

					<description><![CDATA[This is my business card. It works as a USB-HID device, takes input from a 2.4Ghz transceiver and it also comes with some flashy RGB LED&#8217;s and a prototyping header. [&#8230;]]]></description>
										<content:encoded><![CDATA[<p><a href="https://abnielsen.com/wp-content/uploads/2018/10/20181001_0077.jpg"><img loading="lazy" decoding="async" class="alignright wp-image-31 size-large" src="https://abnielsen.com/wp-content/uploads/2018/10/20181001_0077-1024x576.jpg" alt="" width="640" height="360" srcset="https://abnielsen.com/wp-content/uploads/2018/10/20181001_0077-1024x576.jpg 1024w, https://abnielsen.com/wp-content/uploads/2018/10/20181001_0077-300x169.jpg 300w, https://abnielsen.com/wp-content/uploads/2018/10/20181001_0077-768x432.jpg 768w" sizes="auto, (max-width: 640px) 100vw, 640px" /></a></p>
<p>This is my business card. It works as a USB-HID device, takes input from a 2.4Ghz transceiver and it also comes with some flashy RGB LED&#8217;s and a prototyping header. Oh.. And it has my contact information.</p>
<p>Spoiler: This is also on <a href="https://github.com/AndersBNielsen/v-usb-businesscard">Github</a> if you just want to skip to code and PCB files. If you want to know more, read on.</p>
<h3>Why?</h3>
<p>After seeing a couple of PCB business cards on hackaday.com, I knew I had make my own. But how do I make it stand out? What should it do? How expensive can I get away with?</p>
<p>For this little project I decided to squeeze as much as possible out of a cheap ATTiny84. I chose the T84 because it&#8217;s dirt cheap (&lt;1$), I&#8217;ve been through it&#8217;s datasheet more than just a few times, and I wanted to see exactly how much it&#8217;s possible to squeeze into the 8192 bytes available.</p>
<p>Turns out the answer is: A lot!</p>
<p>I have a lot of individually addressable RGB WS2812B&#8217;s LED&#8217;s &#8211; aka NeoPixels &#8211; spread around my home(and about 850 left on a reel) that I&#8217;ve been controlling with prototypes made up of ATMega32u4&#8217;s and ATMega328p&#8217;s with 2.4Ghz nRF24L01+ tranceivers and a Raspberry Pi with the same tranceiver so I can control it from my phone. To justify spending more than a few cents per business card you need it to actually do something useful. Controlling RGB-LED&#8217;s was a start.</p>
<p>Attiny84 √</p>
<p>WS2812B&#8217;s √</p>
<p>nRF24L01+ √ (though i suspect pretty much everything out of China is actually SI24r1)</p>
<p>&nbsp;</p>
<p><a href="https://abnielsen.com/wp-content/uploads/2018/10/20181001_0085.jpg"><img loading="lazy" decoding="async" class="alignleft size-large wp-image-30" src="https://abnielsen.com/wp-content/uploads/2018/10/20181001_0085-1024x576.jpg" alt="" width="640" height="360" srcset="https://abnielsen.com/wp-content/uploads/2018/10/20181001_0085-1024x576.jpg 1024w, https://abnielsen.com/wp-content/uploads/2018/10/20181001_0085-300x169.jpg 300w, https://abnielsen.com/wp-content/uploads/2018/10/20181001_0085-768x432.jpg 768w" sizes="auto, (max-width: 640px) 100vw, 640px" /></a>I also added a 20 pin header that makes it easy to use this board for prototyping with the 14pin ATTiny&#8217;s. Easy access to every pin(and a few extra power pins) means you can easily solder sensors etc. directly onto the pins &#8211; or add male header pins and push it into a breadboard.</p>
<h3>How about USB?</h3>
<p>One of my annoyances when designing prototypes has always been that it&#8217;s really hard to make anything USB-capable(not to speak of compliant) for less than 5$. It is possible though, if you don&#8217;t follow the usual path. OBDev&#8217;s <a href="https://www.obdev.at/products/vusb/index.html">V-USB</a> (with a little bit of help from Adafruit&#8217;s TrinketHidCombo library) made it possible to squeeze some  USB capability into this project without adding much more extra hardware than two zener&#8217;s and three resistors.</p>
<h2>Software</h2>
<p>I have to be honest. I like the Arduino IDE for prototyping. Slapping a couple of libraries together doesn&#8217;t usually result in the most efficient code but when you want to put something together that showcases a lot of features fast &#8211; as in: a few hours &#8211; the vast amount of libraries for interfacing with every popular IC makes it hard no to take the easy route.<br />
Everything didn&#8217;t work straight out of the box though. The RF24 library needed pin definitions changed for the ATTiny84(since the USI&#8217;s DO/DI are reversed compared to MISO and MOSI and this hasn&#8217;t been fixed in the current version) and Adafruit&#8217;s TrinketHidCombo library also needed some tweaking to work with the T84. I also went with the Adafruit NeoPixel library  for controlling the WS2812b&#8217;s, even though it&#8217;s relatively huge for a tiny chip, but somehow I managed to fit the basic functionality into the 8k of flash anyway. It does however, use every single byte available and the debug functions won&#8217;t fit unless something else is disabled.</p>
<p>I thought about using the smaller <a href="https://github.com/sonyhome/FAB_LED">FAB_LED</a> library for driving the LED&#8217;s to leave more space for HID-stuff, but it doesn&#8217;t really play nice with the 10ms USB-polling when controlling more than one LED at a time so I went the easy way with the NeoPixel library and limited the HID capability to just pressing media keys (start/pause, volume up, volume down and stop). I pride myself in making software that&#8217;s good enough for doing the job without too much &#8220;gold plating&#8221;.</p>
<p>So for now, all it does is work as a 2.4Ghz USB-dongle for media keys along with controlling flashy flashy LED&#8217;s. Pretty good for 5$, gold plated board included, though.</p>
<h3>PCB Design</h3>
<p>So h<a href="https://abnielsen.com/wp-content/uploads/2018/10/Skærmbillede-2018-10-06-kl.-12.55.03.png"><img loading="lazy" decoding="async" class="alignleft size-large wp-image-79" src="https://abnielsen.com/wp-content/uploads/2018/10/Skærmbillede-2018-10-06-kl.-12.55.03-1024x558.png" alt="" width="640" height="349" srcset="https://abnielsen.com/wp-content/uploads/2018/10/Skærmbillede-2018-10-06-kl.-12.55.03-1024x558.png 1024w, https://abnielsen.com/wp-content/uploads/2018/10/Skærmbillede-2018-10-06-kl.-12.55.03-300x163.png 300w, https://abnielsen.com/wp-content/uploads/2018/10/Skærmbillede-2018-10-06-kl.-12.55.03-768x418.png 768w" sizes="auto, (max-width: 640px) 100vw, 640px" /></a>ow do you make a PCB business card look cool? The easy way to make it would&#8217;ve been some silkscreen text with contact information etc. but to me the typically low resolution silkscreen text wasn&#8217;t good enough so I went with making a big ground plane and putting the text and logo on the solder mask layer. The font in KiCAD isn&#8217;t my favourite either, so I went with making a footprint of the text from a bitmap instead.<br />
For the surface plating I could&#8217;ve gone with the cheaper options but I really believe the immersion gold(ENIG) makes too much of a difference to skip.<br />
I chose 0.8mm board thickness because it&#8217;s enough not to break unintentionally and also fits in a standard credit card slot of a wallet &#8211; without components that is.</p>
<p>&nbsp;</p>
<h3>How do you program it?</h3>
<p>At first I thought I would just skip the programming interface and use a test probe clip(<a href="https://www.pomonaelectronics.com/products/test-clips/soic-clip-14-pin">like this one from Pomona</a>) to program it.</p>
<p><img loading="lazy" decoding="async" class="alignright wp-image-8 size-large" src="https://abnielsen.com/wp-content/uploads/2018/10/20181001_0146-576x1024.jpg" alt="" width="576" height="1024" srcset="https://abnielsen.com/wp-content/uploads/2018/10/20181001_0146-576x1024.jpg 576w, https://abnielsen.com/wp-content/uploads/2018/10/20181001_0146-169x300.jpg 169w, https://abnielsen.com/wp-content/uploads/2018/10/20181001_0146-768x1366.jpg 768w, https://abnielsen.com/wp-content/uploads/2018/10/20181001_0146.jpg 1129w" sizes="auto, (max-width: 576px) 100vw, 576px" /></p>
<p>But since I have a feeling I will be using this as a protoboard many times, I decided to find a better solution. Of course I could just hold down jumper wires to the 20-pin header or solder them on &#8211; but in my opinion that would either be a hassle for fast prototyping or ruin the look.<br />
Instead I decided to experiment a little bit with programming pads(J2 if you take a look at the schematic), since I already had some pogo pins on the way from China when I ordered this. I didn&#8217;t have exact specs for how big the pads needed to be, so I went with a footprint meant for an SMD male header. When I got the pogo pins I soldered them onto female dupont wire terminators and then onto a perfboard. You can see the final result on the right, together with my overused USBasp. This is a solution I can really recommend, but the next time I make an interface like this I will most likely just use tiny pads 2.54mm(.1&#8243; standard header) apart and as small as possible. With the thickness of the solder mask, the pins slide right into place. The only downside is you need to apply a tiny bit of pressure while programming the device, but I prefer this to connecting jumper wires any day.</p>
<p>If you want to read more about this subject, take a look at my post about <a href="https://abnielsen.com/2018/10/02/programming-an-avr-without-taking-up-board-space/">programming an AVR without taking up board space</a>.</p>
<p>&nbsp;</p>
<h3>Want to make your own PCB Business card?</h3>
<p>The point of a business card is to share it with other people, so I&#8217;ve uploaded this whole project to <a href="https://github.com/AndersBNielsen/v-usb-businesscard">Github</a>. Feel free to fork it and put your own spin on it.</p>
<p>Leave a comment if you have any questions, suggestions etc. Any feedback &#8211; good or bad &#8211; is very welcome <img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f642.png" alt="🙂" class="wp-smiley" style="height: 1em; max-height: 1em;" /></p>
<p>&nbsp;</p>
<p><a href="https://abnielsen.com/wp-content/uploads/2018/10/20181001_0087.jpg"><img loading="lazy" decoding="async" class="aligncenter size-large wp-image-29" src="https://abnielsen.com/wp-content/uploads/2018/10/20181001_0087-1024x576.jpg" alt="" width="640" height="360" srcset="https://abnielsen.com/wp-content/uploads/2018/10/20181001_0087-1024x576.jpg 1024w, https://abnielsen.com/wp-content/uploads/2018/10/20181001_0087-300x169.jpg 300w, https://abnielsen.com/wp-content/uploads/2018/10/20181001_0087-768x432.jpg 768w" sizes="auto, (max-width: 640px) 100vw, 640px" /></a></p>
]]></content:encoded>
					
					<wfw:commentRss>https://abnielsen.com/2018/10/02/business-card-rf24-ws2812b-attiny84-usb/feed/</wfw:commentRss>
			<slash:comments>4</slash:comments>
		
		
			</item>
	</channel>
</rss>
