Project tutorial

Play with Fire Over Wi-Fi (ESP8266, NeoPixels & Android App) © GPL3+

Create a cool fire simulation effect with Wi-Fi wireless control. An Android app is also ready to play with your creation!

  • 6,226 views
  • 5 comments
  • 38 respects

Components and supplies

Necessary tools and machines

Hy gluegun
Hot glue gun (generic)
09507 01
Soldering iron (generic)

Apps and online services

About this project

You can read this and other amazing tutorials on ElectroPeak's official website

Create a cool fire simulation effect with Wi-Fi wireless control. A mobile app (for Android smartphones) with a good looking interface is ready to install to play with your creation! We will also use Arduino and ESP8266 to control the flame. At the end of this project you will learn:

  • How NeoPixels work.
  • How to program ESP8266 and control variables over Wi-Fi
  • How to create a cool fire effect with NeoPixels

An Introduction to NeoPixels

Individually addressable LEDs or often called NeoPixels have been around for quite some time now and you probably know them but, if you don’t, they are like normal RGB LEDs but as the name suggests the color of each one of them can be addressed individually, allowing infinitely cool patterns and animations to be made. For WS2812b you only need 3 wires, 2 for power and 1 for data. That means you just need one free Arduino pin to control a ton of LEDs!

In this project, we are going to use these smart LEDs to create a fire effect. For controlling LEDs we are going to use the awesome FastLED library. We will use the Fire2012 sketch example of the library written by Mark Kriegsman. We use 6 strips of LEDs each having 30 LEDs (a total of 180 LEDs) we stick this LEDs on a piece of PVC pipe and place them in a glass cylinder (these glass cylinders are usually used as vases). We have to diffuse the light of the LEDs to make them look continuous, to do that we used tracing paper which lets light through and diffuses light.

Construction

First off get a proper glass cylinder, our cylinder has a length of 60cm and a diameter of 12cm.

If you can find frosted glass cylinder that will be nice but if it’s a clear glass you can use tracing paper to cover the cylinder surface (either inner or outer surface), tracing paper does a good job of diffusing the light and yields good results.

After getting a glass cylinder measure its internal length and then cut the PVC pipe so that it fits inside the cylinder. Our glass cylinder has a height of 60cm (excluding base it has an internal length of 59cm) so we cut our PVC pipe to 59cm. You will stick LED strips on this pipe, a pipe with diameter of 4cm would be perfect.

Next we have to cut our led strip to 6 equal parts here we use 60LEDs/m density strip (you can use higher densities for better effects if you want to) we use six 50cm lengths, that means we need 3 meters. Space the six lengths equally around the PVC pipe and stick the strips to the pipe. Here’s how it should look like.

To the LED strips together you can either directly solder wires to the strip according to the following drawing or first solder pin headers to the strips and then use breadboard wires to connect them.

When all LED strip conectioins are done you have to place the pipe inside the cylinder. To Center the pipe inside the cylinder you can use foam to cut a circle which has an outer diameter equal to inside diameter of the glass cylinder and an inner diameter equal to outer diameter of the PVC pipe. Prepare two of these for each side of the pipe. Attach these parts to the ends and gently put the pipe inside the cylinder.

Code

We use Arduino IDE for coding and uploading to ESP8266. You have to use a board which has an ESP8266 with 3MB of SPIFFS if you want to upload the controller software files on the SPIFFS. SPIFFS is short for “Serial Peripheral Interface Flash File System” you can upload the controller files to this memory to serve the files from that location. By doing this you can open your browser (either on your phone or notebook) and go the address of your ESP (the default is 192.168.4.1) and you will get the controller interface in your browser without having to install the app, if you have an iPhone or iPad this is your only choice.

Upload the following sketch onto your ESP board. We need FastLED library, so first add it to your Arduino IDE if you haven’t already (You can download it here). The fire simulation code is Mark Kriegsman’s fire2012 sketch which you can find in the examples. That example is for one strip of led but, here we have modified the code to use a variable number of strips. The more the number of strips/leds the greater the effect will be.

