Firmware/Arduino 아두이노

네오픽셀 RGB LED / esp8266 / nodemcu / 아두이노

또난 2021. 1. 13. 21:56

 

보드 매니저 esp 시리즈 라이브러리 설치

https://dl.espressif.com/dl/package_esp32_index.json
http://arduino.esp8266.com/stable/package_esp8266com_index.json

 

네오픽셀
스케줄러

 

웹 소켓

github.com/arkhipenko/TaskScheduler

Adafruit NeoPixel Library: Adafruit_NeoPixel Class Reference

github.com/Links2004/arduinoWebSockets

 

 

esp8266 소스코드

c:\Users\acer\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.7.4\variants\nodemcu\

 

// pins_arduino.h
#ifndef Pins_Arduino_h
#define Pins_Arduino_h

#define PIN_WIRE_SDA (4)
#define PIN_WIRE_SCL (5)

static const uint8_t SDA = PIN_WIRE_SDA;
static const uint8_t SCL = PIN_WIRE_SCL;

#ifndef LED_BUILTIN
#define LED_BUILTIN 2
#endif
#define LED_BUILTIN_AUX 16

static const uint8_t D0   = 16;
static const uint8_t D1   = 5;
static const uint8_t D2   = 4;
static const uint8_t D3   = 0;
static const uint8_t D4   = 2;
static const uint8_t D5   = 14;
static const uint8_t D6   = 12;
static const uint8_t D7   = 13;
static const uint8_t D8   = 15;
static const uint8_t D9   = 3;
static const uint8_t D10  = 1;

#include "../generic/common.h"

#endif /* Pins_Arduino_h */ 

esp8266 은 100개이상 네오픽셀 설정하고 빈번하게 동작시키면 정지되면서 소프트 와치독으로 리셋됨

esp32는 동일 소스인데.. 500개로 설정해도 그런 증상이 없다.

 

 

ESP8266 코드

더보기

 

 

웹소켓 방식
/*
 * Sketch: ESP8266_LED_CONTROL_AJAX_07
 * Intended to be run on an ESP8266
 */
 
String header = "HTTP/1.1 200 OK\r\nContent-Type: text/html\r\n\r\n";

String html_1 = R"=====(
<!DOCTYPE html>
<html>
 <head>
 <meta name='viewport' content='width=device-width, initial-scale=1.0'/>
 <meta charset='utf-8'>
 <style>
  body {font-size:140%; } 
  #main {display: table; margin: auto;  padding: 0 5px 0 5px;  } 
  h2 {text-align:center; } 
  input[type="button"] { width: 4em; font-size: 120%; }
  .green { background-color: #50FF50;  }
  .red   { background-color: #FF5050;  }  
  table {width: 100%; }
 </style>

<script>
  function switchLED1() 
  {
     var button_text = document.getElementById("LED1_button").value;
     if (button_text=="OFF")
     {
       document.getElementById("LED1_button").value = "ON";
       document.getElementById("LED1_button").style.background = "#50FF50";
       ajaxLoad('L11'); 
     }
     else
     {
       document.getElementById("LED1_button").value = "OFF";
       document.getElementById("LED1_button").style.background = "#FF5050";
       ajaxLoad('L10');
     }
  }

  function switchLED2() 
  {
     var button_text = document.getElementById("LED2_button").value;
     if (button_text=="OFF")
     {
       document.getElementById("LED2_button").value = "ON";
       document.getElementById("LED2_button").style.background = "#50FF50";
       ajaxLoad('L21'); 
     }
     else
     {
       document.getElementById("LED2_button").value = "OFF";
       document.getElementById("LED2_button").style.background = "#FF5050";
       ajaxLoad('L20');
     }
  }

  function switchLED3() 
  {
     var button_text = document.getElementById("LED3_button").value;
     if (button_text=="OFF")
     {
       document.getElementById("LED3_button").value = "ON";
       document.getElementById("LED3_button").style.background = "#50FF50";
       ajaxLoad('L31'); 
     }
     else
     {
       document.getElementById("LED3_button").value = "OFF";
       document.getElementById("LED3_button").style.background = "#FF5050";
       ajaxLoad('L30');
     }
  }  

  var ajaxRequest = null;
  if (window.XMLHttpRequest)  { ajaxRequest =new XMLHttpRequest(); }
  else                        { ajaxRequest =new ActiveXObject("Microsoft.XMLHTTP"); }


  function ajaxLoad(ajaxURL)
  {
    if(!ajaxRequest){ alert("AJAX is not supported."); return; }
    
    ajaxRequest.open("GET",ajaxURL,true);
    ajaxRequest.onreadystatechange = function()
    {
      if(ajaxRequest.readyState == 4 && ajaxRequest.status==200)
      {
        var ajaxResult = ajaxRequest.responseText;
      }
    }
    ajaxRequest.send();
  }
   
</script>

 <title>LED Control</title>
</head>
<body>
 <div id='main'>
  <h2>LED Control</h2>
  <table id = "controls">
   <tr>
    <td width="70%">LED R</td>
)=====";

String html_2 = "    <td> <input type='button' id='LED1_button' value='OFF' class='red' onclick='switchLED1()' />  </td>";

String html_3 = R"=====(
   </tr>
   <tr>
    <td width="70%">LED G</td>
)=====";

String html_4 = "    <td> <input type='button' id='LED2_button' value='OFF' class='red' onclick='switchLED2()' />  </td>";

String html_5 = R"=====(
   </tr>
   <tr>
    <td width="70%">LED B</td>
)=====";    

String html_6 = "    <td> <input type='button' id='LED3_button' value='OFF' class='red' onclick='switchLED3()' />  </td>";

String html_7 = R"=====(
   </tr>
  </table>
 </div>
</body>
</html>
 
)=====";



#include <ESP8266WiFi.h>

#include <Adafruit_NeoPixel.h>


#define NEO_RAINBOW 300
#define NEO_LED_PIN 14  //D5
#define NEO_MAX_NUMBER 100

// change these values to match your network
char ssid[] = "xxxx";       //  your network SSID (name)
char pass[] = "xxxx";            //  your network password
 
WiFiServer server(80);

 
String request = "";
int LED1_Pin = 2;
int LED2_Pin = 16;
int LED3_Pin = 0;

volatile bool ctrlLedColor = true;
int LED_Pin = 2;
int LED_ComPin = 16;
int neoColorR = 255;
int neoColorG = 255;
int neoColorB = 255;


// Parameter 1 = number of pixels in strip
// Parameter 2 = Arduino pin number (most are valid)
// Parameter 3 = pixel type flags, add together as needed:
//   NEO_KHZ800  800 KHz bitstream (most NeoPixel products w/WS2812 LEDs)
//   NEO_KHZ400  400 KHz (classic 'v1' (not v2) FLORA pixels, WS2811 drivers)
//   NEO_GRB     Pixels are wired for GRB bitstream (most NeoPixel products)
//   NEO_RGB     Pixels are wired for RGB bitstream (v1 FLORA pixels, not v2)
//   NEO_RGBW    Pixels are wired for RGBW bitstream (NeoPixel RGBW products)
Adafruit_NeoPixel strip = Adafruit_NeoPixel(NEO_MAX_NUMBER, NEO_LED_PIN, NEO_GRB + NEO_KHZ800);

