ESP32(MicroPython) 两轮差速五自由度机械臂小车

这次的项目在软件上没多少调整,但本人希望分享一下硬件上的经验。

小车使用两轮差速底盘,驱动轮在小车中间,前后都要万向轮。这种形式可以实现0转弯半径,但受万向轮及用于加高的铜柱的规格限制,两个万向轮难以调到相同高度。考虑铜柱规格,本人万向轮调到比后面的万向轮略高,这样在向前加速时也更稳定。底盘的底板和盖板均使用4mm亚克力板,强度足够。由于重量较轻,在机械臂未指向正前方时可能出现一边车轮抓地效果不好的情况,建议先调整机械臂再行进。

ESP32(MicroPython) 两轮差速五自由度机械臂小车_第1张图片

 

底盘采用闭环控制,由于对实时性要求高,不适合用同一块主控运行网页,因此使用另一块主控提供网页,并通过串口转发指令,此外还开启热点以便在户外连接。由于要给两块主控和两个编码器供电,对12v电池降压有较大压降,AMS1117不能满足需要,就改用性能更高的LM7805降压模块。由于专门的编码器电机驱动尚无标准化设计,性价比较低,本人使用杜邦线连接编码器电机的接口,电机驱动使用经典的L298N。由于搭载机械臂增大了负载,底盘的PID参数调到P=20、I=2,实测相应速度和稳定性良好。

ESP32(MicroPython) 两轮差速五自由度机械臂小车_第2张图片

 机械臂使用PCA9685进行驱动,舵机为MG996R,由于希望达到6v电压以充分发挥舵机性能,本人尝试了6v电池和使用LM7806对7.4v电池降压的方案,均不能正常运行。之后使用LM7805对7.4v电池降压输出到主控,并由主控输出5v电压到PCA9685,也不能正常运行。最后改用充电宝给主控供电并由主控输出5v电压到PCA9685,可以正常运行。出现这种情况可能是因为PCA9685对电压稳定性要求较高。由于MG996R舵机的线不够长,有3个舵机使用了舵机延长线。为了方便操作,控制机械臂的主控也连接到底盘上的主控发出的热点。本人测试过把这两部分程序合并,但不能正常加载网页,就分两块主控。

ESP32(MicroPython) 两轮差速五自由度机械臂小车_第3张图片

 相应程序

控制电机的ESP32

from machine import *
import time
from motos import *
import _thread
'''
底盘参数计算(最终结果保留3位有效数字)
(speed为编码器脉冲计数)
轮直径:0.065
轮周长:0.2041
每圈脉冲数:110
底盘周长:0.6908
底盘直径/每rad长:0.22
每次脉冲长度:0.001855
线速度:speed*10*0.001855=speed*0.0186
角速度:(speed1-speed2)*10*0.001855/0.22=(speed1-speed2)*0.0843
考虑丢步情况,大约只有63%的脉冲能被统计,因此公式改为:
线速度=speed/0.63*0.0186=speed*0.0295
角速度=(speed1-speed2)/0.63*0.0843=(speed1-speed2)*0.134
每旋转1度(一边轮静止,另一边旋转)所需脉冲数=0.22*2*3.14/360/0.00186*0.63=1.30
每行驶1米所需脉冲数:1/0.001855*0.63=340
'''
# 编码器初始化
pin17 = Pin(17, Pin.IN)
pin5 = Pin(5, Pin.IN)   
encoder1 = encoder1(pin5, pin17, 0)   # 参数(编码器A相引脚,编码器B相引脚,定时器序号)
pin19 = Pin(19, Pin.IN) 
pin18 = Pin(18, Pin.IN) 
encoder2 = encoder2(pin18, pin19, 2)

# 电机初始化
motor1=PWM(Pin(15),freq=1000,duty=0)
motor2=PWM(Pin(2),freq=1000,duty=0)
motor3=PWM(Pin(4),freq=1000,duty=0)
motor4=PWM(Pin(16),freq=1000,duty=0)
 
duty1=0
duty2=0
linear_velocity=0
angular_velocity=0
target1=0
target2=0
offset1=0
offset2=0
'''
distance=0
angle=0
target_distance=0
target_angle=0
flag=0
'''