The logic of the fire simulation is clearly described in the example file. If you want to know how it works read the source code of the example.

#include <ESP8266WiFi.h>
#include <ESP8266WebServer.h>
#include "FastLED.h"
#include "EEPROM.h"
#include "FS.h"  //required for SPIFFS
#define DATA_PIN 5
#define LED_TYPE WS2811
#define COLOR_ORDER GRB
#define NUM_LEDS 30
#define NUM_STRIPS 6
#define CHIPSET     WS2812B
//addresses to save data to EEPROM to preserve the state of fire simulation
#define cs0Adr 0
#define cs1Adr 3
#define cs2Adr 6
#define cs3Adr 9
#define BriAdr 15
#define FpsAdr 16
#define SparkingAdr 17
#define CoolingAdr 18
#define EEPROMCheckAdr 20 //if this value is 250 we assume we have previously saved to EEPROM and load data from that
CRGB leds[NUM_STRIPS * NUM_LEDS];
String inData;
uint8_t FPS = 100; //FRAMES_PER_SECOND
uint8_t SPARKING = 150;
uint8_t COOLING = 90; 
uint8_t BRIGHTNESS = 100;
uint8_t csRGB[4][3] = {{0, 0, 0},
                      {255, 0, 0},
                      {255, 127, 0},
                      {255, 255, 255}};