void setup() 
{    
    pinMode(LED1_Pin, OUTPUT);     
    pinMode(LED2_Pin, OUTPUT);  
    pinMode(LED3_Pin, OUTPUT);  
  
    Serial.begin(115200);
    Serial.println();
    Serial.println("Serial started at 230400");
    Serial.println("ESP8266_LED_CONTROL_AJAX_07");
    Serial.println();
 
    // Connect to a WiFi network
    Serial.print(F("Connecting to "));  Serial.println(ssid);
    WiFi.begin(ssid, pass);
 
    while (WiFi.status() != WL_CONNECTED) 
    {
        Serial.print(".");
        delay(500);
    }
      
    Serial.println("");
    Serial.println(F("[CONNECTED]"));
    Serial.print("[IP ");              
    Serial.print(WiFi.localIP()); 
    Serial.println("]");
 
    // start a server
    server.begin();
    Serial.println("Server started");

    strip.begin();
    strip.setBrightness(10);
    //strip.show(); // Initialize all pixels to 'off'
    //strip.updateLength(16);
    colorWipe(strip.Color(neoColorG, neoColorR, neoColorB), 0); 
    //ctrlLedColor++;
 
} // void setup()
 
 
volatile int servercnt = 0;
void loop() 
{
    if(ctrlLedColor)  
    { 
      //server.stop();
      digitalWrite(LED_ComPin, false);
      //delay(5);
      Serial.println("Control LED..");
      if( neoColorR == NEO_RAINBOW){ 
        //rainbow(1);
        rainbowCycle(1); 
        //restartServer = true;
      }
      else {
        colorWipe(strip.Color(neoColorG, neoColorR, neoColorB), 0); // Green
      }    
      digitalWrite(LED_ComPin, true);
      //yield();
      ctrlLedColor = false;
      //delay(5);
      //server.begin();
    }
    
    if(servercnt++ >= 30000)  // 30000 => 100ms
    {
      WebServer();
      servercnt = 0;   
      //Serial.println("WebServer"); 
    }
    
    
 
  
  // The client will actually be disconnected when the function returns and 'client' object is detroyed
} // void loop()

void WebServer()
{
 // Check if a client has connected
    WiFiClient client = server.available();
    if (!client)  {  return;  }
//    if(ctrlLedColor) {  
//      client.flush();
//        client.print( header );
//        client.print( html_1 );    
//        client.print( html_2 ); 
//        client.print( html_3 ); 
//        client.print( html_4 ); 
//        client.print( html_5 ); 
//        client.print( html_6 ); 
//        client.print( html_7 ); 
//      return;  }
    // Read the first line of the request
    request = client.readStringUntil('\r');

    Serial.print("request: "); Serial.println(request.length()); Serial.println(request); 
    
    if(request.length() == 0 ) return;
    
    if       ( request.indexOf("L10") > 0 )  {       
      neoColorR = 0, ctrlLedColor = true;    
    }
    else if  ( request.indexOf("L11") > 0 )  {       
      neoColorR = 255, ctrlLedColor = true;        
    }
    if       ( request.indexOf("L20") > 0 )  {          
      neoColorG = 0,  ctrlLedColor = true;          
    }
    else if  ( request.indexOf("L21") > 0 )  {       
      neoColorG = 255, ctrlLedColor = true;   
    }
    if       ( request.indexOf("L30") > 0 )  { 
      //digitalWrite(LED3_Pin, HIGH);  
      neoColorB = 0, ctrlLedColor = true;     
    }
    else if  ( request.indexOf("L31") > 0 )  { 
      neoColorB = 255, ctrlLedColor = true;
      //neoColorR = NEO_RAINBOW;           
     }
    else
    {
       if (neoColorR != 0) 
       { 
         html_2 = "    <td> <input type='button' id='LED1_button' value='ON' class='green' onclick='switchLED1()' />  </td>";
       }
       else
       {
         html_2 = "    <td> <input type='button' id='LED1_button' value='OFF' class='red' onclick='switchLED1()' />  </td>";
       }

       
       if (neoColorG != 0) 
       { 
         html_4 = "    <td> <input type='button' id='LED2_button' value='ON' class='green' onclick='switchLED2()' />  </td>";
       }
              else
       {
         html_4 = "    <td> <input type='button' id='LED2_button' value='OFF' class='red' onclick='switchLED2()' />  </td>";
       }


       if (neoColorB != 0) 
       { 
         html_6 = "    <td> <input type='button' id='LED3_button' value='ON' class='green' onclick='switchLED3()' />  </td>";
       }
       else
       {
         html_6 = "    <td> <input type='button' id='LED3_button' value='OFF' class='red' onclick='switchLED3()' />  </td>";
       }

        client.flush();
        client.print( header );
        client.print( html_1 );    
        client.print( html_2 ); 
        client.print( html_3 ); 
        client.print( html_4 ); 
        client.print( html_5 ); 
        client.print( html_6 ); 
        client.print( html_7 ); 
        //yield();
        //delay(5);
    }

  
}


// Input a value 0 to 255 to get a color value.
// The colours are a transition r - g - b - back to r.
uint32_t Wheel(byte WheelPos) {
  WheelPos = 255 - WheelPos;
  if(WheelPos < 85) {
    return strip.Color(255 - WheelPos * 3, 0, WheelPos * 3);
  }
  if(WheelPos < 170) {
    WheelPos -= 85;
    return strip.Color(0, WheelPos * 3, 255 - WheelPos * 3);
  }
  WheelPos -= 170;
  return strip.Color(WheelPos * 3, 255 - WheelPos * 3, 0);
}

// Slightly different, this makes the rainbow equally distributed throughout
void rainbowCycle(volatile uint8_t wait) {
  uint16_t i, j;
  int maxNum = 0;
  if(strip.numPixels() > 100) maxNum = 100;  // 최대 100개까지..
  else maxNum = strip.numPixels();
  Serial.println(maxNum); 
  for(j=0; j<256*5; j++) { // 5 cycles of all colors on wheel
    for(i=0; i< maxNum; i++) {
      strip.setPixelColor(i, Wheel(((i * 256 / maxNum) + j) & 255));      
    }
    strip.show();
    delay(wait);
  }
}

// Fill the dots one after the other with a color
void colorWipe(uint32_t c, volatile uint8_t wait) {
  for(uint16_t i=0; i<strip.numPixels(); i++) {
    strip.setPixelColor(i, c);
    strip.show();
    delay(wait);
  }
}

 

웹 서버 방식
String header = "HTTP/1.1 200 OK\r\nContent-Type: text/html\r\n\r\n";
 
