Showing posts with label Ledstrip. Show all posts
Showing posts with label Ledstrip. Show all posts

Friday, November 21, 2025

Flexible led filament a first look

For an index to all my stories click this text.

In a previous story I showed how to work with led filament. These are rigid tubes that contain leds in one color and can be used for lots of projects. You can read that story here: https://lucstechblog.blogspot.com/2025/11/led-filament-first-look.html

There is however also a flexible version available. These usually consist of micro LED diodes mounted on a flexible metal base, coated with silicone for protection. They are constructed in a way that it looks as if the light of the leds shine 360 degrees. The back side of the strip though looks less bright as the front.

The led filament is indeed flexible. Bending the strip to sharp will break it. So no 90 degree corners, just a smooth bend.

These flexible leds are available in several colors: warm white, pink, green, blue and red.
and they can be bought in several lengths. I have seen lengths up to 450mm (45 cm).

Please note each of these led filaments have 1 color. They are not like ledstrips or neopixels. They have a fixed color. So make sure you order the ones you need.

Beware of the contacts.


There are versions available where both VCC and GND contacts are at one end of the ledstrip. And there are versions that have contacts at both ends, just like the rigid versions. So check which version you need before placing an order. Just be careful when experimenting as the contacts are fragile.

They are available from our usual Chinese friends. Adafruit sells them also (although a lot more expensive) and calls then nOOds (from noodles)

Power requirements.

There is surprisingly few documentation available.

There are two versions available. The first works at 12V and the second at 3V. For our microcontroller projects I advise to use the 3V version.

Adafruit suggest you can supply up to 100mA. Chinese suppliers advise a maximum of 50mA.
Better safe as sorry so I suggest stay below the 50mA.

Breadboard setup

I used the same breadboard setup as in the story about the rigid led filament.


Like in the previous story the led filament is powered by a 5V USB power supply. The Raspberry Pi Pico can not supply enough current from it's IO pins so a 2N2222 transistor is used.

The 2N2222 can supply a maximum of 800ma but that is in optimal circumstances with proper cooling. Stay on the safe side and attach up to 4 led filaments to one transistor so the maximum current the transistor needs to supply will be around 200ma.

You can exchange the Pico by an ESP8266 or ESP32 but then you will need to alter the programs to use the right GPIO.

In this setup I used a resistor of 100 Ohm. The USB wall connector supplies 5V. So the resistor reduces the current to 20Ma
If you are using a different power supply or want more (or less) current please revert to the previous story for an explanation of the calculations. You can find it here : https://lucstechblog.blogspot.com/2025/11/led-filament-first-look.html

If you want the leds to be brighter use a resistor of 47 Ohm. That will give around 40mA although I must say I did not notice any difference with my eyes. So I advise to stick at 100 Ohm.

The programs are also the same:

# -------------------------------------------
# simple test for setting filament on and off
# -------------------------------------------

from machine import Pin
import time

filament = Pin(16, Pin.OUT)

while True:
    filament.value(1)
    time.sleep(1)
    filament.value(0)
    time.sleep(1)


This sets the led filament on and off.

# -------------------------------------
# test program for dimming led filament
# with PWM
# -------------------------------------

import machine
import time

filament = machine.PWM(machine.Pin(16))
filament.freq(1000)

while True:
    min = 0
    max = 65536
    for i in range(min,max):
        filament.duty_u16(i)
        time.sleep(.0001)
    #time.sleep(.5)
    for i in range(max,min,-1):
        filament.duty_u16(i)
        time.sleep(.0001)
    #time.sleep(.2)

This program brings the led slowly to full brightness and then slowly dims it and keeps repeating this sequence.

The led filament consists of leds so if your program does not work try changing the VCC and GND contacts at the filament.

My tests.

I bought a 30 cm long pink strip which had both contacts at 1 side.


First I made a circle around a round object.


And here I draped the led filament around a wooden stick with a diameter of about an inch (2.5 cm).

The led filament is fun to play with. The filament is bright and invites to be used in several creative projects.

Till next time
have fun


Luc Volders

Friday, November 14, 2025

Led filament, a first look

For an index to all my stories click this text

This story is about the rigid led filament. There is also a flexible version which will be discussed in an upcoming story.

I saw on the internet something that looks like a small led strip. They have several names: Led Filament, Cob Led Filament and Edison bulb led parts.


They are meant as ledstrips for use inside filament-lamps like the one above. The yellow strips in the lamp is what I am talking about. They can be bought as tiny led strips.

These are actually really small led strips inside a tubing and have contacts at both sides.


The photo just shows the size of this filament compared to a normal led.
This clearly shows they are slim and long.


The filaments are available in several lengths. I have seen lengths up to 68mm (about 7cm)
For testing purposes I bought a batch of 3.8 cm. Well The advertisement said they were 3.8cm long. And that is correct. However that is inclusive the contacts.


The led filament itself is about 3cm.


And they can be bought in several colors. At the moment of this writing the following colors are available: white, warm white, red, pink, purple, green and blue. They are not like neo-pixels or ordinary led strips. Each strip has only 1 color.

If you are going to buy them just make sure you buy the right ones for your purpose as they are available in 3V and 12V and even higher voltage versions. For our purposes we will be working with the 3V versions. As that is the voltage most of our microcontrollers work with.