unsigned long previousMillis = 0;
bool change = false;            //if true we go to save to EEprom.
unsigned long changeMillis = 0; //changes will be saved 1 minute after no change is applied to avoid EEPROM wear.
bool initSetup = true;
CRGBPalette16 gPal;
ESP8266WebServer server(80); //Web server object. Will be listening in port 80 (default for HTTP)
void setup()
{
 EEPROM.begin(200);
 cWiFi();
 setupFastLED();
 loadConfig();
 gPal = CRGBPalette16( CRGB(csRGB[0][0],csRGB[0][1],csRGB[0][2]), 
                       CRGB(csRGB[1][0],csRGB[1][1],csRGB[1][2]), 
                       CRGB(csRGB[2][0],csRGB[2][1],csRGB[2][2]),  
                       CRGB(csRGB[3][0],csRGB[3][1],csRGB[3][2]));
}
inline void setupFastLED()
{
 delay(1000); // sanity delay
 FastLED.addLeds<CHIPSET, DATA_PIN, COLOR_ORDER>(leds, NUM_STRIPS * NUM_LEDS).setCorrection(TypicalLEDStrip);
 FastLED.setBrightness(BRIGHTNESS);
}
void loop()
{
 server.handleClient(); //Handling of incoming requests
 if (change)
 {
   if (millis() - changeMillis > 60000)
   {
     change = false;
     saveToEEPROM();
   }
 }
 fire();
 FastLED.show();
 FastLED.delay(1000 / FPS);
}
void Fire2012WithPalette(int stripNo)
{
 static byte heat[NUM_STRIPS][NUM_LEDS];
 // Step 1.  Cool down every cell a little
   for( int i = 0; i < NUM_LEDS; i++) {
     heat[stripNo][i] = qsub8( heat[stripNo][i],  random8(0, ((COOLING * 10) / NUM_LEDS) + 2));
   }
   // Step 2.  Heat from each cell drifts 'up' and diffuses a little
   for( int k= NUM_LEDS - 1; k >= 2; k--) {
     heat[stripNo][k] = (heat[stripNo][k - 1] + heat[stripNo][k - 2] + heat[stripNo][k - 2] ) / 3;
   }
   // Step 3.  Randomly ignite new 'sparks' of heat near the bottom
   if( random8() < SPARKING ) {
     int y = random8(5);
     heat[stripNo][y] = qadd8( heat[stripNo][y], random8(160,200) );
   }
   // Step 4.  Map from heat cells to LED colors
   for( int j = 0; j < NUM_LEDS; j++) {
     // Scale the heat value from 0-255 down to 0-240
     // for best results with color palettes.
     byte colorindex = scale8( heat[stripNo][j], 240);
     CRGB color = ColorFromPalette( gPal, colorindex);
     leds[j+stripNo*NUM_LEDS] = color;
   }
}
void fire(){
 for (int i=0; i<NUM_STRIPS; i++){
 Fire2012WithPalette(i);
 }
}
int str2int(String InputStr)
{
 return InputStr.toInt();
}
boolean EveryNSec(uint8_t period)
{
 unsigned long currentMillis = millis();
 if (currentMillis - previousMillis >= period * 1000)
 {
   // save the last time you blinked the LED
   previousMillis = currentMillis;
   return true;
 }
 else
 {
   return false;
 }
}
void EEPROMupdate(byte address, byte value)
{
 if (EEPROM.read(address) != value)
 {
   EEPROM.write(address, value);
   EEPROM.commit();
 }
 return;
}
void saveToEEPROM()
{
 EEPROMupdate(BriAdr, BRIGHTNESS);
 EEPROMupdate(FpsAdr, FPS);
 EEPROMupdate(SparkingAdr, SPARKING);
 EEPROMupdate(CoolingAdr, COOLING);
 for (uint8_t i = 0; i < 4; i++)
 {
   for (uint8_t j = 0; j < 3; j++)
   {
     EEPROMupdate((i * 3 + j), csRGB[i][j]);
   }
 }
}
void handleCS0Change(){
   csRGB[0][0] = str2int(server.arg("R"));
   csRGB[0][1] = str2int(server.arg("G"));
   csRGB[0][2] = str2int(server.arg("B"));
   gPal = CRGBPalette16( CRGB(csRGB[0][0],csRGB[0][1],csRGB[0][2]), CRGB(csRGB[1][0],csRGB[1][1],csRGB[1][2]), CRGB(csRGB[2][0],csRGB[2][1],csRGB[2][2]),  CRGB(csRGB[3][0],csRGB[3][1],csRGB[3][2]));
   changeMillis = millis();
   change = true;
}
void handleCS1Change(){
   csRGB[1][0] = str2int(server.arg("R"));
   csRGB[1][1] = str2int(server.arg("G"));
   csRGB[1][2] = str2int(server.arg("B"));
   gPal = CRGBPalette16( CRGB(csRGB[0][0],csRGB[0][1],csRGB[0][2]), CRGB(csRGB[1][0],csRGB[1][1],csRGB[1][2]), CRGB(csRGB[2][0],csRGB[2][1],csRGB[2][2]),  CRGB(csRGB[3][0],csRGB[3][1],csRGB[3][2]));
   changeMillis = millis();
   change = true;
}
void handleCS2Change(){
   csRGB[2][0] = str2int(server.arg("R"));
   csRGB[2][1] = str2int(server.arg("G"));
   csRGB[2][2] = str2int(server.arg("B"));
   gPal = CRGBPalette16( CRGB(csRGB[0][0],csRGB[0][1],csRGB[0][2]), CRGB(csRGB[1][0],csRGB[1][1],csRGB[1][2]), CRGB(csRGB[2][0],csRGB[2][1],csRGB[2][2]),  CRGB(csRGB[3][0],csRGB[3][1],csRGB[3][2]));
   changeMillis = millis();
   change = true;
}
void handleCS3Change(){
   csRGB[3][0] = str2int(server.arg("R"));
   csRGB[3][1] = str2int(server.arg("G"));
   csRGB[3][2] = str2int(server.arg("B"));
   gPal = CRGBPalette16( CRGB(csRGB[0][0],csRGB[0][1],csRGB[0][2]), CRGB(csRGB[1][0],csRGB[1][1],csRGB[1][2]), CRGB(csRGB[2][0],csRGB[2][1],csRGB[2][2]),  CRGB(csRGB[3][0],csRGB[3][1],csRGB[3][2]));
   changeMillis = millis();
   change = true;
}
void handleConf()
{
 if (server.arg("brightness") != "")
 {
   BRIGHTNESS = str2int(server.arg("brightness"));
   FastLED.setBrightness(BRIGHTNESS);
   changeMillis = millis();
   change = true;
 }
 if (server.arg("fps") != "")
 {
   FPS = str2int(server.arg("fps"));
   changeMillis = millis();
   change = true;
 }
 if (server.arg("sparking") != "")
 {
   SPARKING = str2int(server.arg("sparking"));
   changeMillis = millis();
   change = true;
 }
 if (server.arg("cooling") != "")
 {
   COOLING = str2int(server.arg("cooling"));
   changeMillis = millis();
   change = true;
 }
 server.sendHeader("Connection", "close");
 server.sendHeader("Access-Control-Allow-Origin", "*");
 server.send(200, "text/plain", ""); //Returns the HTTP response
}
void loadConfig()
{
 if (EEPROM.read(EEPROMCheckAdr) == 250)
 {
   BRIGHTNESS = EEPROM.read(BriAdr);
   SPARKING = EEPROM.read(SparkingAdr);
   COOLING = EEPROM.read(CoolingAdr);
   FPS = EEPROM.read(FpsAdr);
   if (FPS == 0)
     FPS = 100;
   for (uint8_t i = 0; i < 4; i++)
   {
     for (uint8_t j = 0; j < 3; j++)
     {
       csRGB[i][j] = EEPROM.read(i * 3 + j);
     }
   }
 }else{
   EEPROMupdate(BriAdr,BRIGHTNESS);
   EEPROMupdate(FpsAdr,FPS);
   EEPROMupdate(CoolingAdr,COOLING);
   EEPROMupdate(SparkingAdr, SPARKING);
   for (uint8_t i = 0; i < 4; i++)
   {
     for (uint8_t j = 0; j < 3; j++)
     {
       EEPROMupdate((i*3+j) , csRGB[i][j]);
     }
   }
   EEPROMupdate(EEPROMCheckAdr, 250);
 }
}
void cWiFi()
{
 WiFi.softAP("ElectroPeak's Flame", ""); //set a password here if you want i.e. WiFi.softAP("ElectroPeak's Flame", "12345678");
 IPAddress myIP = WiFi.softAPIP();
 server.on("/cs0", handleCS0Change);
 server.on("/cs1", handleCS1Change);
 server.on("/cs2", handleCS2Change);
 server.on("/cs3", handleCS3Change);
 server.on("/conf", handleConf);
 server.serveStatic("/", SPIFFS, "/", "max-age=86400");
 server.begin(); //Start the server
}

