Hackster is hosting Hackster Holidays, Ep. 6: Livestream & Giveaway Drawing. Watch previous episodes or stream live on Monday!Stream Hackster Holidays, Ep. 6 on Monday!
HeathenHacks
Published © GPL3+

WS2812B RGB LED Brightness Control & Color Mixing

Using 10K Potentiometers + 16x2 LCD w/ I2C backpack (optional)

BeginnerFull instructions provided8,381
WS2812B RGB LED Brightness Control & Color Mixing

Things used in this project

Hardware components

LED Strip, NeoPixel Digital RGB
LED Strip, NeoPixel Digital RGB
WS2812B Addressable RGB LED Strip
×1
Rotary potentiometer (generic)
Rotary potentiometer (generic)
10k Potentiometers
×4
Arduino Nano R3
Arduino Nano R3
As the brain of operations
×1
I2C 16x2 Arduino LCD Display Module
DFRobot I2C 16x2 Arduino LCD Display Module
Optional
×1
Jumper wires (generic)
Jumper wires (generic)
×1
Breadboard (generic)
Breadboard (generic)
×1

Software apps and online services

Arduino IDE
Arduino IDE
VS Code
Microsoft VS Code
PlatformIO IDE
PlatformIO IDE

Story

Read more

Schematics

Schematic Diagram

Code

Potentiometer Testing Code

Arduino
int Pot = A0;
int PotVal = 0;

void setup() {
  Serial.begin(9600);

}

void loop() {
  PotVal = analogRead(Pot); 
  Serial.println(PotVal);
}

Brightness Test

Arduino
#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();
}

Color Mixing

Arduino
#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();
}

Color Mixing w/ LCD

Arduino
#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();
}

LiquidCrystal_PCF8574.h

C/C++
///
/// \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

LiquidCrystal_PCF8574.cpp

C/C++
///
/// \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.

FastLED Library

LiquidCrystal Library

Credits

HeathenHacks

HeathenHacks

24 projects • 57 followers
I don't know what I'm doing here.

Comments