Fragile

The tubing that encapsulates the leds feels like plastic. It is not flexible but rigid. The tubing can handle some stress but be aware that it is fragile.


As i wanted to know if it was flexible I bend one of the filaments (a bit) and it broke immediately. So be careful when working with these.
Despite being broken it still worked, what amazed me. Only the leds after where the break was, were working as the picture shows.

VCC and GND

Like stated these are led strips. So they need power. And just like normal leds the power needs to be supplied at the right contacts.


Carefully look at the picture.
At the right side there is a small hole in the contact. That is the VCC side. The other side is GND.
Switching the VCC and GND contacts does not do any harm (yes I tried it) as they are leds. But they just do not work when the power is not connected right.

Current delimiting resistor.

As with all leds these need a current delimiting resistor. More on that later.

Power

On our favorite Chinese website there are several suppliers of these filaments. So I scrolled through a lot of them to find some good specifications.


Most of them stated that the maximum current that could be supplied was 100ma at 3V.

The problem is that no microcontroller that I own can supply that much power from it's IO pins. The Raspberry Pi Pico for example can supply 4ma per IO pin and a maximum of 50ma on all IO pins combined. So the current needed for this filament would fry it. The ESP32 can roll out 40ma maximum at a single IO pin but the total (maximum sum of all IO pins) it can supply is 120Ma. Next to that a prolonged delivery of 40ma on a single pin will overheat and damage the chip. Therefore powering the led filament from a microcontroller is no option.

So I am going to supply the power from a 5V USB phone adapter.
That is 5V so we need to reduce that to 3V. The easiest way to do that is by using a resistor.

To calculate what value the resistor should have we need the following formula.

voltage supplied - voltage desired
-------------------------------------------------------
                  milliamps


The voltage supplied = 5V
The voltage desired  = 3V
The milliamps we need is 50 ma

As you can see I am not powering the strip to the maximum 100Ma.
This gives the following formula:

5V - 3V
----------
50 ma


And 50ma is 0.050 Amps
So that gives 2V / 0,050A is 40 and that makes the value of the resistor 40 Ohm.

So the minimal resistor value is 40 Ohm
Any higher value will do.

Supplying the power.

It is obvious that our ESP8266, ESP32 or Raspberry Pi Pico can never supply such power. So we need an external component for that: a transistor.

The most common used transistor for supplying power is the BC547. This transistor can supply a maximum of 100ma. So we could attach a maximum of 2 led filament strips to 1 of these BC547's. The BC547 is dead cheap. You can get about 50 pieces for 1 USD if you shop around.

If you need more current then use the 2N2222. This transistor is pin compatible with the BC547 but capable of delivering 800ma. Beware that this is under ideal conditions. It would need cooling to achieve that much current. So aim for a lower current like 200-400ma maximum.

I opted for the 2N2222

In real life.

In real life I did some experiments and found that a 100ohm resistor already supplied so much current that the ledstrip was very bright and could even be seen in broad daylight.

Let me do the recalculations for you.

5V - 3V
----------
 X ma


This should equal 100 Ohm

So 5-3 / X ma = 100 this gives 2 / 100 = 0.02A = 20 Ma.

Using a 2N2222 transistor I should be able to attach easily 10 led filaments (10 x 20ma - 200ma) to 1 IO pin of the microcontroller.

There is one extra calculation and that is the calculation for the resistor that needs to be attached to the base of the 2N2222 and that defines how much the output will be. I will not bother you with these calculations. But if you mail me I will show these to you in a separate story on this weblog.

The combined calculations.

I will not bother you with the calculations for the base resistor (until you mail me and ask for it).  I needed a resistor of 1.5K to 2K for the base of the transistor and for each led filament a resistor of 100 ohm.

2N2222

The 2N2222 has 3 connections E, B and C which are emitter, base and collector.


The Base is connected to a 1.5K resistor and that determines (the gain) the amount of current that will flow from the Emitter (GND) to the Collector. Any load (like our led filament) gets connected to the collector.
So the GND of the led filament is connected to the collector using the current delimiting resistor of 100Ohm.
The Emitter is connected to GND.

I made a test setup first without using a Microcontroller.

Breadboard for the first test.

Here is the breadboard for the first test.


The setup is the same as discussed above.
A resistor of 1.5K is attached to the base of the 2N2222. It is connected to a pushbutton that is connected to VCC. When the pushbutton is pressed some current will flow to the base of the transistor.
The Emitter is just connected to GND.
The Collector is connected through a 100 Ohm current delimiting resistor and from that to GND of the led filament. The VCC of the filament is connected to VCC.
The project is powered by a USB wall adapter, the kind used for phones.

When you push the button, the led filament will light up.
If the filament does not light up, check your connections. Most likely the VCC and GND of the filament have been swapped. Remember that the side where there is a whole in the connection is the VCC side.

That is all.

Attaching a Microcontroller.

The resistor connected to the base of the transistor is calculated at a value that accepts 3.3V from a microcontroller. We can use any microcontroller we like: ESP8266, ESP32 or Raspberry Pi Pico.