def set_target(duty1,duty2):
    global linear_velocity
    global angular_velocity
    global target1
    global target2
    global target_distance
    global target_angle
    global flag
    while True:
        try:
            target=int(input("input"))
            ''' #控制底盘旋转一定角度并前进一定距离,实测不能正常运行,已弃用
            if target//1000>600: #前3位组成的数大于600时控制行驶距离和旋转角度
                target_distance=target%1000 #后三位为距离*100
                target_angle=target//1000-800 #前三位为旋转角度+800,角度为正时右转
                target_angle=round(target_angle*1.3)
                target_distance=round(target_distance*0.34)
                print(target_angle,target_distance)
                flag=1
                target=0
            elif target>0: #前3位组成的数小于600时控制线速度和角速度
            '''
            linear_velocity=target%1000-400 #前三位为角速度*100+400,角速度为正时右转,后三位为线速度*100+400
            angular_velocity=target//1000-400 #换算时数字放大1000倍,除法运算后结果不用缩小
            target_speed=linear_velocity/2.95 #计算每周期目标脉冲数
            target_offset=angular_velocity/26.8 #计算每周期目标脉冲数差并换算为每边车轮速度与平均速度的差
            target1=round(target_speed+target_offset) #左轮目标每周期脉冲数
            target2=round(target_speed-target_offset) #右轮目标每周期脉冲数
            target=0
        except:
            pass
_thread.start_new_thread(set_target, (duty1, duty2))

while True:
    speed1 = encoder1.read() #编码器读数
    speed2 = encoder2.read()
    Offset1=offset1 #记录上一次偏差
    Offset2=offset2
    offset1=target1-speed1 
    offset2=target2-speed2
    adujstment1=offset1*20-Offset1*18 #PID控制:P=20,I=2
    adujstment2=offset2*20-Offset2*18
    duty1+=adujstment1
    duty2+=adujstment2
    ''' #控制底盘旋转一定角度并前进一定距离,实测不能正常运行,已弃用
    if flag==1: #指定角度转向
        print(flag,angle)
        if 0target_angle-angle>-10:
            target1=0
            target2=0
            flag=2
            angle=0
            target_angle=0
        if target_angle>0: #右转
            target1=20
            target2=0
            angle+=speed1
        if target_angle<0: #左转
            target1=0
            target2=20
            angle+=speed2
    if flag==2: #指定距离直行
        print(flag,distance)
        if target_distance-distance>400:
            target1=100
            target2=100
        elif target_distance-distance>100:
            target1=25
            target2=25
        elif target_distance-distance>40:
            target1=10
            target2=10
        elif target_distance-distance<15:
            target1=0
            target2=0
            flag=0
            distance=0
            target_distance=0
        distance+=speed1
        '''
    if target1<0: #由于实测发现电机反向时不能正常测速,这部分改为开环控制
        duty1=10*target1
    if target2<0:
        duty2=10*target2 
    if duty1<-1023:
        duty1=-1023
    if duty1>1023:
        duty1=1023
    if duty2<-1023:
        duty2=-1023
    if duty2>1023:
        duty2=1023
    if duty1>0:
       motor1.duty(duty1)
       motor2.duty(0)
    if duty1<0:
       motor1.duty(0) 
       motor2.duty(-duty1)
    if duty2>0:
       motor3.duty(duty2)
       motor4.duty(0)
    if duty2<0:
       motor3.duty(0) 
       motor4.duty(-duty2)   
    time.sleep(0.1)

发出热点的ESP32C3

#导入Pin模块
from machine import Pin
import time
from machine import PWM
import network
import socket

#定义LED控制对象
led1=Pin(6,Pin.OUT,Pin.PULL_DOWN)
 
duty=0
speed=0
turn=0
angular=400
linear=400

#WIFI连接
def wifi_connect():
    ap = network.WLAN(network.AP_IF)  # 指定用ap模式
    ap.active(True)                   # 启用wifi前需要先激活接口
    ap.config(essid="ESP32_Motor_Control")      # 设置热点名称
    ap.config(authmode=0)  # 设置认证模式
    return True