String html_1 = R"=====(
<!DOCTYPE html>
<html>
 <head>
 <meta name='viewport' content='width=device-width, initial-scale=1.0'/>
 <meta charset='utf-8'>
 <style>
  body {font-size:110%;} 
  #main {display: table; margin: auto;  padding: 0 10px 0 10px; } 
  #F1 {float:left; margin-right:10px; width:100% }
  h2 {text-align:center; } 
  .button { padding:10px 10px 10px 10px; width:100%; color: #fff; background-color: rgba(200, 0, 200, 1); font-size: 120%;}
  .btnW { padding:10px 10px 10px 10px; width:100%;  color: #ff; background-color: rgba(220, 255, 255, 1); font-size: 120%;}
  .btnR { padding:10px 10px 10px 10px; width:100%;  color: #fff; background-color: rgba(220, 0, 0, 1); font-size: 120%;}
  .btnG { padding:10px 10px 10px 10px; width:100%;  color: #fff; background-color: rgba(0, 220, 0, 1); font-size: 120%;}
  .btnB { padding:10px 10px 10px 10px; width:100%;  color: #fff; background-color: rgba(0, 0, 220, 1); font-size: 120%;}
  .btnRain { padding:10px 10px 10px 10px; width:100%;  color: #fff; background-color: rgba(200, 0, 200, 1); font-size: 120%;}
  .btnOff { padding:10px 10px 10px 10px; width:100%;  color: #fff; background-color: rgba(150, 150, 150, 1); font-size: 120%;}
  input {
        width: 100%;
        margin: 3px 0;
        outline: none;
        text-align: center;
        font-size: 120%;      }
 </style>
 
 <title>LED Control</title>
</head>
<body>
 <div id='main'>
  <h2>Neo Pixel Control</h2>
)=====";
 
String html_2 = "  <form id='' action='RAIN'><input class='btnRain' type='submit' value='Rainbow' ></form>";
String html_3 = "  <form id='F1' action='NEOW'><input class='btnW' type='submit' value='White' ></form>";
String html_4 = "  <form id='F3' action='NEOR'><input class='btnR' type='submit' value='Red' ></form>";
String html_5 = "  <form id='F1' action='NEOG'><input class='btnG' type='submit' value='Green' ></form>";
String html_6 = "  <form id='F5' action='NEOB'><input class='btnB' type='submit' value='Blue' ></form>";
String html_7 = "  <form id='F6' action='OFF'><input class='btnOff' type='submit' value='Off' ></form><br>\r\n";
String html_set = R"=====(
<form action = "" accept-charset="utf-8" name = "datalist" method = "get"> 
  <fieldset style = "width:350 ">
    <legend>< 설정 ></legend>      
      최대갯수(300개이상 동작주의): <input type = "number" min = "1" max = "2000" step = "1" name = "LedNumber" value="100"> <br>  
      밝기 : <input type = "range" min = "5" max = "100" step = "5" name = "range" value="15"> <br>    
      <input type = "submit" value = "적용" />   
  </fieldset>
</form>
)=====";
String html_end = R"=====(
  </div>
 </body>
</html>
)=====";

// === printf ===
#include <stdio.h>
#include <stdarg.h>
// ==================

#include <ESP8266WiFi.h>

#include <TaskScheduler.h>

#include <Adafruit_NeoPixel.h>
#ifdef __AVR__
  #include <avr/power.h>
#endif

// change these values to match your network
char ssid[] = "xxx";       //  your network SSID (name)
char pass[] = "xxxxx";          //  your network password
 
WiFiServer server(80);
 
String request = "";

bool ctrlLedColor = true;
int LED_Pin = 2;
int LED_ComPin = 16;

#define NEO_RAINBOW 300
#define NEO_LED_PIN 14
#define NEO_MAX_NUMBER 200

// Parameter 1 = number of pixels in strip
// Parameter 2 = Arduino pin number (most are valid)
// Parameter 3 = pixel type flags, add together as needed:
//   NEO_KHZ800  800 KHz bitstream (most NeoPixel products w/WS2812 LEDs)
//   NEO_KHZ400  400 KHz (classic 'v1' (not v2) FLORA pixels, WS2811 drivers)
//   NEO_GRB     Pixels are wired for GRB bitstream (most NeoPixel products)
//   NEO_RGB     Pixels are wired for RGB bitstream (v1 FLORA pixels, not v2)
//   NEO_RGBW    Pixels are wired for RGBW bitstream (NeoPixel RGBW products)
Adafruit_NeoPixel strip = Adafruit_NeoPixel(NEO_MAX_NUMBER, NEO_LED_PIN, NEO_GRB + NEO_KHZ800);

// IMPORTANT: To reduce NeoPixel burnout risk, add 1000 uF capacitor across
// pixel power leads, add 300 - 500 Ohm resistor on first pixel's data input
// and minimize distance between Arduino and first pixel.  Avoid connecting


//colorWipe(strip.Color(0, 255, 0), 0); // Green
void _printf(const char *s,...){
  va_list args;
  va_start(args, s);
  int n = vsnprintf(NULL, 0, s, args);
  char *str = new char[n+1];
  vsprintf(str, s, args);
  va_end(args);
  Serial.print(str);
  delete [] str;
}
// ========== 스케줄러 ===========
void t1Callback();
void t2Callback();


Task t1(50, TASK_FOREVER, &t1Callback);
Task t2(100, TASK_FOREVER, &t2Callback);

Scheduler runner;

//=============================
// server
int neoColorR = 255;
int neoColorG = 255;
int neoColorB = 255;

void setup() {
  runner.init();
  runner.addTask(t1);
  runner.addTask(t2);
//  runner.addTask(t3);
//  runner.addTask(t4);

  t1.enable();
  t2.enable();
//  t3.enable();
//  t4.enable();

  pinMode(LED_Pin, OUTPUT);       
  pinMode(LED_ComPin, OUTPUT);
     
    Serial.begin(230400);
    Serial.println();
    Serial.println("Serial started at 115200");
    Serial.println("ESP8266_LED_CONTROL_AJAX_01");
    Serial.println();
 
    // Connecting to a WiFi network
    WiFi.mode(WIFI_AP_STA);
    // wifi 접속 안되면 리셋 되는 현상으로 추가.
    WiFi.persistent(false);
    WiFi.disconnect(true);
    Serial.print(F("Connecting to "));  Serial.println(ssid);
    WiFi.begin(ssid, pass);
 
    while (WiFi.status() != WL_CONNECTED) 
    {
        Serial.print(".");
        delay(500);
    }
 
    Serial.println("");
    Serial.println(F("[CONNECTED]"));
    Serial.print("[IP ");              
    Serial.print(WiFi.localIP()); 
    Serial.println("]");
 
    // start a server
    //server.onNotFound(handle_NotFound);
    server.begin();
    Serial.println("Server started");
    
  // This is for Trinket 5V 16MHz, you can remove these three lines if you are not using a Trinket
  #if defined (__AVR_ATtiny85__)
    if (F_CPU == 16000000) clock_prescale_set(clock_div_1);
  #endif
  // End of trinket special code

  strip.begin();
  strip.setBrightness(10);
  //strip.show(); // Initialize all pixels to 'off'
  //strip.updateLength(16);
  colorWipe(strip.Color(neoColorG, neoColorR, neoColorB), 0); 
  //ctrlLedColor++;
}

void loop() {
  runner.execute();  
  webServer();  
  if(ctrlLedColor)  
  {    
    ctrlLedColor = false;
    //server.stop();
    digitalWrite(LED_ComPin, false);
    //delay(5);
    Serial.println("Control LED..");
    if( neoColorR == NEO_RAINBOW){ 
      //rainbow(1);
      rainbowCycle(1); 
      //restartServer = true;
    }
    else {
      colorWipe(strip.Color(neoColorG, neoColorR, neoColorB), 0); // Green
    }    
    digitalWrite(LED_ComPin, true);
    //server.begin();
  }
  
}
static String RcvRequest="hello";
void webServer()
{    
    
    // Check if a client has connected
    WiFiClient client = server.available();
    if (!client)  {  return;  }
 
    // Read the first line of the request
    request = client.readStringUntil('\r');
    Serial.print("request: "); Serial.println(request.length());Serial.println(request); 
    
    if ( RcvRequest != request && request.indexOf("favicon.ico") < 0 && request.length() > 5 )
    {
      RcvRequest = request;
      ctrlLedColor = true;
      Serial.print("RcvRequest: "); Serial.println(RcvRequest); 
      digitalWrite(LED_Pin, !(digitalRead(LED_Pin)));

     if( RcvRequest.indexOf("LedNumber=") > 0 )  {
      
      int index1 = RcvRequest.indexOf('='); 
      int index2 = RcvRequest.indexOf('&');
      int index3 = RcvRequest.indexOf('=',index2+1);   
      int index4 = RcvRequest.indexOf(" HTTP");   
      //int index3 = request.length();
      int LedMaxNumber = RcvRequest.substring(index1+1, index2).toInt();
      int LedBrightness = RcvRequest.substring(index3+1, index4).toInt();
      //Serial.println("setting Param "); 
      Serial.printf("Param len %d idx1[%d] idx2[%d]\n", RcvRequest.length(), LedMaxNumber, LedBrightness);       
       strip.updateLength(LedMaxNumber+1);  // 최대갯수에서 1을 더해야 정상 갯수 
       strip.setBrightness(LedBrightness);  
      }
    else if       ( RcvRequest.indexOf("OFF") > 0 )  {
      neoColorR = 0, neoColorG = 0, neoColorB = 0;      
      Serial.println("OFF"); 
      }
    else if  ( RcvRequest.indexOf("RAIN") > 0 ) {       
      neoColorR = NEO_RAINBOW;      
      }
    else if  ( RcvRequest.indexOf("NEOW") > 0 ) {       
      neoColorR = 255, neoColorG = 255, neoColorB = 255;      
      }
    else if  ( RcvRequest.indexOf("NEOR") > 0 ) { 
      neoColorR = 255, neoColorG = 0, neoColorB = 0;      
      }
    else if  ( RcvRequest.indexOf("NEOG") > 0 ) {       
      neoColorR = 0, neoColorG = 255, neoColorB = 0;      
      }
    else if  ( RcvRequest.indexOf("NEOB") > 0 ) {       
      neoColorR = 0, neoColorG = 0, neoColorB = 255;      
      }
    }   
    
    //client.flush();
 
    client.print( header );
    client.print( html_1 );        
    client.print( html_3 );
    client.print( html_4 );
    client.print( html_5 );
    client.print( html_6 );   
    client.print( html_2 ); 
    client.print( html_7 );  
    client.print( html_set );      
    client.print( html_end);
    client.flush();
    //delay(5);
    
}
// Fill the dots one after the other with a color
void colorWipe(uint32_t c, uint8_t wait) {
  for(uint16_t i=0; i<strip.numPixels(); i++) {
    strip.setPixelColor(i, c);
    strip.show();
    delay(wait);
  }
}

void rainbow(uint8_t wait) {
  uint16_t i, j;

  for(j=0; j<256; j++) {
    for(i=0; i<strip.numPixels(); i++) {
      strip.setPixelColor(i, Wheel((i+j) & 255));
    }
    strip.show();
    delay(wait);
  }
}

// Slightly different, this makes the rainbow equally distributed throughout
void rainbowCycle(uint8_t wait) {
  uint16_t i, j;
  int maxNum = 0;
  if(strip.numPixels() > 100) maxNum = 100;  // 최대 100개까지..
  else maxNum = strip.numPixels();
  Serial.println(maxNum); 
  for(j=0; j<256*5; j++) { // 5 cycles of all colors on wheel
    for(i=0; i< maxNum; i++) {
      strip.setPixelColor(i, Wheel(((i * 256 / maxNum) + j) & 255));      
    }
    strip.show();
    delay(wait);
  }
}

//Theatre-style crawling lights.
void theaterChase(uint32_t c, uint8_t wait) {
  for (int j=0; j<10; j++) {  //do 10 cycles of chasing
    for (int q=0; q < 3; q++) {
      for (uint16_t i=0; i < strip.numPixels(); i=i+3) {
        strip.setPixelColor(i+q, c);    //turn every third pixel on
      }
      strip.show();

      delay(wait);

      for (uint16_t i=0; i < strip.numPixels(); i=i+3) {
        strip.setPixelColor(i+q, 0);        //turn every third pixel off
      }
    }
  }
}

//Theatre-style crawling lights with rainbow effect
void theaterChaseRainbow(uint8_t wait) {
  for (int j=0; j < 256; j++) {     // cycle all 256 colors in the wheel
    for (int q=0; q < 3; q++) {
      for (uint16_t i=0; i < strip.numPixels(); i=i+3) {
        strip.setPixelColor(i+q, Wheel( (i+j) % 255));    //turn every third pixel on
      }
      strip.show();

      delay(wait);

      for (uint16_t i=0; i < strip.numPixels(); i=i+3) {
        strip.setPixelColor(i+q, 0);        //turn every third pixel off
      }
    }
  }
}

// Input a value 0 to 255 to get a color value.
// The colours are a transition r - g - b - back to r.
uint32_t Wheel(byte WheelPos) {
  WheelPos = 255 - WheelPos;
  if(WheelPos < 85) {
    return strip.Color(255 - WheelPos * 3, 0, WheelPos * 3);
  }
  if(WheelPos < 170) {
    WheelPos -= 85;
    return strip.Color(0, WheelPos * 3, 255 - WheelPos * 3);
  }
  WheelPos -= 170;
  return strip.Color(WheelPos * 3, 255 - WheelPos * 3, 0);
}

void t1Callback() {
  //static uint8_t Timer60sec = 1;
  //Serial.print("t1Callback \r\n");  
  //webServer();
 
}

void t2Callback() {  
  static uint8_t Timer60sec = 1;
  static bool restartServer = false;
  digitalWrite(LED_ComPin, !(digitalRead(LED_ComPin)));
  if(Timer60sec++ >= 5)
  {
    Timer60sec = 1;    
    //Serial.println("t2Callback"); 
    if (WiFi.status() != WL_CONNECTED)
    {
      Serial.println("WIFI Discon..");
      WiFi.begin(ssid, pass);
      delay(100);
      server.begin();
    }
    if(restartServer){
      restartServer = false;
      Serial.println("Server Restart..");
      server.stop();
      delay(100);
      server.begin();
    } 
  }
  
  
//  if(neoColorR + neoColorG + neoColorB == 0)
//  {
//    strip.clear(); // Initialize all pixels to 'off'
//  }
 
}

ESP32 코드 

더보기

 

esp8266 과 큰 차이점은 없다..( client.flush(); 사용안하는 정도)

String header = "HTTP/1.1 200 OK\r\nContent-Type: text/html\r\n\r\n";
 
String html_1 = R"=====(
<!DOCTYPE html>
<html>
 <head>
 <meta name='viewport' content='width=device-width, initial-scale=1.0'/>
 <meta charset='utf-8'>
 <style>
  body {font-size:110%;} 
  #main {display: table; margin: auto;  padding: 0 10px 0 10px; } 
  #F1 {float:left; margin-right:10px; width:100% }
  h2 {text-align:center; } 
  .button { padding:10px 10px 10px 10px; width:100%; color: #fff; background-color: rgba(200, 0, 200, 1); font-size: 120%;}
  .btnW { padding:10px 10px 10px 10px; width:100%;  color: #ff; background-color: rgba(220, 255, 255, 1); font-size: 120%;}
  .btnR { padding:10px 10px 10px 10px; width:100%;  color: #fff; background-color: rgba(220, 0, 0, 1); font-size: 120%;}
  .btnG { padding:10px 10px 10px 10px; width:100%;  color: #fff; background-color: rgba(0, 220, 0, 1); font-size: 120%;}
  .btnB { padding:10px 10px 10px 10px; width:100%;  color: #fff; background-color: rgba(0, 0, 220, 1); font-size: 120%;}
  .btnRain { padding:10px 10px 10px 10px; width:100%;  color: #fff; background-color: rgba(200, 0, 200, 1); font-size: 120%;}
  .btnOff { padding:10px 10px 10px 10px; width:100%;  color: #fff; background-color: rgba(150, 150, 150, 1); font-size: 120%;}
  input {
        width: 100%;
        margin: 3px 0;
        outline: none;
        text-align: center;
        font-size: 120%;      }
 </style>
 
 <title>LED Control</title>
</head>
<body>
 <div id='main'>
  <h2>Neo Pixel Control</h2>
)=====";
 
String html_2 = "  <form id='' action='RAIN'><input class='btnRain' type='submit' value='Rainbow' ></form>";
String html_3 = "  <form id='F1' action='NEOW'><input class='btnW' type='submit' value='White' ></form>";
String html_4 = "  <form id='F3' action='NEOR'><input class='btnR' type='submit' value='Red' ></form>";
String html_5 = "  <form id='F1' action='NEOG'><input class='btnG' type='submit' value='Green' ></form>";
String html_6 = "  <form id='F5' action='NEOB'><input class='btnB' type='submit' value='Blue' ></form>";
String html_7 = "  <form id='F6' action='OFF'><input class='btnOff' type='submit' value='Off' ></form><br>\r\n";
String html_set = R"=====(
<form action = "" accept-charset="utf-8" name = "datalist" method = "get"> 
  <fieldset style = "width:350 ">
    <legend>< 설정 ></legend>      
      최대갯수(300개이상 동작주의): <input type = "number" min = "1" max = "2000" step = "1" name = "LedNumber" value="100"> <br>  
      밝기 : <input type = "range" min = "5" max = "100" step = "5" name = "range" value="15"> <br>    
      <input type = "submit" value = "적용" />   
  </fieldset>
</form>
)=====";
String html_end = R"=====(
  </div>
 </body>
</html>
)=====";

// === printf ===
#include <stdio.h>
#include <stdarg.h>
// ==================

#include <WiFi.h>
#include <WiFiClient.h>
#include <WebServer.h>
#include <ESPmDNS.h>

#include <TaskScheduler.h>

#include <Adafruit_NeoPixel.h>
#ifdef __AVR__
  #include <avr/power.h>
#endif

// change these values to match your network
char ssid[] = "xx";       //  your network SSID (name)
char pass[] = "xxx";          //  your network password
 
WiFiServer server(80);
 
String request = "";

bool ctrlLedColor = true;
int LED_Pin = 21;
int LED_ComPin = 2;

#define NEO_RAINBOW 300
#define NEO_LED_PIN 13


// Parameter 1 = number of pixels in strip
// Parameter 2 = Arduino pin number (most are valid)
// Parameter 3 = pixel type flags, add together as needed:
//   NEO_KHZ800  800 KHz bitstream (most NeoPixel products w/WS2812 LEDs)
//   NEO_KHZ400  400 KHz (classic 'v1' (not v2) FLORA pixels, WS2811 drivers)
//   NEO_GRB     Pixels are wired for GRB bitstream (most NeoPixel products)
//   NEO_RGB     Pixels are wired for RGB bitstream (v1 FLORA pixels, not v2)
//   NEO_RGBW    Pixels are wired for RGBW bitstream (NeoPixel RGBW products)
Adafruit_NeoPixel strip = Adafruit_NeoPixel(100, NEO_LED_PIN, NEO_GRB + NEO_KHZ800);

// IMPORTANT: To reduce NeoPixel burnout risk, add 1000 uF capacitor across
// pixel power leads, add 300 - 500 Ohm resistor on first pixel's data input
// and minimize distance between Arduino and first pixel.  Avoid connecting


//colorWipe(strip.Color(0, 255, 0), 0); // Green
void _printf(const char *s,...){
  va_list args;
  va_start(args, s);
  int n = vsnprintf(NULL, 0, s, args);
  char *str = new char[n+1];
  vsprintf(str, s, args);
  va_end(args);
  Serial.print(str);
  delete [] str;
}
// ========== 스케줄러 ===========
void t1Callback();
void t2Callback();


Task t1(50, TASK_FOREVER, &t1Callback);
Task t2(100, TASK_FOREVER, &t2Callback);

Scheduler runner;

//=============================
// server
int neoColorR = 255;
int neoColorG = 255;
int neoColorB = 255;

void setup() {
   Serial.begin(230400);
    uint64_t chipid;
    chipid=ESP.getEfuseMac(); // The chip ID is essentially its MAC address(length: 6 bytes)
    Serial.printf("ESP32 Chip ID = %04X", (uint16_t)(chipid>>32)); // print High 2 bytes
    Serial.printf("%08X\n", (uint32_t)chipid); // print Low 4bytes
    Serial.println("---------------------------------");
     
    Serial.printf("Chip Revision %d\n", ESP.getChipRevision());
    esp_chip_info_t chip_info;
    esp_chip_info(&chip_info);
    Serial.printf("Number of Core: %d\n", chip_info.cores);
    Serial.printf("CPU Frequency: %d MHz\n", ESP.getCpuFreqMHz()); 
    Serial.println();
     
    Serial.printf("Flash Chip Size = %d byte\n", ESP.getFlashChipSize());
    Serial.printf("Flash Frequency = %d Hz\n", ESP.getFlashChipSpeed());
    Serial.println();
     
    Serial.printf("ESP-IDF version = %s\n", esp_get_idf_version());
    Serial.println();
     
    Serial.printf("Total Heap Size = %d\n", ESP.getHeapSize());
    Serial.printf("Free Heap Size = %d\n", ESP.getFreeHeap());
    Serial.printf("Lowest Free Heap Size = %d\n", ESP.getMinFreeHeap());
    Serial.printf("Largest Heap Block = %d\n", ESP.getMaxAllocHeap());
    Serial.println();
     


  runner.init();
  runner.addTask(t1);
  runner.addTask(t2);
//  runner.addTask(t3);
//  runner.addTask(t4);

  t1.enable();
  t2.enable();
//  t3.enable();
//  t4.enable();

  pinMode(LED_Pin, OUTPUT);       
  pinMode(LED_ComPin, OUTPUT);
     
   
    Serial.println();
    Serial.println("Serial started at 115200");
    Serial.println("ESP8266_LED_CONTROL_AJAX_01");
    Serial.println();
 
    // Connecting to a WiFi network
//    WiFi.mode(WIFI_STA);
//    // wifi 접속 안되면 리셋 되는 현상으로 추가.
//    WiFi.persistent(false);
//    WiFi.disconnect(true);
    Serial.print(F("Connecting to "));  Serial.println(ssid);
    WiFi.begin(ssid, pass);
 
    while (WiFi.status() != WL_CONNECTED) 
    {
        Serial.print(".");
        delay(500);
    }
 
    Serial.println("");
    Serial.println(F("[CONNECTED]"));
    Serial.print("[IP ");              
    Serial.print(WiFi.localIP()); 
    Serial.println("]");
 
    // start a server
    //server.onNotFound(handle_NotFound);
    server.begin();
    Serial.println("Server started");
    
  // This is for Trinket 5V 16MHz, you can remove these three lines if you are not using a Trinket
  #if defined (__AVR_ATtiny85__)
    if (F_CPU == 16000000) clock_prescale_set(clock_div_1);
  #endif
  // End of trinket special code

  strip.begin();
  strip.setBrightness(10);
  //strip.show(); // Initialize all pixels to 'off'
  //strip.updateLength(16);
  colorWipe(strip.Color(neoColorG, neoColorR, neoColorB), 0); 
  //ctrlLedColor++;
}

void loop() {
  runner.execute();  
  webServer();  
  if(ctrlLedColor)  
  {    
    ctrlLedColor = false;
    //server.stop();
    digitalWrite(LED_ComPin, false);
    //delay(5);
    Serial.println("Control LED..");
    if( neoColorR == NEO_RAINBOW){ 
      //rainbow(1);
      rainbowCycle(1); 
      //restartServer = true;
    }
    else {
      colorWipe(strip.Color(neoColorG, neoColorR, neoColorB), 0); // Green
    }    
    digitalWrite(LED_ComPin, true);
    //server.begin();
  }
  
}
static String RcvRequest="hello";
void webServer()
{    
    
    // Check if a client has connected
    WiFiClient client = server.available();
    if (!client)  {  return;  }
 
    // Read the first line of the request
    request = client.readStringUntil('\r');
    Serial.print("request: "); Serial.println(request.length());Serial.println(request); 
    
    if ( RcvRequest != request && request.indexOf("favicon.ico") < 0 && request.length() > 5 )
    {
      RcvRequest = request;
      ctrlLedColor = true;
      Serial.print("RcvRequest: "); Serial.println(RcvRequest); 
      digitalWrite(LED_Pin, !(digitalRead(LED_Pin)));

     if( RcvRequest.indexOf("LedNumber=") > 0 )  {
      
      int index1 = RcvRequest.indexOf('='); 
      int index2 = RcvRequest.indexOf('&');
      int index3 = RcvRequest.indexOf('=',index2+1);   
      int index4 = RcvRequest.indexOf(" HTTP");   
      //int index3 = request.length();
      int LedMaxNumber = RcvRequest.substring(index1+1, index2).toInt();
      int LedBrightness = RcvRequest.substring(index3+1, index4).toInt();
      //Serial.println("setting Param "); 
      _printf("Param len %d idx1[%d] idx2[%d]\n", RcvRequest.length(), LedMaxNumber, LedBrightness);       
       strip.updateLength(LedMaxNumber+1);  // 최대갯수에서 1을 더해야 정상 갯수 
       strip.setBrightness(LedBrightness);  
      }
    else if       ( RcvRequest.indexOf("OFF") > 0 )  {
      neoColorR = 0, neoColorG = 0, neoColorB = 0;      
      Serial.println("OFF"); 
      }
    else if  ( RcvRequest.indexOf("RAIN") > 0 ) {       
      neoColorR = NEO_RAINBOW;      
      }
    else if  ( RcvRequest.indexOf("NEOW") > 0 ) {       
      neoColorR = 255, neoColorG = 255, neoColorB = 255;      
      }
    else if  ( RcvRequest.indexOf("NEOR") > 0 ) { 
      neoColorR = 255, neoColorG = 0, neoColorB = 0;      
      }
    else if  ( RcvRequest.indexOf("NEOG") > 0 ) {       
      neoColorR = 0, neoColorG = 255, neoColorB = 0;      
      }
    else if  ( RcvRequest.indexOf("NEOB") > 0 ) {       
      neoColorR = 0, neoColorG = 0, neoColorB = 255;      
      }
    }   
    
    //client.flush();
 
    client.print( header );
    client.print( html_1 );        
    client.print( html_3 );
    client.print( html_4 );
    client.print( html_5 );
    client.print( html_6 );   
    client.print( html_2 ); 
    client.print( html_7 );  
    client.print( html_set );      
    client.print( html_end);
 
    //delay(5);
    
}
// Fill the dots one after the other with a color
void colorWipe(uint32_t c, uint8_t wait) {
  for(uint16_t i=0; i<strip.numPixels(); i++) {
    strip.setPixelColor(i, c);
    strip.show();
    delay(wait);
  }
}

void rainbow(uint8_t wait) {
  uint16_t i, j;

  for(j=0; j<256; j++) {
    for(i=0; i<strip.numPixels(); i++) {
      strip.setPixelColor(i, Wheel((i+j) & 255));
    }
    strip.show();
    delay(wait);
  }
}

// Slightly different, this makes the rainbow equally distributed throughout
void rainbowCycle(uint8_t wait) {
  uint16_t i, j;
  int maxNum = 0;
  //if(strip.numPixels() > 100) maxNum = 100;  // 최대 100개까지..
  //else maxNum = strip.numPixels();
  maxNum = strip.numPixels();
  Serial.println(maxNum); 
  for(j=0; j<256*5; j++) { // 5 cycles of all colors on wheel
    for(i=0; i< maxNum; i++) {
      strip.setPixelColor(i, Wheel(((i * 256 / maxNum) + j) & 255));      
    }
    strip.show();
    delay(wait);
  }
}

//Theatre-style crawling lights.
void theaterChase(uint32_t c, uint8_t wait) {
  for (int j=0; j<10; j++) {  //do 10 cycles of chasing
    for (int q=0; q < 3; q++) {
      for (uint16_t i=0; i < strip.numPixels(); i=i+3) {
        strip.setPixelColor(i+q, c);    //turn every third pixel on
      }
      strip.show();

      delay(wait);

      for (uint16_t i=0; i < strip.numPixels(); i=i+3) {
        strip.setPixelColor(i+q, 0);        //turn every third pixel off
      }
    }
  }
}

//Theatre-style crawling lights with rainbow effect
void theaterChaseRainbow(uint8_t wait) {
  for (int j=0; j < 256; j++) {     // cycle all 256 colors in the wheel
    for (int q=0; q < 3; q++) {
      for (uint16_t i=0; i < strip.numPixels(); i=i+3) {
        strip.setPixelColor(i+q, Wheel( (i+j) % 255));    //turn every third pixel on
      }
      strip.show();

      delay(wait);

      for (uint16_t i=0; i < strip.numPixels(); i=i+3) {
        strip.setPixelColor(i+q, 0);        //turn every third pixel off
      }
    }
  }
}

// Input a value 0 to 255 to get a color value.
// The colours are a transition r - g - b - back to r.
uint32_t Wheel(byte WheelPos) {
  WheelPos = 255 - WheelPos;
  if(WheelPos < 85) {
    return strip.Color(255 - WheelPos * 3, 0, WheelPos * 3);
  }
  if(WheelPos < 170) {
    WheelPos -= 85;
    return strip.Color(0, WheelPos * 3, 255 - WheelPos * 3);
  }
  WheelPos -= 170;
  return strip.Color(WheelPos * 3, 255 - WheelPos * 3, 0);
}

void t1Callback() {
  //static uint8_t Timer60sec = 1;
  //Serial.print("t1Callback \r\n");  
  //webServer();
 
}

void t2Callback() {  
  static uint8_t Timer60sec = 1;
  static bool restartServer = false;
  digitalWrite(LED_ComPin, !(digitalRead(LED_ComPin)));
  if(Timer60sec++ >= 5)
  {
    Timer60sec = 1;    
    //Serial.println("t2Callback"); 
    if (WiFi.status() != WL_CONNECTED)
    {
      Serial.println("WIFI Discon..");
      WiFi.begin(ssid, pass);
      delay(100);
      server.begin();
    }
    if(restartServer){
      restartServer = false;
      Serial.println("Server Restart..");
      server.stop();
      delay(100);
      server.begin();
    } 
  }
  
  
//  if(neoColorR + neoColorG + neoColorB == 0)
//  {
//    strip.clear(); // Initialize all pixels to 'off'
//  }
 
}
#include <WiFi.h>
#include <WiFiClient.h>
#include <WebServer.h>
#include <ESPmDNS.h>

#include <TaskScheduler.h>
#include <sqlite3.h>
#include "SPIFFS.h"
#include <Adafruit_NeoPixel.h>

String header = "HTTP/1.1 200 OK\r\nContent-Type: text/html\r\n\r\n";
const char html_1[] PROGMEM = R"=====(
<!DOCTYPE html>
<html>
 <head>
 <meta name='viewport' content='width=device-width, initial-scale=1.0'/>
 <meta charset='utf-8'>
 <style>
  body {font-size:120%; width: 400px;} 
  #main {display: table; width:100%; margin: 10px;   } 
  #F1 {  width: 160px ; height: 70px;  }
  #F2 { width:320px;  margin: 30px; }
  h2 {text-align:center; } 
  .tr {display:table-row;  }
  .td {display:table-cell; }
  .button { padding:10px 10px 10px 10px; width:100%; color: #fff; background-color: rgba(200, 0, 200, 1); font-size: 120%;}
  .btnW {   height: 50px; color: #000000; background-color: rgb(248, 248, 248); font-size: 120%;}
  .btnR {   height: 50px; color: #fff; background-color: rgba(220, 0, 0, 1); font-size: 120%;}
  .btnG {   height: 50px; color: #fff; background-color: rgba(0, 220, 0, 1); font-size: 120%;}
  .btnB {   height: 50px; color: #fff; background-color: rgba(0, 0, 220, 1); font-size: 120%;}
  .btnRain {  height: 50px; color: #fff; background-color: rgba(200, 0, 200, 1); font-size: 120%;}
  .btnOff {  height: 50px;  color: #fff; background-color: rgb(56, 46, 46); font-size: 120%;} 
  input {
        width: 100%;
        margin: 3px 0;
        outline: none;
        text-align: center;
        font-size: 120%;      }
  #led {    
    height: 50px;
  }
 </style>
 
 <title>LED Control</title>
</head>
<body>
  <h2>RGB LED Control</h2>
  <div id='main'>  
    <div  class="tr">
      <div  class="td">    
        <form id='F1' action='NEOR'><input class='btnR' type='submit' value='Red' ></form>
        <form id='F1' action='NEOG'><input class='btnG' type='submit' value='Green' ></form>
        <form id='F1' action='NEOB'><input class='btnB' type='submit' value='Blue' ></form>
      </div>
    <div  class="td">    
      <form id='F1' action='RAIN'><input class='btnRain' type='submit' value='Rainbow' ></form>
      <form id='F1' action='NEOW'><input class='btnW' type='submit' value='White' ></form>    
      <form id='F1' action='OFF'><input class='btnOff' type='submit' value='Off' ></form>
    </div> 
  </div> 

</div>
  <form id='F2' action = "" accept-charset="utf-8" name = "datalist" method = "get"> 
  <fieldset >
    <legend>[ 기타 설정 ]</legend>      
      <label>LED 동작 갯수</label> <br>
      <input type = "number" min = "1" max = "2000" step = "1" name = "LedNumber" value="100">
      <label >밝기 [</label> <label id="range"> </label> ]
      <input type = "range" min = "5" max = "255" step = "5" name = "range" value="15" oninput="document.getElementById('range').innerHTML=this.value;">
      <label >사용자 색상[</label> <label id="LedColor"> </label> ]
      <input type="color" id="led" name="LedColor" value="#ffff00" oninput="document.getElementById('LedColor').innerHTML=this.value;">                       
      <input type = "submit" value = "적용" onclick="
        //alert('test')      
      "/>             
  </fieldset>
  </form>
  <script>   
    // 파라메터 정보가 저장될 오브젝트
    // common.js 같은 모든 페이지에서 로딩되는 js 파일에 넣어두면 됨.
    var getParam = function(key){
        var _parammap = {};
        document.location.search.replace(/\??(?:([^=]+)=([^&]*)&?)/g, function () {
            function decode(s) {
                return decodeURIComponent(s.split("+").join(" "));
            } 
            _parammap[decode(arguments[1])] = decode(arguments[2]);
        }); 
        return _parammap[key];
    };
    // console.log(getParam('LedNumber'));
    // console.log(getParam('range'));
    // console.log(getParam('LedColor'));
    if(getParam('range') == undefined){
      //document.getElementById('range').innerHTML= 5;
      //document.getElementsByName('range')[0].value = 5;
    }
    else{
      document.getElementById('range').innerHTML= getParam('range');
      document.getElementsByName('range')[0].value = getParam('range');
    }
    if(getParam('LedNumber') == undefined){   
      //document.getElementsByName('LedNumber')[0].value = 100;
    }
    else{      
      document.getElementsByName('LedNumber')[0].value = getParam('LedNumber');
    }
    if(getParam('LedColor') == undefined){
      //document.getElementById('LedColor').innerHTML= '#ffff00';
      //document.getElementsByName('LedColor')[0].value = '#ffff00';
    }
    else{
      document.getElementById('LedColor').innerHTML= getParam('LedColor');
      document.getElementsByName('LedColor')[0].value = getParam('LedColor');
    }
  </script>
</body>
</html>
)=====";

// change these values to match your network
char ssid[] = "xx";       //  your network SSID (name)
char pass[] = "xxx";          //  your network password
 
WiFiServer server(80);
 
String request = "";

bool ctrlLedColor = true;
int LED_Pin = 21;
int LED_ComPin = 2;

#define NEO_RAINBOW 300
#define NEO_LED_PIN 13


// Parameter 1 = number of pixels in strip
// Parameter 2 = Arduino pin number (most are valid)
// Parameter 3 = pixel type flags, add together as needed:
//   NEO_KHZ800  800 KHz bitstream (most NeoPixel products w/WS2812 LEDs)
//   NEO_KHZ400  400 KHz (classic 'v1' (not v2) FLORA pixels, WS2811 drivers)
//   NEO_GRB     Pixels are wired for GRB bitstream (most NeoPixel products)
//   NEO_RGB     Pixels are wired for RGB bitstream (v1 FLORA pixels, not v2)
//   NEO_RGBW    Pixels are wired for RGBW bitstream (NeoPixel RGBW products)
Adafruit_NeoPixel strip = Adafruit_NeoPixel(100, NEO_LED_PIN, NEO_GRB + NEO_KHZ800);

// IMPORTANT: To reduce NeoPixel burnout risk, add 1000 uF capacitor across
// pixel power leads, add 300 - 500 Ohm resistor on first pixel's data input
// and minimize distance between Arduino and first pixel.  Avoid connecting

// ========== 스케줄러 ===========
void t1Callback();
void t2Callback();


Task t1(100, TASK_FOREVER, &t1Callback);
Task t2(1000, TASK_FOREVER, &t2Callback);

Scheduler runner;

//=============================
// server
int neoColorR = 255;
int neoColorG = 255;
int neoColorB = 255;

void setup() {
  pinMode(LED_Pin, OUTPUT);       
  pinMode(LED_ComPin, OUTPUT);
  Serial.begin(230400);
  esp32inform();
  //SPIFFS_test();   

  runner.init();
  runner.addTask(t1);
  runner.addTask(t2);
  t1.enable();
  t2.enable();  
  //Connecting to a WiFi network 
  WiFi.mode(WIFI_AP_STA); 
  WiFi.softAP("RGB_LED_0001","987654321");
  Serial.print(F("Connecting to "));  Serial.println(ssid);
  WiFi.begin(ssid, pass);
 
  while (WiFi.status() != WL_CONNECTED) 
  {
    Serial.print(".");
    delay(500);
  }
 
  Serial.println("");
  Serial.println(F("[CONNECTED]"));
  Serial.print("[IP ");              
  Serial.print(WiFi.localIP()); 
  Serial.println("]");

  //soft APIP 192.168.4.1
  Serial.print("[soft APIP ");              
  Serial.print(WiFi.softAPIP()); 
  Serial.println("]");
  // start a server
  //server.onNotFound(handle_NotFound);
  server.begin();
  Serial.println("Server started");
  
  strip.begin();
  strip.setBrightness(10);
  //strip.show(); // Initialize all pixels to 'off'
  //strip.updateLength(16);
  colorWipe(strip.Color(neoColorG, neoColorR, neoColorB), 0); 
  //ctrlLedColor++;
}

void loop() {
  runner.execute();  
  webServer();  
}
static String RcvRequest="hello";
void webServer()
{    
    
    // Check if a client has connected
    WiFiClient client = server.available();
    if (!client)  {  return;  }
 
    // Read the first line of the request
    request = client.readStringUntil('\r');
    Serial.print("request: "); Serial.println(request.length());Serial.println(request); 
    
    if ( (RcvRequest != request && request.indexOf("favicon.ico") < 0 && request.length() > 5) || RcvRequest.indexOf("RAIN") > 0 )
    {
      RcvRequest = request;
      ctrlLedColor = true;
      Serial.print("RcvRequest: "); Serial.println(RcvRequest); 
      digitalWrite(LED_Pin, !(digitalRead(LED_Pin)));

     if( RcvRequest.indexOf("LedNumber=") > 0 )  
     {      
      int index1 = RcvRequest.indexOf('='); 
      int index2 = RcvRequest.indexOf('&');
      int index3 = RcvRequest.indexOf('=',index2+1);   
      int index4 = RcvRequest.indexOf('&',index3+1);   
      int index5 = RcvRequest.indexOf("%23",index4+1);   
      int index6 = RcvRequest.indexOf(" HTTP");   
      //int index3 = request.length();
      int LedMaxNumber = RcvRequest.substring(index1+1, index2).toInt();      
      int LedBrightness = RcvRequest.substring(index3+1, index4).toInt();
      String ledColor = RcvRequest.substring(index5+3, index6);
      int rgb = (int)strtol(&ledColor[0], NULL, 16); // #ffffff => int 로 변환.
      Serial.printf("Param len %d idx1[%d] idx2[%d] col[%d]\n", RcvRequest.length(), LedMaxNumber, LedBrightness, rgb);       
      strip.updateLength(LedMaxNumber+1);  // 최대갯수에서 1을 더해야 정상 갯수 
      strip.setBrightness(LedBrightness);  
      neoColorR = rgb >> 16;
      neoColorG = rgb >> 8 & 0xFF;
      neoColorB = rgb & 0xFF;
     }
     else if( RcvRequest.indexOf("OFF") > 0 )    { neoColorR = 0, neoColorG = 0, neoColorB = 0;        }
     else if  ( RcvRequest.indexOf("RAIN") > 0 ) { neoColorR = NEO_RAINBOW;                            }
     else if  ( RcvRequest.indexOf("NEOW") > 0 ) { neoColorR = 255, neoColorG = 255, neoColorB = 255;  }
     else if  ( RcvRequest.indexOf("NEOR") > 0 ) { neoColorR = 255, neoColorG = 0, neoColorB = 0;      }
     else if  ( RcvRequest.indexOf("NEOG") > 0 ) { neoColorR = 0, neoColorG = 255, neoColorB = 0;      }
     else if  ( RcvRequest.indexOf("NEOB") > 0 ) { neoColorR = 0, neoColorG = 0, neoColorB = 255;      }     
    }   
    
    //client.flush(); 
    client.print( header );
    client.print( html_1 );        
    //client.print( html_set );      
    //client.print( html_end); 
    //delay(5);
    
}
// Fill the dots one after the other with a color
void colorWipe(uint32_t c, uint8_t wait) {
  for(uint16_t i=0; i<strip.numPixels(); i++) {
    strip.setPixelColor(i, c);
    strip.show();
    delay(wait);
  }
}

void rainbow(uint8_t wait) {
  uint16_t i, j;

  for(j=0; j<256; j++) {
    for(i=0; i<strip.numPixels(); i++) {
      strip.setPixelColor(i, Wheel((i+j) & 255));
    }
    strip.show();
    delay(wait);
  }
}

// Slightly different, this makes the rainbow equally distributed throughout
void rainbowCycle(uint8_t wait) {
  uint16_t i, j;  
  //if(strip.numPixels() > 100) maxNum = 100;  // 최대 100개까지..
  //else maxNum = strip.numPixels();
  int maxNum = strip.numPixels();
  //Serial.println(maxNum); 
  for(j=0; j<256*5; j++) { // 5 cycles of all colors on wheel
    for(i=0; i< maxNum; i++) {
      strip.setPixelColor(i, Wheel(((i * 256 / maxNum) + j) & 255));      
    }
    strip.show();
    delay(wait);
  }
}

//Theatre-style crawling lights.
void theaterChase(uint32_t c, uint8_t wait) {
  for (int j=0; j<10; j++) {  //do 10 cycles of chasing
    for (int q=0; q < 3; q++) {
      for (uint16_t i=0; i < strip.numPixels(); i=i+3) {
        strip.setPixelColor(i+q, c);    //turn every third pixel on
      }
      strip.show();
      delay(wait);
      for (uint16_t i=0; i < strip.numPixels(); i=i+3) {
        strip.setPixelColor(i+q, 0);        //turn every third pixel off
      }
    }
  }
}

//Theatre-style crawling lights with rainbow effect
void theaterChaseRainbow(uint8_t wait) {
  for (int j=0; j < 256; j++) {     // cycle all 256 colors in the wheel
    for (int q=0; q < 3; q++) {
      for (uint16_t i=0; i < strip.numPixels(); i=i+3) {
        strip.setPixelColor(i+q, Wheel( (i+j) % 255));    //turn every third pixel on
      }
      strip.show();
      delay(wait);
      for (uint16_t i=0; i < strip.numPixels(); i=i+3) {
        strip.setPixelColor(i+q, 0);        //turn every third pixel off
      }
    }
  }
}

// Input a value 0 to 255 to get a color value.
// The colours are a transition r - g - b - back to r.
uint32_t Wheel(byte WheelPos) {
  WheelPos = 255 - WheelPos;
  if(WheelPos < 85) {
    return strip.Color(255 - WheelPos * 3, 0, WheelPos * 3);
  }
  if(WheelPos < 170) {
    WheelPos -= 85;
    return strip.Color(0, WheelPos * 3, 255 - WheelPos * 3);
  }
  WheelPos -= 170;
  return strip.Color(WheelPos * 3, 255 - WheelPos * 3, 0);
}

void t1Callback() {
  //static uint8_t Timer60sec = 1;
  //Serial.print("t1Callback \r\n");  
  //webServer();
  digitalWrite(LED_ComPin, !(digitalRead(LED_ComPin)));
  if(ctrlLedColor)  
  {    
    
    //server.stop();
    digitalWrite(LED_ComPin, true);
    //delay(5);
    Serial.printf("start Control LED..R%d G%d B%d\n",neoColorR,neoColorG,neoColorB  );
    if( neoColorR == NEO_RAINBOW){ 
      //rainbow(1);
      rainbowCycle(1); 
      //restartServer = true;
    }
    else {
      colorWipe(strip.Color(neoColorG, neoColorR, neoColorB), 0); // Green
    }    
    //digitalWrite(LED_ComPin, true);
    ctrlLedColor = false;
    Serial.println("Finsh Control LED..");
    //server.begin();
  }
 
}

void t2Callback() {  
  static uint8_t Timer60sec = 1;
  static bool restartServer = false;
  //digitalWrite(LED_ComPin, !(digitalRead(LED_ComPin)));
  if(Timer60sec++ >= 5)
  {
    Timer60sec = 1;    
    //Serial.println("t2Callback"); 
    if (WiFi.status() != WL_CONNECTED)
    {
      Serial.println("WIFI Discon..");
      WiFi.begin(ssid, pass);
      delay(100);
      server.begin();
    }
    if(restartServer){
      restartServer = false;
      Serial.println("Server Restart..");
      server.stop();
      delay(100);
      server.begin();
    } 
  } 
}

void esp32inform()
{
  uint64_t chipid;
  chipid=ESP.getEfuseMac(); // The chip ID is essentially its MAC address(length: 6 bytes)
  Serial.printf("ESP32 Chip ID = %04X", (uint16_t)(chipid>>32)); // print High 2 bytes
  Serial.printf("%08X\n", (uint32_t)chipid); // print Low 4bytes
  Serial.println("---------------------------------");
     
  Serial.printf("Chip Revision %d\n", ESP.getChipRevision());
  esp_chip_info_t chip_info;
  esp_chip_info(&chip_info);
  Serial.printf("Number of Core: %d\n", chip_info.cores);
  Serial.printf("CPU Frequency: %d MHz\n", ESP.getCpuFreqMHz()); 
  Serial.println();
     
  Serial.printf("Flash Chip Size = %d byte\n", ESP.getFlashChipSize());
  Serial.printf("Flash Frequency = %d Hz\n", ESP.getFlashChipSpeed());
  Serial.println();
     
  Serial.printf("ESP-IDF version = %s\n", esp_get_idf_version());
  Serial.println();
     
  Serial.printf("Total Heap Size = %d\n", ESP.getHeapSize());
  Serial.printf("Free Heap Size = %d\n", ESP.getFreeHeap());
  Serial.printf("Lowest Free Heap Size = %d\n", ESP.getMinFreeHeap());
  Serial.printf("Largest Heap Block = %d\n", ESP.getMaxAllocHeap());
  Serial.println();
}

void SPIFFS_test()
{
 if(!SPIFFS.begin(true)) {
  Serial.println("# ERROR: can not mount SPIFFS");
  while (1) ;
 }
 
 File f = SPIFFS.open("/data.txt");
 if (!f) {  // can not open file
  Serial.println("# ERROR: can not open file");
  delay(5000);
  return;
 }

 while (f.available()) {
  Serial.write(f.read());
 }
 Serial.println("");

 f.close();
}

 

led_con_pio_esp32.zip
0.12MB