🚥 Arduino and LED address strip WS2812B

Daniil Zhuk

In this article, we will learn how to work with addressable LED RGB tape WS2812B. The tape consists of RGB pixels WS2812B in an LED 5050 package (the physical dimensions of each element are 5 × 5 mm).

Each pixel contains red, green and blue LEDs and a PWM controller, with which you can control the brightness of each LED and get a lot of different colors from the three main ones.

Since each WS2812B consists of three LEDs and a PWM controller, it is better to call them pixels rather than LEDs. In the photo on the right, you can see the device of this pixel.

A little about the characteristics of the address LEDs WS2812B:

  • Power supply: 5 ± 0.5 V;
  • Current consumption: ~ 20 mA one LED, i.e. ~ 60 mA whole pixel.

At the beginning, we need to connect the LEDs to the Arduino. Make it extremely simple. Contacts + 5V and GND are connected to the positive and negative power supply, respectively. Din is connected to an Arduino digital pin, by default it will be the 6th digital pin, but youcan use any other.

In addition, it is advisable to connect the ground of the Arduino with the ground of the power source. It is undesirable to use the Arduino as a power source since the + 5V output can provide only 800 mA of current. This is enough for no more than 13 pixels of the LED strip.

On the other side of the tape, there is a Do output, it connects to the next tape, allowing you to control the tapes in a cascade manner, like one. The power connector at the end is also duplicated.

 

Next, we will deal with the management of the tape. A description of the control protocol is present in the Datasheet for WS2812B.

All pixels are by default connected to each other in series. Din input of each of them is connected to the output Do of the next. The control signal must come to the first one.

Control commands are given in packets of 3 bytes, one for each of the three colors. Between packets, there is a pause with a duration of 50 µs, a pause of more than 100 µs means the end of the transmission.

The duration of any bit is 1.25 µs. A bit “1” is encoded by a pulse with a duration of 0.8 μs and a pause of 0.45 μs. The “0” bit is 0.4 and 0.85 μs. Time differences up to 150 ns are possible. Such a packet must be sent for each pixel in the LED strip. The diagram shows the desired signal.

Most Popular Libraries:

FastLED

Supports all versions of Arduino and a variety of data transfer protocols (not only for our tape). The programming language in which it is written is pure C.

Adafruit NeoPixel

The library is designed to work with LED rings NeoPixel Ring, the development and production of Adafruit. It works slower, has less power, but contains only the most necessary. Written in C, assembly language and some Wiring. Supports the entire line of Arduino.

CONNECTING WS2812B IN ARDUINO IDE

Let's try both libraries and compare them. Let's write a standard Blink sketch so that the tape lights up red for half a second and turns off for the same interval.

By default, the number of pixels in the tape is 30, but if necessary it can be changed in the sketch.

An example using the FastLED library:

#include "FastLED.h"
#define LED_COUNT 30
#define LED_PIN 6
CRGB strip[LED_COUNT];

void setup()
{
FastLED.addLeds<WS2812B, LED_PIN, RGB>(strip, LED_COUNT);
}

void loop()
{
for (int i = 0; i < LED_COUNT; i++)
{
strip[i] = CRGB::Red; 
}
FastLED.show();
delay(500);
for (int i = 0; i < LED_COUNT; i++)
{
strip[i] = CRGB::Black;
}
FastLED.show();
delay(500);
}

The sketch will occupy 3758 bytes in program memory of Arduino and 187 bytes of RAM.

Now let's try the same thing with the Adafruit NeoPixel library:

#include "Adafruit_NeoPixel.h"

#define LED_COUNT 30

#define LED_PIN 6

Adafruit_NeoPixel strip = Adafruit_NeoPixel(LED_COUNT, LED_PIN, NEO_GRB + NEO_KHZ800);

void setup()
{
strip.begin();
}

void loop()
{
for (int i = 0; i < LED_COUNT; i++)
{
strip.setPixelColor(i, strip.Color(255, 0, 0)); 
}
strip.show();
delay(500);
for (int i = 0; i < LED_COUNT; i++)
{
strip.setPixelColor(i, strip.Color(0, 0, 0));
}
strip.show();
delay(500);
}

