임베디드 보드/ESP32

ESP32 + LED STRIP + 블루투스 제어

ZEROWIN.TECH 2021. 12. 30. 18:34
728x90

ESP32

ESP32-WROOM-32는 저전력 센서 네트워크에서 음성 인코딩, 음악 스트리밍 및 MP3 디코딩과 같은 가장 까다로운 작업에 이르기까지 다양한 애플리케이션을 대상으로 하는 강력한 일반 Wi-Fi BT BLE MCU 모듈입니다. 이 모듈의 핵심은 ESP32-D0WDQ6 칩*입니다. 임베디드 칩은 확장 가능하고 적응할 수 있도록 설계되었습니다. 개별적으로 제어할 수 있는 2개의 CPU 코어가 있으며 CPU 클럭 주파수는 80MHz에서 240MHz까지 조정 가능합니다. 또한 이 칩에는 주변 장치 모니터링과 같이 컴퓨팅 성능이 많이 필요하지 않은 작업을 수행하는 동안 전력을 절약하기 위해 CPU 대신 사용할 수 있는 저전력 보조 프로세서가 있습니다. ESP32는 정전식 터치 센서, 홀 센서, SD 카드 인터페이스, 이더넷, 고속 SPI, UART, I²S 및 I²C에 이르는 다양한 주변 장치를 통합합니다.
  • 18 Analog-to-Digital Converter (ADC) channels
  • 3 SPI interfaces
  • 3 UART interfaces
  • 2 I2C interfaces
  • 16 PWM output channels
  • 2 Digital-to-Analog Converters (DAC)
  • 2 I2S interfaces
  • 10 Capacitive sensing GPIOs

    아날로그-디지털 컨버터(ADC) 채널 18개 
    SPI 인터페이스 3개 
    UART 인터페이스 3개
    2개 I2C 인터페이스
    16개 PWM 출력 채널
    2개 DAC(디지털-아날로그 변환기) 2개
    I2S 인터페이스 2개
    정전 용량 감지 GPIO 10개
참조 사이트 : https://www.studiopieters.nl/esp32-pinout/


 

블루투스 LED STRIP 제어

앱 다운로드
https://play.google.com/store/apps/details?id=de.kai_morich.serial_bluetooth_terminal
스마트폰 블루투스 터미널 앱을 이용하여 ESP32 + LED STRIP 를 제어합니다.

라이브러리 설치

https://github.com/adafruit/Adafruit_NeoPixel
https://github.com/h2zero/NimBLE-Arduino

소스코드

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

#define USE_BLE  1

#define PIXEL_PIN4      16    // $Data Pin of Led strip 
#define PIXEL_PIN5      17    // $Data Pin of Led strip 
#define PIXEL_PIN6      18    // $Data Pin of Led strip 
#define PIXEL_COUNT    1024 // (64*6) //  (16*6)   // $64Number of LEDs in the strip
#define BRIGHTNESS   60   // ~255 use 96 for medium brightness
#define SPEED          50    // Speed of each Color Transition (in ms)
#define IMMEDIATELY    0    // Transition happen instantly
#define RAINBOW_SPEED  50    // Rainbow Transition speed

Adafruit_NeoPixel strip = Adafruit_NeoPixel(PIXEL_COUNT, PIXEL_PIN4, NEO_GRB + NEO_KHZ800);
Adafruit_NeoPixel strip2 = Adafruit_NeoPixel(PIXEL_COUNT, PIXEL_PIN5, NEO_GRB + NEO_KHZ800);
Adafruit_NeoPixel strip3 = Adafruit_NeoPixel(PIXEL_COUNT, PIXEL_PIN6, NEO_GRB + NEO_KHZ800);

bool offOld = LOW;
bool WhiteOld = LOW;
bool RedOld = LOW;
bool GreenOld = LOW;
bool BlueOld = LOW;
bool TopazOld = LOW;
bool LilacOld = LOW;
bool RainbowOld = LOW;
bool rgbOld = LOW;
int  showType = 1; // 0;

void colorWipe(uint32_t c, uint8_t wait);

#if USE_BLE
//#include <BLEServer.h>
//#include <BLEUtils.h>
//#include <BLE2902.h>
#include <NimBLEDevice.h>
BLEServer *pServer = NULL;
BLECharacteristic * pTxCharacteristic;
bool deviceConnected = false;
int deviceConnected_timeout = 0;
bool oldDeviceConnected = false;
uint8_t txValue = 0;

