[Digi-Key Follow me Issue 2] ESP32 Color Light Controller
[Copy link]
The video introduction is as follows
Task 1
Display Chinese characters on the screen using ARDUINO programming. There are many routines for this screen ST7789 that can be used as a reference. Here, the TFT ESPI library is used. After taking the Chinese characters, the task of displaying Chinese characters can be completed.
Display Chinese characters through functions, draw dot matrix characters, the drawing function is as follows, Chinese characters cannot be printed through print, need to be output through the following function.
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;
}
}
The screen initialization function is as follows
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);
}
Physical display effect:
Task 2
Create hotspot and connect to wifi through Arduino programming
Create a hotspot. After your phone is connected to the hotspot, you can see that the router IP is the same as that set in the program.
The procedure for creating a hotspot is as follows:
#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() {
}
Connect to wifi. Here, use the mobile phone to create a hotspot. When ESP32 is connected to the network, you can see the ESP32 device through the mobile phone manager. In the following task, since the network function is not used, the routine contains the http function. For some novel websites, this function can be used to grab the text content of the novel.
The code to connect to wifi is as follows:
#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();
}
Task 3
Control the RGB display light effect on the board by pressing buttons. ARDUINO can use the official library Adafruit_NeoPixel to control the LED effect display.
According to the official pin diagram, the button is pin 0. When the button is pressed, the color of the breathing light changes. The following is the code. The pins refer to the official information.
It should be noted that the power supply is supplied by pulling up an IO port, so this IO port must be set to a high level so that the lamp beads can light up normally.
Due to the purpose of taking photos, the brightness of the lamp beads cannot be set too high.
#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);
}
}
Task 4
In Task 4, I choose to control 12 ws2812 lamp beads, which is equivalent to combining the programs of Task 1 and Task 3. Here, another library Freenove_WS2812_Lib_for_ESP32 is used to control WS2812. Because this library itself has two good color light effects, it is directly referenced instead of continuing to use the official library. The program switches between the two lighting effects of rainbow and flowing light by pressing buttons. When switching the lighting effect, the screen displays effect 1 or effect 2.
For lighting effects, please refer to the two routines in the Freenove_WS2812_Lib_for_ESP32 library.
Here is the code:
#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);
}
}
}
This development board is suitable for IoT applications. It uses two other chips, SAMD21 and RP2040, as slaves, so that ESP32 can connect to more devices. Since there is no wireless module here, wired connection is used to control the LED effect using RP2040 and SAMD21 respectively.
Both chips support ARDUINO programming, and development using the same platform is very convenient and fast.
Since the original library of RP2040 does not support colored lights, it can be used directly through actual testing <FastLED.h>. The board made by RP2040 does not have a light itself, and an external RGB lamp bead model B3DK3BRG is connected for display. The display program is as follows.
#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);
}
The SAMD21 board has an LED indicator light, so we can use the light on the door to make a routine.
By comparison, this development board supports low power consumption, and the compilation speed is significantly faster than the other two. However, the download program is relatively unstable, and the burning fails frequently. After the failure, short-circuit rst, and a USB flash drive appears to re-burn. Here is the breathing light code on the ESP32 control board as follows:
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
}
}
My experience of participating in this project
1. If you are familiar with python, it will be much more convenient to use python development, because Arduino burning requires manual entry into bootload, and you have to manually reset it every time, and the serial port will often change, causing computer instability.
2. Although Arduino has many libraries, you need to pay attention to the pin definition when using many libraries.
3. Among the boards used, samd21 has the fastest compilation, but if the output feels problematic, burn it again first. Sometimes the burning is successful, but in fact it is not. This bootload is not as stable as rp2040 and esp32 s3.
4. The screen quality of this board is very good and the size is small. I hope to get more development information on the official website later.
|