The sketch will take 2592 permanent and 40 bytes of Arduino RAM.

As you can see, the FastLED library is more resource-intensive. In addition, using it in Arduino with 2 KB of RAM (such as, for example, UNO), you can control up to 600 pixels of the LED strip. This is due to the fact that 3 bytes of memory are reserved for each pixel.

But in Adafruit NeoPixel the minimum necessary functions and less memory consumption. Which one to use is your choice.

Read more →

Arduino and GSM module SIM900A. How to flash and use?

Daniil Zhuk
In this article, I will talk about working with the GSM-module SIM900A. With it, you can make automated calls and send messages in the same way. Also, it supports the GPRS protocol.

Read more →

NRF24L01 - Connection to Arduino

Daniil Zhuk
Many of you have probably heard about the remote control when everything is controlled at a great distance with a couple of simple taps. Pressed a button on the remote - and the light came on or your favorite robot clung to your feet.

Read more →

Connection to PADI via UART interface

Daniil Zhuk
The UART interface is one of the first external computer interfaces that was already used in the first self-assembled computers as a COM port (RS232, is still in use). It would be strange if PADI did not have at least one such interface, and it has as many as 3!

Read more →

☁️ DHT22 and Arduino – connection circuit

Daniil Zhuk
The vast majority of beginner projects on the Arduino are in one way or another connected with obtaining environmental data, such as weather stations. Usually, they use ultra-cheap low-flow DHT11, which normally measures the only temperature, and humidity only indirectly depends on the environment. 

Read more →

💡 Automatic staircase lighting with Arduino

Daniil Zhuk2 comments

In this post, I want to share with the Internet community about how I happened to make automatic lighting of the stairs in my two-story cottage. About four months ago, returning from work in complete darkness, I did not slip well and broke two metatarsal bones (fingers) on my left foot. The whole month had to fall into bed, as stepping on my foot was incredibly painful. Then he was limp without a plaster for another half month (those who had fractures would immediately understand me). After this sad story, I began to think about the automation of staircase lighting. After playing a little with search queries, I found a very simple solution for myself on this blog, just based on my favorite Arduino microcontroller. The scheme did not cause any difficulties, but it scared the number and length of the wires that I had to mount. Before that, I did not do anything like that. Buying ready-made solutions or hiring someone is expensive. Within a month I ordered the necessary components and unhurriedly assembled it on my stairs in a few days. Everyone who is interested in what came of it, welcome to the cut!

Components:

I will give an approximate cost of all the components that were used in the work. Most of the components purchased in the shops in my city so I will give everything in rubles.

Arduino pro mini
HC-SR04 — 2x
LED driver L5450
Voltage regulator L78M05CV
Photoresistor
Cable channel 20 × 10 mm - 10 M
Wire 2 × 0.12 - 100 M (with a margin for tapes)
4 × 0.12 - 20 M wire (for sensors)
LED Strip LSP0603W15 White - 17 pieces of 30 cm
Small things: textolite 15 × 15 cm, ferric chloride, 0.9 mm drill bit, PLS type pin connectors, BLS connectors, heat shrink tubing, capacitors and resistors
The power supply unit 12B (it is the case) from the Parus 4 alarm system

Prototype

I debugged the firmware for Arduino, like everything else, on a breadboard using ordinary LEDs.

Scheme

With the help of the notorious environment for the design of Eagle CAD, the author’s scheme and printed circuit board were improved. Here I added a voltage regulator to 5 V, changed the sensors from 3-pin expensive Ping to four-pin cheap HC-SR04. In order for the staircase lighting to work only in the dark, a Soviet photoresistor FR-764 was added to the circuit (you can also use another one).

 

 

 Sketch

The sketch uses a freely distributed library for working with the LED driver M5450, as well as a library for working with the ultrasonic range finder HC-SR04.

#include "lightuino3.h"
#include "Ultrasonic.h"
 
