625|1

27

帖子

2

TA的资源

一粒金砂(中级)

楼主
 

【得捷电子Follow me第2期】+交作业 [复制链接]

  本帖最后由 superw 于 2023-10-16 01:06 编辑

内容一、演示视频

演示视频

内容二、 项目总结报告

 

任务0:准备工作

本期follow me活动使用的是来自Adafruit的ESP32-S3 TFT Feather,可以在arduino和circuitpython环境下开发,也可以使用乐鑫官方的esp-idf进行开发,由于circuitpython本身也是由adafruit开发维护的,所以本着适配性和兼容性,选择使用circuitpython进行学习。

首先需要将板子刷上circuitpython的固件,让circuitpython在开发板上跑起来。

https://circuitpython.org/board/adafruit_feather_esp32s3_tft/下载基于ESP32-S3 TFT Feather的circuitpython UF2文件。

然后双击板上的reset按键,这个时候电脑上会出现一个叫FTHRS3BOOT的磁盘驱动器,把UF2文件直接拖到里面,磁盘驱动器会消失,并自动加载UF2文件,之后会出现一个叫CIRCUITPY的磁盘驱动器。这样就代表circuitpython的固件成功刷入,可以在板上进行circuitpython学习开发。具体刷入过程以及过程中LED状态的变化,可以根据官方文档操作

https://learn.adafruit.com/adafruit-esp32-s3-tft-feather/circuitpython

 

任务1:控制屏幕显示中文

任务要求:完成屏幕的控制,并且能显示中文

Circuitpython内嵌的只有一种字体,可以通过terminalio模块实现调用,进而操控TFT屏幕,但是调用这个模块只能显示英文。具体代码如下:

import board
import terminalio
from adafruit_display_text import label


text = "Hello world"
text_area = label.Label(terminalio.FONT, text=text)
text_area.x = 10
text_area.y = 10
board.DISPLAY.show(text_area)
while True:
    pass

通过terminalio.FONT设置字体,并显示text中的文本。现象如下:

进一步要想显示中文,需要有一个中文字库。根据直播中老师的介绍讲解以及其他坛友分享的经验,通过下面的代码可以在屏幕上显示元素周期表中前20位元素的中文。

import board
import displayio
from adafruit_display_text import label
from adafruit_bitmap_font import bitmap_font

display = board.DISPLAY

font = bitmap_font.load_font("fonts/wenquanyi_13px.pcf")

text_group = displayio.Group()

text = "氢氦锂铍硼\n碳氮氧氟氖\n钠镁铝硅磷\n硫氯氩钾钙"
text_area = label.Label(font,text=text,color=0x00FF00,x=10,y=10)

text_group.append(text_area)
display.show(text_group)

while True:
    pass

此段代码中导入了一个新的模块bitmap_font,通过这个模块可以将添加进来的字库文件加载进来并进一步使用。现象如下:

 

任务2:网络功能使用

任务要求:完成网络功能的使用,能够创建热点和连接到WiFi

根据官方提供的文档https://learn.adafruit.com/adafruit-esp32-s3-tft-feather/circuitpython-internet-test,可以使用板子连接到附近的WiFi,此种状态下,板子作为station连接附件的AP。根据Circuitpython的内嵌WiFi模块的文档https://docs.circuitpython.org/en/8.2.x/shared-bindings/wifi/index.html,可以将板子设为AP模式,等待附件的设备连接。具体代码如下:

import board
import time
import digitalio
import wifi
import os
import ipaddress

ssid = "Adafruit"
password = "12344321"

led = digitalio.DigitalInOut(board.LED)
led.direction = digitalio.Direction.OUTPUT

button = digitalio.DigitalInOut(board.BUTTON)
button.switch_to_input(pull=digitalio.Pull.UP)
button_count = 0

def AP_Mode(status):
    if status:
        print("ESP32-S3 AP Mode Open")
        print(f"My AP MAC address: {[hex(i) for i in wifi.radio.mac_address_ap]}")
        #wifi.radio.set_ipv4_address_ap
        wifi.radio.start_ap(ssid,password)
        if wifi.radio.ap_active:
            print("ap_active")
        else:
            print("restart")
    else:
        print("ESP32-S3 AP Mode Close")
        wifi.radio.stop_ap()

