[作品提交] 【得捷电子Follow me第2期】Adafruit ESP32-S3 TFT Feather外设模块控制WS2812B

Devin522   2023-10-15 23:42 楼主

1.演示视频

        这次参加Follow me活动,也是第一次参加eeworld的活动,通过Adafruit ESP32-S3 TFT Feather这块开发板,这块开发板是Adafruit基于ESP32-S3所开发的,熟悉arduino的肯定知道,adafruit在各平台有非常多的开源库,这次学习了ESP32 S3在Arduino平台下很多外设的驱动。本次用到的模块有W25Q16外部存储模块,WS2812LED模块,LIS3DH,还有一个不太常见的MSM261S4030H0 硅麦克风模块,这个模块目前arduino没有什么参考资料,所幸最终还是驱动成功了。以下是视频介绍。


2.任务实现

2.1屏幕驱动显示中文

        这里用到的是arduino平台的tft_espi库,这个库用之前首先需要进入库文件目录C:\Users\lzx\Documents\Arduino\libraries\TFT_eSPI,修改头文件User_Setup.h,这里板子的屏幕驱动芯片是st7789,分辨率是240x135,需要将头文件里面#define ST7789_DRIVER取消注释,并修改#define TFT_WIDTH  135,#define TFT_HEIGHT 240这两条语句,到这里屏幕已经可以正常驱动了,但是任务是需要显示中文字符,官方的库并不支持中文字符,这里需要用到C:\Users\lzx\Documents\Arduino\libraries\TFT_eSPI\Tools\Create_Smooth_Font\Create_font这个目录下一个工具,通过下载的Processing,添加需要的中文字符后再生成对应的头文件,即可显示中文。以下是这个任务的程序。

         首先需要将45脚背光控制引脚设置为高电平。初始化加载字库后可以正常显示中文。

#include <TFT_eSPI.h> 
#include <SPI.h>
#include "zhuanyong.h"//自定义字库头文件
#define TFT_GREY 0x5AEB // New colour
TFT_eSPI tft = TFT_eSPI();  // Invoke library
//自定义字库可以搜这个关键词“tft espi vlw”
void setup(void) {
  pinMode(45, OUTPUT);
  digitalWrite(45, HIGH); 
  tft.init();
  //digitalWrite(45, LOW); 
  tft.setRotation(1);
  
      tft.begin();                  //初始化TFT屏幕
    tft.fillScreen(TFT_BLACK);    //刷屏底色为黑色
    tft.setTextColor(TFT_YELLOW); //设置字体颜色
    tft.loadFont(zhuanyong);     //设定我们制作的华光准圆的字体
    tft.setCursor(20, 20);       //设置光标位置
    tft.println("中文");     //打印文字
    tft.unloadFont(); 
}

        实物显示效果:

IMG_20231015_181350.jpg
 
2.2网络功能使用
          由于我后面没有用到联网功能,所以这里连接网络和创建热点只是简单实现,能实现连接,没有具体的驱动其他设备,联网只需要从http的例程中修改ssid和password即可,创建热点需要用到其他的API,详细的代码如下:
#include <Arduino.h>
#include <WiFi.h>
#include <WiFiMulti.h>
#include <HTTPClient.h>
#define USE_SERIAL Serial
WiFiMulti wifiMulti;

void setup() {

    USE_SERIAL.begin(115200);
    USE_SERIAL.println();
    USE_SERIAL.println();
    USE_SERIAL.println();

    for(uint8_t t = 4; t > 0; t--) {
        USE_SERIAL.printf("[SETUP] WAIT %d...\n", t);
        USE_SERIAL.flush();
        delay(1000);
    }

    wifiMulti.addAP("MERCURY_3BE8", "asdf1245");

}