For our example we will be using the Raspberry Pi Pico.
The only thing we need to do for our first test is to attach a GPIO pin to the base resistor.
And of course connect the GND of the Pico to the rest of the project.

The Pico will get powered from our computer so:
DO NOT CONNECT THE VCC FROM THE USB POWER ADAPTER TO THE PICO'S POWER RAIL.
CONNECTING BOTH THE PICO WITH THE COMPUTER AND THE EXTRA USB POWER ADAPTER WILL BLAST YOUR PICO AND YOUR COMPUTER TO KINGDOM COME.



The first test program.

This is a small test program that puts the pin GPIO16 at HIGH, waits a second and then puts the pin LOW. The ledstrip will go on for a second, then off for a second and that sequence repeats.

# -------------------------------------------
# simple test for setting filament on and off
# -------------------------------------------

from machine import Pin
import time

filament = Pin(16, Pin.OUT)

while True:
    filament.value(1)
    time.sleep(1)
    filament.value(0)
    time.sleep(1)

Make sure this works before trying the next step.

Dimming the led filament

Now let's see if we can dim the filament with our program.
We can fake the voltage output of a GPIO pin by using PWM.

If you are not aware on how this works I can recommend my books on the Raspberry Pi Pico with MicroPython which you can find at the bottom of this story.

Here is the program that sends a PWM signal to GPIO16.
The led filament is off at first and then slowly gets brighter. When the maximum brightness has been reached it slowly dims till its off again and then the sequence repeats.

# -------------------------------------
# test program for dimming led filament
# with PWM
# -------------------------------------

import machine
import time

filament = machine.PWM(machine.Pin(16))
filament.freq(1000)

while True:
    min = 0
    max = 65536
    for i in range(min,max):
        filament.duty_u16(i)
        time.sleep(.00015)
    time.sleep(1)
    for i in range(max,min,-1):
        filament.duty_u16(i)
        time.sleep(.00015)
    time.sleep(1)

You can adjust the minimum value and the time between steps to your own liking.

Now everything works as expected we can start some real projects with this led filament.

So have fun,
Till next time

Luc Volders

Friday, December 9, 2022

Last post of 2022

For an index to all my stories click this text.

The holliday season is coming up. Lots of time to celebrate with your loved ones and friends, but also lots of time to spend with your hobby. And maybe you have relatives or friends also want to start with electronics or the Internet Of Things. What better way than a book that explains it all in an easy to understand manner.  

Next to being the author of this blog I also wrote (until now) 3 books in plain English and one in Dutch that explain these things in an easy way. That is why the series is called xxxx Simplified.

Raspberry Pico W Simplified.

 


This is my latest book and was released in October this year.
The book covers the already very popular Raspberry Pi Pico W. In which the W stands for Wifi. The Raspberry Pi Pico W is a serious competitor to the famous ESP32. Not only has this board a lot of memory, a fast dual-core processor, loads of IO ports and USB for easy programming. It also has Wifi which makes it ideal for the Internet of Things. Look at it as an Arduino with added Wifi.

This book covers the following subjects:
Installing MicroPython, the MicroPython language, the pins layout, how to use a breadboard, adding power, how to use a button, how to use leds, fading leds with PWM, connecting to wifi, check if someone is at home with ping, Dallas DS18B20 thermometer chip, building your own MicroPython library, access internet data with Urequests, getting jokes from the internet, publishing to and retrieving data from Thingspeak, using an LDR for measuring light intensity, using mains power with a relay, movement detection with a PIR, getting notifications on your phone with Pushbullet, vibration detection, sending data to Telegram Messenger, how to use JSON, sending data to and retrieving data from Dweet, building a webserver that displays data and has buttons to control leds and lamps etc., attach a reset button.

Every project is build on a breadboard. All programs in the book are written in MicroPython and fully documented in detail.

This book is available through my publisher and through Amazon

https://www.lulu.com/shop/luc-volders/raspberry-pico-w-simplified/paperback/product-ke8vz9.html?q=luc+volders&page=1&pageSize=4

https://www.amazon.com/Raspberry-Pico-Simplified-Luc-Volders/dp/1471032361/ref=sr_1_3?crid=1W8CKDJ1TDLOC&keywords=luc+volders&qid=1668207187&sprefix=%2Caps%2C357&sr=8-3


Raspberry Pi Pico Simplified


The Raspberry Pi Pico was the first microcontroller released by the Raspberry Foundation. Within a year 1.000.000 (yes 1 million) pieces were sold. The Pico is a serious competitor for the Arduino range of microcontrollers. It has a fast processor, loads of IO pins and can easily be programmed with MicroPython. This book focuses on the MicroPython language and on how to use a multitude of sensors with this microcontroller.

The book covers the following subjects:
Getting started, installing libaries, Pico's pins layout, introduction to using a breadboard, power, basic programming knowlegde, buttons, leds, fading leds with PWM, Dallas DS18B20 Digital Thermometer, using an LDR for measuring light intensity, potmeter, servo motor, more power, using mains power with a relay, touch sensor, controlling a motor, making sound with a buzzer, neopixels, H-Bridge for advanced motor control, movement detection with a PIR, motion detection with the RCWL-0156 Radar, measuring distance, tilt sensor, vibration detection, display your data, rotary encoder, oled display and how to build a reset button.