To control the “look and feel” of the fire there are two variables to play with: SPARKING and COOLING, which you can dynamically control in the controller software uploaded to the SPIFFS or the android app you can download. You can also control FPS here.

The color of the fire is controlled with a color palette which is also changeable through the controller software (through 4 color stops). Just click/tap each color circle representing a color stop to set the color, after setting the color hit close to close the dialog and see the change.

How to Upload to SPIFFS?

To upload the files to the SPIFFS memory using Arduino IDE first you need to create a folder called “data” inside the sketch’s folder and place all the files you want to be uploaded in that folder. The file uploaded here contains both the sketch and this folder.

Next, you need Arduino ESP8266 filesystem uploader plugin for Arduino. Follow the instructions on its Github page and install the plugin. When installed you will find ESP8266 Sketch Data Upload under tools menu. Put your ESP into programming mode and click that. Be patient and let the files upload, that might take a little while. Note: set “upload speed” to 921600 to make it faster.

How Does It Work?

The sketch uploaded onto the ESP8266 board creates a web server on that, which responds to the requests sent from the app. The app simply sends GET requests to the server (ESP8266). The data of color to create the palette are sent as arguments in the get request, the same is true for other parameters such as Sparking and Cooling parameters.

For example, to set the brightness, the following request is sent by the app