void loop() {
    // wait for WiFi connection
    if((wifiMulti.run() == WL_CONNECTED)) {

        USE_SERIAL.println("wifi connected");
        while(1)
        {}

        HTTPClient http;

        USE_SERIAL.print("[HTTP] begin...\n");
        // configure traged server and url
        //http.begin("https://www.howsmyssl.com/a/check", ca); //HTTPS
        http.begin("http://example.com/index.html"); //HTTP

        USE_SERIAL.print("[HTTP] GET...\n");
        // start connection and send HTTP header
        int httpCode = http.GET();

        // httpCode will be negative on error
        if(httpCode > 0) {
            // HTTP header has been send and Server response header has been handled
            USE_SERIAL.printf("[HTTP] GET... code: %d\n", httpCode);

            // file found at server
            if(httpCode == HTTP_CODE_OK) {
                String payload = http.getString();
                USE_SERIAL.println(payload);
            }
        } else {
            USE_SERIAL.printf("[HTTP] GET... failed, error: %s\n", http.errorToString(httpCode).c_str());
        }

        http.end();
    }

    delay(5000);
}

        创建热点需要修改部分的代码如下:

#include <WiFi.h>
const char *ssid = "ssid";
 
const char *password = "yourpassword";
void setup() {
  Serial.begin(9600);
  WiFi.softAP(ssid,password);
  Serial.print("Access Point: ");
  Serial.println(ssid);
  Serial.println(WiFi.softAPIP());
}
 
void loop() {
  delay(1000);
}

2.3控制WS2812B

        控制WS2812B用的是FastLED这个库,因为后面任务4需要用到其他的LED,这个库对多个LED和多组LED控制十分方便,板子上的LED因为供电是用的ESP32的34引脚,所以首先需要将34引脚设置为输出模式,并且输出高电平。这里需要初始化两个类,分别控制板子上的LED和外接的LED,初始化时对应的引脚不同。

        以下是一段简单的demo


#include <FastLED.h>


#define NUM_LEDS 16  


#define DATA_PIN 35
#define DATA_PIN2 33

CRGB leds[NUM_LEDS];
CRGB leds2[1];


void setup() {
	// sanity check delay - allows reprogramming if accidently blowing power w/leds
   	delay(2000);
    pinMode(34, OUTPUT);
    digitalWrite(34, HIGH);

    // Uncomment/edit one of the following lines for your leds arrangement.
    // ## Clockless types ##
    // FastLED.addLeds<NEOPIXEL, DATA_PIN>(leds, NUM_LEDS);  // GRB ordering is assumed
    // FastLED.addLeds<SM16703, DATA_PIN, RGB>(leds, NUM_LEDS);
    // FastLED.addLeds<TM1829, DATA_PIN, RGB>(leds, NUM_LEDS);
    // FastLED.addLeds<TM1812, DATA_PIN, RGB>(leds, NUM_LEDS);
    // FastLED.addLeds<TM1809, DATA_PIN, RGB>(leds, NUM_LEDS);
    // FastLED.addLeds<TM1804, DATA_PIN, RGB>(leds, NUM_LEDS);
    // FastLED.addLeds<TM1803, DATA_PIN, RGB>(leds, NUM_LEDS);
    // FastLED.addLeds<UCS1903, DATA_PIN, RGB>(leds, NUM_LEDS);
    // FastLED.addLeds<UCS1903B, DATA_PIN, RGB>(leds, NUM_LEDS);
    // FastLED.addLeds<UCS1904, DATA_PIN, RGB>(leds, NUM_LEDS);
    // FastLED.addLeds<UCS2903, DATA_PIN, RGB>(leds, NUM_LEDS);
    // FastLED.addLeds<WS2812, DATA_PIN, RGB>(leds, NUM_LEDS);  // GRB ordering is typical
    // FastLED.addLeds<WS2852, DATA_PIN, RGB>(leds, NUM_LEDS);  // GRB ordering is typical
    // FastLED.addLeds<WS2812B, DATA_PIN, RGB>(leds, NUM_LEDS);  // GRB ordering is typical
    // FastLED.addLeds<GS1903, DATA_PIN, RGB>(leds, NUM_LEDS);
    // FastLED.addLeds<SK6812, DATA_PIN, RGB>(leds, NUM_LEDS);  // GRB ordering is typical
    // FastLED.addLeds<SK6822, DATA_PIN, RGB>(leds, NUM_LEDS);
    // FastLED.addLeds<APA106, DATA_PIN, RGB>(leds, NUM_LEDS);
    // FastLED.addLeds<PL9823, DATA_PIN, RGB>(leds, NUM_LEDS);
    // FastLED.addLeds<SK6822, DATA_PIN, RGB>(leds, NUM_LEDS);
    FastLED.addLeds<WS2811, DATA_PIN, RGB>(leds, NUM_LEDS);
    FastLED.addLeds<WS2811, 33, RGB>(leds2, 1);
    //FastLED.addLeds<WS2811, DATA_PIN2, RGB>(leds, NUM_LEDS);
    // FastLED.addLeds<WS2813, DATA_PIN, RGB>(leds, NUM_LEDS);
    // FastLED.addLeds<APA104, DATA_PIN, RGB>(leds, NUM_LEDS);
    // FastLED.addLeds<WS2811_400, DATA_PIN, RGB>(leds, NUM_LEDS);
    // FastLED.addLeds<GE8822, DATA_PIN, RGB>(leds, NUM_LEDS);
    // FastLED.addLeds<GW6205, DATA_PIN, RGB>(leds, NUM_LEDS);
    // FastLED.addLeds<GW6205_400, DATA_PIN, RGB>(leds, NUM_LEDS);
    // FastLED.addLeds<LPD1886, DATA_PIN, RGB>(leds, NUM_LEDS);
    // FastLED.addLeds<LPD1886_8BIT, DATA_PIN, RGB>(leds, NUM_LEDS);
    // ## Clocked (SPI) types ##
    // FastLED.addLeds<LPD6803, DATA_PIN, CLOCK_PIN, RGB>(leds, NUM_LEDS);  // GRB ordering is typical
    // FastLED.addLeds<LPD8806, DATA_PIN, CLOCK_PIN, RGB>(leds, NUM_LEDS);  // GRB ordering is typical
    // FastLED.addLeds<WS2801, DATA_PIN, CLOCK_PIN, RGB>(leds, NUM_LEDS);
    // FastLED.addLeds<WS2803, DATA_PIN, CLOCK_PIN, RGB>(leds, NUM_LEDS);
    // FastLED.addLeds<SM16716, DATA_PIN, CLOCK_PIN, RGB>(leds, NUM_LEDS);
    // FastLED.addLeds<P9813, DATA_PIN, CLOCK_PIN, RGB>(leds, NUM_LEDS);  // BGR ordering is typical
    // FastLED.addLeds<DOTSTAR, DATA_PIN, CLOCK_PIN, RGB>(leds, NUM_LEDS);  // BGR ordering is typical
    // FastLED.addLeds<APA102, DATA_PIN, CLOCK_PIN, RGB>(leds, NUM_LEDS);  // BGR ordering is typical
    // FastLED.addLeds<SK9822, DATA_PIN, CLOCK_PIN, RGB>(leds, NUM_LEDS);  // BGR ordering is typical

    FastLED.setBrightness(100);
    leds2[0] = CRGB::White;
    leds2[1] = CRGB::White;
}