Every project is build on a breadboard. All programs in the book are written in MicroPython and fully documented in detail.

This book is available through my publisher and through Amazon:


https://www.lulu.com/en/en/shop/luc-volders/raspberry-pi-pico-simplified/paperback/product-znrgmy.html?page=1&pageSize=4

https://www.amazon.com/Raspberry-Pico-Simplified-Luc-Volders/dp/1329449533/ref=sr_1_3?dchild=1&keywords=raspberry+pi+pico+simplified&qid=1629483987&sr=8-3

ESP32 Simplified



When the ESP8266 was released it was a sensation. It was a microcontroller like an Arduino but then with Wifi. The ESP32 offers even more benefits. The ESP32 has many IO pins, a fast processor, a lot of memory, bluetooth and an USB port so you can easily program it. The popular Arduino language (which is C++) is vailable for it and that opens the gate to many libraries for sensors and access to web-services. The ESP32 is a popular widely used microcontroller and therefore this book is a valuable source of information for anyone who wants to start with electronics and the Internet of Things.

This book covers the following subjects:
Installing the Arduino IDE, ESP32 board install, using the IDE, using the library manager, using ZIP libraries, installing libraries manually, first use of libraries, ESP32 Pin layout, ESP32 on a breadboard, introduction to using a breadboard, power, USB Breadboard connector,batteries, external Power Supply, programming basics, how to attach a button, buttons or switches, led, fading leds with PWM, Dallas DS18B20 digital thermometer, using an LDR for measuring light intensity, potmeter, make a dimmer, servo Motor, building a web server, more power, using mains power with a relay, automatic night light, touch sensor, a touch sensitive lamp, plant watering system, IFTTT, neopixels, thermometer with led indication, roll the dice, H-Bridge for advanced motor control, movement detection with a PIR, motion detection with the RCWL-0156 Radar, vibration detection, tilt sensor, display data with the TM1637, oled display, Thingspeak a cloud basede IOT, sending thermometer values to Thingspeak.

Every example is build on a breadboard so no soldering is required. Every example has an accompanying program which is documented in detail.

This book is available through my publisher and through Amazon:


https://www.lulu.com/shop/luc-volders/esp32-simplified/paperback/product-5yr98e.html?page=1&pageSize=4



https://www.amazon.com/ESP32-Simplified-Control-your-internet/dp/171694211X/ref=sr_1_1?dchild=1&keywords=esp32+simplified&qid=1601666983&sr=8-1



ESP32 Uitgelegd

This is the Dutch version of ESP32 Simplified and was the first book I published. It is available through my publisher, electronic shops like Otronic and Bol.

https://www.boekenbestellen.nl/boek/esp32-uitgelegd/9789463456814

https://www.otronic.nl/a-61328375/esp32/boek-esp32-uitgelegd-door-luc-volders/

https://www.bol.com/nl/nl/p/esp32-uitgelegd/9200000116004013/?bltgh=hWzTXg8hh8H1i6DDTvFJNw.1_4.5.ProductImage



Thanks for reading.
Have a great Xmas, a happy and healthy new year and loads of fun.

Luc Volders

Friday, March 11, 2022

ESP webserver tutorial part 5 - Neopixel control

For a complete index to all my articles click this text.

This is a series on building a webpage with the ESP8266 and the ESP32. When this series is completed all the information on building a webpage with buttons, textfields, sliders and color pickers witch have interaction with the ESP8266 or ESP32 will be discussed and demonstrated.

This fifth part leans heavy on the previous four parts in this series, so I urge you to read these stories first:

ESP webserver tutorial part 1 - textfields
ESP webserver tutorial part 2 - button
ESP webserver tutorial part 3 - button with save
ESP webserver tutorial part 4 - slider

The last part showed you how to build a webpage with the ESP8266 and ESP32 that incorporates a slider with which you can dim a led.



As promised in that story I am going to show you here how to build a webpage with 3 sliders with which you can control the colors of a ledstrip. The ledstrip I am going to use here is a strip of Neopixels.


Again I am writing the program in Arduino language (C++)

As a bonus there is a nice trick build into the software that makes the colors change automatically when you alter the slider settings. You do not have to press a confirmation button as was required in the previous story.

The ESP8266 breadboard setup.

The breadboard setup is off course different from the setup in the previous stories because we are goiung to attach a neopixels strip to the ESP8266. You can find a full blown explanation/tutorial on Neopixels in a previous story on my weblog which you can find here:
http://lucstechblog.blogspot.com/2015/10/neopixels-ws2812-intro.html



In this setup I used an ESP8266 (the3 Wemos D1 mini version). The Neopixelstrip is connected to D7 with a current delimiting resistor of 470 Ohm. And a large capacitor for stabilising the current is connected over the power lines (mind the polarity). I used the symbol of an existing neopixel strip from the fritzing library but you may use a ring of strip or even matrix of your own liking. Keep the amount of neopixels low (like 7 to 8) and you can get the current directly from the ESP8266. If you want to attach a larger amount of neopixels make sure you give them an external power supply.

The ESP32 breadboard setup.

The ESP32 breadboard setup is equally simple.



