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

news2024/9/29 17:38:12

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

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

 

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

 机械臂使用PCA9685进行驱动,舵机为MG996R,由于希望达到6v电压以充分发挥舵机性能,本人尝试了6v电池和使用LM7806对7.4v电池降压的方案,均不能正常运行。之后使用LM7805对7.4v电池降压输出到主控,并由主控输出5v电压到PCA9685,也不能正常运行。最后改用充电宝给主控供电并由主控输出5v电压到PCA9685,可以正常运行。出现这种情况可能是因为PCA9685对电压稳定性要求较高。由于MG996R舵机的线不够长,有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 0<target_angle-angle<10 or 0>target_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 = """<html>
<head>
  <meta name="viewport" content="width=device-width, initial-scale=1">
  
  <style>
    .button{display: inline-block; background-color: #8080f0; border: none; 
    border-radius: 4px; color: white; padding: 8px 15px; text-decoration: none; font-size: 20px; margin: 2px; cursor: pointer;}
    a:link {text-decoration:none;}a:visited {text-decoration:none;}a:hover {text-decoration:none;}
    a:active {text-decoration:none;} 
    html {
     font-family: Arial;
     display: inline-block;
     margin: 0px auto;
     text-align: center;
    }
    h2 { font-size: 1.5rem; }
    p { font-size: 1.5rem; }
    .units { font-size: 1rem; }
    .dht-labels{
      font-size: 1rem;
      vertical-align:middle;
      padding-bottom: 7px;
    }
  </style>
</head>
<body>
  <h2>ESP32 Motor Control</h2> <p><a href="/?d1">linear: <strong>""" + str(speed) + """</strong></a></p>
        <p><a href="/?w10"><button class="button">-3.00</button></a>
        <a href="/?w11"><button class="button">-2.75</button></a>
        <a href="/?w12"><button class="button">-2.50</button></a>
        <a href="/?w13"><button class="button">-2.25</button></a>
        <a href="/?w14"><button class="button">-2.00</button></a>
        <a href="/?w15"><button class="button">-1.75</button></a>
        <a href="/?w16"><button class="button">-1.50</button></a>
        <a href="/?w17"><button class="button">-1.25</button></a>
        <a href="/?w18"><button class="button">-1.00</button></a>
        <a href="/?w19"><button class="button">-0.75</button></a>
        <a href="/?w1a"><button class="button">-0.50</button></a>
        <a href="/?w1b"><button class="button">-0.25</button></a>
        <a href="/?w1c"><button class="button">0.00</button></a>
        <a href="/?w1d"><button class="button">0.25</button></a>
        <a href="/?w1e"><button class="button">0.50</button></a>
        <a href="/?w1f"><button class="button">0.75</button></a>
        <a href="/?w1g"><button class="button">1.00</button></a>
        <a href="/?w1h"><button class="button">1.25</button></a>
        <a href="/?w1i"><button class="button">1.50</button></a>
        <a href="/?w1j"><button class="button">1.75</button></a>
        <a href="/?w1k"><button class="button">2.00</button></a>
        <a href="/?w1l"><button class="button">2.25</button></a>
        <a href="/?w1m"><button class="button">2.50</button></a>
        <a href="/?w1n"><button class="button">2.75</button></a>
        <a href="/?w1o"><button class="button">3.00</button></a></p>
        <p><a href="/?d2">angular: <strong>""" + str(turn) + """</strong></a></p>
        <p><a href="/?w20"><button class="button">-3.00</button></a>
        <a href="/?w21"><button class="button">-2.75</button></a>
        <a href="/?w22"><button class="button">-2.50</button></a>
        <a href="/?w23"><button class="button">-2.25</button></a>
        <a href="/?w24"><button class="button">-2.00</button></a>
        <a href="/?w25"><button class="button">-1.75</button></a>
        <a href="/?w26"><button class="button">-1.50</button></a>
        <a href="/?w27"><button class="button">-1.25</button></a>
        <a href="/?w28"><button class="button">-1.00</button></a>
        <a href="/?w29"><button class="button">-0.75</button></a>
        <a href="/?w2a"><button class="button">-0.50</button></a>
        <a href="/?w2b"><button class="button">-0.25</button></a>
        <a href="/?w2c"><button class="button">0.00</button></a>
        <a href="/?w2d"><button class="button">0.25</button></a>
        <a href="/?w2e"><button class="button">0.50</button></a>
        <a href="/?w2f"><button class="button">0.75</button></a>
        <a href="/?w2g"><button class="button">1.00</button></a>
        <a href="/?w2h"><button class="button">1.25</button></a>
        <a href="/?w2i"><button class="button">1.50</button></a>
        <a href="/?w2j"><button class="button">1.75</button></a>
        <a href="/?w2k"><button class="button">2.00</button></a>
        <a href="/?w2l"><button class="button">2.25</button></a>
        <a href="/?w2m"><button class="button">2.50</button></a>
        <a href="/?w2n"><button class="button">2.75</button></a>
        <a href="/?w2o"><button class="button">3.00</button></a></p>
</body>
</html>"""
    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 = """<html>
<head>
  <meta name="viewport" content="width=device-width, initial-scale=1">
  
  <style>
    .button{display: inline-block; background-color: #971080; border: none; 
    border-radius: 4px; color: white; padding: 8px 15px; text-decoration: none; font-size: 20px; margin: 2px; cursor: pointer;}
    a:link {text-decoration:none;}a:visited {text-decoration:none;}a:hover {text-decoration:none;}
    a:active {text-decoration:none;} 
    html {
     font-family: Arial;
     display: inline-block;
     margin: 0px auto;
     text-align: center;
    }
    h2 { font-size: 1.5rem; }
    p { font-size: 1.5rem; }
    .units { font-size: 1rem; }
    .dht-labels{
      font-size: 1rem;
      vertical-align:middle;
      padding-bottom: 7px;
    }
  </style>
</head>
<body>
  <h2>ESP32 Servo Control</h2>
        <p><a href="/?d0">Servo0: <strong>""" + str(a0) + """</strong></a></p>
        <p><a href="/?b00"><button class="button">0</button></a>
        <a href="/?b01"><button class="button">10</button></a>
        <a href="/?b02"><button class="button">20</button></a>
        <a href="/?b03"><button class="button">30</button></a>
        <a href="/?b04"><button class="button">40</button></a>
        <a href="/?b05"><button class="button">50</button></a>
        <a href="/?b06"><button class="button">60</button></a>
        <a href="/?b07"><button class="button">70</button></a>
        <a href="/?b08"><button class="button">80</button></a>
        <a href="/?b09"><button class="button">90</button></a>
        <a href="/?b0a"><button class="button">100</button></a>
        <a href="/?b0b"><button class="button">110</button></a>
        <a href="/?b0c"><button class="button">120</button></a>
        <a href="/?b0d"><button class="button">130</button></a>
        <a href="/?b0e"><button class="button">140</button></a>
        <a href="/?b0f"><button class="button">150</button></a>
        <a href="/?b0g"><button class="button">160</button></a>
        <a href="/?b0h"><button class="button">170</button></a>
        <a href="/?b0i"><button class="button">180</button></a></p>
        <p><a href="/?d1">Servo1: <strong>""" + str(a1) + """</strong></a></p>
        <p><a href="/?b10"><button class="button">0</button></a>
        <a href="/?b11"><button class="button">10</button></a>
        <a href="/?b12"><button class="button">20</button></a>
        <a href="/?b13"><button class="button">30</button></a>
        <a href="/?b14"><button class="button">40</button></a>
        <a href="/?b15"><button class="button">50</button></a>
        <a href="/?b16"><button class="button">60</button></a>
        <a href="/?b17"><button class="button">70</button></a>
        <a href="/?b18"><button class="button">80</button></a>
        <a href="/?b19"><button class="button">90</button></a>
        <a href="/?b1a"><button class="button">100</button></a>
        <a href="/?b1b"><button class="button">110</button></a>
        <a href="/?b1c"><button class="button">120</button></a>
        <a href="/?b1d"><button class="button">130</button></a>
        <a href="/?b1e"><button class="button">140</button></a>
        <a href="/?b1f"><button class="button">150</button></a>
        <a href="/?b1g"><button class="button">160</button></a>
        <a href="/?b1h"><button class="button">170</button></a>
        <a href="/?b1i"><button class="button">180</button></a></p>
        <p><a href="/?d2">Servo2: <strong>""" + str(a2) + """</strong></a></p>
        <p><a href="/?b10"><button class="button">0</button></a>
        <a href="/?b21"><button class="button">10</button></a>
        <a href="/?b22"><button class="button">20</button></a>
        <a href="/?b23"><button class="button">30</button></a>
        <a href="/?b24"><button class="button">40</button></a>
        <a href="/?b25"><button class="button">50</button></a>
        <a href="/?b26"><button class="button">60</button></a>
        <a href="/?b27"><button class="button">70</button></a>
        <a href="/?b28"><button class="button">80</button></a>
        <a href="/?b29"><button class="button">90</button></a>
        <a href="/?b2a"><button class="button">100</button></a>
        <a href="/?b2b"><button class="button">110</button></a>
        <a href="/?b2c"><button class="button">120</button></a>
        <a href="/?b2d"><button class="button">130</button></a>
        <a href="/?b2e"><button class="button">140</button></a>
        <a href="/?b2f"><button class="button">150</button></a>
        <a href="/?b2g"><button class="button">160</button></a>
        <a href="/?b2h"><button class="button">170</button></a>
        <a href="/?b2i"><button class="button">180</button></a></p>
        <p><a href="/?d3">Servo3: <strong>""" + str(a3) + """</strong></a></p>
        <p><a href="/?b30"><button class="button">0</button></a>
        <a href="/?b31"><button class="button">10</button></a>
        <a href="/?b32"><button class="button">20</button></a>
        <a href="/?b33"><button class="button">30</button></a>
        <a href="/?b34"><button class="button">40</button></a>
        <a href="/?b35"><button class="button">50</button></a>
        <a href="/?b36"><button class="button">60</button></a>
        <a href="/?b37"><button class="button">70</button></a>
        <a href="/?b38"><button class="button">80</button></a>
        <a href="/?b39"><button class="button">90</button></a>
        <a href="/?b3a"><button class="button">100</button></a>
        <a href="/?b3b"><button class="button">110</button></a>
        <a href="/?b3c"><button class="button">120</button></a>
        <a href="/?b3d"><button class="button">130</button></a>
        <a href="/?b3e"><button class="button">140</button></a>
        <a href="/?b3f"><button class="button">150</button></a>
        <a href="/?b3g"><button class="button">160</button></a>
        <a href="/?b3h"><button class="button">170</button></a>
        <a href="/?b3i"><button class="button">180</button></a></p>
        <p><a href="/?d4">Servo4: <strong>""" + str(a4) + """</strong></a></p>
        <p><a href="/?b30"><button class="button">0</button></a>
        <a href="/?b41"><button class="button">10</button></a>
        <a href="/?b42"><button class="button">20</button></a>
        <a href="/?b43"><button class="button">30</button></a>
        <a href="/?b44"><button class="button">40</button></a>
        <a href="/?b45"><button class="button">50</button></a>
        <a href="/?b46"><button class="button">60</button></a>
        <a href="/?b47"><button class="button">70</button></a>
        <a href="/?b48"><button class="button">80</button></a>
        <a href="/?b49"><button class="button">90</button></a>
        <a href="/?b4a"><button class="button">100</button></a>
        <a href="/?b4b"><button class="button">110</button></a>
        <a href="/?b4c"><button class="button">120</button></a>
        <a href="/?b4d"><button class="button">130</button></a>
        <a href="/?b4e"><button class="button">140</button></a>
        <a href="/?b4f"><button class="button">150</button></a>
        <a href="/?b4g"><button class="button">160</button></a>
        <a href="/?b4h"><button class="button">170</button></a>
        <a href="/?b4i"><button class="button">180</button></a></p>
</body>
</html>"""
    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

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

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