void loop() {
   // Move a single white led 
   for(int whiteLed = 0; whiteLed < NUM_LEDS; whiteLed = whiteLed + 1) {
      // Turn our current led on to white, then show the leds
      leds[whiteLed] = CRGB::White;

      // Show the leds (only one of which is set to white, from above)
      FastLED.show();

      // Wait a little bit
      delay(100);

      // Turn our current led back to black for the next loop around
      leds[whiteLed] = CRGB::Black;
   }
      for(int whiteLed = 0; whiteLed < NUM_LEDS; whiteLed = whiteLed + 1) {
      // Turn our current led on to white, then show the leds
      leds[whiteLed] = CRGB::White;

      // Show the leds (only one of which is set to white, from above)
      FastLED.show();

      // Wait a little bit
      delay(100);

      // Turn our current led back to black for the next loop around
      leds[whiteLed] = CRGB::Yellow;
		leds2[0] = CRGB::Yellow;
   }
}

2.4 WS2812B效果控制

        这里用了其他的外部模块来对WS2812实现更多种不同功能的控制,分别用W25Q16外部存储模块,WS2812LED模块,LIS3DH模块对实现对灯不同的控制方式。

        这里用到W25Q16的原因是ESP32虽然本身的空间很大,但是如果需要更大的字库或者显示图片等功能就需要扩展外部存储,这里演示的是通过W25Q16的数据读取功能,对灯珠的亮度进行预设,当上电时,板子初始化时是根据W25Q16的预设亮度显示,进入主循环后按照另外一个预设进行显示。W25Q16这里参考网上的代码,驱动实现更简单。代码如下:

