Hardware components | ||||||
| × | 1 | ||||
| × | 4 | ||||
| × | 1 | ||||
| × | 1 | ||||
| × | 1 | ||||
| × | 1 | ||||
Software apps and online services | ||||||
| ||||||
| ||||||
|
Well, well, well...
Look who's back uploading projects again.
It's me. I'm talking about me.
This is a step-by-step project tutorial on how you can set a WS2812B strip's brightness level and mix its colors to your desired hue.
By just using a few 10k potentiometers and a WS2812B Addressable RGB LED strp, you can make your own background lighting for video production, photos, biased lighting behind your monitor or ambient/mood lighting for your room.
The applications depends on your creativity or where you want to use it.
Yes. There are better aftermarket products available for cheap that has Bluetooth or WiFi connectivity, but the fact is that you can also add those functions to this if you really wanted to.
Code-wise, it's pretty simple/easy since most of it are sample codes from the Arduino IDE.
******************************************************************************
Helpful Links:Analog In-Out Serial Sample Code
FastLED Github Library Basic Usage
******************************************************************************
Social Media Links To Follow (I mean, if you want to):******************************************************************************
int Pot = A0;
int PotVal = 0;
void setup() {
Serial.begin(9600);
}
void loop() {
PotVal = analogRead(Pot);
Serial.println(PotVal);
}
#include <FastLED.h>
#define NUM_LEDS 1
#define DATA_PIN 2
CRGB leds[NUM_LEDS];
int Pot = A0;
int PotVal = 0;
int OutVal = 0;
void setup() {
Serial.begin(9600);
FastLED.addLeds<WS2812B, DATA_PIN, GRB>(leds, NUM_LEDS);
}
void loop() {
PotVal = analogRead(Pot);
Serial.println(OutVal);
OutVal = map(PotVal, 0, 1023, 0, 255);
analogWrite(NUM_LEDS, OutVal);
FastLED.setBrightness(OutVal);
leds[0] = CRGB(255, 255, 255);
FastLED.show();
}
#include <FastLED.h>
#define NUM_LEDS 1
#define DATA_PIN 2
CRGB leds[NUM_LEDS];
int BrightPot = A0;
int BrightPotVal = 0;
int BrightOutVal = 0;
int RedPot = A1;
int RedPotVal = 0;
int RedOutVal = 0;
int GreenPot = A2;
int GreenPotVal = 0;
int GreenOutVal = 0;
int BluePot = A3;
int BluePotVal = 0;
int BlueOutVal = 0;
void setup() {
Serial.begin(9600);
FastLED.addLeds<WS2812B, DATA_PIN, GRB>(leds, NUM_LEDS);
}
void loop() {
//BRIGHTNESS
FastLED.setBrightness(BrightOutVal);
BrightPotVal = analogRead(BrightPot);
BrightOutVal = map(BrightPotVal, 0, 1023, 0, 255);
analogWrite(NUM_LEDS, BrightOutVal);
if (BrightOutVal <= 5)
{
Serial.print("");
}
if (BrightOutVal >= 10)
{
Serial.print("Brightness Value= ");
Serial.println(BrightOutVal);
}
//RED
RedPotVal = analogRead(RedPot);
RedOutVal = map(RedPotVal, 0, 1023, 0, 255);
analogWrite(NUM_LEDS, RedOutVal);
if (RedOutVal <= 5)
{
Serial.print("");
}
if (RedOutVal >= 10)
{
Serial.print("Red Value= ");
Serial.println(RedOutVal);
}
//GREEN
GreenPotVal = analogRead(GreenPot);
GreenOutVal = map(GreenPotVal, 0, 1023, 0, 255);
analogWrite(NUM_LEDS, GreenOutVal);
if (GreenOutVal <= 5)
{
Serial.print("");
}
if (GreenOutVal >= 10)
{
Serial.print("Green Value= ");
Serial.println(GreenOutVal);
}
//BLUE
BluePotVal = analogRead(BluePot);
BlueOutVal = map(BluePotVal, 0, 1023, 0, 255);
analogWrite(NUM_LEDS, BlueOutVal);
if (BlueOutVal <= 5)
{
Serial.print("");
}
if (BlueOutVal >= 10)
{
Serial.print("Blue Value= ");
Serial.println(BlueOutVal);
}
leds[0] = CRGB(RedOutVal, GreenOutVal, BlueOutVal);
FastLED.show();
}
#include <FastLED.h>
#include "LiquidCrystal_PCF8574.h"
#define NUM_LEDS 1
#define DATA_PIN 2
#define LCD_ADDRESS 0x27
#define LCD_ROWS 2
#define LCD_COLUMNS 16
#define SCROLL_DELAY 150
#define BACKLIGHT 255
LiquidCrystal_PCF8574 LCDi2C;
CRGB leds[NUM_LEDS];
int BrightPot = A0;
int BrightPotVal = 0;
int BrightOutVal = 0;
int RedPot = A1;
int RedPotVal = 0;
int RedOutVal = 0;
int GreenPot = A2;
int GreenPotVal = 0;
int GreenOutVal = 0;
int BluePot = A3;
int BluePotVal = 0;
int BlueOutVal = 0;
void setup()
{
Serial.begin(9600);
LCDi2C.begin(LCD_COLUMNS, LCD_ROWS, LCD_ADDRESS, BACKLIGHT);
FastLED.addLeds<WS2812B, DATA_PIN, GRB>(leds, NUM_LEDS);
}
void loop()
{
//BRIGHTNESS
FastLED.setBrightness(BrightOutVal);
BrightPotVal = analogRead(BrightPot);
BrightOutVal = map(BrightPotVal, 0, 1023, 0, 255);
analogWrite(NUM_LEDS, BrightOutVal);
//RED
RedPotVal = analogRead(RedPot);
RedOutVal = map(RedPotVal, 0, 1023, 0, 255);
analogWrite(NUM_LEDS, RedOutVal);
//GREEN
GreenPotVal = analogRead(GreenPot);
GreenOutVal = map(GreenPotVal, 0, 1023, 0, 255);
analogWrite(NUM_LEDS, GreenOutVal);
//BLUE
BluePotVal = analogRead(BluePot);
BlueOutVal = map(BluePotVal, 0, 1023, 0, 255);
analogWrite(NUM_LEDS, BlueOutVal);
LCDi2C.setCursor(0, 0);
LCDi2C.print("Brightness:");
LCDi2C.print(BrightOutVal);
LCDi2C.print(" ");
LCDi2C.setCursor(0, 1);
LCDi2C.print("R:");
LCDi2C.print(RedOutVal);
LCDi2C.print(" G:");
LCDi2C.print(GreenOutVal);
LCDi2C.print(" B:");
LCDi2C.print(BlueOutVal);
LCDi2C.print(" ");
leds[0] = CRGB(RedOutVal, GreenOutVal, BlueOutVal);
FastLED.show();
}
///
/// \file LiquidCrystal_PCF8574.h
/// \brief LiquidCrystal library with PCF8574 I2C adapter.
///
/// \author Matthias Hertel, http://www.mathertel.de
/// \copyright Copyright (c) 2014 by Matthias Hertel.\n
/// This work is licensed under a BSD style license.\n
/// See http://www.mathertel.de/License.aspx
///
/// Copyright (c) 2005-2012 by Matthias Hertel, http://www.mathertel.de/
/// All rights reserved.
///
/// * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
/// * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
/// * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the
/// documentation and/or other materials provided with the distribution. Neither the name of the copyright owners nor the names of its
/// contributors may be used to endorse or promote products derived from this software without specific prior written permission.
///
/// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
/// INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
/// IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
/// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
/// OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
/// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
/// \details
/// This is a library for driving LiquidCrystal displays (LCD) by using the I2C bus and an PCF8574 I2C adapter.
/// This library is derived from the original Arduino LiquidCrystal library and uses the original Wire library for communication.
///
/// ChangeLog:
/// --------
/// * 19.10.2013 created.
/// * 24.05.2015 Arduino Library Manager compatible.
/// * 20.12.2016 circuito.io:
/// * Added scrolling multiple chars to scrolling functions
/// * Added selectLine function, same as setCursor(0, line - 1)
/// * Added checkI2CConnection - prints to the serial monitor if connection faild. it is called inside begin.
#ifndef LiquidCrystal_PCF8574_h
#define LiquidCrystal_PCF8574_h
#include <inttypes.h>
#include "Print.h"
// commands
#define LCD_CLEARDISPLAY 0x01
#define LCD_RETURNHOME 0x02
#define LCD_ENTRYMODESET 0x04
#define LCD_DISPLAYCONTROL 0x08
#define LCD_CURSORSHIFT 0x10
#define LCD_FUNCTIONSET 0x20
#define LCD_SETCGRAMADDR 0x40
#define LCD_SETDDRAMADDR 0x80
// flags for display entry mode
#define LCD_ENTRYRIGHT 0x00
#define LCD_ENTRYLEFT 0x02
#define LCD_ENTRYSHIFTINCREMENT 0x01
#define LCD_ENTRYSHIFTDECREMENT 0x00
// flags for display on/off control
#define LCD_DISPLAYON 0x04
#define LCD_DISPLAYOFF 0x00
#define LCD_CURSORON 0x02
#define LCD_CURSOROFF 0x00
#define LCD_BLINKON 0x01
#define LCD_BLINKOFF 0x00
// flags for display/cursor shift
#define LCD_DISPLAYMOVE 0x08
#define LCD_CURSORMOVE 0x00
#define LCD_MOVERIGHT 0x04
#define LCD_MOVELEFT 0x00
// flags for function set
#define LCD_8BITMODE 0x10
#define LCD_4BITMODE 0x00
#define LCD_2LINE 0x08
#define LCD_1LINE 0x00
#define LCD_5x10DOTS 0x04
#define LCD_5x8DOTS 0x00
class LiquidCrystal_PCF8574 : public Print {
public:
LiquidCrystal_PCF8574();
LiquidCrystal_PCF8574(uint8_t addr);
void begin(uint8_t cols, uint8_t rows, uint8_t charsize = LCD_5x8DOTS);
void begin(uint8_t cols, uint8_t lines, uint8_t addr, uint8_t backlight);
bool checkI2CConnection();
void clear();
void home();
void noDisplay();
void display();
void noBlink();
void blink();
void noCursor();
void cursor();
void scrollDisplayLeft(int charsToScroll, int scrollSpeed);
void scrollDisplayRight(int charsToScroll, int scrollSpeed);
void leftToRight();
void rightToLeft();
void autoscroll();
void noAutoscroll();
void setBacklight(uint8_t brightness);
void createChar(uint8_t, uint8_t[]);
void setCursor(uint8_t col, uint8_t row);
void selectLine(uint8_t line);
virtual size_t write(uint8_t);
using Print::write;
private:
// low level functions
void _command(uint8_t);
void _send(uint8_t value, uint8_t mode);
void _sendNibble(uint8_t halfByte, uint8_t mode);
void _write2Wire(uint8_t halfByte, uint8_t mode, uint8_t enable);
// NEW:
uint8_t _Addr; ///< Wire Address of the LCD
uint8_t _backlight; ///< the backlight intensity
uint8_t _displayfunction; ///< lines and dots mode
uint8_t _displaycontrol; ///< cursor, display, blink flags
uint8_t _displaymode; ///< left2right, autoscroll
uint8_t _numlines; ///< The number of rows the display supports.
};
#endif
///
/// \file LiquidCrystal_PCF8574.cpp
/// \brief LiquidCrystal (LCD) library with PCF8574 I2C adapter.
///
/// \author Matthias Hertel, http://www.mathertel.de
/// \copyright Copyright (c) 2014 by Matthias Hertel.\n
/// This work is licensed under a BSD style license.\n
/// See http://www.mathertel.de/License.aspx
///
/// \details
/// This is a library for driving LiquidCrystal displays (LCD) by using the I2C bus and an PCF8574 I2C adapter.
/// This library is derived from the original Arduino LiquidCrystal library and uses the original Wire library for communication.
///
/// More documentation and source code is available at http://www.mathertel.de/Arduino
///
/// ChangeLog see: LiquidCrystal_PCF8574.h
#include "LiquidCrystal_PCF8574.h"
#include <stdio.h>
#include <string.h>
#include <inttypes.h>
#include "Arduino.h"
#include <Wire.h>
/// Definitions on how the PCF8574 is connected to the LCD
/// These are Bit-Masks for the special signals and background light
#define PCF_RS 0x01
#define PCF_RW 0x02
#define PCF_EN 0x04
#define PCF_BACKLIGHT 0x08
// Definitions on how the PCF8574 is connected to the LCD
// These are Bit-Masks for the special signals and Background
#define RSMODE_CMD 0
#define RSMODE_DATA 1
// When the display powers up, it is configured as follows:
//
// 1. Display clear
// 2. Function set:
// DL = 1; 8-bit interface data
// N = 0; 1-line display
// F = 0; 5x8 dot character font
// 3. Display on/off control:
// D = 0; Display off
// C = 0; Cursor off
// B = 0; Blinking off
// 4. Entry mode set:
// I/D = 1; Increment by 1
// S = 0; No shift
//
// Note, however, that resetting the Arduino doesn't reset the LCD, so we
// can't assume that its in that state when a sketch starts (and the
// LiquidCrystal constructor is called).
// modification:
// don't use ports from Arduino, but use ports from Wire
// a nibble is a half Byte
// NEW: http://playground.arduino.cc//Code/LCDAPI
// NEW: setBacklight
LiquidCrystal_PCF8574::LiquidCrystal_PCF8574()
{
//_backlight = 255;
} // LiquidCrystal_PCF8574
LiquidCrystal_PCF8574::LiquidCrystal_PCF8574(uint8_t addr)
{
_Addr = addr;
_backlight = 0;
} // LiquidCrystal_PCF8574
void LiquidCrystal_PCF8574::begin(uint8_t cols, uint8_t lines, uint8_t addr, uint8_t backlight)
{
_backlight = backlight;
_Addr = addr;
begin(cols, lines);
}
void LiquidCrystal_PCF8574::begin(uint8_t cols, uint8_t lines, uint8_t dotsize) {
// cols ignored !
_numlines = lines;
_displayfunction = 0;
if (lines > 1) {
_displayfunction |= LCD_2LINE;
}
// for some 1 line displays you can select a 10 pixel high font
if ((dotsize != 0) && (lines == 1)) {
_displayfunction |= LCD_5x10DOTS;
}
// SEE PAGE 45/46 FOR INITIALIZATION SPECIFICATION!
// according to datasheet, we need at least 40ms after power rises above 2.7V
// before sending commands. Arduino can turn on way befor 4.5V so we'll wait 50
Wire.begin();
// initializing th display
_write2Wire(0x00, LOW, false);
delayMicroseconds(50000);
// put the LCD into 4 bit mode according to the hitachi HD44780 datasheet figure 26, pg 47
_sendNibble(0x03, RSMODE_CMD);
delayMicroseconds(4500);
_sendNibble(0x03, RSMODE_CMD);
delayMicroseconds(4500);
_sendNibble(0x03, RSMODE_CMD);
delayMicroseconds(150);
// finally, set to 4-bit interface
_sendNibble(0x02, RSMODE_CMD);
// finally, set # lines, font size, etc.
_command(LCD_FUNCTIONSET | _displayfunction);
// turn the display on with no cursor or blinking default
_displaycontrol = LCD_DISPLAYON | LCD_CURSOROFF | LCD_BLINKOFF;
display();
// clear it off
clear();
// Initialize to default text direction (for romance languages)
_displaymode = LCD_ENTRYLEFT | LCD_ENTRYSHIFTDECREMENT;
// set the entry mode
_command(LCD_ENTRYMODESET | _displaymode);
setBacklight(_backlight);
checkI2CConnection();
}
/********** high level commands, for the user! */
void LiquidCrystal_PCF8574::clear()
{
_command(LCD_CLEARDISPLAY); // clear display, set cursor position to zero
delayMicroseconds(2000); // this command takes a long time!
}
void LiquidCrystal_PCF8574::home()
{
_command(LCD_RETURNHOME); // set cursor position to zero
delayMicroseconds(2000); // this command takes a long time!
}
/// Set the cursor to a new position.
void LiquidCrystal_PCF8574::setCursor(uint8_t col, uint8_t row)
{
int row_offsets[] = { 0x00, 0x40, 0x14, 0x54 };
if ( row >= _numlines ) {
row = _numlines-1; // we count rows starting w/0
}
_command(LCD_SETDDRAMADDR | (col + row_offsets[row]));
}
/** select begining of line
* line - 1 for first row, 2 for second row
*
*/
void LiquidCrystal_PCF8574::selectLine(uint8_t line)
{
setCursor(0, line - 1);
}
// Turn the display on/off (quickly)
void LiquidCrystal_PCF8574::noDisplay() {
_displaycontrol &= ~LCD_DISPLAYON;
_command(LCD_DISPLAYCONTROL | _displaycontrol);
}
void LiquidCrystal_PCF8574::display() {
_displaycontrol |= LCD_DISPLAYON;
_command(LCD_DISPLAYCONTROL | _displaycontrol);
}
// Turns the underline cursor on/off
void LiquidCrystal_PCF8574::noCursor() {
_displaycontrol &= ~LCD_CURSORON;
_command(LCD_DISPLAYCONTROL | _displaycontrol);
}
void LiquidCrystal_PCF8574::cursor() {
_displaycontrol |= LCD_CURSORON;
_command(LCD_DISPLAYCONTROL | _displaycontrol);
}
// Turn on and off the blinking cursor
void LiquidCrystal_PCF8574::noBlink() {
_displaycontrol &= ~LCD_BLINKON;
_command(LCD_DISPLAYCONTROL | _displaycontrol);
}
void LiquidCrystal_PCF8574::blink() {
_displaycontrol |= LCD_BLINKON;
_command(LCD_DISPLAYCONTROL | _displaycontrol);
}
/** These commands scroll the display without changing the RAM
* charsToScroll - how many chars to scroll left
* scrollSpeed - define scrolling speed, im milliseconds.
*/
void LiquidCrystal_PCF8574::scrollDisplayLeft(int charsToScroll, int scrollSpeed) {
for (int i=0 ; i < charsToScroll ; i++)
{
_command(LCD_CURSORSHIFT | LCD_DISPLAYMOVE | LCD_MOVELEFT);
delay(scrollSpeed);
}
}
/** These commands scroll the display without changing the RAM
* charsToScroll - how many chars to scroll right
* scrollSpeed - define scrolling speed, im milliseconds.
*/
void LiquidCrystal_PCF8574::scrollDisplayRight(int charsToScroll, int scrollSpeed) {
for (int i=0 ; i < charsToScroll ; i++)
{
_command(LCD_CURSORSHIFT | LCD_DISPLAYMOVE | LCD_MOVERIGHT);
delay(scrollSpeed);
}
}
// This is for text that flows Left to Right
void LiquidCrystal_PCF8574::leftToRight(void) {
_displaymode |= LCD_ENTRYLEFT;
_command(LCD_ENTRYMODESET | _displaymode);
}
// This is for text that flows Right to Left
void LiquidCrystal_PCF8574::rightToLeft(void) {
_displaymode &= ~LCD_ENTRYLEFT;
_command(LCD_ENTRYMODESET | _displaymode);
}
// This will 'right justify' text from the cursor
void LiquidCrystal_PCF8574::autoscroll(void) {
_displaymode |= LCD_ENTRYSHIFTINCREMENT;
_command(LCD_ENTRYMODESET | _displaymode);
}
// This will 'left justify' text from the cursor
void LiquidCrystal_PCF8574::noAutoscroll(void) {
_displaymode &= ~LCD_ENTRYSHIFTINCREMENT;
_command(LCD_ENTRYMODESET | _displaymode);
}
/// Setting the brightness of the background display light.
/// The backlight can be switched on and off.
/// The current brightness is stored in the private _backlight variable to have it available for further data transfers.
void LiquidCrystal_PCF8574::setBacklight(uint8_t brightness) {
_backlight = brightness;
// send no data but set the background-pin right;
_write2Wire(0x00, RSMODE_DATA, false);
} // setBacklight
// Allows us to fill the first 8 CGRAM locations
// with custom characters
void LiquidCrystal_PCF8574::createChar(uint8_t location, uint8_t charmap[]) {
location &= 0x7; // we only have 8 locations 0-7
_command(LCD_SETCGRAMADDR | (location << 3));
for (int i=0; i<8; i++) {
write(charmap[i]);
}
}
/* The write function is needed for derivation from the Print class. */
inline size_t LiquidCrystal_PCF8574::write(uint8_t value) {
_send(value, RSMODE_DATA);
return 1; // assume sucess
}
/* ----- low level functions ----- */
inline void LiquidCrystal_PCF8574::_command(uint8_t value) {
_send(value, RSMODE_CMD);
} // _command()
// write either command or data
void LiquidCrystal_PCF8574::_send(uint8_t value, uint8_t mode) {
// separate the 4 value-nibbles
uint8_t valueLo = value & 0x0F;
uint8_t valueHi = value>>4 & 0x0F;
_sendNibble(valueHi, mode);
_sendNibble(valueLo, mode);
} // _send()
// write a nibble / halfByte with handshake
void LiquidCrystal_PCF8574::_sendNibble(uint8_t halfByte, uint8_t mode) {
_write2Wire(halfByte, mode, true);
delayMicroseconds(1); // enable pulse must be >450ns
_write2Wire(halfByte, mode, false);
delayMicroseconds(37); // commands need > 37us to settle
} // _sendNibble
// private function to change the PCF8674 pins to the given value
void LiquidCrystal_PCF8574::_write2Wire(uint8_t halfByte, uint8_t mode, uint8_t enable) {
// map the given values to the hardware of the I2C schema
uint8_t i2cData = halfByte << 4;
if (mode > 0) i2cData |= PCF_RS;
// PCF_RW is never used.
if (enable > 0) i2cData |= PCF_EN;
if (_backlight > 0) i2cData |= PCF_BACKLIGHT;
Wire.beginTransmission(_Addr);
Wire.write(i2cData);
Wire.endTransmission();
} // write2Wire
bool LiquidCrystal_PCF8574::checkI2CConnection()
{
int error;
// See http://playground.arduino.cc/Main/I2cScanner
Wire.begin();
Wire.beginTransmission(_Addr);
error = Wire.endTransmission();
if (error)
{
Serial.println("LCD not found.");
}
return error;
}
// The End.
Comments