def Station_Mode(status):
    if status:
        print("ESP32-S3 Station Mode Open")
        print(f"My MAC address: {[hex(i) for i in wifi.radio.mac_address]}")
        print("Available WiFi networks:")
        for network in wifi.radio.start_scanning_networks():
            print("\t%s\t\tRSSI: %d\tChannel: %d" % (str(network.ssid, "utf-8"),
                                                    network.rssi, network.channel))
        
        wifi.radio.stop_scanning_networks()
        
        print(f"Connecting to {os.getenv('CIRCUITPY_WIFI_SSID')}")
        wifi.radio.connect(os.getenv("CIRCUITPY_WIFI_SSID"), os.getenv("CIRCUITPY_WIFI_PASSWORD"))
        print(f"Connected to {os.getenv('CIRCUITPY_WIFI_SSID')}")
        print(f"My IP address: {wifi.radio.ipv4_address}")
        
        ping_ip = ipaddress.IPv4Address("8.8.8.8")
        ping = wifi.radio.ping(ip=ping_ip)
        # retry once if timed out
        if ping is None:
            ping = wifi.radio.ping(ip=ping_ip)
            
        if ping is None:
            print("Couldn't ping 'google.com' successfully")
        else:
            # convert s to ms
            print(f"Pinging 'google.com' took: {ping * 1000} ms")
            
        if wifi.radio.connected:
            print("station connected")
        else:
            print("restart")
            
    else:
        print("ESP32-S3 Station Mode Close")
        wifi.radio.stop_station()
        

while True:
    if not button.value:
        button_count += 1
        if button_count%2:
            AP_Mode(False)
            Station_Mode(True)
        else:
            Station_Mode(False)
            AP_Mode(True)
    else:
        a=1

    led.value = not led.value
    time.sleep(0.5)

当第一次按下按键时,会先关闭板子的AP模式,启动板子的station模式,连接附近的WiFi;当第二次按下按键时,会先关闭板子的station模式,启动板子的AP模式,等待附件的设备连接。现象如下:

 

 

任务3:控制WS2812B

任务要求:使用按键控制板载Neopixel LED的显示和颜色切换

使用按键进行计数,当第一次按下时,控制Neopixel LED显示红色,第二次显示绿色,第三次显示蓝色,依次是红绿蓝青紫黄白黑,当按键的值超过8之后,使用random模块生成随机数控制Neopixel LED显示的颜色,同时用random模块控制Neopixel LED显示的亮度。具体代码如下:

import board
import digitalio
import time
import random
import neopixel

led = digitalio.DigitalInOut(board.LED)
led.direction = digitalio.Direction.OUTPUT

button = digitalio.DigitalInOut(board.BUTTON)
button.switch_to_input(pull=digitalio.Pull.UP)
button_count = 0

pixel = neopixel.NeoPixel(board.NEOPIXEL,1)

pixel.brightness = 0.3

while True:
    if not button.value:
        button_count += 1
        pixel.brightness = random.random()
        if button_count == 1:
            pixel.fill((255,0,0))
        elif button_count == 2:
            pixel.fill((0,255,0))
        elif button_count == 3:
            pixel.fill((0,0,255))
        elif button_count == 4:
            pixel.fill((0,255,255))
        elif button_count == 5:
            pixel.fill((255,0,255))
        elif button_count == 6:
            pixel.fill((255,255,0))
        elif button_count == 7:
            pixel.fill((255,255,255))
        elif button_count == 8:
            pixel.fill((0,0,0))
        else:
            pixel.fill((random.randint(0,255),random.randint(0,255),random.randint(0,255)))
    else:
        a=1
    
    led.value = not led.value
    time.sleep(0.5)

现象如图:

 

任务4:WS2812B效果控制

任务要求:完成一个Neopixel(12灯珠或以上)控制器,通过按键和屏幕切换显示效果

通过按键控制12灯珠Neopixel显示不同的灯效,并在TFT屏幕上做相应的显示。具体代码如下:

import time
import board
import digitalio
import neopixel
import terminalio
import displayio
from adafruit_display_text import label

button = digitalio.DigitalInOut(board.BUTTON)
button.switch_to_input(pull=digitalio.Pull.UP)
button_count =0

BORDER = 20
FONTSCALE = 2
BACKGROUND_COLOR = 0x00FF00  # Bright Green
FOREGROUND_COLOR = 0xAA0088  # Purple
RED_COLOR = 0xFF0000
GREEN_COLOR = 0x00FF00
BLUE_COLOR = 0x0000FF