#include <FastLED.h>
#include <SPI.h>
 #define SOFTWARE_SPI           // use software spi

#define NORFLASH_CS_PIN         17
#define NORFLASH_CLK_PIN        18        
#define NORFLASH_MOSI_PIN       16       
#define NORFLASH_MISO_PIN       15        
// #define NORFLASH_HOLD_PIN       9   // hold pin no connect 3.3V 
// #define NORFLASH_WP_PIN         14  // hold pin no connect 3.3V  
#define NORFLASH_HOLD_PIN       -1     // hold pin connect 3.3V
#define NORFLASH_WP_PIN         -1     // wp pin connect 3.3V

#define ManufactDeviceID_CMD	0x90   
#define READ_JEDEC_ID_CMD       0x9F
#define WRITE_STATUS            0x01    
#define READ_STATU_REGISTER_1   0x05    
#define READ_STATU_REGISTER_2   0x35
#define READ_DATA_CMD	        0x03
#define WRITE_ENABLE_CMD	    0x06
#define WRITE_DISABLE_CMD	    0x04
#define SECTOR_ERASE_CMD	    0x20
#define CHIP_ERASE_CMD	        0xC7
#define PAGE_PROGRAM_CMD        0x02

#define ONE_PAGE_SIZE           256     
#define SPI_FREQUENCY           40 * 10000



///////////////////////////////////////////////////////////////////////////////////////////
//
// Move a white dot along the strip of leds.  This program simply shows how to configure the leds,
// and then how to turn a single pixel white and then off, moving down the line of pixels.
// 

// How many leds are in the strip?
#define NUM_LEDS 16  

// For led chips like WS2812, which have a data line, ground, and power, you just
// need to define DATA_PIN.  For led chipsets that are SPI based (four wires - data, clock,
// ground, and power), like the LPD8806 define both DATA_PIN and CLOCK_PIN
// Clock pin only needed for SPI based chipsets when not using hardware SPI
#define DATA_PIN 35
#define DATA_PIN2 33
//#define CLOCK_PIN 13

// This is an array of leds.  One item for each led in your strip.
CRGB leds[NUM_LEDS];
CRGB leds2[1];

unsigned char buf2[2];

/* Norflash spi init */
void norflash_spi_init()
{    // gpio init
    pinMode(NORFLASH_HOLD_PIN, OUTPUT); 
    pinMode(NORFLASH_WP_PIN, OUTPUT);  
    digitalWrite(NORFLASH_HOLD_PIN, HIGH); 
    digitalWrite(NORFLASH_WP_PIN, HIGH); 
    pinMode(NORFLASH_CS_PIN, OUTPUT);  
    digitalWrite(NORFLASH_CS_PIN, HIGH);
#ifdef HARDWARE_SPI
    SPI.begin(NORFLASH_CLK_PIN, NORFLASH_MISO_PIN, NORFLASH_MOSI_PIN, NORFLASH_CS_PIN);
    SPI.setDataMode(SPI_MODE0);
    SPI.setBitOrder(MSBFIRST);
    SPI.setFrequency(SPI_FREQUENCY);
#else
    pinMode(NORFLASH_CLK_PIN, OUTPUT);  
    pinMode(NORFLASH_MOSI_PIN, OUTPUT); 
    pinMode(NORFLASH_MISO_PIN, INPUT); 
    digitalWrite(NORFLASH_CLK_PIN, LOW);
    delay(1);
#endif
    // check write enable status
    uint8_t data = 0;
    write_enable();                
    data = read_status();
#ifdef NORFLASH_DEBUG_ENABLE
    Serial.printf("norflash write enable status:");
    Serial.println(data, BIN);
#endif

    // read device id
    uint16_t device_id = 0;
    device_id = read_norflash_id();
#ifdef NORFLASH_DEBUG_ENABLE
    Serial.printf("norflash device id: 0x%04X", device_id);
#endif
}

/* Norflash write one byte */
void write_byte(uint8_t data)
{
#ifdef HARDWARE_SPI
    // SPI.transfer(data);
    SPI.write(data);
#else if SOFTWARE_SPI
    for(uint8_t i = 0; i < 8; i++)
    {     
        uint8_t status;
        status = data & (0x80 >> i);
        digitalWrite(NORFLASH_MOSI_PIN, status);
        digitalWrite(NORFLASH_CLK_PIN, LOW);
        digitalWrite(NORFLASH_CLK_PIN, HIGH);   
    }
#endif
}