http://192.168.4.1/conf?brightness=224

there is a handler for this request in the sketch that when gets this request sets the brightness. Review the code to find out more.

Android App

Android app is created using Phonegap. It is a technology that allows you to create cross-platform mobile apps using web technologies (HTML, CSS, Javascript). You can get the source code by visiting this page

You can read this and other amazing tutorials on ElectroPeak's official website

Code

Fire Effect CodeArduino
#include 
#include 
#include "FastLED.h"
#include "EEPROM.h"
#include "FS.h"  //required for SPIFFS

#define DATA_PIN 5
#define LED_TYPE WS2811
#define COLOR_ORDER GRB
#define NUM_LEDS 30
#define NUM_STRIPS 6
#define CHIPSET     WS2812B

//addresses to save data to EEPROM to preserve the state of fire simulation
#define cs0Adr 0
#define cs1Adr 3
#define cs2Adr 6
#define cs3Adr 9
#define BriAdr 15
#define FpsAdr 16
#define SparkingAdr 17
#define CoolingAdr 18
#define EEPROMCheckAdr 20 //if this value is 250 we assume we have previously saved to EEPROM and load data from that

CRGB leds[NUM_STRIPS * NUM_LEDS];

String inData;
uint8_t FPS = 100; //FRAMES_PER_SECOND
uint8_t SPARKING = 150;
uint8_t COOLING = 90; 
uint8_t BRIGHTNESS = 100;
uint8_t csRGB[4][3] = {{0, 0, 0},
                       {255, 0, 0},
                       {255, 127, 0},
                       {255, 255, 255}};

unsigned long previousMillis = 0;
bool change = false;            //if true we go to save to EEprom.
unsigned long changeMillis = 0; //changes will be saved 1 minute after no change is applied to avoid EEPROM wear.

bool initSetup = true;


CRGBPalette16 gPal;

ESP8266WebServer server(80); //Web server object. Will be listening in port 80 (default for HTTP)

void setup()
{
  EEPROM.begin(200);
  cWiFi();
  setupFastLED();
  loadConfig();
  gPal = CRGBPalette16( CRGB(csRGB[0][0],csRGB[0][1],csRGB[0][2]), 
                        CRGB(csRGB[1][0],csRGB[1][1],csRGB[1][2]), 
                        CRGB(csRGB[2][0],csRGB[2][1],csRGB[2][2]),  
                        CRGB(csRGB[3][0],csRGB[3][1],csRGB[3][2]));
                                           
}

inline void setupFastLED()
{
  delay(1000); // sanity delay
  FastLED.addLeds<CHIPSET, DATA_PIN, COLOR_ORDER>(leds, NUM_STRIPS * NUM_LEDS).setCorrection(TypicalLEDStrip);
  FastLED.setBrightness(BRIGHTNESS);
}

void loop()
{

  server.handleClient(); //Handling of incoming requests
  if (change)
  {
    if (millis() - changeMillis > 60000)
    {
      change = false;
      saveToEEPROM();
    }
  }
  fire();
  FastLED.show();
  FastLED.delay(1000 / FPS);
}


void Fire2012WithPalette(int stripNo)
{
  static byte heat[NUM_STRIPS][NUM_LEDS];

  // Step 1.  Cool down every cell a little
    for( int i = 0; i < NUM_LEDS; i++) { heat[stripNo][i] = qsub8( heat[stripNo][i], random8(0, ((COOLING * 10) / NUM_LEDS) + 2)); } // Step 2. Heat from each cell drifts 'up' and diffuses a little for( int k= NUM_LEDS - 1; k >= 2; k--) {
      heat[stripNo][k] = (heat[stripNo][k - 1] + heat[stripNo][k - 2] + heat[stripNo][k - 2] ) / 3;
    }
    
    // Step 3.  Randomly ignite new 'sparks' of heat near the bottom
    if( random8() < SPARKING ) {
      int y = random8(5);
      heat[stripNo][y] = qadd8( heat[stripNo][y], random8(160,200) );
    }

    // Step 4.  Map from heat cells to LED colors
    for( int j = 0; j < NUM_LEDS; j++) {
      // Scale the heat value from 0-255 down to 0-240
      // for best results with color palettes.
      byte colorindex = scale8( heat[stripNo][j], 240);
      CRGB color = ColorFromPalette( gPal, colorindex);
      
      leds[j+stripNo*NUM_LEDS] = color;
    }
}