// See the following for generating UUIDs:
// https://www.uuidgenerator.net/

#define SERVICE_UUID           "6E400001-B5A3-F393-E0A9-E50E24DCCA9E" // UART service UUID
#define CHARACTERISTIC_UUID_RX "6E400002-B5A3-F393-E0A9-E50E24DCCA9E"
#define CHARACTERISTIC_UUID_TX "6E400003-B5A3-F393-E0A9-E50E24DCCA9E"


/**  None of these are required as they will be handled by the library with defaults. **
 **                       Remove as you see fit for your needs                        */  
class MyServerCallbacks: public BLEServerCallbacks {
  
    void onConnect(BLEServer* pServer) {
      deviceConnected = true;
      Serial.println("USER connect");
    };

    void onDisconnect(BLEServer* pServer) {
      deviceConnected = false;
      Serial.println("USER disconnect");  
    }
  /***************** New - Security handled here ********************
  ****** Note: these are the same return values as defaults ********/
    uint32_t onPassKeyRequest(){
      Serial.println("Server PassKeyRequest");
      return 123456; 
    }

    bool onConfirmPIN(uint32_t pass_key){
      Serial.print("The passkey YES/NO number: ");Serial.println(pass_key);
      return true; 
    }

    void onAuthenticationComplete(ble_gap_conn_desc desc){
      Serial.println("Starting BLE work!");
    }
  /*******************************************************************/
};

class MyCallbacks: public BLECharacteristicCallbacks {
    void onWrite(BLECharacteristic *pCharacteristic) {
      std::string rxValue = pCharacteristic->getValue();

      if (rxValue.length() > 0) {
        Serial.println("*********");
        Serial.print("Received Value: ");
        Serial.print(rxValue.c_str());
        Serial.println();

        int value = atoi(rxValue.c_str());
        Serial.print("value=");
        Serial.println(value);
        showType = value;
      } 
    }
};



void BLE_setup() {
  // Serial.begin(115200);

  // Create the BLE Device
  BLEDevice::init("ESP32 BLE");

  // Create the BLE Server
  pServer = BLEDevice::createServer();
  pServer->setCallbacks(new MyServerCallbacks());

  // Create the BLE Service
  BLEService *pService = pServer->createService(SERVICE_UUID);

  // Create a BLE Characteristic
  pTxCharacteristic = pService->createCharacteristic(
                                        CHARACTERISTIC_UUID_TX,
                                    /******* Enum Type NIMBLE_PROPERTY now *******      
                                        BLECharacteristic::PROPERTY_NOTIFY
                                        );
                                    **********************************************/  
                                        NIMBLE_PROPERTY::NOTIFY
                                       );
                                    
  /***************************************************   
   NOTE: DO NOT create a 2902 descriptor 
   it will be created automatically if notifications 
   or indications are enabled on a characteristic.
   
   pCharacteristic->addDescriptor(new BLE2902());
  ****************************************************/                  

  BLECharacteristic * pRxCharacteristic = pService->createCharacteristic(
                                            CHARACTERISTIC_UUID_RX,
                                    /******* Enum Type NIMBLE_PROPERTY now *******       
                                            BLECharacteristic::PROPERTY_WRITE
                                            );
                                    *********************************************/  
                                            NIMBLE_PROPERTY::WRITE
                                            );

  pRxCharacteristic->setCallbacks(new MyCallbacks());

  // Start the service
  pService->start();

  // Start advertising
  pServer->getAdvertising()->start();
  Serial.println("Waiting a client connection to notify...");
}

void BLE_loop() {

    if (deviceConnected) {
      /*
        pTxCharacteristic->setValue(&txValue, 1);
        pTxCharacteristic->notify();
        txValue++;
        delay(10); // bluetooth stack will go into congestion, if too many packets are sent */
        //Serial.print("deviceConnecting=");        
        //Serial.println(deviceConnected_timeout);

        deviceConnected_timeout += 1;
        if(5*10 < deviceConnected_timeout) {
            deviceConnected = false;
            deviceConnected_timeout = 0;
        }
    }

    // disconnecting
    if (!deviceConnected && oldDeviceConnected) {
        delay(500); // give the bluetooth stack the chance to get things ready
        
        pServer->startAdvertising(); // restart advertising
        Serial.println("Disconnected! start advertising");
        oldDeviceConnected = deviceConnected;

        
    }
    // connecting
    if (deviceConnected && !oldDeviceConnected) {
        // do stuff here on connecting
        oldDeviceConnected = deviceConnected;

        Serial.println("deviceConnected"); 

        deviceConnected_timeout = 0;
    }
}