#网页数据
def web_page():
    global a1
    global a2
    global a3
    global a4
  
    html = """

  
  
  


  

ESP32 Motor Control

linear: """ + str(speed) + """

angular: """ + str(turn) + """

""" return html #程序入口 if __name__=="__main__": wifi_connect() #SOCK_STREAM表示的是TCP协议,SOCK_DGRAM表示的是UDP协议 my_socket=socket.socket(socket.AF_INET, socket.SOCK_STREAM) #创建socket连接 # 将socket对象绑定ip地址和端口号 my_socket.bind(('', 80)) # 相当于电话的开机 括号里的参数表示可以同时接收5个请求 my_socket.listen(5) while True: try: # 进入监听状态,等待别人链接过来,有两个返回值, #一个是对方的socket对象,一个是对方的ip以及端口 client, addr = my_socket.accept() # recv表示接收,括号里是最大接收字节 request = client.recv(1024) request = str(request) w10 = request.find('/?w10') w11 = request.find('/?w11') w12 = request.find('/?w12') w13 = request.find('/?w13') w14 = request.find('/?w14') w15 = request.find('/?w15') w16 = request.find('/?w16') w17 = request.find('/?w17') w18 = request.find('/?w18') w19 = request.find('/?w19') w1a = request.find('/?w1a') w1b = request.find('/?w1b') w1c = request.find('/?w1c') w1d = request.find('/?w1d') w1e = request.find('/?w1e') w1f = request.find('/?w1f') w1g = request.find('/?w1g') w1h = request.find('/?w1h') w1i = request.find('/?w1i') w1j = request.find('/?w1j') w1k = request.find('/?w1k') w1l = request.find('/?w1l') w1m = request.find('/?w1m') w1n = request.find('/?w1n') w1o = request.find('/?w1o') w20 = request.find('/?w20') w21 = request.find('/?w21') w22 = request.find('/?w22') w23 = request.find('/?w23') w24 = request.find('/?w24') w25 = request.find('/?w25') w26 = request.find('/?w26') w27 = request.find('/?w27') w28 = request.find('/?w28') w29 = request.find('/?w29') w2a = request.find('/?w2a') w2b = request.find('/?w2b') w2c = request.find('/?w2c') w2d = request.find('/?w2d') w2e = request.find('/?w2e') w2f = request.find('/?w2f') w2g = request.find('/?w2g') w2h = request.find('/?w2h') w2i = request.find('/?w2i') w2j = request.find('/?w2j') w2k = request.find('/?w2k') w2l = request.find('/?w2l') w2m = request.find('/?w2m') w2n = request.find('/?w2n') w2o = request.find('/?w2o') d1 = request.find('/?d1') d2 = request.find('/?d2') if d1 == 6: speed=0.00 linear=400 print(str(angular)+str(linear)) if d2 == 6: turn=0.00 angular=400 print(str(angular)+str(linear)) if w10 == 6: speed=-3.00 linear=100 print(str(angular)+str(linear)) if w11 == 6: speed=-2.75 linear=125 print(str(angular)+str(linear)) if w12 == 6: speed=-2.50 linear=150 print(str(angular)+str(linear)) if w13 == 6: speed=-2.25 linear=175 print(str(angular)+str(linear)) if w14 == 6: speed=-2.00 linear=200 print(str(angular)+str(linear)) if w15 == 6: speed=-1.75 linear=225 print(str(angular)+str(linear)) if w16 == 6: speed=-1.50 linear=250 print(str(angular)+str(linear)) if w17 == 6: speed=-1.25 linear=275 print(str(angular)+str(linear)) if w18 == 6: speed=-1.00 linear=300 print(str(angular)+str(linear)) if w19 == 6: speed=-0.75 linear=325 print(str(angular)+str(linear)) if w1a == 6: speed=-0.50 linear=350 print(str(angular)+str(linear)) if w1b == 6: speed=-0.25 linear=375 print(str(angular)+str(linear)) if w1c == 6: speed=0.00 linear=400 print(str(angular)+str(linear)) if w1d == 6: speed=0.25 linear=425 print(str(angular)+str(linear)) if w1e == 6: speed=0.50 linear=450 print(str(angular)+str(linear)) if w1f == 6: speed=0.75 linear=475 print(str(angular)+str(linear)) if w1g == 6: speed=1.00 linear=500 print(str(angular)+str(linear)) if w1h == 6: speed=1.25 linear=525 print(str(angular)+str(linear)) if w1i == 6: speed=1.50 linear=550 print(str(angular)+str(linear)) if w1j == 6: speed=1.75 linear=575 print(str(angular)+str(linear)) if w1k == 6: speed=2.00 linear=600 print(str(angular)+str(linear)) if w1l == 6: speed=2.25 linear=625 print(str(angular)+str(linear)) if w1m == 6: speed=2.50 linear=650 print(str(angular)+str(linear)) if w1n == 6: speed=2.75 linear=675 print(str(angular)+str(linear)) if w1o == 6: speed=3.00 linear=700 print(str(angular)+str(linear)) if w20 == 6: turn=-3.00 angular=100 print(str(angular)+str(linear)) if w21 == 6: turn=-2.75 angular=125 print(str(angular)+str(linear)) if w22 == 6: turn=-2.50 angular=150 print(str(angular)+str(linear)) if w23 == 6: turn=-2.25 angular=175 print(str(angular)+str(linear)) if w24 == 6: turn=-2.00 angular=200 print(str(angular)+str(linear)) if w25 == 6: turn=-1.75 angular=225 print(str(angular)+str(linear)) if w26 == 6: turn=-1.50 angular=250 print(str(angular)+str(linear)) if w27 == 6: turn=-1.25 angular=275 print(str(angular)+str(linear)) if w28 == 6: turn=-1.00 angular=300 print(str(angular)+str(linear)) if w29 == 6: turn=-0.75 angular=325 print(str(angular)+str(linear)) if w2a == 6: turn=-0.50 angular=350 print(str(angular)+str(linear)) if w2b == 6: turn=-0.25 angular=375 print(str(angular)+str(linear)) if w2c == 6: turn=0.00 angular=400 print(str(angular)+str(linear)) if w2d == 6: turn=0.25 angular=425 print(str(angular)+str(linear)) if w2e == 6: turn=0.50 angular=450 print(str(angular)+str(linear)) if w2f == 6: turn=0.75 angular=475 print(str(angular)+str(linear)) if w2g == 6: turn=1.00 angular=500 print(str(angular)+str(linear)) if w2h == 6: turn=1.25 angular=525 print(str(angular)+str(linear)) if w2i == 6: turn=1.50 angular=550 print(str(angular)+str(linear)) if w2j == 6: turn=1.75 angular=575 print(str(angular)+str(linear)) if w2k == 6: turn=2.00 angular=600 print(str(angular)+str(linear)) if w2l == 6: turn=2.25 angular=625 print(str(angular)+str(linear)) if w2m == 6: turn=2.50 angular=650 print(str(angular)+str(linear)) if w2n == 6: turn=2.75 angular=675 print(str(angular)+str(linear)) if w2o == 6: turn=3.00 angular=700 print(str(angular)+str(linear)) response = web_page() client.send('HTTP/1.1 200 OK\n') client.send('Content-Type: text/html\n') client.send('Connection: close\n\n') client.sendall(response) client.close() except: pass