相关文章

3ds MAX 洗菜池

在家居中我们显然离不开这个对吧 首先绘制一个长方体作为基础 注意设置长宽高的网格大小&#xff0c;方便后续调整 俯视图网格线如下&#xff1a; 长方形变换为可编辑网络&#xff0c;并在【多边形】界面选择底面的所有多边形&#xff0c;按delete删除&#xff0c;形成一个壳体…

AtcoderABC233场

A - 10yen StampA - 10yen Stamp 题目大意 Takahashi已有X日元邮票&#xff0c;计算出Takahashi至少需要再贴多少个10日元的邮票才能使得信封上的邮票总价值达到Y日元。 思路分析 我们只需要计算Y - X&#xff0c;即Y日元减去X日元的差值。如果该差值大于等于0&#xff0c;则…

MyBatisPlus分页功能实现

MyBatisPlus分页功能实现 1. MyBatisPlus分页使用1.1 设置分页拦截器作为Spring管理的bean1.2 执行分页查询 2. 开启MyBatisPlus日志3. 解决日志打印过多问题3.1 取消初始化spring日志打印3.2 取消SpringBoot启动banner图标3.3 取消MybatisPlus启动banner图标 1. MyBatisPlus分…

零信任安全解决方案

什么是零信任 零信任网络架构 &#xff08;ZTNA&#xff09; 或零信任安全是一种新的组织网络安全方法。它旨在修复传统基于边界的安全性中的缺陷并简化网络设计。 它以“永不信任&#xff0c;始终验证”的原则运作。这意味着&#xff0c;无论用户或设备位于何处&#xff0c;…