/* Norflash read one byte */
uint8_t read_byte(uint8_t tx_data)
{   
#ifdef HARDWARE_SPI
    uint8_t data = 0;
    data = SPI.transfer(tx_data);
    return data;
#else if SOFTWARE_SPI
    uint8_t i = 0, data = 0;
    for(i = 0; i < 8; i++)
    {        
        digitalWrite(NORFLASH_CLK_PIN, HIGH);
        digitalWrite(NORFLASH_CLK_PIN, LOW);
        if(digitalRead(NORFLASH_MISO_PIN)) 
        {
            data |= 0x80 >> i;
        }
    }
    return data;
#endif
}

/* Norflash write enable */
void write_enable()
{
    digitalWrite(NORFLASH_CS_PIN, LOW);
    write_byte(WRITE_ENABLE_CMD);
    digitalWrite(NORFLASH_CS_PIN, HIGH);
}

/* Norflash write disable */
void write_disable()
{
    digitalWrite(NORFLASH_CS_PIN, LOW);
    write_byte(WRITE_DISABLE_CMD);
    digitalWrite(NORFLASH_CS_PIN, HIGH);
}

/* Read norflash status */
uint8_t read_status()
{
    uint8_t status = 0; 
    digitalWrite(NORFLASH_CS_PIN, LOW);
    write_byte(READ_STATU_REGISTER_1);      
    status = read_byte(0);                      
    digitalWrite(NORFLASH_CS_PIN, HIGH);  
    return status;
}

/* check norflash busy status */
void check_busy(char *str)
{
    while(read_status() & 0x01)
    {
    #ifdef NORFLASH_DEBUG_ENABLE
        Serial.printf("status = 0, flash is busy of %s\n", str);   
    #endif 
    }
}

/* Write less than oneblock(256 byte) data */
void write_one_block_data(uint32_t addr, uint8_t * pbuf, uint16_t len)
{
    uint16_t i; 
    check_busy("write_one_block_data");
    write_enable();                               
    digitalWrite(NORFLASH_CS_PIN, LOW);           
    write_byte(PAGE_PROGRAM_CMD);                 
    write_byte((uint8_t)(addr >> 16));             
    write_byte((uint8_t)(addr >> 8));   
    write_byte((uint8_t)addr);      
    for(i = 0; i < len; i++)                       
    {
        write_byte(*pbuf++);   
    }
    digitalWrite(NORFLASH_CS_PIN, HIGH);                              
    check_busy("write_one_block_data");
} 

/* Write less than one sector(4096 byte) length data  */
void write_one_sector_data(uint32_t addr, uint8_t * pbuf, uint16_t len)
{ 
    uint16_t free_space, head, page, remain;  
    free_space = ONE_PAGE_SIZE - addr % ONE_PAGE_SIZE;  
    if(len <= free_space) 
    {
        head = len;
        page = 0;                      
        remain = 0; 
    }
    if(len > free_space) 
    {
        head = free_space;
        page = (len - free_space) / ONE_PAGE_SIZE;     
        remain = (len - free_space) % ONE_PAGE_SIZE;
    }
    
    if(head != 0)
    {
    #ifdef NORFLASH_DEBUG_ENABLE
        Serial.print("head:");
        Serial.println(head);
    #endif
        write_one_block_data(addr, pbuf, head);
        pbuf = pbuf + head;
        addr = addr + head;
    }
    if(page != 0) 
    {
    #ifdef NORFLASH_DEBUG_ENABLE
        Serial.print("page:");
        Serial.println(page);
    #endif
        for(uint16_t i = 0; i < page; i++) 
        {
            write_one_block_data(addr, pbuf, ONE_PAGE_SIZE);
            pbuf = pbuf + ONE_PAGE_SIZE;
            addr = addr + ONE_PAGE_SIZE;
        }
    }
    if(remain != 0) 
    {
    #ifdef NORFLASH_DEBUG_ENABLE
        Serial.print("remain:");
        Serial.println(remain);
    #endif
        write_one_block_data(addr, pbuf, remain);
    }  
}