控制机械臂的ESP32C3

#导入Pin模块
from machine import Pin
import time
from machine import SoftI2C
from servo import Servos
import network
import socket

#定义LED控制对象
led1=Pin(4,Pin.OUT,Pin.PULL_DOWN)
i2c=SoftI2C(sda=Pin(9),scl=Pin(8),freq=10000)
servos=Servos(i2c,address=0x40)

#连接的WIFI账号和密码
ssid = "ESP32_Motor_Control"
password=None
#舵机默认角度
servos.position(0,90)
servos.position(1,90)
servos.position(2,90)
servos.position(3,90)
servos.position(4,90)

#WIFI连接
def wifi_connect():
    wlan=network.WLAN(network.STA_IF)  #STA模式
    wlan.active(True)  #激活
    
    if not wlan.isconnected():
        print("conneting to network...")
        wlan.connect(ssid,password)  #输入 WIFI 账号密码
        
        while not wlan.isconnected():
            led1.value(1)
            time.sleep_ms(300)
            led1.value(0)
            time.sleep_ms(300)
        led1.value(0)
        return False
    else:
        led1.value(0)
        print("network information:", wlan.ifconfig())
        return True

a0=90
a1=90
a2=90
a3=90
a4=90
#网页数据
def web_page():
    global a0
    global a1
    global a2
    global a3
    global a4
  
    html = """

  
  
  


  

ESP32 Servo Control

Servo0: """ + str(a0) + """

Servo1: """ + str(a1) + """

Servo2: """ + str(a2) + """

Servo3: """ + str(a3) + """

Servo4: """ + str(a4) + """

""" return html #程序入口 if __name__=="__main__": wifi_connect() #SOCK_STREAM表示的是TCP协议,SOCK_DGRAM表示的是UDP协议 my_socket=socket.socket(socket.AF_INET, socket.SOCK_STREAM) #创建socket连接 # 将socket对象绑定ip地址和端口号 my_socket.bind(('', 80)) # 相当于电话的开机 括号里的参数表示可以同时接收5个请求 my_socket.listen(5) while True: try: # 进入监听状态,等待别人链接过来,有两个返回值, #一个是对方的socket对象,一个是对方的ip以及端口 client, addr = my_socket.accept() print('Got a connection from %s' % str(addr)) # recv表示接收,括号里是最大接收字节 request = client.recv(1024) request = str(request) print('Content = %s' % request) b00 = request.find('/?b00') b01 = request.find('/?b01') b02 = request.find('/?b02') b03 = request.find('/?b03') b04 = request.find('/?b04') b05 = request.find('/?b05') b06 = request.find('/?b06') b07 = request.find('/?b07') b08 = request.find('/?b08') b09 = request.find('/?b09') b0a = request.find('/?b0a') b0b = request.find('/?b0b') b0c = request.find('/?b0c') b0d = request.find('/?b0d') b0e = request.find('/?b0e') b0f = request.find('/?b0f') b0g = request.find('/?b0g') b0h = request.find('/?b0h') b0i = request.find('/?b0i') b10 = request.find('/?b10') b11 = request.find('/?b11') b12 = request.find('/?b12') b13 = request.find('/?b13') b14 = request.find('/?b14') b15 = request.find('/?b15') b16 = request.find('/?b16') b17 = request.find('/?b17') b18 = request.find('/?b18') b19 = request.find('/?b19') b1a = request.find('/?b1a') b1b = request.find('/?b1b') b1c = request.find('/?b1c') b1d = request.find('/?b1d') b1e = request.find('/?b1e') b1f = request.find('/?b1f') b1g = request.find('/?b1g') b1h = request.find('/?b1h') b1i = request.find('/?b1i') b20 = request.find('/?b10') b21 = request.find('/?b21') b22 = request.find('/?b22') b23 = request.find('/?b23') b24 = request.find('/?b24') b25 = request.find('/?b25') b26 = request.find('/?b26') b27 = request.find('/?b27') b28 = request.find('/?b28') b29 = request.find('/?b29') b2a = request.find('/?b2a') b2b = request.find('/?b2b') b2c = request.find('/?b2c') b2d = request.find('/?b2d') b2e = request.find('/?b2e') b2f = request.find('/?b2f') b2g = request.find('/?b2g') b2h = request.find('/?b2h') b2i = request.find('/?b2i') b30 = request.find('/?b30') b31 = request.find('/?b31') b32 = request.find('/?b32') b33 = request.find('/?b33') b34 = request.find('/?b34') b35 = request.find('/?b35') b36 = request.find('/?b36') b37 = request.find('/?b37') b38 = request.find('/?b38') b39 = request.find('/?b39') b3a = request.find('/?b3a') b3b = request.find('/?b3b') b3c = request.find('/?b3c') b3d = request.find('/?b3d') b3e = request.find('/?b3e') b3f = request.find('/?b3f') b3g = request.find('/?b3g') b3h = request.find('/?b3h') b3i = request.find('/?b3i') b40 = request.find('/?b40') b41 = request.find('/?b41') b42 = request.find('/?b42') b43 = request.find('/?b43') b44 = request.find('/?b44') b45 = request.find('/?b45') b46 = request.find('/?b46') b47 = request.find('/?b47') b48 = request.find('/?b48') b49 = request.find('/?b49') b4a = request.find('/?b4a') b4b = request.find('/?b4b') b4c = request.find('/?b4c') b4d = request.find('/?b4d') b4e = request.find('/?b4e') b4f = request.find('/?b4f') b4g = request.find('/?b4g') b4h = request.find('/?b4h') b4i = request.find('/?b4i') if b00 == 6: servos.position(0,0) a0=0 if b11 == 6: servos.position(0,10) a0=10 if b02 == 6: servos.position(0,20) a0=20 if b03 == 6: servos.position(0,30) a0=30 if b04 == 6: servos.position(0,40) a0=40 if b05 == 6: servos.position(0,50) a0=50 if b06 == 6: servos.position(0,60) a0=60 if b07 == 6: servos.position(0,70) a0=70 if b08 == 6: servos.position(0,80) a0=80 if b09 == 6: servos.position(0,90) a0=90 if b0a == 6: servos.position(0,100) a0=100 if b0b == 6: servos.position(0,110) a0=110 if b0c == 6: servos.position(0,120) a0=120 if b0d == 6: servos.position(0,130) a0=130 if b0e == 6: servos.position(0,140) a0=140 if b0f == 6: servos.position(0,150) a0=150 if b0g == 6: servos.position(0,160) a0=160 if b0h == 6: servos.position(0,170) a0=170 if b0i == 6: servos.position(0,180) a0=180 if b10 == 6: servos.position(1,0) a1=0 if b11 == 6: servos.position(1,10) a1=10 if b12 == 6: servos.position(1,20) a1=20 if b13 == 6: servos.position(1,30) a1=30 if b14 == 6: servos.position(1,40) a1=40 if b15 == 6: servos.position(1,50) a1=50 if b16 == 6: servos.position(1,60) a1=60 if b17 == 6: servos.position(1,70) a1=70 if b18 == 6: servos.position(1,80) a1=80 if b19 == 6: servos.position(1,90) a1=90 if b1a == 6: servos.position(1,100) a1=100 if b1b == 6: servos.position(1,110) a1=110 if b1c == 6: servos.position(1,120) a1=120 if b1d == 6: servos.position(1,130) a1=130 if b1e == 6: servos.position(1,140) a1=140 if b1f == 6: servos.position(1,150) a1=150 if b1g == 6: servos.position(1,160) a1=160 if b1h == 6: servos.position(1,170) a1=170 if b1i == 6: servos.position(1,180) a1=180 if b20 == 6: servos.position(2,0) a2=0 if b21 == 6: servos.position(2,10) a2=10 if b22 == 6: servos.position(2,20) a2=20 if b23 == 6: servos.position(2,30) a2=30 if b24 == 6: servos.position(2,40) a2=40 if b25 == 6: servos.position(2,50) a2=50 if b26 == 6: servos.position(2,60) a2=60 if b27 == 6: servos.position(2,70) a2=70 if b28 == 6: servos.position(2,80) a2=80 if b29 == 6: servos.position(2,90) a2=90 if b2a == 6: servos.position(2,100) a2=100 if b2b == 6: servos.position(2,110) a2=110 if b2c == 6: servos.position(2,120) a2=120 if b2d == 6: servos.position(2,130) a2=130 if b2e == 6: servos.position(2,140) a2=140 if b2f == 6: servos.position(2,150) a2=150 if b2g == 6: servos.position(2,160) a2=160 if b2h == 6: servos.position(2,170) a2=170 if b2i == 6: servos.position(2,180) a2=180 if b30 == 6: servos.position(3,0) a3=0 if b31 == 6: servos.position(3,10) a3=10 if b32 == 6: servos.position(3,20) a3=20 if b33 == 6: servos.position(3,30) a3=30 if b34 == 6: servos.position(3,40) a3=40 if b35 == 6: servos.position(3,50) a3=50 if b36 == 6: servos.position(3,60) a3=60 if b37 == 6: servos.position(3,70) a3=70 if b38 == 6: servos.position(3,80) a3=80 if b39 == 6: servos.position(3,90) a3=90 if b3a == 6: servos.position(3,100) a3=100 if b3b == 6: servos.position(3,110) a3=110 if b3c == 6: servos.position(3,120) a3=120 if b3d == 6: servos.position(3,130) a3=130 if b3e == 6: servos.position(3,140) a3=140 if b3f == 6: servos.position(3,150) a3=150 if b3g == 6: servos.position(3,160) a3=160 if b3h == 6: servos.position(3,170) a3=170 if b3i == 6: servos.position(3,180) a3=180 if b40 == 6: servos.position(4,0) a4=0 if b41 == 6: servos.position(4,10) a4=10 if b42 == 6: servos.position(4,20) a4=20 if b43 == 6: servos.position(4,30) a4=30 if b44 == 6: servos.position(4,40) a4=40 if b45 == 6: servos.position(4,50) a4=50 if b46 == 6: servos.position(4,60) a4=60 if b47 == 6: servos.position(4,70) a4=70 if b48 == 6: servos.position(4,80) a4=80 if b49 == 6: servos.position(4,90) a4=90 if b4a == 6: servos.position(4,100) a4=100 if b4b == 6: servos.position(4,110) a4=110 if b4c == 6: servos.position(4,120) a4=120 if b4d == 6: servos.position(4,130) a4=130 if b4e == 6: servos.position(4,140) a4=140 if b4f == 6: servos.position(4,150) a4=150 if b4g == 6: servos.position(4,160) a4=160 if b4h == 6: servos.position(4,170) a4=170 if b4i == 6: servos.position(4,180) a4=180 response = web_page() client.send('HTTP/1.1 200 OK\n') client.send('Content-Type: text/html\n') client.send('Connection: close\n\n') client.sendall(response) client.close() except: pass

你可能感兴趣的:(ESP32,嵌入式硬件,开发语言,python,HTML)