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();
}
实物显示效果:
#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 编辑