基于自适应运动补偿的双向运动估计算法matlab仿真

目录 1.算法运行效果图预览 2.算法运行软件版本 3.部分核心程序 4.算法理论概述 5.算法完整程序工程 1.算法运行效果图预览 2.算法运行软件版本 matlab2022a 3.部分核心程序 ..........................................................................% 单向运动法 …

繁體標楷體 如何安装使用?

中文繁體標楷體。 ——这个地方下载&#xff1a;http://www.downcc.com/font/316365.html ——下载下来被叫做“台湾标楷体DFKai-SB.ttf” ——安装到“C:\Windows\Fonts”以后名字叫 ——在WPS中使用&#xff0c;被称为这个

使用node内置test runner,和 Jest say 拜拜

参考 https://nodejs.org/dist/latest-v20.x/docs/api/test.html#test-runner 在之前&#xff0c;我们写单元测试&#xff0c;必须安装第三方依赖包&#xff0c;而从node 20.0.0 版本之后&#xff0c;可以告别繁琐的第三方依赖包啦&#xff0c;可直接使用node的内置test runner…

【搜索引擎Solr】Apache Solr 神经搜索

Sease[1] 与 Alessandro Benedetti&#xff08;Apache Lucene/Solr PMC 成员和提交者&#xff09;和 Elia Porciani&#xff08;Sease 研发软件工程师&#xff09;共同为开源社区贡献了 Apache Solr 中神经搜索的第一个里程碑。 它依赖于 Apache Lucene 实现 [2] 进行 K-最近邻…