//Устанавливаем контакты для первого датчика
#define  TRIG_PIN  12
#define  ECHO_PIN  13
//Устанавливаем контакты для второго датчика
#define  TRIG2_PIN  10
#define  ECHO2_PIN  11
//Определяем первый датчик
Ultrasonic OurModuleUp(TRIG_PIN, ECHO_PIN);
//Определяем второй датчик
Ultrasonic OurModuleDown(TRIG2_PIN, ECHO2_PIN);
// pins 0, 1 used by Serial
const unsigned char DataPin = 6;
const unsigned char clockPin = 7;
 
// задержка между ступеньками
const long lightSpacing = 280;
//задержка свечения всей лестницы
const long lightHold = 10000;
//задержка выстрела сенсоров
const long pingReadDelay = 50;
 
// Диапазон при котором сработает сенсор
const float minBottomIn = 33.0f;
const float minTopIn = minBottomIn;
 
LightuinoSink sinks(clockPin, DataPin, 100, 4);
 
boolean bClimbStarted = false;
boolean bDescentStarted = false;
 
int val;
void setup() {
  Serial.begin(9600);
  pinMode(DataPin, OUTPUT);
  pinMode(clockPin, OUTPUT);
  delay(1000);
  sinks.set(0,0,0);
}
 
void loop() {
   val = analogRead(0);
   //Проверяем освещенность в помещении
   if (val>=1020){
 
 UltrasonicDownFire();//Выстрел нижнего датчика
  if(bClimbStarted) {
    bClimbStarted = false;
    bDescentStarted = false;
    climbLightSequence();
  }
  else {
    // Выстрел верхнего датчика
    UltrasonicUpFire();
    if(bDescentStarted) {
      bClimbStarted = false;
      bDescentStarted = false;
      descentLightSequence();
    }
  }
  delay(pingReadDelay);
  }
}
 
//Обработка верхнего датчика
void UltrasonicUpFire() {
 
if((OurModuleUp.Ranging(INC) < minTopIn) && (OurModuleUp.Ranging(INC) > 0))
{
Serial.println("Top sensor tripped.");
bDescentStarted = true;
}
}
 
//Обработка нижнего датчика]
void UltrasonicDownFire() {
 
    if((OurModuleDown.Ranging(INC) < minTopIn) && (OurModuleDown.Ranging(INC) > 0)) {
      Serial.println("Bottom sensor tripped.");
      bClimbStarted = true;
    }
}
 
void climbLightSequence(){
LedsOnDown();
}
void LedsOnDown(){
  //Обнуляем
   byte ledState[9];
  for (int j=0;j=0;k--)
  {
  for (int j=8;j>=1;j--)
  {
   ledState[k] = (ledState[k] >> 1) + 128;
    sinks.set(ledState);
    delay(lightSpacing);
  }
     }
//Задержка
  delay(lightHold);
//Гасим
  for (int k=1;k>=0;k--)
  {
  for (int j=8;j>=1;j--)
    {
    ledState[k] = (ledState[k] >> 1);
    sinks.set(ledState);
    delay(lightSpacing);
    }
  }
 delay(pingReadDelay);
}
 
void descentLightSequence(){
  LedsOnUp();
}
 
