micropython开发与实战阅读笔记

news2024/12/23 9:03:45

对本文的一些说明
本文来源于阅读《MicroPython开发与实战》时所做的笔记,这本书不是很厚,所以内容也不是很全面,但作为一个入门工具书还是够的,再由于本人不是这方面的大佬,也不是这个专业的,所做的笔记也必然不是很全面,这仅是我本人阅读笔记,放出来希望能帮助到一些刚入门的ESP32学者。在这里插入图片描述

本人使用的开发板是合宙esp32c3,书籍使用的是NodeMCU-32S,大部分只是引脚不同和资源个数不同,资源的使用方法是相通的,我对部分代码参数进行调整以适配合宙esp32c3,如果有使用其他型号开发板的学者,也可以很容易复现代码。
书中部分代码我在开发板上无法运行成功,对此类代码已做标注

书籍情况介绍,本书共262页
1~12MPy介绍及Python安装,占比4.6%,累计4.6%
13~125讲解Python语法,占比43.1%,累计47.7%
126~172讲通过MPy使用WIFI,PWM,ADC,定时器,UART,SPI(ADC和SPI仅作必要介绍),占比17.94%,累计65.65%
后面讲的MQTT连接阿里云,MPy for STM32F4,暂未看到,先不写。

  • 初始环境配置
  1. 下载对应的micropython固件
  2. pip install esptool
  3. 清空flash: esptool.py --chip esp32c3 --port COM? erase_flash
  4. 烧写固件:esptool.py --chip esp32c3 --port COM? --baud 460800 write_flash -z 0x0 esp32c3-xxx.bin
  5. 写代码,注意utf-8编码,main.py
  6. cp ./main.py /pyboard/
  7. pip install rshell,安装完成后rshell --buffer-size 512 --editor D:\programfiles\notepad++\notepad++.exe -p COM?
  8. repl并重启开发板,可以看到输出信息
    由于每次都要重新输入rshell的一长串命令,十分不便,所以想写成一个bat脚本,但是由于从未接触过bat命令,从网上找了不少,又结合AI,勉强拼凑出一份能用的脚本
    conn.bat文件内容,该文件会调用下面的getCOM.bat文件
@echo off  
chcp 65001
call getCOM.bat
setlocal EnableDelayedExpansion  
  
:: 获取用户输入的COM端口号  
set /p "port=请输入COM端口号: "  
  
:: 移除用户输入中可能的前导"COM"字符串  
set "COM_PORT=!port:COM=!"  
  
:: 如果用户没有输入"COM",则添加前缀  
if not "!COM_PORT:~0,3!"=="COM" set "COM_PORT=COM!COM_PORT!"  
  
:: 调用rshell命令,使用用户输入的COM端口  
rshell --buffer-size 512 --editor "D:\programfiles\notepad++\notepad++.exe" -p !COM_PORT!  

goto :EOF

getCOM.bat内容

@echo off
setlocal

:: wmic /format:list strips trailing spaces (at least for path win32_pnpentity)
for /f "tokens=1* delims==" %%I in ('wmic path win32_pnpentity get caption /format:list ^| find "COM"') do (
    call :setCOM "%%~J"
)

:: display all _COM* variables
set _COM

:: end main batch
goto :EOF

