Friday, April 19, 2019

Unlimited outputs for your microcontroller part II

For an index to all my stories click this line

In the previous part I showed you how to use WS2811 chips to create an almost unlimited number of PWM controlled outputs for an ESP8266. You can find that story here: http://lucstechblog.blogspot.com/2019/04/unlimited-outputs-for-your_12.html

The WS2811's are the chips that are build into the so called Neopixels. More detailed basic information about Neopixels can be found here: http://lucstechblog.blogspot.nl/2015/10/neopixels-ws2812-intro.html

So a Neopixel is basically a WS2811 and 3 leds build as a single chip. I am using just the WS2811's. As these can control 3 leds we should be able to use them as 3 outputs for a microcontroller. By daisy chaining them (just like we do with Neopixels) we can create an infinite number of outputs for any microcontroller. I did this succesfully with an ESP using LUA and Basic in Part 1 of this series.

Now let's see if we can use this technique also with an Arduino or an Attiny85.


Oh and by the way, with a little modification (mainly altering the pin number) you can use this also for the ESP8266 and ESP32 in Arduino language.

As both the Arduino and the Attiny85 have no Wifi capability it is more difficult to control them from the outside world. Control has to be taken care off with potentio meters or sensors. In the examples I am going to show here there is no outside control. The programs will control everything. For demo purposes this is sufficient and I am sure you find ways to incorporate this in your own projects.

Breadboard setup




As you can see the setup is almost the same as in the previous story. I attached the Arduino's ground and +5Volt to the ground and power rails of the rest of the circuit to power the complete setup. The Arduino's pin 6 is used to control the WS2811's through a 470 OHM resistor.
It is the same setup you would use to attach a bunch of Neopixels to your Arduino. As long as you use just a few WS2811's and leds youn can power the setup from your Arduino.

When you are going to attach more WS2811's use the seperate USB power supply for the WS2811's like discussed in part 1 in this series.


The Arduino program

The program is written in C++ the standard programming environment for the Arduino. Lets look at the code:



// WS2811 Test by Luc Volders
// This program sets multiple leds on and off in a sequence

#include <Adafruit_NeoPixel.h>
#include <avr/power.h>

// Which pin on the Arduino is connected to the NeoPixels?
#define PIN            6

// How many NeoPixels are attached to the Arduino?
#define NUMPIXELS      2

// When we setup the NeoPixel library, we tell it how many pixels, and which pin to use to send signals.
Adafruit_NeoPixel pixels = Adafruit_NeoPixel(NUMPIXELS, PIN, NEO_GRB + NEO_KHZ800);

int delayval = 500; // delay for half a second

void setup() 
{
  pixels.begin(); // This initializes the NeoPixel library.
}

void loop() 
{
    pixels.setPixelColor(0, pixels.Color(00,0255,255)); 
    pixels.setPixelColor(1, pixels.Color(00,0255,255));
    pixels.show(); 
    delay(delayval); 
    pixels.setPixelColor(0, pixels.Color(0255,0,0));
    pixels.setPixelColor(1, pixels.Color(0255,0,0));
    pixels.show();
    delay(delayval); 
}


The first thing the code does is to import Adafruit's Neopixel library. If you do not already have installed this library you will find a description on how to do that here:
https://learn.adafruit.com/adafruit-neopixel-uberguide/arduino-library-installation

Next step is that we tell the program that the WS2811's are attached to pin 6. I/O port no 6 on the Arduino is a PWM port and that is what we need to control the WS2811's.

Then we define the number of WS2811's which is 2 in this case. These 2 WS2811's will give us 6 output ports.

Adafruit_NeoPixel pixels = Adafruit_NeoPixel(NUMPIXELS, PIN, NEO_GRB + NEO_KHZ800);

This line does the actual setup for the WS2811's.
NUMPIXELS is the amount of WS2811's, PIN is on which IO port they are attached, NEO_GRB tells the library that it must use GRB instead of RGB and NEO_KHZ800 tells it the frequency with wthat the WS2811's should be controlled.

Let's look at the main loop:

pixels.setPixelColor(0, pixels.Color(00,0255,255));

The first zero is the number of the WS2811 in the line. The last 3 numbers are the PWM values we are going to send to the individual outputs of that WS2811. So in this line we set the first led OFF and the second and third led ON.

After the delay we turn that around:

pixels.setPixelColor(0, pixels.Color(0255,0,0));

This sets the first led ON and the other two OFF.

Altering the value 255 in any figure between 0 and 255 will DIM the led in stead of setting it to full brightness.

And here are the real life results:





So this works flawlessly. With 2 WS2811's I have created 6 extra outputs for the Arduino.

On to the Attiny85

We can use this technique also with an Attiny85. The Attiny85 normally just has 5 output pins. It would give our projects an enormous advantage if we could expand this to many more PWM able outputs. Well here we go.

Breadboard setup:



As you can see the breadboard setup is again almost identical to the previous setups.
In this case you need to use the USB external power supply.

As usual the WS2811's are attached through a 470 Ohm resistor to I/O port 1 of the Attiny85.


And this is what it looks like in real life.

The program


// Attiny85 code for controlling 6 output with ws2811
// Code written by Luc Volders

#include <Adafruit_NeoPixel.h>

// Which pin on the Attiny85 is connected to the NeoPixels?
#define PIN            1
// How many NeoPixels are attached to the Arduino?
#define NUMPIXELS      2

// Setup the NeoPixel library with how many pixels, and which pin to use to send signals.
// Note that for older NeoPixel strips you might need to change the third parameter
Adafruit_NeoPixel pixels = Adafruit_NeoPixel(NUMPIXELS, PIN, NEO_GRB + NEO_KHZ800);

int toets1=0;

void setup() 
{
  pixels.begin(); // This initializes the NeoPixel library.
  for(int i=0;i<NUMPIXELS;i++)
  pixels.setPixelColor(i, 0,0,0);
  pixels.show();
}

void loop() 
{
  for(int i=0; i<255; i++)
  {
  pixels.setPixelColor(0, 255-i,i,i);
  pixels.setPixelColor(1, 255-i,i,i);
  pixels.show();
  delay (10);
  }
}


I just altered the Arduino program a bit. The program is going to fade the leds in and out. This is done in the main loop.

The first leds are going to fade from bright to OFF and the other leds are fading from OFF to full bright.


 

And here is the result. Six extra (PWM) outputs for an Attiny85 !!!!

The next part is going to show you how we can use this technique for expanding the BBC's Micro:Bit output ports.

Till next time.
Have fun

Luc Volders