void fire(){
  for (int i=0; i<NUM_STRIPS; i++){ Fire2012WithPalette(i); } } int str2int(String InputStr) { return InputStr.toInt(); } boolean EveryNSec(uint8_t period) { unsigned long currentMillis = millis(); if (currentMillis - previousMillis >= period * 1000)
  {
    // save the last time you blinked the LED
    previousMillis = currentMillis;
    return true;
  }
  else
  {
    return false;
  }
}

void EEPROMupdate(byte address, byte value)
{
  if (EEPROM.read(address) != value)
  {
    EEPROM.write(address, value);
    EEPROM.commit();
  }
  return;
}

void saveToEEPROM()
{
  EEPROMupdate(BriAdr, BRIGHTNESS);
  EEPROMupdate(FpsAdr, FPS);
  EEPROMupdate(SparkingAdr, SPARKING);
  EEPROMupdate(CoolingAdr, COOLING);
  for (uint8_t i = 0; i < 4; i++)
  {
    for (uint8_t j = 0; j < 3; j++)
    {
      EEPROMupdate((i * 3 + j), csRGB[i][j]);
    }
  }
}

void handleCS0Change(){
    csRGB[0][0] = str2int(server.arg("R"));
    csRGB[0][1] = str2int(server.arg("G"));
    csRGB[0][2] = str2int(server.arg("B"));
    gPal = CRGBPalette16( CRGB(csRGB[0][0],csRGB[0][1],csRGB[0][2]), CRGB(csRGB[1][0],csRGB[1][1],csRGB[1][2]), CRGB(csRGB[2][0],csRGB[2][1],csRGB[2][2]),  CRGB(csRGB[3][0],csRGB[3][1],csRGB[3][2]));
    changeMillis = millis();
    change = true;
}
void handleCS1Change(){
    csRGB[1][0] = str2int(server.arg("R"));
    csRGB[1][1] = str2int(server.arg("G"));
    csRGB[1][2] = str2int(server.arg("B"));
    gPal = CRGBPalette16( CRGB(csRGB[0][0],csRGB[0][1],csRGB[0][2]), CRGB(csRGB[1][0],csRGB[1][1],csRGB[1][2]), CRGB(csRGB[2][0],csRGB[2][1],csRGB[2][2]),  CRGB(csRGB[3][0],csRGB[3][1],csRGB[3][2]));
    changeMillis = millis();
    change = true;
}
void handleCS2Change(){
    csRGB[2][0] = str2int(server.arg("R"));
    csRGB[2][1] = str2int(server.arg("G"));
    csRGB[2][2] = str2int(server.arg("B"));
    gPal = CRGBPalette16( CRGB(csRGB[0][0],csRGB[0][1],csRGB[0][2]), CRGB(csRGB[1][0],csRGB[1][1],csRGB[1][2]), CRGB(csRGB[2][0],csRGB[2][1],csRGB[2][2]),  CRGB(csRGB[3][0],csRGB[3][1],csRGB[3][2]));
    changeMillis = millis();
    change = true;
}
void handleCS3Change(){
    csRGB[3][0] = str2int(server.arg("R"));
    csRGB[3][1] = str2int(server.arg("G"));
    csRGB[3][2] = str2int(server.arg("B"));
    gPal = CRGBPalette16( CRGB(csRGB[0][0],csRGB[0][1],csRGB[0][2]), CRGB(csRGB[1][0],csRGB[1][1],csRGB[1][2]), CRGB(csRGB[2][0],csRGB[2][1],csRGB[2][2]),  CRGB(csRGB[3][0],csRGB[3][1],csRGB[3][2]));
    changeMillis = millis();
    change = true;
}

