1286|1

94

帖子

1

TA的资源

一粒金砂(高级)

楼主
 

【得捷电子Follow me第2期】+ 提交帖:Adafruit ESP32-S3的折腾 [复制链接]

  本帖最后由 aramy 于 2023-10-13 15:59 编辑

内容一:演示视频

 

本帖为“得捷电子Follow me第2期”汇总贴。本帖内容与分贴会有相同处,不是抄袭只是搬运。

内容二:项目总结报告


  • 任务四选择的是:分任务1:日历&时钟——完成一个可通过互联网更新的万年历时钟,并显示当地的天气信息

                               分任务2:WS2812B效果控制——完成一个Neopixel(12灯珠或以上)控制器,通过按键和屏幕切换展示效果.

 

任务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这个活动能一直做下去!建议活动前明确活动规则,中途修改规则,有些突兀。

内容四:附件

日历时钟天气.zip (6.32 MB, 下载次数: 2)

esp32s3.zip (220.21 KB, 下载次数: 1)

 

最新回复

任务完成,辛苦了,下期可以继续参与。  详情 回复 发表于 2023-10-14 13:15
点赞 关注
 
 

回复
举报

7181

帖子

11

TA的资源

版主

沙发
 
任务完成,辛苦了,下期可以继续参与。
 
 
 

回复
您需要登录后才可以回帖 登录 | 注册

猜你喜欢
随便看看
查找数据手册?

EEWorld Datasheet 技术支持

相关文章 更多>>
推荐帖子
RBS2000基站维护经验与体会(转)

RBS2000系列基站是爱立信公司的新一代产品,广泛应用于我国的GSM900MHz及GSM1800MHz通信系统。由于其高度的集成化和良好的人机接 ...

MPEG4编解C源代码-以移植到ARM和DSP上

MPEG4编解C源代码-以移植到ARM和DSP上,经典

拆机啦~~看看怡成5D-1血糖仪

某天趁着促销5.6包邮购入怡成5D-1血糖仪一个~当时好几个说要抢后来却没行动说估计是骗人的哼哼,我现在拆给你们看~不管是真是假 ...

今晚8点TI直播:最新DLP产品及汽车应用方案来啦,解读动态照地灯、AR-HUD方案

想了解市场更新的DLP产品? 想了解最新、创新的DLP汽车应用方案? 想找资深DLP资深工程师带你熟悉DLP开发? 欢迎锁定今 ...

【花雕动手做】有趣好玩的音乐可视化系列小项目(03)---RGB律动灯

本帖最后由 eagler8 于 2021-10-7 21:28 编辑 偶然脑子发热心血来潮,想要做一个声音可视化的系列专题。这个专题的难度有点高 ...

关于MOS管并联温度降低的原因讨论

原先设计了个电路,测试交流电流大小,设计值是5A最大,有多个量程。量程切换是通过MOS管IRF540进行,这个管子Ids为33A,Vgs ...

[国民技术N32WB452测评] 四、蓝牙控制RGB全彩氛围灯的实现

国民技术的评测板,当初申请的目的,其实是想用它的5MADC的,只是后面由于工作方面的原因,一直没空做PCB板,不过,当初申请的时 ...

全志V853 放开快启方案打印及在快起方式下配置isp led的方法

> # 全志V85x芯片 如何放开快启方案的打印? ## 1.主题 如何放开快启方案的打印 ## 2.问题背景 产品:v851系列快启方案 ...

【CH32X035DIY】+步进电机驱动控制

本帖最后由 jinglixixi 于 2024-2-14 12:52 编辑 在绣花机仿真系统中,是靠托板的二维运动来实现绣针的相对位移,所采用的步 ...

帧率与刷新率的区别,及应用VTSG

本帖最后由 clibo024 于 2025-1-17 13:32 编辑 帧率(Frame Rate)是指每秒显示静态图像的次数,通常以FPS为单位‌。在视 ...

关闭
站长推荐上一条 1/10 下一条
立即报名 | 2025 瑞萨电子工业以太网技术日即将开启!
3月-4月 深圳、广州、北京、苏州、西安、上海 走进全国6城
2025瑞萨电子工业以太网技术巡回沙龙聚焦工业4.0核心需求,为工程师与企业决策者提供实时通信技术最佳解决方案。
预报从速,好礼等您拿~

查看 »

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

 
机器人开发圈

About Us 关于我们 客户服务 联系方式 器件索引 网站地图 最新更新 手机版

站点相关: 国产芯 安防电子 汽车电子 手机便携 工业控制 家用电子 医疗电子 测试测量 网络通信 物联网

北京市海淀区中关村大街18号B座15层1530室 电话:(010)82350740 邮编:100190

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2025 EEWORLD.com.cn, Inc. All rights reserved
快速回复 返回顶部 返回列表