void LedsOnUp(){
 //Обнуляем
  byte ledState[9];
  for (int j=0;j    ledState[j] = B00000000;
  }
 //Зажигаем
  for (int k=0;k  {
  for (int j=0;j  {
    ledState[k]=(ledState[k] << 1) + 1;
    sinks.set(ledState);
     delay(lightSpacing);
  }    }
  delay(lightHold);
  for (int k=0;k  {
  for (int j=0;j  {
    ledState[k]=(ledState[k] << 1);
    sinks.set(ledState);
     delay(lightSpacing);
  }
}
 delay(pingReadDelay);
}

 

A little bit about the installation

Since I have the simplest wooden staircase (without a landing board), the mounting of LED strips was carried out from the end of each step.

 

 The cable channel runs along the entire length with the wires laid and glued to liquid nails. LED strips initially have a sticky side, they stick perfectly on the tree.

 

 Sensors were installed at the beginning of each first step at the top and bottom of the stairs. As a fastener, I used ordinary flush-mounted backing plates.

 

 A dead battery was thrown out of the case of the power supply unit for the alarm; our controller easily fitted into its place.

The lid is in place. Place the controller under the landing.

Result

In fact, the video does not reflect the real picture. The staircase is lit much more beautiful and brighter.

Read more →

🌟 Writing in the air with LEDs

Daniil Zhuk

Everyone probably knows about the effect of the resulting inscription or pattern when the bar is quickly moved, sometimes a disc with a strip of LEDs that light up in a specially synchronized manner. The effect is called persistence. The effect itself is based on the inertia of the human eye. In order for such an effect to occur, the LEDs must light up at certain points in time so that they shine at fixed points in space when moving left-right.

In the design, which will be discussed, the author used an accelerometer on a circuit board with an LED strip and Arduino Diecimila for control. Power is supplied via USB, but you can connect and stand-alone.

Assembly

Installation was made on a breadboard. The LED strip, direct connectors for connection to the Arduino board and the edge connector for the accelerometer were mounted. The board connects to the Arduino as a standard expansion card.

The small green board is a three-axis accelerometer, from which the value is taken through the analog inputs of the Arduino. Depending on the acceleration, the accelerometer changes the voltage at its outputs.

Code:

// Display goes on PORTD
// GS1 on 10 Sensitivity Selection pins
// GS2 on 11 +- 4g selected here
// SLEEP on 12 and active LOW

int GS1 = 10;
int GS2 = 11;
int SLEEP = 12;

int Y=0; // Temp
int p=0; //Temp

// Tells the microcontroller how to write letters. Little Kid.
// Taken from Sparkfun Library
int text_array[475] = {
0x00,0x00,0x00,0x00,0x00,/*space*/ // is 32 in ASCII
0x00,0xF6,0xF6,0x00,0x00,/*!*/
0x00,0xE0,0x00,0xE0,0x00,/*"*/
0x28,0xFE,0x28,0xFE,0x28,/*#*/
0x00,0x64,0xD6,0x54,0x08,/*$*/
0xC2,0xCC,0x10,0x26,0xC6,/*%*/
0x4C,0xB2,0x92,0x6C,0x0A,/*&*/
0x00,0x00,0xE0,0x00,0x00,/*'*/
0x00,0x38,0x44,0x82,0x00,/*(*/
0x00,0x82,0x44,0x38,0x00,/*)*/
0x88,0x50,0xF8,0x50,0x88,/***/
0x08,0x08,0x3E,0x08,0x08,/*+*/
0x00,0x00,0x05,0x06,0x00,/*,*/
0x08,0x08,0x08,0x08,0x08,/*-*/
0x00,0x00,0x06,0x06,0x00,/*.*/
0x02,0x0C,0x10,0x60,0x80,/*/*/
0x7C,0x8A,0x92,0xA2,0x7C,/*0*/
0x00,0x42,0xFE,0x02,0x00,/*1*/
0x42,0x86,0x8A,0x92,0x62,/*2*/
0x44,0x82,0x92,0x92,0x6C,/*3*/
0x10,0x30,0x50,0xFE,0x10,/*4*/
0xE4,0xA2,0xA2,0xA2,0x9C,/*5*/
0x3C,0x52,0x92,0x92,0x0C,/*6*/
0x80,0x86,0x98,0xE0,0x80,/*7*/
0x6C,0x92,0x92,0x92,0x6C,/*8*/
0x60,0x92,0x92,0x94,0x78,/*9*/
0x00,0x00,0x36,0x36,0x00,/*:*/
0x00,0x00,0x35,0x36,0x00,/*;*/
0x10,0x28,0x44,0x82,0x00,/*<*/
0x28,0x28,0x28,0x28,0x28,/*=*/
0x00,0x82,0x44,0x28,0x10,/*>*/
0x40,0x80,0x8A,0x90,0x60,/*?*/
0x7C,0x82,0xBA,0xBA,0x62,/*@*/
0x3E,0x48,0x88,0x48,0x3E,/*A*/
0xFE,0x92,0x92,0x92,0x6C,/*B*/
0x7C,0x82,0x82,0x82,0x44,/*C*/
0xFE,0x82,0x82,0x82,0x7C,/*D*/
0xFE,0x92,0x92,0x92,0x82,/*E*/
0xFE,0x90,0x90,0x90,0x80,/*F*/
0x7C,0x82,0x82,0x8A,0x4E,/*G*/
0xFE,0x10,0x10,0x10,0xFE,/*H*/
0x82,0x82,0xFE,0x82,0x82,/*I*/
0x84,0x82,0xFC,0x80,0x80,/*J*/
0xFE,0x10,0x28,0x44,0x82,/*K*/
0xFE,0x02,0x02,0x02,0x02,/*L*/
0xFE,0x40,0x20,0x40,0xFE,/*M*/
0xFE,0x60,0x10,0x0C,0xFE,/*N*/
0x7C,0x82,0x82,0x82,0x7C,/*O*/
0xFE,0x90,0x90,0x90,0x60,/*P*/
0x7C,0x82,0x82,0x86,0x7E,/*Q*/
0xFE,0x90,0x98,0x94,0x62,/*R*/
0x64,0x92,0x92,0x92,0x4C,/*S*/
0x80,0x80,0xFE,0x80,0x80,/*T*/
0xFC,0x02,0x02,0x02,0xFC,/*U*/
0xF8,0x04,0x02,0x04,0xF8,/*V*/
0xFC,0x02,0x0C,0x02,0xFC,/*W*/
0xC6,0x28,0x10,0x28,0xC6,/*X*/
0xC0,0x20,0x1E,0x20,0xC0,/*Y*/
0x86,0x8A,0x92,0xA2,0xC2,/*Z*/
0x00,0x00,0xFE,0x82,0x00,/*[*/
0x00,0x00,0x00,0x00,0x00,/*this should be / */
0x80,0x60,0x10,0x0C,0x02,/*]*/
0x20,0x40,0x80,0x40,0x20,/*^*/
0x01,0x01,0x01,0x01,0x01,/*_*/
0x80,0x40,0x20,0x00,0x00,/*`*/
0x04,0x2A,0x2A,0x2A,0x1E,/*a*/
0xFE,0x12,0x22,0x22,0x1C,/*b*/
0x1C,0x22,0x22,0x22,0x14,/*c*/
0x1C,0x22,0x22,0x12,0xFE,/*d*/
0x1C,0x2A,0x2A,0x2A,0x18,/*e*/
0x10,0x7E,0x90,0x80,0x40,/*f*/
0x18,0x25,0x25,0x25,0x1E,/*g*/
0xFE,0x10,0x10,0x10,0x0E,/*h*/
0x00,0x12,0x5E,0x02,0x00,/*i*/
0x02,0x01,0x01,0x11,0x5E,/*j*/
0xFE,0x08,0x08,0x14,0x22,/*k*/
0x00,0x82,0xFE,0x02,0x00,/*l*/
0x3E,0x20,0x1C,0x20,0x1E,/*m*/
0x3E,0x20,0x20,0x20,0x1E,/*n*/
0x1C,0x22,0x22,0x22,0x1C,/*o*/
0x3F,0x24,0x24,0x24,0x18,/*p*/
0x18,0x24,0x24,0x3F,0x01,/*q*/
0x3E,0x10,0x20,0x20,0x10,/*r*/
0x12,0x2A,0x2A,0x2A,0x04,/*s*/
0x00,0x10,0x3C,0x12,0x04,/*t*/
0x3C,0x02,0x02,0x02,0x3E,/*u*/
0x30,0x0C,0x02,0x0C,0x30,/*v*/
0x38,0x06,0x18,0x06,0x38,/*w*/
0x22,0x14,0x08,0x14,0x22,/*x*/
0x38,0x05,0x05,0x05,0x3E,/*y*/
0x22,0x26,0x2A,0x32,0x22,/*z*/
0x00,0x10,0x6C,0x82,0x82,/*{*/
//0x00,0x00,0xFF,0x00,0x00,/*|*/
0x04,0x02,0xFF,0x02,0x04,/*|, arrow*/
0x82,0x82,0x6C,0x10,0x00,/*}*/
0x08,0x10,0x18,0x08,0x10/*~*/
};

// Displays the text
void display(char c)
{
int i = (c - 32)*5;
for ( int temp = i; temp < i + 5; temp++ ) {
PORTD = text_array[temp]; delayMicroseconds(500);
PORTD = 0x00; delay(3);
}
PORTD = 0x00; delay(3);
}

void setup()
{
pinMode(0,OUTPUT); // Set display as OUTPUT
pinMode(1,OUTPUT);
pinMode(2,OUTPUT);
pinMode(3,OUTPUT);
pinMode(4,OUTPUT);
pinMode(5,OUTPUT);
pinMode(6,OUTPUT);
pinMode(7,OUTPUT);
pinMode(8,OUTPUT);
pinMode(9,OUTPUT);
pinMode(10,OUTPUT);
pinMode(11,OUTPUT);
pinMode(12,OUTPUT);
pinMode(13,OUTPUT);

digitalWrite(GS1,HIGH); // Sensitivity Select
digitalWrite(GS2,LOW);
digitalWrite(SLEEP,HIGH); // Don't let the Accelerometer sleep !!!
}

void loop()
{
Y = analogRead(1); // Read the sensor...
if ( Y > 650)
{
p++;
if(p=2) // Take alternate acceleration...
{
p=0;
delay(60); // Wait a moment before starting

display('P'); // Paaaaraaammm...
display('a');
display('r');
display('a');
display('m');
display(':');
display('-');
display(')');
display(' ');
}
}
}

Now it remains to connect the assembly to the computer and swing it.

Read more →

📸 Photo flash control with Arduino controller

Daniil Zhuk

In this project, we will explain how to control the flash using the Arduino controller. To control the flash will need a “hot shoe”, through which we will give a sync signal. This assembly uses a shoe with a standard connector for a 1/8-inch plug. In general, you can use any other shoe. The signal for the flash in the overwhelming majority is the closure of the contacts of the sync cable. An optocoupler (characteristic) is used for the galvanic isolation of the flash circuit and the Arduino circuit. Using an optocoupler will allow you to isolate the controller from possible surges when the flash is triggered, which is especially characteristic of old flashes.

The control circuit is shown in the figure. It is very simple: we simply apply HIGH to the digital output, which closes the flash circuit through the optocoupler. The duration of the signal is 0.1 s.

Code:

// Maurice Ribble

#define CAMERA_FLASH_PIN 4

void setup()
{
pinMode(CAMERA_FLASH_PIN, OUTPUT);
digitalWrite(CAMERA_FLASH_PIN, LOW);
Serial.begin(9600); // open serial
Serial.println("Press the spacebar to trigger the flash");
}

void loop()
{
int cmd;

while (Serial.available() > 0)
{
int cmd = Serial.read();

switch (cmd)
{
case ' ':
{
digitalWrite(CAMERA_FLASH_PIN, HIGH);
delay(100);
digitalWrite(CAMERA_FLASH_PIN, LOW);
break;
}
default:
{
Serial.println("Press the spacebar to trigger the flash");
}
}
}
}

 

Read more →

✨ Arduino and RGB 8x8 LED Matrix

Daniil Zhuk
In this project, the author will show how you can connect a full-color 8x8 LED matrix to the Arduino. The matrix itself has 32 inputs: 8 anodes, 8 red cathodes, 8 green and 8 blue. At the same time to control the matrix will be involved only 3 outputs on the Arduino. There is no magic here, but there are 4 shift registers 74HC595.

Read more →

🔌 Digital Voltmeter on Arduino with PC connection via serial port

Daniil Zhuk
This article shows how to connect Arduino and a PC and transfer data to the PC from the ADC. A Windows program written using Visual C ++ 2008 Express. The program of the voltmeter is very simple and has an extensive field for improvements. Its main purpose was to show the work with the COM port and the exchange of data between the computer and the Arduino.

Read more →