I am using the ESP32 Devkit board. These boards will not fit a breadboard. Therefore I use 2 breadboards. From one of these breadboards I stripped the power rail as discussed in the story you can read here:
https://lucstechblog.blogspot.com/2018/08/breadboard-hack-for-esp32-and-esp8266.html

The led is attached to GPIO22 through a 470 Ohm current delimiting resistor, and there is a large capacitor connected to the power rail to stabilising the current.
I attached an external USB power connector because the ESP32 consumes a lot of power in itself and attaching a ledstrip might impose too much to its power leads.
You can find a detailed explanation on powering the ESP32 in my book (which is in Dutch or English) called ESP32 uitgelegd and in English ESP32 Simplified on which you can find detailed info here:
http://lucstechblog.blogspot.com/2019/07/esp32-uitgelegd-nu-verkrijgbaar.html 

and here https://lucstechblog.blogspot.com/2020/10/esp32-simplified-world-wide-available.html

You can find a story on external powering the ESP microcontrollers here:
https://lucstechblog.blogspot.com/2017/10/powering-your-project.html

The program

Just like the previous entries in this series the program is written in Arduino language (C++) and is almost identical for the ESP8266 and the ESP32. The changes for the ESP32 are really minimal. I will give you the ESP8266 program as a whole and you can find the few lines which have to be modified for the ESP32 at the end of this story.


// ======================================================
// Libraries needed
// ======================================================

#include <ESP8266WiFi.h>
#include <ESP8266WebServer.h>
#include <Adafruit_NeoPixel.h>

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

// Your credentials
ESP8266WebServer server(80);
const char* ssid = "XXXXXXXXXXXXXXX";
const char* password = "YYYYYYYYYYYYYY";

int neoPin = D7; 

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

String responseHTML = ""
  "<!DOCTYPE html><html><head><title>CaptivePortal</title></head><body>"
  "<h1>Hello World!</h1><p>This is a captive portal example. All requests will "
  "be redirected here.</p></body></html>";

// ==========================================
// initial variables
// ========================================== 

int sliderREDvalue = 0;
int sliderGREENvalue = 0;
int sliderBLUEvalue = 0;

// =========================================
// Build the webpage
// =========================================
String getPage()
  {
  String page = "<!DOCTYPE HTML>";
  page += "<html>";
  page += "<head>";
  page += "<meta name = \"viewport\" content = \"width = device-width, initial-scale = 1.0 maximum-scale = 2.5, user-scalable=1\">";
  page += "<title>Luc's Neopixels slider demo</title>";
  page += "<style>";
  page += "body { background-color: powderblue}";
  page += "</style>";
  page += "</head>";
  page += "<body>";
  page += "<h1 style='color:red'>Luc's Neopixels slider demo</h1>";

  page += "<form id=\"myForm\" action=\"/\" method=\"post\">";
  page += "Move the slider for choosing the color :<br><br>";
  page += "RED&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;";
  page += "<input type=\"range\" min=\"0\" max=\"255\" onmouseleave=\"myFunction()\" id=\"sliderred\" name=\"sliderred\" value=\"";
  page += sliderREDvalue;
  page +="\" > <br>";
  
  page += "GREEN&nbsp;&nbsp;&nbsp;";
  page += "<input type=\"range\" min=\"0\" max=\"255\" onmouseleave=\"myFunction()\" id=\"slidergreen\" name=\"slidergreen\" value=\"";
  page += sliderGREENvalue;
  page +="\" > <br>";
  
  page += "BLUE&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;";
  page += "<input type=\"range\" min=\"0\" max=\"255\" onmouseleave=\"myFunction()\" id=\"sliderblue\" name=\"sliderblue\" value=\"";
  page += sliderBLUEvalue;
  page +="\" > <br>";
  page += "</form>";
  page += "<br>";

  page += "<script>";
  page += "function myFunction() {";
  page += "document.getElementById(\"myForm\").submit()";
  page +="}";
  page +="</script>";

  page += "</body>";
  page += "</html>";
  return page;
  }




// ==========================================
// Handle if unknown command
// ==========================================
void handleNotFound()
{
  server.send(200, "text/html", getPage());
}


// ===========================================
// Submit page
// ===========================================
void handleSubmit()
  {
  if (server.hasArg("slidergreen"))
     {
      sliderGREENvalue = server.arg("slidergreen").toInt();
      Serial.print("The slider Green has value: ");
      Serial.println(sliderGREENvalue);
      for(int i=0;i<NUMPIXELS;i++)
         {
    // pixels.Color takes RGB values, from 0,0,0 up to 255,255,255
    pixels.setPixelColor(i, pixels.Color(sliderREDvalue,sliderGREENvalue,sliderBLUEvalue)); // Moderately bright green color.

    pixels.show(); // This sends the updated pixel color to the hardware.
         }
      }

   if (server.hasArg("sliderred"))
     {
      sliderREDvalue = server.arg("sliderred").toInt();
      Serial.print("The slider Red has value: ");
      Serial.println(sliderREDvalue);
      for(int i=0;i<NUMPIXELS;i++)
         {
    // pixels.Color takes RGB values, from 0,0,0 up to 255,255,255
    pixels.setPixelColor(i, pixels.Color(sliderREDvalue,sliderGREENvalue,sliderBLUEvalue)); // Moderately bright green color.
    pixels.show(); // This sends the updated pixel color to the hardware.
         }
      }     

   if (server.hasArg("sliderblue"))
     {
      sliderBLUEvalue = server.arg("sliderblue").toInt();
      Serial.print("The slider Blue has value: ");
      Serial.println(sliderBLUEvalue);
      for(int i=0;i<NUMPIXELS;i++)
        {
    // pixels.Color takes RGB values, from 0,0,0 up to 255,255,255
    pixels.setPixelColor(i, pixels.Color(sliderREDvalue,sliderGREENvalue,sliderBLUEvalue)); // Moderately bright green color.
    pixels.show(); // This sends the updated pixel color to the hardware.
        }
      } 
  server.send(200, "text/html", getPage());       //Response to the HTTP request
  }  