:setCOM <WMIC_output_line>
:: sets _COM#=line
setlocal
set "str=%~1"
set "num=%str:*(COM=%"
set "num=%num:)=%"
set str=%str:(COM=&rem.%
endlocal & set "_COM%num%=%str%"
goto :EOF

现象截图
在这里插入图片描述
在这里插入图片描述
如果我有任何错误及改进意见,欢迎指出!

esp32网络基础使用

import network

sta_if = network.WLAN(network.STA_IF)    #STA模式
ap_if = network.WLAN(network.AP_IF)     #AP模式

使用以下命令检查接口是否有效

sta_if.active()
ap_if.active()

连接WIFI

#首先激活station接口
sta_if.active(True)
#然后连接到网络
sta_if.connect("WIFI名","WIFI密码")

使用以下命令检查连接是否建立sta_if.isconnected()

查看IPsta_if.ifconfig()

开机自动连接WIFI

下面的函数可以自动运行并连接到WIFI网络,放入boot.py可以自启动

def  do_connect():
    import network
    sta_if = network.WLAN(network.STA_IF)
    if not sta_if.isconnected():
        print('connecting to network...')
        sta_if.active(True)
        sta_if.connect("WIFI名","WIFI密码")
        while not sta_if.isconnected():
            pass
    print('network config:', sta_ifconfig())

获取系统时间

import time
time.localtime()

此方法获取的并不是当前真正的时间,若需获取准确时间,可以用MPY的ntptime时间同步模块,从服务器校准时间

ntptime.settime(timezone = 8,server = 'ntp.ntsc.ac.cn')为默认参数,可以自己修改,目前感觉似乎没有参数

import time
import ntptime
print(f'同步前本地时间{str(time.localtime())}')
ntptime.settime()
print(f'同步后本地时间{str(time.localtime())}')

网上找的

import ntptime
def sync_ntp():
     ntptime.NTP_DELTA = 3155644800   # 可选 UTC+8偏移时间(秒),不设置就是UTC0
     ntptime.host = 'ntp1.aliyun.com'  # 可选,ntp服务器,默认是"pool.ntp.org"
     ntptime.settime()   # 修改设备时间,到这就已经设置好了

sync_ntp()

get请求

import urequests
a = urequests.get("http://www.baidu.com")
a.text

socket模块

socket模块的宏

名称含义
socket.AF_INET地址簇TCP/IP-IPV4
socket.AF_INET6地址簇TCP/IP-IPV6
socket.SOCK_STREAM套接字类型TCP流
socket.SOCK_DGRAM套接字类型UDP数据报
socket.SOCK_RAW套接字类型原始套接字
socket.SO_REUSEADDR套接字选项允许重用地址
socket.IPPROTO_TCPIP协议号TCP协议
socket.IPPROTO_UDPIP协议号UDP协议
socket.SOL_SOCKET套接字选项等级套接字选项

socket模块的API

1.socket.getaddrinfo(host, port)
将主机域名和端口转换为用于创建套接字的5元组序列
(family, type, proto, canonname, sockaddr)

>>> info = socket.getaddrinfo("172.0.0.1",80)
>>> info
[(2, 1, 0, '172.0.0.1', ('172.0.0.1', 80))]

2.socket.socket([af, type, proto])
创建套接字
af:地址,type:类型,proto:协议号
一般不指定proto

>>> s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
>>> print(s)
>>> print(s)
<socket>

3.socket.bind(address)
以列表或元组方式绑定地址和端口号
address:一个包含地址和端口号的元组或列表

addr = ("127.0.0.1", 10000)
s.bind(addr)

4.socket.listen([backlog])
监听套接字,使服务器能够接收连续
backlog:接收套接字的最大个数,有默认值

s.listen(100)

5.socket.accept()
阻塞接收连接请求,只能在绑定地址端口号和监听后调用,返回conn和address
返回值:conn:新的套接字对象,可以用来收发消息
address:连接到服务器的客户端地址

conn, address = s.accept()

6.socket.connect(address)
连接服务器
address:服务器地址和端口号的元组或列表

host = "192.168.3.147"
port = 100
s.connect((host, port))

7.socket.send(bytes)
发送数据,并返回发送的字节数。
bytes:bytes类型数据

s.send("hello, I am TCP Client")

8.socket.recv(bufsize)
接收数据,并返回接收到的数据对象
bufsize: 接收数据的最大字节数

data = conn.recv(1024)

9.socket.close()
关闭套接字

s.close()

利用socket下载网页数据

使用socket定义一个可以下载和打印URL的函数

# 目前似乎无法成功
import socket
def httpGet(url):
    _,_,host,path = url.split('/', 3)
    addr = socket.getaddrinfo(host, 80)[0][-1]
    s = socket.socket()
    s.connect(addr)
    s.send(bytes('GET /%s HTTP/1.0\r\nHost: %s\r\n\r\n' % (path, host), 'utf8'))
    while True:
        data = s.recv(100)
        if data:
            print(str(data, 'utf8'), end='')
        else:
            break
    s.close()

    # 函数使用
    httpGet('http://www.baidu.com/')

利用socket实现ESP32的网络通信

esp32与PC须在同一局域网内

电脑端代码

import socket
import _thread

def tcplink(conn, addr):
    print('addr:',addr)
    print('conn',conn)
    while 1:
        data = conn.recv(1024)
        #防止对面断线连接没关掉
        if not data:
            break
        print('msg:', str(data,"utf-8"))
    conn.close()

sock_tcp = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock_tcp.bind(('0.0.0.0', 6000))
sock_tcp.listen(100)
print('listening')
while 1:
    conn, addr = sock_tcp.accept()
    _thread.start_new_thread(tcplink, (conn, addr))

ESP32端代码

import socket
import _thread

sock_tcp = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock_tcp.connect(("电脑IP地址172.26.96.101", 6000))
sock_tcp.sendall(bytes("i am zzp!", "utf-8"))

硬件控制

Pin例程

from machine import Pin
D4 = Pin(12, Pin.OUT)
led.value([x])# 可读可写
led.on()
led.off()

延时

utime模块
utime.sleep(s)
utime.sleep_ms(ms)
utime.sleep_us(us)

import utime
utime.sleep_ms(500) #延时500ms

控制LED闪烁

import utime
from machine import Pin

D4 = Pin(12, Pin.OUT)
# 循环10次亮灭
for i in range(10):
    D4.value(1)
    utime.sleep_ms(500)
    D4.value(0)
    utime.sleep_ms(500)

PWM脉宽调制技术-呼吸灯

ESP32的占空比(duty)不是百分比而是一个分辨率,范围0~1023

from machine import Pin, PWM
D4 = Pin(2, Pin.OUT)
# 把Pin对象传入PWM构造器
D4 = PWM(D4) #也可以直接初始化,D4 = PWM(D4, freq=1000, duty=500)

方法

  1. PWM.init(freq, duty)
  2. PWM.freq([freq_val]) 可读可写
  3. PWM.duty([duty_val]) 可读可写
  4. PWM.deinit() 释放PWM对象

PWM控制LED亮度

把下列代码保存为pwm_led.py

from machine import Pin, PWM
class PWM_LED:
    def __init__(self,pinNum,freq=1000):
        pin = Pin(pinNum,Pin.OUT)
        self.pwm = PWM(pin,freq=freq)
    def change_duty(self,duty):
        self.pwm.duty(duty)
    def deinit(self):
        self.pwm.deinit()

呼吸灯

import machine, utime, math
from pwm_led import *
from machine import Pin

pwm_led = PWM_LED(12)
def pulse(switch, period, gears):
    # 呼吸灯核心代码
    # 借用sin正弦函数,将PWM范围控制在23~1023
    # switch开关对象
    # period呼吸一次的周期,单位ms
    #gears呼吸过程经历的亮度档位数
    for i in range(2*gears):
        switch.change_duty(int(math.sin(i/gears*math.pi)*500)+523)
        # 延时
        utime.sleep_ms(int(period/(2*gears)))

# 呼吸10次
for i in range(10):
    pulse(pwm_led, 2000, 100)
# 释放资源
pwm_led.deinit()

ADC例程

构造对象

classmachine.ADC(pin)
创建与设定引脚关联的ADC对象。用户可以读取该引脚上的模拟值
Pin:ADC在专用因脚伤可以用

from machine import ADC, Pin
adc = ADC(Pin(0))

方法

  • ADC.atten(db)设置ADC衰减量,即设置输入范围,未设置默认为1V
宏定义衰减量/db数值满量程电压
ADC.ATTN_0DB001
ADC.ATTN_2_5DB2.511.5
ADC.ATTN_6DB622
ADC.ATTN_11DB1133.3
  • ADC.width(bit)设置分辨率
宏定义数值满量程
ADC.WIDTH_9BIT0511
ADC.WIDTH_10BIT11023
ADC.WIDTH_11BIT22047
ADC.WIDTH_12BIT34095
  • ADC.read()读取ADC值并返回读取结果

RTC例程

RTC是独立的时钟,可以跟踪日期和时间

构造对象

classmachine.RTC()创建RTC对象

初始化RTC时间

RTC.init([datetimetuple])
元组(年,月,日,周(0~6),时,分,秒,毫秒)
rtc.init((2024, 4, 17, 2, 15, 50, 40, 0))

查看RTC时间

RTC.init([datetimetuple])
未给参数则读取时间

缺陷:每过7h45min就会有秒级别的误差,所以建议每隔7小时校准一次时间

Timer例程

构造对象

  • class machine.Timer(id,...)构造给定id的新计时器对象,id为任意正数

初始化定时器

  • Timer.init(*, mode=Timer.PERIODIC, period=-1,callback=None)
    mode是定时器模式之一
    • Timer.ONE_SHOT:计时器运行一次
    • Timer.PERIODIC:计时器运行多次

period:定时时间,0~3 435 973 836ms
callback:回调函数
示例代码:tim.init(mode=Timer.ONE_SHOT, period=1000, callback=lambda t:print('haha))

释放定时器资源

Timer.deinit()取消定时器初始化,停止计时器,并禁用计时器外围设备

定时器控制LED闪烁

示例代码

from machine import Timer, Pin
import utime
def toggle_led(led_pin):
    # LED翻转
    led_pin.value(not led_pin.value())
def led_blink_timed(timer, led_pin, freq):
    """
    led按照特定的频率闪烁
    LED闪烁周期 = 1000ms/2
    状态变换时间间隔(period) = LED闪烁周期/2
    """
    # 计算状态变换时间间隔
    period = int(1000/freq/2)
    #初始化定时器
    # 这里回调是使用了lambda表达式,因为回调函数需要传入led_pin
    timer.init(period=period, mode=Timer.PERIODIC, callback=lambda t:toggle_led(led_pin))
# 声明D4作为LED引脚
led_pin = Pin(12, Pin.OUT)
timer = Timer(0) # 创建定时器对象,实测1不好使
led_blink_timed(timer, led_pin, freq=20)

串口UART例程

合宙esp32c3
UART0_RX:08 UART0_TX:09
UART1_RX:01 UAER1_TX:00

构造对象

class machine.UART(id, baudrate, bits, parity, rx, tx, stop, timeout)
id:串口编号
bandrate:波特率
bits:数据位,默认8,可选7,9
parity:校验方式,默认None不校验,0偶校验,1奇校验
rx:接收口的GPIO编号
tx:发送口的GPIO编号
stop:停止位,默认1,可选2
timeout:超时时间,0~2 147 483 647

>>> from machine import UART
>>> u = UART(1)
>>> print(u)
UART(1, baudrate=115211, bits=8, parity=None, stop=1, tx=10, rx=9, rts=-1, cts=-1, txbuf=256, rxbuf=256, timeout=0, timeout_char=0)

方法

  • UART.read([nbytes]):读字符,参数可选,为最多读取字节数,否则尽可能读取多的数据
    返回值:包含读入的字节的字节对象,超时返回None
  • UART.readinto(buf[, nbytes]):将字节读入buf.
    返回读取并写入到buf的字节数,超时返回None
  • UART.readline():读一行,读到换行符结束,超时返回None
  • UART.write(buf):串口发送数据,返回发送的字节数,超时返回None
  • UART.any():检查是否有可读的数据,返回可读数据长度

ESP32串口通信——字符串自收发实验

将UART1的TX和RX连接起来,在合宙esp32c3中就是IO00和IO01连接

from machine import UART, Timer
import select, time

# 创建一个UART对象,将引脚0和引脚1相连
uart = UART(1, baudrate=9600, tx=01, rx=00)
# 创建一个Timer,使用中断来轮询串口是否有数据可读
timer = Timer(0)
timer.init(period=50,mode=Timer.PERIODIC, callback=lambda t:read_uart(uart))

def read_uart(uart):
    if uart.any():
        print('received:'+uart.read().decode()+'\n')

if __name__ == '__main__':
    try:
        for i in range(10):
            uart.write(input('send:'))
            time.sleep_ms(50)
    except:
        timer.deinit()

SPI例程

构造对象

硬件SPI

HSPI后遭,代码如下

>>> from machine import SPI
>>> hspi = SPI(1)
>>> print(hspi)
SPI(id=1, baudrate=500000, polarity=0, phase=0, bits=8, firstbit=0, sck=6, mosi=7, miso=2)
软件SPI

方法1:类构造

  • SPI(baudrate, polarity, phase, bits, firstbit, sck, mosi, miso)
    baudrate:SCK时钟频率,范围0~0x0FFFFFFF(2 147 483 647)
    polarity:极性,分为以下两种情况:
    • 0:空闲电平:底
    • 1:空闲电平:高
      phase:相位,分为以下两种情况:
    • 0:在第一时钟沿采集数据
    • 1:在第二时钟沿采集数据
      bits:数据位
      firstbit:从地位向高位发还是从高位往低位发
      sck:时钟引脚
      mosi:主设备出,从设备入引脚
      miso:主设备入,从设备出引脚
from machine import SPI, Pin
spi = SPI(baudrate=115200, polarity=1, phase=0, sck=Pin(17), mosi=Pin(27), miso=Pin(18))

方法2:使用init构造

  • SPI.init(baudrate, polarity, phase, sck, mosi, miso)
    初始化SPI总线
from machine import SPI, Pin
spi = SPI.init(baudrate=115200, polarity=1, phase=0, sck=Pin(17), mosi=Pin(27), miso=Pin(18))

方法

  • SPI.deinit():关闭SPI总线
  • SPI.read(nbytes, write=0x00):读取由nbytes指定的字节数,同时连续写入由write给定的单字节
    (Read a number of bytes specified by nbytes while continuously writing the single byte given by write. Returns a bytes object with the data that was read.)
  • SPI.readinto(buf, write=0x00):读入由buf指定的缓冲区,同时不断写入由write给定的单字节。返回读取的字节数
  • SPI.write(buf):写入buf中的字节,返回写入的字节数
  • SPI.write_readinto(write_buf, read_buf)
    从write_buf中写入字节,同时读入read_buf中。缓冲区可以是相同的,也可以不同,但是两个缓冲区都必须有相同长度,
    返回写入的字节数

MQTT与阿里云平台实战-未写

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1602488.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

C++ UML 类图介绍与设计

1 类图概述 UML(Unified Modeling Language)&#xff0c;即统一建模语言&#xff0c;是用来设计软件的可视化建模语言。它的特点是简单、统一、图形化、能表达软件设计中的动态与静态信息。UML从目标系统的不同角度出发&#xff0c;定义了用例图、类图、对象图、状态图、活动图…

C++ stl容器list的底层模拟实现

目录 前言&#xff1a; 1.创建节点 2.普通迭代器的封装 3.反向迭代器的封装 为什么要对正向迭代器进行封装&#xff1f; 4.const迭代器 5.构造函数 6.拷贝构造 7.赋值重载 8.insert 9.erase 10.析构 11.头插头删&#xff0c;尾插尾删 12.完整代码简单测试 总结&…

【艾体宝方案】智驾未来:高性能实时数据库,车企的数据分析变革!

近年来&#xff0c;汽车行业持续朝向互联互通以及自动化方向的演进&#xff0c;无论是在优化制造流程、提升车辆安全与性能&#xff0c;还是提供定制化客户体验方面&#xff0c;汽车行业的都未来牢牢根植于其有效处理和利用数据的能力。 一、汽车行业面临的挑战 &#xff08;…

group by 多字段分组查询和 order by

直接看试验步骤就知道了. 表 一.单列group by 执行单列group by语句 SELECT name, COUNT(1) count FROM nomol GROUP BY name 执行结果 我们发现他把原始表分为了两个小组&#xff0c;狗狗小组和猫猫小组。从这可以看出分组查询就是把相同的数据分到一个组 . 二.多列group …

在做程序员的道路上,你掌握了什么概念或技术使你感觉自我提升突飞猛进?

不要扯那些假大空或是看似高级的技术概念&#xff0c;真正让我感觉到自我提升突飞猛进的是摒弃了码农思维。 先别开骂&#xff0c;我指的码农思维是把自己当代码工人的码农思维。其实程序员本质上就是打工人&#xff0c;无论是掌握了高新技术的程序员&#xff0c;还是在底层摸爬…

MT3026 砍玉米

样例1&#xff1a; 输入&#xff1a; 6 1 3 4 2 5 1 7 8 19 10 30 2 输出&#xff1a; 6 其中1<n<10^5,1<xi,hi<10^9 思路&#xff1a;贪心&#xff1a;从左到右或者从右到左依次判断每一棵玉米是否可以倒下 &#xff08;以从左到右为例&#xff1a;先往左倒&…

Windows版Apache 2.4.59解压直用(免安装-绿色-项目打包直接使用)

windows下Apache分类 Apache分为 安装版和解压版 安装版: 安装方便&#xff0c;下一步------下一步就OK了&#xff0c;但重装系统更换环境又要重新来一遍&#xff0c;会特别麻烦 解压版&#xff08;推荐&#xff09;&#xff1a; 这种方式&#xff08;项目打包特别方便&#x…

c++修炼之路之vector--标准库中的vector

目录 前言 一&#xff1a;vector的简介 二&#xff1a;vector的常用接口 1.构造函数 2.迭代器访问遍历数组 3.容量接口函数 4.增删查改接口函数 三&#xff1a;vector常用接口的全部代码 接下来的日子会顺顺利利&#xff0c;万事胜意&#xff0c;生活明朗----------…

钉钉OA审批评论接口,如何@ 人并发送通知

钉钉OA审批评论接口&#xff0c;如何 人并发送通 问题描述&#xff1a; 相关接口&#xff1a;https://oapi.dingtalk.com/topapi/process/instance/comment/add 我希望在钉钉oa审批流程中&#xff0c;添加评论的同时通过“”或者其他方式提醒流程发起人去跟进审批工作。 但我…

比起本地渲染,网渲的优势在哪里?渲染100邀请码1a12

网渲的应用很广泛&#xff0c;在建筑设计和室内装修等行业都能看到它的身影&#xff0c;比起本地渲染&#xff0c;它有以下几个优势。 1、资源充足 网渲平台的资源充足&#xff0c;会根据渲染作业的规模和复杂度自动扩展或缩减分配&#xff0c;以达到动态调节的目的&#xff0c…

小米汽车SU7隐藏款曝光!新配色和透明车身亮了 coreldraw教程入门零基础 coreldraw下载 coreldraw2024

刘强东说&#xff0c;论营销&#xff0c;没有任何人能比得过小米。 小米SU7发布会24小时&#xff0c;下定量就超过了蔚来汽车2023年四季度的交付量。 ▲雷军发布的小米SU7 24小时订单量 小米SU7发布会后五天&#xff0c;雷军在北京亦庄工厂亲自交付了第一批创世版本小米SU7&a…

【性能测试】接口测试各知识第4篇:Jmeter 八大元件及执行顺序,学习目标【附代码文档】

接口测试完整教程&#xff08;附代码资料&#xff09;主要内容讲述&#xff1a;接口测试&#xff0c;学习目标学习目标,2. 接口测试课程大纲,3. 接口学完样品,4. 学完课程,学到什么,5. 参考:,1. 理解接口的概念。学习目标&#xff0c;RESTFUL1. 理解接口的概念,2.什么是接口测试…

《综合品酒师》培训刷新纪录:FENDI CLUB精酿啤酒点亮行业里程碑

导语&#xff1a;在璀璨的品酒文化星空中&#xff0c;一颗新星正悄然升起&#xff0c;它就是云仓酒庄。近日&#xff0c;云仓酒庄成功举办的《综合品酒师》培训活动不仅刷新了大世界基尼斯纪录&#xff0c;更以其与众不同的FENDI CLUB精酿啤酒品鉴课程引起了品酒新风尚。这一盛…

TCP的一些功能详述

文章制作不易&#xff0c;望各位大佬多多点赞&#xff0c;球球各位啦&#xff01;&#xff01;&#xff01;&#xff01; 目录 1.TCP的简介 2.TCP协议中部分数据的理解 1.端口号 2.序列号 3.四位首部长度 4.6位保留位 5. 16位校验和 6.数据&#xff08;TCP的载荷&#…

upload-labs第九十关

第九关 $is_upload false; $msg null; if (isset($_POST[submit])) {if (file_exists(UPLOAD_PATH)) {$deny_ext array(".php",".php5",".php4",".php3",".php2",".html",".htm",".phtml"…

HarmonyOS Next 悬浮窗拖拽和吸附动画

介绍 本示例使用position绝对定位实现应用内悬浮窗&#xff0c;并且通过animateTo结合curves动画曲线实现悬浮窗拖拽跟手和松手吸附边缘的弹性动画效果。 效果图预览 使用说明 按住悬浮窗可以拖拽&#xff0c;松开后悬浮窗自动靠左或靠右&#xff0c;如果悬浮窗超出内容区上…

【C++】深度解析--拷贝构造函数(从0开始,详解浅拷贝到深拷贝,小白一看就懂!!!)

目录 一、前言 二、拷贝构造函数 &#x1f34e;概念解析 &#x1f95d;特性解析 &#x1f4a6;为什么拷贝构造函数使用传值方式会引发无穷递归调用&#xff1f; &#x1f4a6;为什么拷贝构造函数的形参中要加入 const 修饰 &#x1f4a6;若未显式定义&#xff0c;编译器会生…

c语言,单链表的实现----------有全代码!!!!

1.单链表的定义和结构 单链表是一种链式的数据结构&#xff0c;它用一组不连续的储存单元存反线性表中的数据元素。链表中的数据是以节点的形式来表示的&#xff0c;节点和节点之间相互连接 一般来说节点有两部分组成 1.数据域 &#xff1a;数据域用来存储各种类型的数据&…

深入理解同步与异步编程及协程管理在Python中的应用

文章目录 1. 同步与异步函数的对比1.1 同步函数1.2 异步函数1.3 对比 2. 管理多个协程与异常处理2.1 并发执行多个协程2.2 错误处理2.3 任务取消 本文将探索Python中同步与异步编程的基本概念及其区别。还会详细介绍如何使用asyncio库来有效管理协程&#xff0c;包括任务的创建…

一文读懂uniapp中的tabBar底部导航

目录 1. 基本知识2. Demo 1. 基本知识 UniApp 中的 tabBar 是用来在应用程序底部显示可切换的选项卡的组件&#xff0c;通常用于实现底部导航栏 允许用户通过点击不同的选项卡来切换应用程序的不同页面或功能模块 其代码如下&#xff1a; "tabBar":{"color&q…