/* Write arbitrary length data */
void write_arbitrary_data(uint32_t addr, uint8_t* pbuf, uint32_t len)   
{ 
	uint32_t secpos;
	uint16_t secoff;
	uint16_t secremain;	   
 	uint16_t i;    
    uint8_t *write_buf = pbuf;	 
    uint8_t save_buffer[4096];  // save sector original data and add new data  
 	secpos = addr / 4096;       // sector number  
	secoff = addr % 4096;       // sector offset
	secremain = 4096 - secoff;  // sector remaining space   
    
 	if(len <= secremain)
    {
        secremain = len;        // sector remaining space less than 4096
    }
	while(1) 
	{	
		read_data(secpos * 4096, save_buffer, 4096); // read sector data
		for(i = 0; i < secremain; i++)
		{// check data, if all data is 0xFF no need erase sector
			if(save_buffer[secoff + i] != 0XFF)
            {// need erase sector
                break;	  
            }
		}
		if(i < secremain)
		{// erase sector and write data
			sector_erase(secpos);
			for(i = 0; i < secremain; i++)	       
			{
				save_buffer[i + secoff] = write_buf[i];	 // add new data 
			}
			write_one_sector_data(secpos * 4096, save_buffer, 4096); // write sector
		}
        else 
        {// no need erase sector
            write_one_sector_data(addr, write_buf, secremain);	
        }			   
		if(len == secremain)
        {// write done
            break; 
        }
		else
		{// continue write
			secpos ++;  // sector number + 1
			secoff = 0; // sector offset = 0 	 

		   	write_buf += secremain;  // write buff offset
			addr += secremain;       // addr offset	   
		   	len -= secremain;		 // remaining data len
			if(len > 4096)
            {// remaining data more than one sector(4096 byte)
                secremain = 4096;	 
            }
			else 
            {// remaining data less than one sector(4096 byte)
                secremain = len;			
            }
		}	 
	}	 
}

/* Read arbitrary length data */
void read_data(uint32_t addr24, uint8_t *pbuf, uint32_t len)
{
    check_busy("read_data");
    digitalWrite(NORFLASH_CS_PIN, LOW);
    write_byte(READ_DATA_CMD);
    write_byte((uint8_t)(addr24 >> 16));   
    write_byte((uint8_t)(addr24 >> 8));   
    write_byte((uint8_t)addr24);  
    for(uint32_t i = 0; i < len; i++)
    {
        *pbuf = read_byte(0xFF);
        pbuf ++;
    }
    digitalWrite(NORFLASH_CS_PIN, HIGH); 
}

/* Erase sector */
void sector_erase(uint32_t addr24)     
{
    addr24 *= 4096;  
    check_busy("sector_erase");
    write_enable();                     
    
    digitalWrite(NORFLASH_CS_PIN, LOW);
    write_byte(SECTOR_ERASE_CMD);          
    write_byte((uint8_t)(addr24 >> 16));    
    write_byte((uint8_t)(addr24 >> 8));   
    write_byte((uint8_t)addr24);  
      
    digitalWrite(NORFLASH_CS_PIN, HIGH);
    check_busy("sector_erase");
} 

/* Read norflash id */
uint16_t read_norflash_id()
{
    uint8_t data = 0;
    uint16_t device_id = 0;

    digitalWrite(NORFLASH_CS_PIN, LOW);
    write_byte(ManufactDeviceID_CMD);
    write_byte(0x00);
    write_byte(0x00);
    write_byte(0x00);
    data = read_byte(0);
    device_id |= data;  // low byte
    data = read_byte(0);
    device_id |= (data << 8);  // high byte
    digitalWrite(NORFLASH_CS_PIN, HIGH);
    
    return device_id;
}