龙芯iTOP-2K1000开发板制作启动U盘

我们准备一个 U 盘&#xff08;最小不要小于 4G&#xff0c;最大不要大于 32G&#xff09;&#xff0c;U 盘有且只有一个分区&#xff0c;U 盘格式化成 FAT32 分区&#xff0c;&#xff0c;如不满足要求&#xff0c;请格式化您的 U 盘&#xff0c;准备完成如下图所示 格式化软…

推荐系统(十)用户行为序列建模-Pooling 路线

对推荐系统而言&#xff0c;准确捕捉用户兴趣是其面临的核心命题。不管是样本、特征还是模型结构等方面的优化&#xff0c;本质上做的事情都是在提高推荐系统对用户兴趣的捕捉能力&#xff0c;因此如何提高这种能力&#xff0c;对推荐效果的提升有重要作用&#xff0c;也是算法…

性能优化问题

提升首屏的加载速度&#xff0c;是前端性能优化中「最重要」的环节&#xff0c;这里笔者梳理出一些 常规且有效 的首屏优化建议 1、路由懒加载 SPA 项目&#xff0c;一个路由对应一个页面&#xff0c;如果不做处理&#xff0c;项目打包后&#xff0c;会把所有页面打包成一个文…

使用lua脚本操作redis

redis中实现事务有两种方法&#xff1a; 1.WATCH监视键的变动&#xff0c;然后MULTI开始事务&#xff0c;EXEC提交事务 WATCH key [key…]&#xff1a;监视一个或多个键&#xff0c;如果在事务执行之前被修改&#xff0c;则事务被打断。 MULTI&#xff1a;标记一个事务的开始。…