// =============================================
// Test if commands received
// =============================================
void handleRoot() 
    {   
    if (server.args() ) 
       {
       handleSubmit();
       } 
       else 
       {
       server.send(200, "text/html", getPage());  
       }
    }

// =============================================
// Setup
// =============================================
void setup()
    {
    delay(1000);
    Serial.begin(115200);

    // WiFi initilisation part
    // Connect to Wi-Fi network with SSID and password
    Serial.print("Connecting to ");
    Serial.println(ssid);
    WiFi.begin(ssid,password);
    while (WiFi.status() != WL_CONNECTED) 
          {
          delay(500);
          Serial.print(".");
          }
     // Print local IP address and start web server
     Serial.println("");
     Serial.println("WiFi connected.");
     Serial.println("IP address: ");
     Serial.println(WiFi.localIP());
     server.begin();
     server.on("/", handleRoot);
     server.onNotFound(handleNotFound);
     delay(500);

     pixels.begin(); // This initializes the NeoPixel library.
 
     pixels.Color(sliderREDvalue,sliderGREENvalue,sliderBLUEvalue);
     pixels.show();
     }


// ===============================================
// LOOP
// =============================================== 
void loop()
  {  
  server.handleClient(); 
  delay(50);
  }

The program is almost identical to the program in the previous stories. All explanation therefore has been done in those stories except for the few lines that are required for putting the three sliders on the screen. This is done in the <form> part of the webpage.

First we need to activate the neopixels code and that is done by these entries at the beginning of the program:


#include <Adafruit_NeoPixel.h>

int neoPin = D7;

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

As you can see the neopixels code is attached to I/O pin D7.

int sliderREDvalue = 0;
int sliderGREENvalue = 0;
int sliderBLUEvalue = 0;

The above lines make sure that the neopixels are set off when the program starts.

In the setup() routine at the end of the program the IP adress is printed in the Serialmonitor so you will know which IP adress you should fill in on your computers or phones browser to find the webpage.

  pixels.begin(); // This initializes the NeoPixel library.


  pixels.Color(sliderREDvalue,sliderGREENvalue,sliderBLUEvalue);

  pixels.show();

These lines activate the neopixels and set the color to the initial values which were defined at the start of the program (0,0,0).

The important changes are in the HTML code where the form is made and the sliders defined.

  page += "<form id=\"myForm\" action=\"/\" method=\"post\">";

  page += "Move the slider for choosing the color :<br><br>";

    page += "RED&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;";

    page += "<input type=\"range\" min=\"0\" max=\"255\" onmouseleave=\"myFunction()\" id=\"sliderred\" name=\"sliderred\" value=\"";

  page += sliderREDvalue;

  page +="\" > <br>";

    page += "GREEN&nbsp;&nbsp;&nbsp;";

    page += "<input type=\"range\" min=\"0\" max=\"255\" onmouseleave=\"myFunction()\" id=\"slidergreen\" name=\"slidergreen\" value=\"";

  page += sliderGREENvalue;

  page +="\" > <br>";

    page += "BLUE&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;";

    page += "<input type=\"range\" min=\"0\" max=\"255\" onmouseleave=\"myFunction()\" id=\"sliderblue\" name=\"sliderblue\" value=\"";

  page += sliderBLUEvalue;

  page +="\" > <br>";

  page += "</form>";

As you can see there are some things different from the program in the previous story.

page += "RED&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;";

After each name of the slider I put some &nbsp commands wich will neatly lineup the sliders. You could do this even better by putting the names of the sliders and the sliders itself into a table. A nice HTML excercise for those who want to expand their knowledge.

Now lets look at the html code that defines the red slider.

page += "<input type=\"range\" min=\"0\" max=\"255\" onmouseleave=\"myFunction()\" id=\"sliderred\" name=\"sliderred\" value=\"";

The first part is easy to understand. The type of input is range which means a slider and the minimum and maximum values are defined.
onmouseleave is an HTML function that is activated when the mouse moves over the slider and then leaves its aerea. When that happens the function myFunction() is called.

The code for the green and blue sliders is almost identical as you can see. The difference is in the id and name settings.

page += "<script>";

page += "function myFunction() {";

 page += "document.getElementById(\"myForm\").submit()";

page +="}";

page +="</script>";