// This function sets up the ledsand tells the controller about them
void setup() {
	// sanity check delay - allows reprogramming if accidently blowing power w/leds
   	delay(2000);
    pinMode(34, OUTPUT);
    digitalWrite(34, HIGH);

    // Uncomment/edit one of the following lines for your leds arrangement.
    // ## Clockless types ##
    // FastLED.addLeds<NEOPIXEL, DATA_PIN>(leds, NUM_LEDS);  // GRB ordering is assumed
    // FastLED.addLeds<SM16703, DATA_PIN, RGB>(leds, NUM_LEDS);
    // FastLED.addLeds<TM1829, DATA_PIN, RGB>(leds, NUM_LEDS);
    // FastLED.addLeds<TM1812, DATA_PIN, RGB>(leds, NUM_LEDS);
    // FastLED.addLeds<TM1809, DATA_PIN, RGB>(leds, NUM_LEDS);
    // FastLED.addLeds<TM1804, DATA_PIN, RGB>(leds, NUM_LEDS);
    // FastLED.addLeds<TM1803, DATA_PIN, RGB>(leds, NUM_LEDS);
    // FastLED.addLeds<UCS1903, DATA_PIN, RGB>(leds, NUM_LEDS);
    // FastLED.addLeds<UCS1903B, DATA_PIN, RGB>(leds, NUM_LEDS);
    // FastLED.addLeds<UCS1904, DATA_PIN, RGB>(leds, NUM_LEDS);
    // FastLED.addLeds<UCS2903, DATA_PIN, RGB>(leds, NUM_LEDS);
    // FastLED.addLeds<WS2812, DATA_PIN, RGB>(leds, NUM_LEDS);  // GRB ordering is typical
    // FastLED.addLeds<WS2852, DATA_PIN, RGB>(leds, NUM_LEDS);  // GRB ordering is typical
    // FastLED.addLeds<WS2812B, DATA_PIN, RGB>(leds, NUM_LEDS);  // GRB ordering is typical
    // FastLED.addLeds<GS1903, DATA_PIN, RGB>(leds, NUM_LEDS);
    // FastLED.addLeds<SK6812, DATA_PIN, RGB>(leds, NUM_LEDS);  // GRB ordering is typical
    // FastLED.addLeds<SK6822, DATA_PIN, RGB>(leds, NUM_LEDS);
    // FastLED.addLeds<APA106, DATA_PIN, RGB>(leds, NUM_LEDS);
    // FastLED.addLeds<PL9823, DATA_PIN, RGB>(leds, NUM_LEDS);
    // FastLED.addLeds<SK6822, DATA_PIN, RGB>(leds, NUM_LEDS);
    FastLED.addLeds<WS2811, DATA_PIN, RGB>(leds, NUM_LEDS);
    FastLED.addLeds<WS2811, 33, RGB>(leds2, 1);
    //FastLED.addLeds<WS2811, DATA_PIN2, RGB>(leds, NUM_LEDS);
    // FastLED.addLeds<WS2813, DATA_PIN, RGB>(leds, NUM_LEDS);
    // FastLED.addLeds<APA104, DATA_PIN, RGB>(leds, NUM_LEDS);
    // FastLED.addLeds<WS2811_400, DATA_PIN, RGB>(leds, NUM_LEDS);
    // FastLED.addLeds<GE8822, DATA_PIN, RGB>(leds, NUM_LEDS);
    // FastLED.addLeds<GW6205, DATA_PIN, RGB>(leds, NUM_LEDS);
    // FastLED.addLeds<GW6205_400, DATA_PIN, RGB>(leds, NUM_LEDS);
    // FastLED.addLeds<LPD1886, DATA_PIN, RGB>(leds, NUM_LEDS);
    // FastLED.addLeds<LPD1886_8BIT, DATA_PIN, RGB>(leds, NUM_LEDS);
    // ## Clocked (SPI) types ##
    // FastLED.addLeds<LPD6803, DATA_PIN, CLOCK_PIN, RGB>(leds, NUM_LEDS);  // GRB ordering is typical
    // FastLED.addLeds<LPD8806, DATA_PIN, CLOCK_PIN, RGB>(leds, NUM_LEDS);  // GRB ordering is typical
    // FastLED.addLeds<WS2801, DATA_PIN, CLOCK_PIN, RGB>(leds, NUM_LEDS);
    // FastLED.addLeds<WS2803, DATA_PIN, CLOCK_PIN, RGB>(leds, NUM_LEDS);
    // FastLED.addLeds<SM16716, DATA_PIN, CLOCK_PIN, RGB>(leds, NUM_LEDS);
    // FastLED.addLeds<P9813, DATA_PIN, CLOCK_PIN, RGB>(leds, NUM_LEDS);  // BGR ordering is typical
    // FastLED.addLeds<DOTSTAR, DATA_PIN, CLOCK_PIN, RGB>(leds, NUM_LEDS);  // BGR ordering is typical
    // FastLED.addLeds<APA102, DATA_PIN, CLOCK_PIN, RGB>(leds, NUM_LEDS);  // BGR ordering is typical
    // FastLED.addLeds<SK9822, DATA_PIN, CLOCK_PIN, RGB>(leds, NUM_LEDS);  // BGR ordering is typical

    
    leds2[0] = CRGB::White;
    leds2[1] = CRGB::White;
    norflash_spi_init();
    read_data(0, buf2,1);
    //Serial.println(buf2[0]);
    FastLED.setBrightness(buf2[0]); 

   for(int whiteLed = 0; whiteLed < NUM_LEDS; whiteLed = whiteLed + 1) {
      // Turn our current led on to white, then show the leds
      leds[whiteLed] = CRGB::White;

      // Show the leds (only one of which is set to white, from above)
      FastLED.show();

      // Wait a little bit
      delay(100);

      // Turn our current led back to black for the next loop around
      leds[whiteLed] = CRGB::Black;
   }

}