void handleConf()
{
  if (server.arg("brightness") != "")
  {
    BRIGHTNESS = str2int(server.arg("brightness"));
    FastLED.setBrightness(BRIGHTNESS);
    changeMillis = millis();
    change = true;
  }
  if (server.arg("fps") != "")
  {
    FPS = str2int(server.arg("fps"));
    changeMillis = millis();
    change = true;
  }
  if (server.arg("sparking") != "")
  {
    SPARKING = str2int(server.arg("sparking"));
    changeMillis = millis();
    change = true;
  }
  if (server.arg("cooling") != "")
  {
    COOLING = str2int(server.arg("cooling"));
    changeMillis = millis();
    change = true;
  }
  
  server.sendHeader("Connection", "close");
  server.sendHeader("Access-Control-Allow-Origin", "*");
  server.send(200, "text/plain", ""); //Returns the HTTP response
}

void loadConfig()
{

  if (EEPROM.read(EEPROMCheckAdr) == 250)
  {
    BRIGHTNESS = EEPROM.read(BriAdr);
    SPARKING = EEPROM.read(SparkingAdr);
    COOLING = EEPROM.read(CoolingAdr);
    FPS = EEPROM.read(FpsAdr);
    if (FPS == 0)
      FPS = 100;

    for (uint8_t i = 0; i < 4; i++)
    {
      for (uint8_t j = 0; j < 3; j++)
      {
        csRGB[i][j] = EEPROM.read(i * 3 + j);
      }
    }
  }else{
    EEPROMupdate(BriAdr,BRIGHTNESS);
    EEPROMupdate(FpsAdr,FPS);
    EEPROMupdate(CoolingAdr,COOLING);
    EEPROMupdate(SparkingAdr, SPARKING);
    for (uint8_t i = 0; i < 4; i++)
    {
      for (uint8_t j = 0; j < 3; j++)
      {
        EEPROMupdate((i*3+j) , csRGB[i][j]);
      }
    }
    EEPROMupdate(EEPROMCheckAdr, 250);
  }
}

void cWiFi()
{
  WiFi.softAP("ElectroPeak's Flame", ""); //set a password here if you want i.e. WiFi.softAP("ElectroPeak's Flame", "12345678");

  IPAddress myIP = WiFi.softAPIP();
  server.on("/cs0", handleCS0Change);
  server.on("/cs1", handleCS1Change);
  server.on("/cs2", handleCS2Change);
  server.on("/cs3", handleCS3Change);
  server.on("/conf", handleConf);
  server.serveStatic("/", SPIFFS, "/", "max-age=86400");
  server.begin(); //Start the server
}
Sketch and Data folderArduino
This zip file contains both the sketch file and the data folder (SPIFFS upload)
No preview (download only).

Custom parts and enclosures

EP's Flame Android App
eps_flame_android_u5Zy5Bksvp.apk

Comments

Similar projects you might like

Make an Enhanced R2-D2 to Be Controlled by an Android App

Project tutorial by Kutluhan Aktar

  • 1,280 views
  • 0 comments
  • 2 respects

Personal Weather Station (Arduino+ ESP8266 + Thingspeak)

Project tutorial by Jayraj Desai

  • 51,583 views
  • 32 comments
  • 108 respects

How to Configure NeoPixels Using Vixen Lights and Arduino

Project tutorial by Victor Aguilar

  • 13,359 views
  • 23 comments
  • 28 respects

DIY Speedometer Using Arduino and Processing Android App

Project tutorial by user334153146

  • 13,108 views
  • 0 comments
  • 18 respects

Health Band - A Smart Assistant for the Elderly

Project tutorial by Technovation

  • 20,075 views
  • 11 comments
  • 53 respects
Add projectSign up / Login