TEXT_COLOR = 0xFFFF00

display = board.DISPLAY

# On CircuitPlayground Express, and boards with built in status NeoPixel -> board.NEOPIXEL
# Otherwise choose an open pin connected to the Data In of the NeoPixel strip, i.e. board.D1
pixel_pin = board.D5

# The number of NeoPixels
num_pixels = 12

# The order of the pixel colors - RGB or GRB. Some NeoPixels have red and green reversed!
# For RGBW NeoPixels, simply change the ORDER to RGBW or GRBW.
ORDER = neopixel.GRB

pixels = neopixel.NeoPixel(
    pixel_pin, num_pixels, brightness=0.2, auto_write=False, pixel_order=ORDER
)


def wheel(pos):
    # Input a value 0 to 255 to get a color value.
    # The colours are a transition r - g - b - back to r.
    if pos < 0 or pos > 255:
        r = g = b = 0
    elif pos < 85:
        r = int(pos * 3)
        g = int(255 - pos * 3)
        b = 0
    elif pos < 170:
        pos -= 85
        r = int(255 - pos * 3)
        g = 0
        b = int(pos * 3)
    else:
        pos -= 170
        r = 0
        g = int(pos * 3)
        b = int(255 - pos * 3)
    return (r, g, b) if ORDER in (neopixel.RGB, neopixel.GRB) else (r, g, b, 0)


def rainbow_cycle(wait):
    for j in range(255):
        for i in range(num_pixels):
            pixel_index = (i * 256 // num_pixels) + j
            pixels[i] = wheel(pixel_index & 255)
        pixels.show()
        time.sleep(wait)

def TFT_show(color,color_text):
    splash = displayio.Group()
    display.show(splash)
    
    inner_bitmap = displayio.Bitmap(display.width - BORDER * 2, display.height - BORDER * 2, 1)
    inner_palette = displayio.Palette(1)
    inner_palette[0] = color
    inner_sprite = displayio.TileGrid(inner_bitmap, pixel_shader=inner_palette, x=BORDER, y=BORDER)
    splash.append(inner_sprite)
    
    text = color_text
    text_area = label.Label(terminalio.FONT, text=text, color=TEXT_COLOR)
    text_width = text_area.bounding_box[2] * FONTSCALE
    text_group = displayio.Group(scale=FONTSCALE,x=display.width // 2 - text_width // 2,
                                                   y=display.height // 2,)
    text_group.append(text_area)  # Subgroup for text scaling
    splash.append(text_group)

def switch_color_show(count):
    if count == 1:
        pixels.fill((255, 0, 0))
        pixels.show()
        TFT_show(RED_COLOR,"Red")
    elif count == 2:
        pixels.fill((0, 255, 0))
        pixels.show()
        TFT_show(GREEN_COLOR,"Green")
    elif count == 3:
        pixels.fill((0, 0, 255))
        pixels.show()
        TFT_show(BLUE_COLOR,"Blue")
    elif count == 4:
        rainbow_cycle(0.001)  # rainbow cycle with 1ms delay per step
    #else:
        

while True:
    if not button.value:
        time.sleep(0.2)
        button_count += 1
        print("button_count %d" %button_count)
        switch_color_show(button_count)
        if button_count == 4:
            button_count = 0
    else:
        pass
        

 

心得体会

从第一期的RP2040的micropython,到这期ESP32-S3的circuitpython,得捷和eeworld真的有用心在帮大家打基础,这些MCU都是市面上非常常见的,在这些上面可以学习到很多基于MCU的微型python语言,非常棒,期待下期的新板卡!

 

内容三、可编译下载的代码

task.zip (3.17 KB, 下载次数: 1)

 

 

最新回复

效果不错       详情 回复 发表于 2023-10-16 08:13
点赞 关注
 
 

回复
举报

6562

帖子

9

TA的资源

版主

沙发
 

效果不错    

个人签名

在爱好的道路上不断前进,在生活的迷雾中播撒光引

 
 
 

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

随便看看
查找数据手册?

EEWorld Datasheet 技术支持

相关文章 更多>>
关闭
站长推荐上一条 1/6 下一条

 
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
快速回复 返回顶部 返回列表