At the end of the HTML page the Javascript function myFunction is called when the mouse has left the area of one of the sliders. This code actually takes the values of the sliders from the form and uses submit() to send them to the webserver.

In the handlesubmit() routine the webserver receives the information from the form on the webpage and the slider settings are analysed. Every slider info is analysed individually and processed. Lets look at the information from the green slider coming in:

  if (server.hasArg("slidergreen"))
     {
      sliderGREENvalue = server.arg("slidergreen").toInt();
      Serial.print("The slider Green has value: ");
      Serial.println(sliderGREENvalue);
      for(int i=0;i<NUMPIXELS;i++)
         {
    // pixels.Color takes RGB values, from 0,0,0 up to 255,255,255
    pixels.setPixelColor(i, pixels.Color(sliderREDvalue,sliderGREENvalue,sliderBLUEvalue)); // Moderately bright green color.
    pixels.show(); // This sends the updated pixel color to the hardware.
         }
      }

As you can see the name slidergreen is the name that is tested for. That is why each slider got his own name and ID in the above mentioned HTML code.
The received value is put into the sliderGREENvalue variable and printed in the Serialmonitor.
Then the information is send to the neopixels strip. All slider values are send so the settings of the other colors is not changed unless their sliders have been changed.

Dont forget the pixels.show() command. that will actually activate the new settings.

ESP32 code

Well there is not much difference in the ESP8266 and ESP32 code on the software side.

The same Adafruit Neopixel library is used as for the ESP8266 as its compatible for both. We only have to alter the pin assignment as you can see in the breadboard setup. The Neopixels are attached to pin 22.

int neoPin = D7;

And for the webserver we only have to Change the following lines:

#include <ESP8266WiFi.h>;
#include <ESP8266WebServer.h>;

ESP8266WebServer server(80);

into:

#include <WiFi.h>;
#include <WebServer.h>;

WebServer server(80);

Thats all.

Pitfall.

The above code works flawlessly on my PC with Windows 10 in the Firefox and Chrome browsers. There is however a problem with this code which is not really interesting when you use it to control a ledstrip or neopixels. It might impose a problem if you are going to use this for steering a motor, pump or likewise.


As you can see the slidervalues are send very often to the webserver and processed. Indeed evrytime you move your mouse over a slider even if you did not alter it. So if you alter and use this code to send PWM values to a motor or pump the motor might hick up everytime the info is send and processed in the webserver.

You can avoid this by changing onmouseleave in onblur like this in the red slider code:


page += "<input type=\"range\" min=\"0\" max=\"255\" onblur=\"myFunction()\" id=\"sliderred\" name=\"sliderred\" value=\"";

Pitfall 2

Another pitfall is that this code does not work on Android phones (and Iphones for that) because the html onmouse functions are not compatble with touch screens.

So to get this working on PC and on Android systems we sadly have to revert to the old system where a button is pressed after the slider has been changed. I will give you the code for this here in its total without any explanation and am sure you can figure it out yourself.


// ======================================================
// Libraries needed
// ======================================================

#include <ESP8266WiFi.h>
#include <ESP8266WebServer.h>
#include <Adafruit_NeoPixel.h>

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

// Your credentials
ESP8266WebServer server(80);
const char* ssid = "ZyXEL9680AC";
const char* password = "B9BB53BCA049";

int neoPin = D7; 

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

String responseHTML = ""
  "<!DOCTYPE html><html><head><title>CaptivePortal</title></head><body>"
  "<h1>Hello World!</h1><p>This is a captive portal example. All requests will "
  "be redirected here.</p></body></html>";

// ==========================================
// initial variables
// ========================================== 

int sliderREDvalue = 0;
int sliderGREENvalue = 0;
int sliderBLUEvalue = 0;

// =========================================
// Build the webpage
// =========================================
String getPage()
  {
  String page = "<!DOCTYPE HTML>";
  page += "<html>";
  page += "<head>";
  page += "<meta name = \"viewport\" content = \"width = device-width, initial-scale = 1.0 maximum-scale = 2.5, user-scalable=1\">";
  page += "<title>Luc's Neopixels slider demo</title>";
  page += "<style>";
  page += "body { background-color: powderblue}";
  page += "</style>";
  page += "</head>";
  page += "<body>";
  page += "<h1 style='color:red'>Luc's Neopixels slider demo</h1>";

  page += "<form action=\"/\" method=\"post\">";
  page += "Move the slider for choosing the color :<br><br>";
  page += "RED&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;";
  page += "<input type=\"range\" min=\"0\" max=\"255\" id=\"sliderred\" name=\"sliderred\" value=\"";
  page += sliderREDvalue;
  page +="\" class=\"slider\"> <br>";
  
  page += "GREEN&nbsp;&nbsp;&nbsp;";
  page += "<input type=\"range\" min=\"0\" max=\"255\" id=\"slidergreen\" name=\"slidergreen\" value=\"";
  page += sliderGREENvalue;
  page +="\" class=\"slider\"> <br>";
  
  page += "BLUE&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;";
  page += "<input type=\"range\" min=\"0\" max=\"255\" id=\"sliderblue\" name=\"sliderblue\" value=\"";
  page += sliderBLUEvalue;
  page +="\" class=\"slider\"> <br><br>";
  page += "<input type=\"submit\" value=\"Confirm\">";
  page += "</form>";
  page += "<br>";
  page += "<br>";
  page += "<br>";

  page += "</body>";
  page += "</html>";
  return page;
  }