#endif


void setup() {
  Serial.begin(9600);
  Serial.println("START");
   
#if USE_BLE
  BLE_setup();
#endif     

  strip.setBrightness(BRIGHTNESS);  
  strip.begin();
  strip.show();

    strip2.setBrightness(BRIGHTNESS);  
  strip2.begin();
  strip2.show();

    strip3.setBrightness(BRIGHTNESS);  
  strip3.begin();
  strip3.show();

}

char a;

// ************** loop **************
void loop() {

#if USE_BLE
  BLE_loop();
#endif  

  startShow(showType);


}

void startShow(int i) {

  Serial.print("startShow=");
  Serial.print(i);
  
  switch(i){

    case 0: colorWipe(strip.Color(0, 0, 0), SPEED);    // Black/off
            break;

    case 1: 
            rainbowCycle(1);// $ Initial Pattern 2싸이클 추가. 
            break;  

    case 2: colorWipe(strip.Color(255, 0, 0), SPEED);  // Red
            break;

    case 3: colorWipe(strip.Color(0, 255, 0), SPEED);  // Green
            break;

    case 4: colorWipe(strip.Color(0, 0, 255), SPEED);  // Blue
            break;

    case 5: colorWipe(strip.Color(0, 250, 255), SPEED);  // Topaz
            break;            

    case 6: colorWipe(strip.Color(221, 130, 255), SPEED);  // Lilac
            break;            
    
    case 7: colorWipe(strip.Color(255, 0, 0), SPEED);  // Red
            colorWipe(strip.Color(0, 255, 0), SPEED);  // Green
            colorWipe(strip.Color(0, 0, 255), SPEED);  // Blue
            theaterChase(strip.Color(  0,   0, 127), SPEED); // Blue
            theaterChase(strip.Color(127,   0,   0), SPEED); // Red
            theaterChase(strip.Color(0,   127,   0), SPEED); // Green
            break;

    case 8: rainbowCycle(25);
            break;
  }

  Serial.println("=end");
}
void colorWipe(uint32_t c, uint8_t wait) {
  for(uint16_t i=0; i < strip.numPixels(); i++) {
    strip.setPixelColor(i, c);
    strip2.setPixelColor(i, c);
    strip3.setPixelColor(i, c);
    
    // delay(wait);
  }
  strip.show();
  strip2.show();
  strip3.show();
}

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

  for(j=0; j<256; j += 10) { // 5 cycles of all colors on wheel
    
    for(i=0; i< strip.numPixels(); i++) {
      
      strip.setPixelColor(i, Wheel(((i * 256 / strip.numPixels()) + j) & 255));
      strip2.setPixelColor(i, Wheel(((i * 256 / strip.numPixels()) + j) & 255));
      strip3.setPixelColor(i, Wheel(((i * 256 / strip.numPixels()) + j) & 255));
      
    }
    
    strip.show();
    strip2.show();
    strip3.show();
    
    delay(wait);
  }
}

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 (int i=0; i < strip.numPixels(); i=i+3) {
        strip.setPixelColor(i+q, c);    //turn every third pixel on
        strip2.setPixelColor(i+q, c);    //turn every third pixel on
        strip3.setPixelColor(i+q, c);    //turn every third pixel on
      }
      strip.show();
      strip2.show();
      strip3.show();

      delay(wait);

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

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);
}

'임베디드 보드 > ESP32' 카테고리의 다른 글

ESP32 + Ethernet W5500  (0) 2022.02.25
ESP32 + LED STRIP + SOUND SENSOR  (0) 2022.01.08
ESP32 DOWNLOAD  (0) 2021.12.29
ESP8266 on thingsboard server  (0) 2021.05.01
String Bouncer  (0) 2021.03.21