【得捷电子Follow me第2期】ESP32彩灯控制器
[复制链接]
视频介绍如下
任务一
通过屏幕显示中文字符,使用ARDUINO编程,对于这款屏幕ST7789有很多得例程可以参考,这里使用TFT ESPI库,汉字取模后即可完成汉字显示得任务。
显示汉字通过函数,绘制点阵字符,绘制函数如下,中文字符无法通过print打印,需要通过下面的函数输出。
void showMyFont(int32_t x, int32_t y, const char c[3], uint32_t color) {
for (int k = 0; k < 25; k++)// 根据字库的字数调节循环的次数
if (hanzi[k].Index[0] == c[0] && hanzi[k].Index[1] == c[1] && hanzi[k].Index[2] == c[2])
{
tft.drawBitmap(x, y, hanzi[k].hz_Id, hanzi[k].hz_width, 16, color);
}
}
/*******************整句汉字显示****************/
void showMyFonts(int32_t x, int32_t y, const char str[], uint32_t color) { //显示整句汉字,字库比较简单,上下、左右输出是在函数内实现
int x0 = x;
for (int i = 0; i < strlen(str); i += 3) {
showMyFont(x0, y, str+i, color);
x0 += 17;
}
}
屏幕初始化函数如下
void setup(void) {
pinMode(45, OUTPUT);
digitalWrite(45, HIGH);
tft.init();
tft.setRotation(1);
tft.begin();
tft.fillScreen(TFT_WHITE); //初始化TFT屏幕
pinMode(0,INPUT_PULLUP);
strip.begin();
strip.setBrightness(20);
}
实物显示效果:
任务二
通过arduino编程,实现创建热点和连接wifi
· 创建热点,手机连接热点后,可以看到路由IP和程序中设定的是一样的。
创建热点的程序如下:
#include <WiFi.h>
#include <WiFiClient.h>
const char* ssid = "aptest";
const char* password = "12345678";
WiFiServer ServerPort(1234);
IPAddress LocalIP(192,168,4,22);
IPAddress Gateway(192,168,4,22);
IPAddress SubNet(255,255,255,0);
void setup() {
Serial.begin(115200);
delay(1000);
WiFi.mode(WIFI_AP); // 设置为AP模式
WiFi.softAPConfig(LocalIP,Gateway,SubNet);
WiFi.softAP(ssid, password); // 创建WiFi接入点
IPAddress ip = WiFi.softAPIP(); // 获取AP的IP地址
ServerPort.begin();
}
void loop() {
}
连接wifi,这里用手机创建一个热点,当ESP32连接到网络后,可以通过手机管理器看到ESP32的设备。下面的任务中由于没有用到网络功能,但例程有包含http的功能,对于一些类似小说网站,可以通过这个函数抓取到小说的文本内容。
· 连接wifi的代码如下:
#include <Arduino.h>
#include <WiFi.h>
#include <HTTPClient.h>
const char* ssid = "test"; // WIFI账户
const char* password = "12345678"; // WIFI密码
int page;
int pagestarchar[100];
int pageendchar[100];
int flag;
struct tx
{ int starchar;
int endchar;
int page_starchar;
int page_endchar;
int rowscount;
String payload;
};
tx tx;
void setup(void) {
Serial.begin(115200);
WiFi.begin(ssid, password);
for(uint8_t t = 4; t > 0; t--) {
Serial.printf("[SETUP] WAIT %d...\n", t);
Serial.flush();
delay(1000);
}
while (WiFi.status() != WL_CONNECTED) {
Serial.print(".");
// wait 1 second for re-trying
delay(1000);
}
Serial.print("Connected to ");
Serial.println(ssid);
HTTPClient http;
Serial.print("[HTTP] begin...\n");
http.begin("https://www.ppzuowen.com/book/en/wangerdedeshiyingwenban/534113.html"); //访问服务器地址https://www.ppzuowen.com/book/en/wangerdedeshiyingwenban/534113.html
http.setUserAgent("Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Safari/537.36");
Serial.print("[HTTP] GET...\n");
// start connection and send HTTP header
int httpCode = http.GET();
// httpCode will be negative on error
if(httpCode > 0) {
Serial.printf("[HTTP] GET... code: %d\n", httpCode);
if(httpCode == HTTP_CODE_OK) {
String payload = http.getString();
tx.payload=payload;
}
} else {
Serial.printf("[HTTP] GET... failed, error: %s\n", http.errorToString(httpCode).c_str());
}
http.end();
}
任务三
通过按键控制板上RGB显示灯效果,ARDUINO这里可以使用官方的库Adafruit_NeoPixel来控制LED效果显示.
根据官方的引脚图,按键是0脚,当按键按下是,呼吸灯的颜色发生变化,以下是代码,引脚参考官方的资料。
需要注意电源是通过一个IO口拉高的方式供电,因此要将这个IO口设置为高电平,灯珠才能正常亮起。
· 由于拍照的原因,这里灯珠的亮度设置不能太高。
#include <Adafruit_NeoPixel.h>
//#ifdef __AVR__
// #include <avr/power.h> // Required for 16 MHz Adafruit Trinket
//#endif
// Which pin on the Arduino is connected to the NeoPixels?
#define PIN 33 // On Trinket or Gemma, suggest changing this to 1
// How many NeoPixels are attached to the Arduino?
#define NUMPIXELS 1 // Popular NeoPixel ring size
// When setting up the NeoPixel library, we tell it how many pixels,
// and which pin to use to send signals. Note that for older NeoPixel
// strips you might need to change the third parameter -- see the
// strandtest example for more information on possible values.
Adafruit_NeoPixel pixels(NUMPIXELS, PIN, NEO_GRB + NEO_KHZ800);
#define DELAYVAL 500 // Time (in milliseconds) to pause between pixels
unsigned char a,b;
bool flag;
void setup() {
// These lines are specifically to support the Adafruit Trinket 5V 16 MHz.
// Any other board, you can remove this part (but no harm leaving it):
pinMode(34, OUTPUT);
pinMode(0,INPUT_PULLUP);
pinMode(1,OUTPUT);
digitalWrite(34, HIGH);
#if defined(__AVR_ATtiny85__) && (F_CPU == 16000000)
clock_prescale_set(clock_div_1);
#endif
// END of Trinket-specific code.
a=15;b=15;flag=true;
pixels.begin(); // INITIALIZE NeoPixel strip object (REQUIRED)
}
void loop() {
pixels.clear(); // Set all pixel colors to 'off'
// The first NeoPixel in a strand is #0, second is 1, all the way up
// to the count of pixels minus one.
for(int i=0; i<NUMPIXELS; i++) { // For each pixel...
// pixels.Color() takes RGB values, from 0,0,0 up to 255,255,255
// Here we're using a moderately bright green color:
pixels.setPixelColor(i, pixels.Color(a, b, a));
if(digitalRead(0)==0)
{ while(digitalRead(0)==0);
if(flag){a=50;b=0;flag=false;}
else{a=15;b=15;flag=true;}
}
pixels.show(); // Send the updated pixel colors to the hardware.
delay(DELAYVAL); // Pause before next pass through loop
pixels.setPixelColor(i, pixels.Color(a, b, 0));
pixels.show();
delay(DELAYVAL);
}
}
任务四
任务四我这里选择控制12个ws2812灯珠,相当于结合了任务一和任务三的程序,这里用到另一个库Freenove_WS2812_Lib_for_ESP32来控制WS2812,因为这个库本身有两个效果不错的彩灯特效,所以直接引用了,没有继续使用官方的库。程序通过按键切换彩虹和流水灯两种灯效,当切换灯效时,屏幕显示效果一或者效果二。
灯效可以参考Freenove_WS2812_Lib_for_ESP32库里面两个例程。
以下是代码:
#include <TFT_eSPI.h> // Graphics and font library for ILI9341 driver chip
#include <SPI.h>
#include "MyFont.h"
#include "Freenove_WS2812_Lib_for_ESP32.h"
#define LEDS_COUNT 12
#define LEDS_PIN 2
#define CHANNEL 0
#define TFT_GREY 0x5AEB // New colour
TFT_eSPI tft = TFT_eSPI(); // Invoke library
Freenove_ESP32_WS2812 strip = Freenove_ESP32_WS2812(LEDS_COUNT, LEDS_PIN, CHANNEL, TYPE_GRB);
u8 m_color[5][3] = { {255, 0, 0}, {0, 255, 0}, {0, 0, 255}, {255, 255, 255}, {0, 0, 0} };
int delayval = 100;
bool a;
/*******************单个汉字显示****************/
void showMyFont(int32_t x, int32_t y, const char c[3], uint32_t color) {
for (int k = 0; k < 25; k++)// 根据字库的字数调节循环的次数
if (hanzi[k].Index[0] == c[0] && hanzi[k].Index[1] == c[1] && hanzi[k].Index[2] == c[2])
{
tft.drawBitmap(x, y, hanzi[k].hz_Id, hanzi[k].hz_width, 16, color);
}
}
/*******************整句汉字显示****************/
void showMyFonts(int32_t x, int32_t y, const char str[], uint32_t color) { //显示整句汉字,字库比较简单,上下、左右输出是在函数内实现
int x0 = x;
for (int i = 0; i < strlen(str); i += 3) {
showMyFont(x0, y, str+i, color);
x0 += 17;
}
}
//tft espi vlw
void setup(void) {
pinMode(45, OUTPUT);
digitalWrite(45, HIGH);
tft.init();
tft.setRotation(1);
tft.begin();
tft.fillScreen(TFT_WHITE); //初始化TFT屏幕
pinMode(0,INPUT_PULLUP);
strip.begin();
strip.setBrightness(20);
a=true;
}
void loop() {
if(digitalRead(0)==0)
{ while(digitalRead(0)==0);
a=!a;
}
if(a==true){
tft.fillScreen(TFT_WHITE);
showMyFonts(40, 50, "效果一", TFT_BLACK);
for (int j = 0; j < 255; j += 2) {
for (int i = 0; i < LEDS_COUNT; i++) {
strip.setLedColorData(i, strip.Wheel((i * 256 / LEDS_COUNT + j) & 255));
}
strip.show();
delay(10);
}
}
if(a==false)
{ tft.fillScreen(TFT_WHITE);showMyFonts(40, 50, "效果二", TFT_BLACK);
for (int j = 0; j < 5; j++) {
for (int i = 0; i < LEDS_COUNT; i++) {
strip.setLedColorData(i, m_color[j][0], m_color[j][1], m_color[j][2]);
strip.show();
delay(delayval);
}
delay(500);
}
}
}
这款开发板适合用作物联网方面应用,使用另外两种芯片SAMD21和RP2040作为从机,使得ESP32能够连接更多的设备。这里由于暂时没有无线模块,使用有线连接的方式分别使用RP2040和SAMD21控制LED的效果。
这两款芯片都支持ARDUINO编程,使用同一个平台开发十分方便快捷。
RP2040由于原来的库不支持彩灯,通过实测<FastLED.h>可以直接使用,RP2040所做的板子本身没有灯,外接了一个型号为B3DK3BRG的RGB灯珠来显示,显示的程序如下。
#define FASTLED_FORCE_SOFTWARE_SPI
#define FASTLED_FORCE_SOFTWARE_PINS
#include <FastLED.h>
#define NUM_LEDS 1
#define DATA_PIN 1
CRGB leds[NUM_LEDS];
void setup() {
delay(2000);
pinMode(34, OUTPUT);
pinMode(1, OUTPUT);
pinMode(2, OUTPUT);
pinMode(5,INPUT_PULLUP);
FastLED.addLeds<WS2811, DATA_PIN, RGB>(leds, NUM_LEDS);
FastLED.setBrightness(100);
}
void loop() {
leds[1] = CRGB::Black;leds[0] = CRGB::Black;
FastLED.show();
delay(1000);
leds[1] = CRGB::White;leds[0] = CRGB::Black;
FastLED.show();
delay(1000);
}
SAMD21这个小板子上带有LED指示灯,因此直接使用上门的灯做一个例程。
通过对比,这款开发板支持低功耗,并且编译速度也比其他两款明显更快,但是下载程序相对不稳定,经常出现烧录失败的情况,失败后短接rst,出现U盘即可重新烧录,这里通过ESP32控制板上呼吸灯代码如下:
void setup() {
// initialize digital pin LED_BUILTIN as an output.
pinMode(LED_BUILTIN, OUTPUT);
pinMode(1,INPUT);
}
// the loop function runs over and over again forever
void loop() {
if(digitalRead(1)){
digitalWrite(LED_BUILTIN, HIGH); // turn the LED on (HIGH is the voltage level)
delay(1000); // wait for a second
digitalWrite(LED_BUILTIN, LOW); // turn the LED off by making the voltage LOW
delay(1000); // wait for a second
}
}
这次参加项目的心得体会
1. 如果熟悉python的话,尽量使用python开发会方便很多,因为arduino烧录是需要手动进入bootload,每次都要手动复位,并且串口也会经常变化导致电脑不稳定。
2. arduino虽然库比较多,但是很多库的使用需要注意引脚定义。
3. 用到的板子里,samd21的编译是最快的,但是如果输出感觉有问题,先重新烧一遍,有时候烧录成功,实际上并没有,这个bootload相对于rp2040和esp32 s3不那么稳定。
4. 这款板子的屏幕素质很不错,体积小巧,希望后面能在官网获取到更多开发资料。
|