// ==========================================
// Handle if unknown command
// ==========================================
void handleNotFound()
  {
  server.send(200, "text/html", getPage());
  }


// ===========================================
// Submit page
// ===========================================
void handleSubmit()
  {
  if (server.hasArg("slidergreen"))
     {
      sliderGREENvalue = server.arg("slidergreen").toInt();
      Serial.print("The slider has value: ");
      Serial.println(sliderGREENvalue);
      for(int i=0;i<NUMPIXELS;i++)
         {
          // pixels.Color takes RGB values, from 0,0,0 up to 255,255,255
          pixels.setPixelColor(i, pixels.Color(sliderREDvalue,sliderGREENvalue,sliderBLUEvalue)); // Moderately bright green color.
          pixels.show(); // This sends the updated pixel color to the hardware.
         }
      }

   if (server.hasArg("sliderred"))
      {
      sliderREDvalue = server.arg("sliderred").toInt();
      Serial.print("The slider has value: ");
      Serial.println(sliderREDvalue);
      for(int i=0;i<NUMPIXELS;i++)
         {
         // pixels.Color takes RGB values, from 0,0,0 up to 255,255,255
         pixels.setPixelColor(i, pixels.Color(sliderREDvalue,sliderGREENvalue,sliderBLUEvalue)); // Moderately bright green color.
         pixels.show(); // This sends the updated pixel color to the hardware.
        }
      }     

   if (server.hasArg("sliderblue"))
      {
      sliderBLUEvalue = server.arg("sliderblue").toInt();
      Serial.print("The slider has value: ");
      Serial.println(sliderBLUEvalue);
      for(int i=0;i<NUMPIXELS;i++)
         {
         // pixels.Color takes RGB values, from 0,0,0 up to 255,255,255
         pixels.setPixelColor(i, pixels.Color(sliderREDvalue,sliderGREENvalue,sliderBLUEvalue)); // Moderately bright green color.
         pixels.show(); // This sends the updated pixel color to the hardware.
         }
      } 

  server.send(200, "text/html", getPage());       //Response to the HTTP request
}  

// =============================================
// Test if commands received
// =============================================
void handleRoot() 
     {   
     if (server.args() ) 
        {
        handleSubmit();
        } 
     else 
        {
      server.send(200, "text/html", getPage());  
        }
     }

// =============================================
// Setup
// =============================================
void setup()
  {
  delay(1000);
  Serial.begin(115200);

  // WiFi initilisation part
  // Connect to Wi-Fi network with SSID and password
  Serial.print("Connecting to ");
  Serial.println(ssid);
  WiFi.begin(ssid,password);
  while (WiFi.status() != WL_CONNECTED) 
       {
       delay(500);
       Serial.print(".");
       }
  // Print local IP address and start web server
  Serial.println("");
  Serial.println("WiFi connected.");
  Serial.println("IP address: ");
  Serial.println(WiFi.localIP());
  server.begin();
  server.on("/", handleRoot);
  server.onNotFound(handleNotFound);

  server.begin();
  delay(500);

  pixels.begin(); // This initializes the NeoPixel library.
 
  pixels.Color(sliderREDvalue,sliderGREENvalue,sliderBLUEvalue);
  pixels.show();
  }


//++++++++++++++++++++++++++++++++++++++++++++++//
//              LOOP                            //
//++++++++++++++++++++++++++++++++++++++++++++++//
void loop()
  {  
  server.handleClient(); 
  delay(50);
  }


This will look on your PC screen like this.



On android it looks like this.



Going further.

So there you have it a complete means to put sliders on a webpage and control the ESP8266 or ESP32 with them.

There are several uses for this. You can change the hardware and code to use this with RGB ledstrips in stead of Neopixels. The webserver software should not be difficult to adapt. You can find the hardware here:
https://lucstechblog.blogspot.com/2018/04/rgb-strip-control-over-wifi-part-2.html

You could also use this to rebuild the remote controlled car which I showed you in a previous story and in which the software was written in ESPBasic which you can find here: http://lucstechblog.blogspot.com/2019/02/remote-controlled-car-with-wifi.html

And combining buttons and a slider you could even rewrite the tea-timer I build in this story: https://lucstechblog.blogspot.com/2018/08/teatimer.html

And like stated earlier in this story you could make the webpage more structured by putting the texts and sliders in a table. You can learn how to do that and everything else about HTML and javascript from this website: https://www.w3schools.com/

Now you have all the tools to make a decent webpage and control your ESP8266 or ESP32 from this page and even put all kind of sensor values on this page. 


In the past I always have used ESPBasic as my favorite devellopment environment. Unfortunately ESPBasic is not further develloped and there is no ESP32 version available. This method of building a webserver makes it easy to replace ESPBasic with the standard Arduino environment for both ESP versions. So it is slowly time to say goodbye to ESPBasic. 

Go ahead and build a project using this. I will give you a complete project in an upcoming story. So stay tuned.

Have fun.

Luc Volders