// This function runs over and over, and is where you do the magic to light
// your leds.
void loop() {
   // Move a single white led 
   FastLED.setBrightness(200);
   for(int whiteLed = 0; whiteLed < NUM_LEDS; whiteLed = whiteLed + 1) {
      // Turn our current led on to white, then show the leds
      leds[whiteLed] = CRGB::White;

      // Show the leds (only one of which is set to white, from above)
      FastLED.show();

      // Wait a little bit
      delay(100);

      // Turn our current led back to black for the next loop around
      leds[whiteLed] = CRGB::Black;
   }
}

        通过麦克风模块控制LED效果,LED模块这里可以参考官方的驱动例程,但是需要根据板子修改引脚,还有模式需要修改成I2S_PHILIPS_MODE,采样速率和采样位宽可以自行修改,这里程序实现了对声音响度控制,当一定响度声音持续一段时间后,会产生流水灯效果。

        主要代码如下,详细代码参见附件。

if (!I2S.begin(I2S_PHILIPS_MODE, 8000, 16)) {
    Serial.println("Failed to initialize I2S!");
    while (1); // do nothing
  }
}

void loop() {

  int sample = I2S.read();

  Serial.println(sample);
  if(sample>800)//sample>500
  {   count2++;
      if(count2>1000)
      { count2=0;
    for(int whiteLed = 0; whiteLed < NUM_LEDS; whiteLed = whiteLed + 1) {

      leds[whiteLed] = CRGB::White;


      FastLED.show();

      delay(100);

      leds[whiteLed] = CRGB::Black;
   }}
  }
  //delay(5000);
}

        通过加速度传感器控制LED效果。加速度传感器可以很方便识别震动,比如当检测到人体移动产生的震动,可以控制灯亮起,这里通过判断Z轴的数据,如果加速度大于某个值,LED就会显示流水灯效果。详细程序见附件,以下是主要的代码。

void loop()
{

  float x1=SensorOne.readFloatAccelX();
  float y1=SensorOne.readFloatAccelY();
  float z1=SensorOne.readFloatAccelZ();
  Serial.print(" X1 = ");
  Serial.println(x1, 4);
 Serial.print(" Y1 = ");
  Serial.println(y1, 4);
 Serial.print(" Z1 = ");
 Serial.println(z1, 4);
  if(z1>0.9)
  {
    //Serial.println("move");
       for(int whiteLed = 0; whiteLed < NUM_LEDS; whiteLed = whiteLed + 1) {
      // Turn our current led on to white, then show the leds
      leds[whiteLed] = CRGB::White;

      // Show the leds (only one of which is set to white, from above)
      FastLED.show();

      // Wait a little bit
      delay(100);

      // Turn our current led back to black for the next loop around
      leds[whiteLed] = CRGB::Black;
   }

  }

  delay(100);
}

 

总结

        感谢eeworld和得捷电子举办的活动,通过这次的活动很全面的了解了esp32在arduino下的编程应用,总体来说相对于python还是要复杂的多,特别是很多库不支持的时候需要翻看电路图查找资料,需要后续有机会能继续学习python。

本帖最后由 Devin522 于 2023-10-15 23:40 编辑

回复评论

暂无评论,赶紧抢沙发吧
电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 京公网安备 11010802033920号
    写回复