【得捷电子Follow me第2期】+ 提交帖:Adafruit ESP32-S3的折腾
[复制链接]
本帖最后由 aramy 于 2023-10-13 15:59 编辑
内容一:演示视频
本帖为“得捷电子Follow me第2期”汇总贴。本帖内容与分贴会有相同处,不是抄袭只是搬运。
内容二:项目总结报告
任务1:Adafruit ESP32-S3 TFT Feather 控制屏幕显示中文
"Follow me活动”是DigiKey联合EEWORLD发起的为期一年的“跟技术大咖学技术,完成任务返现报销”活动。这是我参加第二期活动的开发板Adafruit ESP32-S3 TFT Feather。主控是ESP32-
烧写固件:
ESP32-S3支持Arduino,esp-idf,micropython,circuitpython做开发。其中觉着circuitpython最简单,所以这里就用circuitpython来做开发啦!板子拿到手有厂家的程序,可以点亮屏幕,我们这里从一无所有开始做起。首先到这里下载厂家的固件Adafruit_Feather_ESP32S3_TFT_FactoryTest.bin。使用esp烧写工具通过串口烧写到板子里。如果提示:连接串口失败。就按住boot按键,再按下reset按键就好了。
然后烧写固件完成后,上电重启开发板,电脑会有U盘弹出,将circuitpython固件(adafruit-circuitpython-adafruit_feather_esp32s3_tft-en_US-8.2.2.uf2)拖到U盘里,然后开发板就会自动重启。circuitpython就准备好了。
驱动屏幕:
circuitpython环境非常好,已经帮忙初始化好了 彩色 1.14“ IPS TFT屏幕。我这里用Thonny作为编辑器,来进行代码的开发。 circuitpython中有个board的库,可以使用dir(board)查看这个类库的方法,这个类库中有DISPLAY是用来控制屏幕显示的,通过dir(board.DISPLAY)可以查看有哪些方法可以使用。这里有个board.DISPLAY.brightness变量,可以用来控制屏幕亮度,设置为0,则屏幕熄灭,设置为1,屏幕为最大亮度。
显示汉字:
给lib目录下上传 adafruit的字库文件,但是这里adafruit的字库都是英文字库,要想显示汉字,还需要额外的中文字库。这里我使用了网上找的 。这里要留意,因为空间有限,装不了太大的字库,这里我只载入了wenquanyi_10pt.pcf这个汉字字库。最后将这段代码写到code.py里。就能显示啦!横屏、竖屏都做了适配。
import board
import displayio
from adafruit_display_text import label, wrap_text_to_lines
from adafruit_bitmap_font import bitmap_font
dis_str=" 搭载 Xtensa® 32 位 LX7 双核处理器,主频高达 240 MHz,内置 512 KB SRAM (TCM),具有 45 个可编程 GPIO 管脚和丰富的通信接口,集成 2.4 GHz Wi-Fi 和 Bluetooth 5 (LE),配备原生 USB,可用作键盘/鼠标、MIDI 设备、磁盘驱动器等"
def screen_dispstr(str):
if board.DISPLAY.rotation%180==0:
char_num=23 #横屏
else:
char_num=13 #竖屏
strbuf="";
for i in range(len(str)/char_num):
strbuf=strbuf+str[i*char_num:(i+1)*char_num]+"\n"
return strbuf
display = board.DISPLAY
board.DISPLAY.brightness = 0.35
board.DISPLAY.rotation = 0
font = bitmap_font.load_font("wenquanyi_10pt.pcf")
color = 0x00FF00
text_group = displayio.Group()
text_area = label.Label(font, text=screen_dispstr(dis_str), color=color)
text_area.x = 2
text_area.y = 10
text_area.line_spacing = 0.8
text_area.scale = 1
text_group.append(text_area)
display.show(text_group)
while True:
pass
任务2:网络功能使用
1 、创建Wifi热点
circuitpython 真的很优秀,屏幕帮忙初始化好了,WiFi也能帮忙初始化。有建好的轮子,我们就直接拿来用啦! ESP32-S3在circuitpython下创建wifi热点非常简单:
import wifi
# 1 - give it an AuthMode
wifi.Radio.start_ap(ssid='followme2', password='12345678', authmode=[wifi.AuthMode.WPA2, wifi.AuthMode.PSK])
2 、连接WiFi
circuitpython连接WiFi就更加简单啦!之前介绍了,circuitpythony在启动时就有帮忙驱动起WiFi,所以只需要简单的做一下wifi设置,告诉circuitpython需要连接的wifi的sid和密码即可。修改文件settings.toml,这样在开机上电后就会自动连上wifi。
CIRCUITPY_WIFI_SSID = "AAA"
CIRCUITPY_WIFI_PASSWORD = "weile120"
3、通过wifi连接网络
有了wifi,意味着这个Adafruit ESP32-S3 TFT Feather已经连接上了网络,我们通过socker编程,连连接一下电脑。
import wifi
import socketpool
import time
HOST = "192.168.2.104"
PORT = 6000
TIMEOUT = 30
pool = socketpool.SocketPool(wifi.radio)
print("Creating Socket")
sock=pool.socket(pool.AF_INET, pool.SOCK_STREAM)
sock.settimeout(TIMEOUT)
sock.connect((HOST, PORT))
while True:
print("Sending")
sent = sock.send(b"Hello, world")
print("Receiving")
buff = bytearray(5)
numbytes = sock.recv_into(buff)
#sock.close()
print(repr(buff))
time.sleep(1)
这样就创建了一个简单的socker的客户端,能够通过wifi与上位机通讯了。
任务3:控制WS2812B
Adafruit ESP32-S3 TFT Feather的板子上集成了一颗炫彩LED灯WS2812B。还有两颗按键,不过一个按键是复位键,不能拿来当功能键使用,所以在不接外设的情况下,只有一个按键可以使用。
1 按键
这里遇到了一个问题,circuitpython 是很好用,但是我没找到对应的中断实现的例子。按键的实现一般有两种方式。1:轮训。优点是简单易实现,缺点是实时性差,占CPU资源。2:中断。优点是响应时间快,几乎没有缺点。但是在circuitpython 却没找到中断的实现方法,所以这里使用轮训的方式来实现按键功能。一个简单的例子,按键按下LED灯亮,松开LED灭。
import board
import digitalio
led = digitalio.DigitalInOut(board.LED)
led.direction = digitalio.Direction.OUTPUT
button = digitalio.DigitalInOut(board.BUTTON)
button.direction = digitalio.Direction.INPUT
button.pull = digitalio.Pull.UP
# 按键控制LED
def ledwithbutton():
led.value = not button.value
while True:
ledwithbutton()
2 WS2812B
WS2812B 是一种智能控制 LED 光源,将控制电路和 RGB 芯片集成在一起。内部包括智能数字端口数据锁存和信号整形放大驱动电路。还包括精密的内部振荡器和电压可编程恒流控制部分,有效保证像素点的光色高度一致。数据传输协议采用单 NZR 通信模式。像素上电复位后,DIN 端口从控制器接收数据,第一像素采集初始 24位数据,然后发送给内部数据锁存器,其他经过内部信号整形放大电路整形后的数据通过 DO 端口发送给下一个级联像素。每传输一个像素后,信号减少 24 位。像素采用自整形传输技术,使得像素级联数不受信号传输的限制,只取决于信号传输的速度。复位时>280us,中断时不会误复位。刷新频率更新至 2KHz,无闪烁,提高了出色的显示效果。
circuitpython 中有专门的类库来驱动这个WS2812B,这样就不用再劳心费力地去编程实现协议啦!
import board
import digitalio
import time
import neopixel
from adafruit_display_text import label
from adafruit_bitmap_font import bitmap_font
pixel = neopixel.NeoPixel(board.NEOPIXEL, 1)
pixel.brightness = 0.8
button = digitalio.DigitalInOut(board.BUTTON)
button.direction = digitalio.Direction.INPUT
button.pull = digitalio.Pull.UP
but_in=3
led = digitalio.DigitalInOut(board.LED)
led.direction = digitalio.Direction.OUTPUT
display = board.DISPLAY
font_file = "fonts/LibreBodoniv2002-Bold-27.bdf"
font = bitmap_font.load_font(font_file)
grape = (190, 75, 219)
pixel.fill(0xFF0000)
# 按键控制LED
def colbutton():
global but_in
if(not button.value):
but_in=but_in+1
if (but_in>3):
but_in=0
def dispinfo(str):
if(str=="RED"):
color = 0xFF0000
text_area = label.Label(font, text="RED", color=color)
text_area.x = 100
text_area.y = 60
display.show(text_area)
pixel.fill(color)
elif(str=="GREEN"):
color = 0x00FF00
text_area = label.Label(font, text="GREEN", color=color)
text_area.x = 80
text_area.y = 60
pixel.fill(color)
elif(str=="BLUE"):
color = 0x0000FF
text_area = label.Label(font, text="BLUE", color=color)
text_area.x = 90
text_area.y = 60
pixel.fill(color)
else :
color = 0xFFFFFF
text_area = label.Label(font, text="WAITING", color=color)
text_area.x = 70
text_area.y = 60
pixel.fill(color)
display.show(text_area)
while True:
colbutton()
if(but_in==0):
dispinfo("RED")
elif(but_in==1):
dispinfo("BLUE")
elif(but_in==2):
dispinfo("GREEN")
else:
dispinfo("WAITING")
time.sleep(0.5)
任务4:之一 分任务1:日历&时钟
【得捷电子Follow me第2期】 任务4:分任务1:日历&时钟——完成一个可通过互联网更新的万年历时钟,并显示当地的天气信息。
开发工具:Vscode+platformio 。使用arduino进行进行编程。
配置文件:platformio.ini
[env:adafruit_feather_esp32s3_tft]
platform = espressif32
board = adafruit_feather_esp32s3_tft
framework = arduino
monitor_speed = 115200
upload_speed = 1500000
board_build.f_cpu = 240000000L
board_build.f_flash = 80000000L
board_build.flash_mode = dio
build_flags =
-DCORE_DEBUG_LEVEL=3
-Iinclude
lib_deps =
adafruit/Adafruit GFX Library @ ^1.11.8
adafruit/Adafruit ST7735 and ST7789 Library @ ^1.10.3
arduino-libraries/NTPClient @ ^3.2.1
bblanchon/ArduinoJson @ ^6.21.3
adafruit/Adafruit BMP280 Library @ ^2.6.8
玩了好久的CPY,想再尝试一下Arduino。板子上缺失的BMP280芯片,从淘宝上购买了一块焊上了,手艺不好,搞得屏幕黄了一块。既然装上了BMP280就做个简单的日历/时钟+天气展示吧!
作为时钟+天气,那么首先就要联网。通过互联网获取这些内容最为容易。通过一个单独的任务处理连接wifi的功能。连接完成wif后,与互联网进行校时。这里自动校时使用了NTPClient这个库。
#include "wifi_conn.h"
/**
* Task: monitor the WiFi connection and keep it alive!
*
* When a WiFi connection is established, this task will check it every 10 seconds
* to make sure it's still alive.
*
* If not, a reconnect is attempted. If this fails to finish within the timeout,
* the ESP32 will wait for it to recover and try again.
*/
WiFiUDP ntpUDP;
// NTPClient timeClient(ntpUDP);
NTPClient timeClient(ntpUDP, "ntp1.aliyun.com", 60 * 60 * 8, 30 * 60 * 1000);
// NTPClient timeClient(ntpUDP,"ntp.tuna.tsinghua.edu.cn");
void keepWiFiAlive(void *parameter)
{
for (;;)
{
if (WiFi.status() == WL_CONNECTED)
{
// Serial.print(WiFi.localIP());
// Serial.print(" ");
// Serial.println(timeClient.getFormattedTime());
vTaskDelay(10000 / portTICK_PERIOD_MS);
continue;
}
ESP_LOGE(TAG, "[WIFI] Connecting");
WiFi.mode(WIFI_STA);
WiFi.begin(WIFI_NETWORK, WIFI_PASSWORD);
unsigned long startAttemptTime = millis();
// Keep looping while we're not connected and haven't reached the timeout
while (WiFi.status() != WL_CONNECTED &&
millis() - startAttemptTime < WIFI_TIMEOUT_MS)
{
}
// When we couldn't make a WiFi connection (or the timeout expired)
// sleep for a while and then retry.
if (WiFi.status() != WL_CONNECTED)
{
ESP_LOGE(TAG, "[WIFI] FAILED");
vTaskDelay(WIFI_RECOVER_TIME_MS / portTICK_PERIOD_MS);
continue;
}
timeClient.begin();
timeClient.setTimeOffset(28800); //+1区,偏移3600,+8区,偏移3600*8
timeClient.update();
log_i("[WIFI] Connected: %s %s", (WiFi.localIP()).toString(), timeClient.getFormattedTime());
Serial.print(WiFi.localIP());
Serial.print(" ");
Serial.println(timeClient.getFormattedTime());
}
}
联网后,需要获取天气信息。天气信息使用独立的任务来循环进行。每5分钟获取一次。天气信息从心知天气获取。心知天气获取到的是json数据,这里json数据解析学习了论坛中老师的帖子!然后还有个BMP280芯片,这个芯片能够获得当前环境的温度和气压。通过BMP280的库,很方便地通过IIC总线方式获得了温度(摄氏度),气压(帕斯卡)。该库还提供了一个计算高度的方法,也拿来用用,不过计算出的高度有点怪,貌似是用气压直接换算出来的。
有了天气信息还需要展示信息,这里使用了第三方的st7789的库进行展示。使用第三方库驱动屏幕简单了很多,不用去写麻烦的寄存器了!
最后是将所有收集到到的信息一股脑地展示到tft屏幕上去,从上到下依次是 :
第一行:日历信息:年月日 时分秒。
第二行:当前气压(千帕),和温度(摄氏度)。
第三行:当前高度(米)(这里测出来我这里是低于海平面)
第四行:所处的城市。和当前天气预报的温度值(摄氏度)。
第五行:天气情况。
这里代码还是有些乱,有空了需要将功能模块化!
#include <Arduino.h>
#include "WiFi.h"
#include <Adafruit_GFX.h> // Core graphics library
#include "Adafruit_ST7789.h"
#include "wifi_conn.h"
#include <ArduinoJson.h>
#include <Adafruit_BMP280.h>
Adafruit_BMP280 bmp; // I2C
// 心知天气HTTP请求所需信息
String reqUserKey = "xxxx"; // 私钥
String reqLocation = "dongguan"; // 城市
String reqUnit = "c"; // 摄氏/华氏
uint32_t weather_query_delay = 0;
//心知天气
const char *host = "api.seniverse.com"; // 将要连接的服务器地址
const int httpPort = 80; // 将要连接的服务器端口
Adafruit_ST7789 tft = Adafruit_ST7789(TFT_CS, TFT_DC, TFT_RST);
void Tft_Init(void)
{
// turn on backlite
pinMode(TFT_BACKLITE, OUTPUT);
digitalWrite(TFT_BACKLITE, HIGH);
// turn on the TFT / I2C power supply
pinMode(TFT_I2C_POWER, OUTPUT);
digitalWrite(TFT_I2C_POWER, HIGH);
delay(10);
// initialize TFT
tft.init(135, 240); // Init ST7789 240x135
tft.setRotation(3);
tft.fillScreen(ST77XX_BLACK);
Serial.println(F("TFT ST7789 240* 135 Initialized"));
tft.setCursor(20, 50);
tft.setTextColor(ST77XX_BLUE);
tft.setTextSize(3);
tft.println("Follow me 2");
}
// 利用ArduinoJson库解析心知天气响应信息
String results_0_now_text_str;
int results_0_now_temperature_int;
void parseInfo(WiFiClient client)
{
const size_t capacity = JSON_ARRAY_SIZE(1) + JSON_OBJECT_SIZE(1) + 2 * JSON_OBJECT_SIZE(3) + JSON_OBJECT_SIZE(6) + 230;
DynamicJsonDocument doc(capacity);
deserializeJson(doc, client);
JsonObject results_0 = doc["results"][0];
JsonObject results_0_now = results_0["now"];
const char *results_0_now_text = results_0_now["text"];
const char *results_0_now_code = results_0_now["code"];
const char *results_0_now_temperature = results_0_now["temperature"];
results_0_now_text_str = results_0_now["text"].as<String>();
int results_0_now_code_int = results_0_now["code"].as<int>();
results_0_now_temperature_int = results_0_now["temperature"].as<int>();
Serial.println(F("======Weahter Now======="));
Serial.print(F("Weather Now: "));
Serial.print(results_0_now_text_str);
Serial.print(F(" "));
Serial.println(results_0_now_code_int);
Serial.print(F("Temperature: "));
Serial.print(results_0_now_temperature_int);
Serial.print("C ");
Serial.println(timeClient.getFormattedTime());
Serial.println(F("========================"));
tft.fillScreen(ST77XX_BLACK);
tft.setCursor(0, 74);
tft.setTextColor(ST77XX_ORANGE);
tft.setTextSize(2);
tft.println("DONG GUAN");
tft.setCursor(0, 100);
tft.setTextColor(ST77XX_RED);
tft.print(results_0_now_text_str);
tft.print(" ");
tft.setTextSize(3);
tft.setTextColor(ST77XX_GREEN);
tft.setCursor(150, 80);
tft.print(String(results_0_now_temperature_int));
tft.println("C");
tft.setCursor(10, 24); //显示BMP280信息
tft.setTextSize(2);
float f = bmp.readTemperature(); //摄氏度
float P = bmp.readPressure() / 1000.0; // kPa
float A = bmp.readAltitude(1013.25); //米
char strbuf[64];
sprintf(strbuf,"P:%.fkPa T:%.1fC ",P,f);
tft.println(strbuf);
sprintf(strbuf,"H:%.fM",A);
tft.setCursor(10, 48);
tft.println(strbuf);
}
// 向心知天气服务器服务器请求信息并对信息进行解析
void httpRequest(String reqRes)
{
WiFiClient client;
// 建立http请求信息
String httpRequest = String("GET ") + reqRes + " HTTP/1.1\r\n" +
"Host: " + host + "\r\n" +
"Connection: close\r\n\r\n";
Serial.println("");
Serial.print("Connecting to ");
Serial.print(host);
// 尝试连接服务器
if (client.connect(host, 80))
{
Serial.println(" Success!");
// 向服务器发送http请求信息
client.print(httpRequest);
Serial.println("Sending request: ");
Serial.println(httpRequest);
// 获取并显示服务器响应状态行
String status_response = client.readStringUntil('\n');
Serial.print("status_response: ");
Serial.println(status_response);
// 使用find跳过HTTP响应头
if (client.find("\r\n\r\n"))
{
Serial.println("Found Header End. Start Parsing.");
}
weather_query_delay = 1000 * 60 * 5;
// 利用ArduinoJson库解析心知天气响应信息
parseInfo(client);
}
else
{
weather_query_delay = 3000;
Serial.println(" connection failed!");
}
//断开客户端与服务器连接工作
client.stop();
}
void Task_Weather_Get(void *pvParameters)
{
(void)pvParameters;
// 建立心知天气API当前天气请求资源地址
String reqRes = "/v3/weather/now.json?key=" + reqUserKey +
+"&location=" + reqLocation +
"&language=en&unit=" + reqUnit;
for (;;)
{
// 向心知天气服务器服务器请求信息并对信息进行解析
httpRequest(reqRes);
Serial.println("Next Weather Query will be " + String(weather_query_delay / 1000 / 60) + " min later");
vTaskDelay(weather_query_delay / portTICK_PERIOD_MS);
}
}
void setup(void)
{
Serial.begin(115200);
Tft_Init();
if (!bmp.begin())
{
Serial.println(F("Could not find a valid BMP280 sensor, check wiring!"));
while (1)
;
}
/* Default settings from datasheet. */
bmp.setSampling(Adafruit_BMP280::MODE_NORMAL, /* Operating Mode. */
Adafruit_BMP280::SAMPLING_X2, /* Temp. oversampling */
Adafruit_BMP280::SAMPLING_X16, /* Pressure oversampling */
Adafruit_BMP280::FILTER_X16, /* Filtering. */
Adafruit_BMP280::STANDBY_MS_500); /* Standby time. */
xTaskCreatePinnedToCore(keepWiFiAlive, "keepWiFiAlive", 1024 * 4, NULL, 2, NULL, ARDUINO_RUNNING_CORE);
vTaskDelay(5000 / portTICK_PERIOD_MS);
xTaskCreatePinnedToCore(Task_Weather_Get, "Task_Weather_Get", 1024 * 4, NULL, 1, NULL, 0);
}
void loop(void)
{
timeClient.update();
unsigned long epochTime = timeClient.getEpochTime();
//将epochTime换算成年月日
struct tm *ptm = gmtime((time_t *)&epochTime);
// int monthDay = ptm->tm_mday;
// Serial.print(ptm->tm_year);
// Serial.print(" ");
// Serial.print(ptm->tm_wday);
// Serial.print(" ");
char strbuf[64];
sprintf(strbuf, "%d/%02d/%02d %s", ptm->tm_year + 1900, ptm->tm_mon + 1, ptm->tm_mday, timeClient.getFormattedTime());
tft.fillRect(0, 0, 240, 16, ST77XX_BLACK);
tft.setCursor(5, 1);
tft.setTextColor(ST77XX_CYAN);
tft.setTextSize(2);
tft.print(strbuf);
// tft.setCursor(136, 0);
// tft.print(timeStamp);
// delay(1000);
delay(1000);
}
在使用Arduino做开发过程中,freertos还是挺有意思的。ESP32集成了freertos操作系统,这样在开发过程中不同的功能模块使用不同的任务去调用。并且Arduino中的loop方法,本质上也是一个freertos任务。
任务4:之二 WS2812B效果控制
分任务2:WS2812B效果控制——完成一个Neopixel(12灯珠或以上)控制器,通过按键和屏幕切换展示效果.
以前淘的灯带,一直放着吃灰。灯带是WS2812B灯珠构成的,一条灯带8颗颗灯珠。WS2812B 是一种智能控制 LED 光源,将控制电路和 RGB 芯片集成在一个 5050 个组件的封装中。内部包括智能数字端口数据锁存和信号整形放大驱动电路。还包括精密的内部振荡器和电压可编程恒流控制部分,有效保证像素点的光色高度一致。数据传输协议采用单 NZR 通信模式。像素上电复位后,DIN 端口从控制器接收数据,第一像素采集初始 24位数据,然后发送给内部数据锁存器,其他经过内部信号整形放大电路整形后的数据通过 DO 端口发送给下一个级联像素。每传输一个像素后,信号减少 24 位。像素采用自整形传输技术,使得像素级联数不受信号传输的限制,只取决于信号传输的速度。复位时>280us,中断时不会误复位。刷新频率更新至 2KHz,无闪烁,提高了出色的显示效果。
要想驱动WS2812其实也挺不容易,对时序要求特别的高。但是cpy里已经造好了轮子,直接调用库来驱动就好,就变得特别简单了。这里将两条灯带连起来,构成个环,一共是16颗灯珠。使用杜邦线,接到Adafruit ESP32-S3 TFT Feather板子的D12接口。电源也从开发板上取电。
代码流程,使用按键控制灯珠的颜色。按键按键使用轮询方式进行查询。使用轮询方式并不是太好,如果要做灯珠的特效,会导致控制WS2812的时间较长,影响按键响应。cpy的多线程尝试了一下,还是有问题,就放弃放弃了。WS2812显示颜色的同时在屏幕上也显示当前灯珠对应的颜色。
import board
import digitalio
import time
import neopixel
from adafruit_display_text import label
from adafruit_bitmap_font import bitmap_font
pixel = neopixel.NeoPixel(board.D12, 16)
pixel.brightness = 0.8
button = digitalio.DigitalInOut(board.BUTTON)
button.direction = digitalio.Direction.INPUT
button.pull = digitalio.Pull.UP
but_in=3
led = digitalio.DigitalInOut(board.LED)
led.direction = digitalio.Direction.OUTPUT
display = board.DISPLAY
font_file = "fonts/LibreBodoniv2002-Bold-27.bdf"
font = bitmap_font.load_font(font_file)
grape = (190, 75, 219)
pixel.fill(0xFF0000)
# 按键控制LED
def colbutton():
global but_in
if(not button.value):
but_in=but_in+1
if (but_in>3):
but_in=0
def dispinfo(str):
if(str=="RED"):
color = 0xFF0000
text_area = label.Label(font, text="RED", color=color)
text_area.x = 100
text_area.y = 60
display.show(text_area)
pixel.fill(color)
elif(str=="GREEN"):
color = 0x00FF00
text_area = label.Label(font, text="GREEN", color=color)
text_area.x = 80
text_area.y = 60
pixel.fill(color)
elif(str=="BLUE"):
color = 0x0000FF
text_area = label.Label(font, text="BLUE", color=color)
text_area.x = 90
text_area.y = 60
pixel.fill(color)
else :
color = 0xFFFFFF
text_area = label.Label(font, text="WAITING", color=color)
text_area.x = 70
text_area.y = 60
pixel.fill(color)
display.show(text_area)
while True:
colbutton()
if(but_in==0):
dispinfo("RED")
elif(but_in==1):
dispinfo("BLUE")
elif(but_in==2):
dispinfo("GREEN")
else:
dispinfo("WAITING")
time.sleep(0.5)
内容三:总结
ESP32-S3功能真的很强大,circuitpython也是简单易学。希望follow me这个活动能一直做下去!建议活动前明确活动规则,中途修改规则,有些突兀。
内容四:附件
|