Redis原理篇(二)

Redis原理 Redis数据结构 Redis网络模型 RESP协议 Redis内存回收 Redis原理篇 一、原理篇-Redis数据结构 1.1 Redis数据结构-动态字符串 我们都知道Redis中保存的Key是字符串&#xff0c;value往往是字符串或者字符串的集合。可见字符串是Redis中最常用的一种数据结构。 不…

JVM理论(六)执行引擎--垃圾回收

概述 垃圾: 指的是在运行程序中没有任何指针指向的对象垃圾回收目的: 为了及时清理空间使得程序可以正常运行垃圾回收机制: JVM采取的是自动内存管理,即JVM负责对象的创建以及回收,将程序员从繁重的内存管理释放出来,更加专注业务的开发垃圾回收区域: 频繁收集Young区(新生代)…

【前端知识】React 基础巩固(三十二)——Redux的三大原则、使用流程及实践

React 基础巩固(三十二)——Redux的三大原则 一、Redux的三大原则 单一数据源 整个应用程序的state被存储在一颗object tree 中&#xff0c;并且这个object tree 只存储在一个store中&#xff1b;Redux并没有强制让我们不能创建多个Store&#xff0c;但是那样做不利于数据维护…

Java网络编程(一)基本网络概念

一、网络 网络(network) 是几乎可以实时相互发送和接收数据的计算机和其他设备的集合。网络通常用线缆连接&#xff0c;数据位转换为电磁波&#xff0c;通过线缆移动。不过&#xff0c;无线网络会通过无线电波传输数据&#xff0c;许多长距离的传输现在会用通过玻璃纤维发送可见…

全加器(多位)的实现

一&#xff0c;半加器 定义 半加器&#xff08;Half Adder&#xff09;是一种用于执行二进制数相加的简单逻辑电路。它可以将两个输入位的和&#xff08;Sum&#xff09;和进位&#xff08;Carry&#xff09;计算出来。 半加器有两个输入&#xff1a;A 和 B&#xff0c;分别代表…

【Unity学习笔记】AssetBundle

文章目录 什么是AB包&#xff1f;为什么使用AB包? 如何导出AB包AB包导出文件 如何使用AB包AB包的加载同步加载异步加载 AB包的卸载依赖加载 AB包资源管理器 什么是AB包&#xff1f; AssetBundle是Unity提供的一种用于存储资源的压缩集合&#xff0c;它可以存储任何一种Unity可…

分布式操作系统会不会是操作系统的终端形态?

昨天一位网友私信我&#xff0c;提出一个问题&#xff1a;“Laxcus分布式操作系统会不会是操作系统发展的终极形态&#xff1f;”。今天觉得有必要把这件事说一说&#xff0c;所以就忙里偷闲写下这篇文章。 咱们先说结论&#xff1a;是也不是&#xff0c;需要具体情况具…

shell 脚本通过 dumpsys SurfaceFlinger --latency 数据计算 FPS 和评价流畅度。

目录 前言&#xff1a; 开篇前述&#xff1a; 一、设计初衷 二、设定预期倒推查找解决方案 设计实现部分 一、确定数据来源原因&#xff08;dumpsys SurfaceFlinger --latency&#xff09; 二、根据需求确定计算规则 三、代码实现 四、监控数据可视化交互结果设计 前言…