ESP32(MicroPython) 两轮差速五自由度机械臂小车
这次的项目在软件上没多少调整,但本人希望分享一下硬件上的经验。
小车使用两轮差速底盘,驱动轮在小车中间,前后都要万向轮。这种形式可以实现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_velocityglobal angular_velocityglobal target1global target2global target_distanceglobal target_angleglobal flagwhile True:try:target=int(input("input"))''' #控制底盘旋转一定角度并前进一定距离,实测不能正常运行,已弃用if target//1000>600: #前3位组成的数大于600时控制行驶距离和旋转角度target_distance=target%1000 #后三位为距离*100target_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=1target=0elif target>0: #前3位组成的数小于600时控制线速度和角速度'''linear_velocity=target%1000-400 #前三位为角速度*100+400,角速度为正时右转,后三位为线速度*100+400angular_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=0except:pass
_thread.start_new_thread(set_target, (duty1, duty2))while True:speed1 = encoder1.read() #编码器读数speed2 = encoder2.read()Offset1=offset1 #记录上一次偏差Offset2=offset2offset1=target1-speed1 offset2=target2-speed2adujstment1=offset1*20-Offset1*18 #PID控制:P=20,I=2adujstment2=offset2*20-Offset2*18duty1+=adujstment1duty2+=adujstment2''' #控制底盘旋转一定角度并前进一定距离,实测不能正常运行,已弃用if flag==1: #指定角度转向print(flag,angle)if 0<target_angle-angle<10 or 0>target_angle-angle>-10:target1=0target2=0flag=2angle=0target_angle=0if target_angle>0: #右转target1=20target2=0angle+=speed1if target_angle<0: #左转target1=0target2=20angle+=speed2if flag==2: #指定距离直行print(flag,distance)if target_distance-distance>400:target1=100target2=100elif target_distance-distance>100:target1=25target2=25elif target_distance-distance>40:target1=10target2=10elif target_distance-distance<15:target1=0target2=0flag=0distance=0target_distance=0distance+=speed1'''if target1<0: #由于实测发现电机反向时不能正常测速,这部分改为开环控制duty1=10*target1if target2<0:duty2=10*target2 if duty1<-1023:duty1=-1023if duty1>1023:duty1=1023if duty2<-1023:duty2=-1023if duty2>1023:duty2=1023if 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 a1global a2global a3global a4html = """<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.00linear=400print(str(angular)+str(linear))if d2 == 6:turn=0.00angular=400print(str(angular)+str(linear)) if w10 == 6:speed=-3.00linear=100print(str(angular)+str(linear))if w11 == 6:speed=-2.75linear=125print(str(angular)+str(linear)) if w12 == 6:speed=-2.50linear=150print(str(angular)+str(linear))if w13 == 6:speed=-2.25linear=175print(str(angular)+str(linear))if w14 == 6:speed=-2.00linear=200print(str(angular)+str(linear))if w15 == 6:speed=-1.75linear=225print(str(angular)+str(linear)) if w16 == 6:speed=-1.50linear=250print(str(angular)+str(linear))if w17 == 6:speed=-1.25linear=275print(str(angular)+str(linear))if w18 == 6:speed=-1.00linear=300print(str(angular)+str(linear))if w19 == 6:speed=-0.75linear=325print(str(angular)+str(linear)) if w1a == 6:speed=-0.50linear=350print(str(angular)+str(linear))if w1b == 6:speed=-0.25linear=375print(str(angular)+str(linear))if w1c == 6:speed=0.00linear=400print(str(angular)+str(linear))if w1d == 6:speed=0.25linear=425print(str(angular)+str(linear)) if w1e == 6:speed=0.50linear=450print(str(angular)+str(linear))if w1f == 6:speed=0.75linear=475print(str(angular)+str(linear))if w1g == 6:speed=1.00linear=500print(str(angular)+str(linear))if w1h == 6:speed=1.25linear=525print(str(angular)+str(linear)) if w1i == 6:speed=1.50linear=550print(str(angular)+str(linear))if w1j == 6:speed=1.75linear=575print(str(angular)+str(linear))if w1k == 6:speed=2.00linear=600print(str(angular)+str(linear))if w1l == 6:speed=2.25linear=625print(str(angular)+str(linear)) if w1m == 6:speed=2.50linear=650print(str(angular)+str(linear))if w1n == 6:speed=2.75linear=675print(str(angular)+str(linear))if w1o == 6:speed=3.00linear=700print(str(angular)+str(linear))if w20 == 6:turn=-3.00angular=100print(str(angular)+str(linear))if w21 == 6:turn=-2.75angular=125print(str(angular)+str(linear)) if w22 == 6:turn=-2.50angular=150print(str(angular)+str(linear))if w23 == 6:turn=-2.25angular=175print(str(angular)+str(linear))if w24 == 6:turn=-2.00angular=200print(str(angular)+str(linear))if w25 == 6:turn=-1.75angular=225print(str(angular)+str(linear)) if w26 == 6:turn=-1.50angular=250print(str(angular)+str(linear))if w27 == 6:turn=-1.25angular=275print(str(angular)+str(linear))if w28 == 6:turn=-1.00angular=300print(str(angular)+str(linear))if w29 == 6:turn=-0.75angular=325print(str(angular)+str(linear)) if w2a == 6:turn=-0.50angular=350print(str(angular)+str(linear))if w2b == 6:turn=-0.25angular=375print(str(angular)+str(linear))if w2c == 6:turn=0.00angular=400print(str(angular)+str(linear))if w2d == 6:turn=0.25angular=425print(str(angular)+str(linear)) if w2e == 6:turn=0.50angular=450print(str(angular)+str(linear))if w2f == 6:turn=0.75angular=475print(str(angular)+str(linear))if w2g == 6:turn=1.00angular=500print(str(angular)+str(linear))if w2h == 6:turn=1.25angular=525print(str(angular)+str(linear)) if w2i == 6:turn=1.50angular=550print(str(angular)+str(linear))if w2j == 6:turn=1.75angular=575print(str(angular)+str(linear))if w2k == 6:turn=2.00angular=600print(str(angular)+str(linear))if w2l == 6:turn=2.25angular=625print(str(angular)+str(linear)) if w2m == 6:turn=2.50angular=650print(str(angular)+str(linear))if w2n == 6:turn=2.75angular=675print(str(angular)+str(linear))if w2o == 6:turn=3.00angular=700print(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 Falseelse:led1.value(0)print("network information:", wlan.ifconfig())return Truea0=90
a1=90
a2=90
a3=90
a4=90
#网页数据
def web_page():global a0global a1global a2global a3global a4html = """<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=0if b11 == 6:servos.position(0,10)a0=10if b02 == 6:servos.position(0,20)a0=20if b03 == 6:servos.position(0,30)a0=30if b04 == 6:servos.position(0,40)a0=40if b05 == 6:servos.position(0,50)a0=50if b06 == 6:servos.position(0,60)a0=60if b07 == 6:servos.position(0,70)a0=70if b08 == 6:servos.position(0,80)a0=80if b09 == 6:servos.position(0,90)a0=90if b0a == 6:servos.position(0,100)a0=100if b0b == 6:servos.position(0,110)a0=110if b0c == 6:servos.position(0,120)a0=120if b0d == 6:servos.position(0,130)a0=130if b0e == 6:servos.position(0,140)a0=140if b0f == 6:servos.position(0,150)a0=150if b0g == 6:servos.position(0,160)a0=160if b0h == 6:servos.position(0,170)a0=170if b0i == 6:servos.position(0,180)a0=180if b10 == 6:servos.position(1,0)a1=0if b11 == 6:servos.position(1,10)a1=10if b12 == 6:servos.position(1,20)a1=20if b13 == 6:servos.position(1,30)a1=30if b14 == 6:servos.position(1,40)a1=40if b15 == 6:servos.position(1,50)a1=50if b16 == 6:servos.position(1,60)a1=60if b17 == 6:servos.position(1,70)a1=70if b18 == 6:servos.position(1,80)a1=80if b19 == 6:servos.position(1,90)a1=90if b1a == 6:servos.position(1,100)a1=100if b1b == 6:servos.position(1,110)a1=110if b1c == 6:servos.position(1,120)a1=120if b1d == 6:servos.position(1,130)a1=130if b1e == 6:servos.position(1,140)a1=140if b1f == 6:servos.position(1,150)a1=150if b1g == 6:servos.position(1,160)a1=160if b1h == 6:servos.position(1,170)a1=170if b1i == 6:servos.position(1,180)a1=180if b20 == 6:servos.position(2,0)a2=0if b21 == 6:servos.position(2,10)a2=10if b22 == 6:servos.position(2,20)a2=20if b23 == 6:servos.position(2,30)a2=30if b24 == 6:servos.position(2,40)a2=40if b25 == 6:servos.position(2,50)a2=50if b26 == 6:servos.position(2,60)a2=60if b27 == 6:servos.position(2,70)a2=70if b28 == 6:servos.position(2,80)a2=80if b29 == 6:servos.position(2,90)a2=90if b2a == 6:servos.position(2,100)a2=100if b2b == 6:servos.position(2,110)a2=110if b2c == 6:servos.position(2,120)a2=120if b2d == 6:servos.position(2,130)a2=130if b2e == 6:servos.position(2,140)a2=140if b2f == 6:servos.position(2,150)a2=150if b2g == 6:servos.position(2,160)a2=160if b2h == 6:servos.position(2,170)a2=170if b2i == 6:servos.position(2,180)a2=180if b30 == 6:servos.position(3,0)a3=0if b31 == 6:servos.position(3,10)a3=10if b32 == 6:servos.position(3,20)a3=20if b33 == 6:servos.position(3,30)a3=30if b34 == 6:servos.position(3,40)a3=40if b35 == 6:servos.position(3,50)a3=50if b36 == 6:servos.position(3,60)a3=60if b37 == 6:servos.position(3,70)a3=70if b38 == 6:servos.position(3,80)a3=80if b39 == 6:servos.position(3,90)a3=90if b3a == 6:servos.position(3,100)a3=100if b3b == 6:servos.position(3,110)a3=110if b3c == 6:servos.position(3,120)a3=120if b3d == 6:servos.position(3,130)a3=130if b3e == 6:servos.position(3,140)a3=140if b3f == 6:servos.position(3,150)a3=150if b3g == 6:servos.position(3,160)a3=160if b3h == 6:servos.position(3,170)a3=170if b3i == 6:servos.position(3,180)a3=180if b40 == 6:servos.position(4,0)a4=0if b41 == 6:servos.position(4,10)a4=10if b42 == 6:servos.position(4,20)a4=20if b43 == 6:servos.position(4,30)a4=30if b44 == 6:servos.position(4,40)a4=40if b45 == 6:servos.position(4,50)a4=50if b46 == 6:servos.position(4,60)a4=60if b47 == 6:servos.position(4,70)a4=70if b48 == 6:servos.position(4,80)a4=80if b49 == 6:servos.position(4,90)a4=90if b4a == 6:servos.position(4,100)a4=100if b4b == 6:servos.position(4,110)a4=110if b4c == 6:servos.position(4,120)a4=120if b4d == 6:servos.position(4,130)a4=130if b4e == 6:servos.position(4,140)a4=140if b4f == 6:servos.position(4,150)a4=150if b4g == 6:servos.position(4,160)a4=160if b4h == 6:servos.position(4,170)a4=170if 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(MicroPython) 两轮差速五自由度机械臂小车
这次的项目在软件上没多少调整,但本人希望分享一下硬件上的经验。 小车使用两轮差速底盘,驱动轮在小车中间,前后都要万向轮。这种形式可以实现0转弯半径,但受万向轮及用于加高的铜柱的规格限制,两个万向轮难以调到相同…...

mysql基本函数(五)
目录 一、数字函数二、字符函数三、日期时间函数3.1 获取系统日期时间的函数3.2 日期格式化函数3.3 日期偏移计算3.4 日期之间相隔的天数 四、条件函数4.1 IF语句4.2 条件语句 一、数字函数 函数功能用例ABS绝对值ABS(-100)ROUND四舍五入ROUND(4.62)FLOOR向下取值FLOOR(9.9)CE…...

liteflow 2.10 配置中心简单记录
除nacos是一个key 同时管理chain和script node外,可以理解为配置文件整体放到一个key下nacos下的文件必须是xml格式,系统只实现了xml parser其它etcd,zk,Apollo 是两个namespace/path(chain及script node各一)下多个key,每个key对应一个chain/node所有配置中心的核心代码…...

【C++】引用、内联函数等
文章目录 一、引用1.引用概念2.引用特性3.引用时的权限问题4 .使用场景5 .引用和指针的联系与区别 二、内联函数1.概念2.注意点 三、auto关键字1.概念2.auto的使用细则 四、 基于范围的for循环1.概念2.范围for的使用条件 五、 指针空值nullptr1.概念2.使用注意 一、引用 1.引用…...

RocketMQ教程-(4)-主题(Topic)
本文介绍 Apache RocketMQ 中主题(Topic)的定义、模型关系、内部属性、行为约束、版本兼容性及使用建议。 定义 主题是 Apache RocketMQ 中消息传输和存储的顶层容器,用于标识同一类业务逻辑的消息。 主题的作用主要如下: 定义…...

睡眠健康数据分析
项目背景 背景描述 本数据集涵盖了与睡眠和日常习惯有关的诸多变量。如性别、年龄、职业、睡眠时间、睡眠质量、身体活动水平、压力水平、BMI类别、血压、心率、每日步数、以及是否有睡眠障碍等细节。 数据集的主要特征: 综合睡眠指标: 探索睡眠持续时…...

Spring Boot 3.x 系列【47】启动流程 | 启动监听器
有道无术,术尚可求,有术无道,止于术。 本系列Spring Boot版本3.1.0 源码地址:https://gitee.com/pearl-organization/study-spring-boot3 文章目录 1. 前言2. 核心类2.1 SpringApplicationRunListener2.2 ApplicationStartup2.3 ApplicationListener3. 执行流程3.1 获取监…...

【KD】知识蒸馏与迁移学习的不同
知识蒸馏与迁移学习的不同 (1)数据域不同. 知识蒸馏中的知识通常是在同一个目标数据集上进行迁移,而迁移学习中的知识往往是在不同目标的数据集上进行转移. (2)网络结构不同. 知识蒸馏的两个网络可以是同构或者异构的,而迁移学习通常是在单个网络上利用其…...

计算机内存中的缓存Cache Memories
这篇写一下计算机系统中的缓存Cache应用场景和实现方式介绍。 Memory hierarchy 在讲缓存之前,首先要了解计算机中的内存结构层次Memory hierarchy。也就是下图金字塔形状的结构。 从上到下,内存层次结构如下: 寄存器:这是计算机…...

Flask的send file和send_from_directory的区别
可以自行查看flask 文档。 send file高效; send from directory安全,且适用于静态资源交互。 都是实现相同的功能的。 send_file send_from_directory...

Java 队列
基本介绍 数组模拟队列 思路分析 代码实现 import java.util.Scanner;public class Test {public static void main(String[] args) {// 创建一个队列ArrayQueue queue new ArrayQueue(3);int select;Scanner scanner new Scanner(System.in);boolean loop true;while (lo…...

【算法基础:搜索与图论】3.6 二分图(染色法判定二分图匈牙利算法)
文章目录 二分图介绍染色法判定二分图例题:860. 染色法判定二分图 匈牙利匹配二分图最大匹配匈牙利匹配算法思想例题:861. 二分图的最大匹配 二分图介绍 https://oi-wiki.org/graph/bi-graph/ 二分图是图论中的一个概念,它的所有节点可以被…...

SpringMVC 怎么和 AJAX 相互调用的
通过 Jackson 框架就可以把 Java 里面的对象直接转化成 Js 可以识别的 Json 对象。 步骤如下 : a、加入 Jackson.jar b、在配置文件中配置 json 的映射 c、在接受 Ajax 方法里面可以直接返回 Object,List 等,但方法前面要加上ResponseBody 详细步骤: …...

UCDOS和WPS推动计算机领域的汉字化发展,中文编程该谁力扛大旗?
你还记得UCDOS吗? 从DOS时代过来的人,还知道UCDOS的,现在可能已经是中年人了! 当时,鲍岳桥的UCDOS可以称得上是中国的国产操作系统。 在Windows还没来得及进入中国市场时,UCDOS可以说是走向了巅峰时刻&a…...

golang+layui提升界面美化度--[推荐]
一、背景 golanglayui提升界面美化度--[推荐]; golang后端写的页面很难看,如何好看点呢,那就是layui https://layui.dev/ 也是一个简单上手容易使用的框架,类似jquery,对于后端开发来说满足使用需求 二、使用注意点…...

42. 接雨水
题目介绍 给定 n 个非负整数表示每个宽度为 1 的柱子的高度图,计算按此排列的柱子,下雨之后能接多少雨水。 示例 1: 输入:height [0,1,0,2,1,0,1,3,2,1,2,1] 输出:6 解释:上面是由数组 [0,1,0,2,1,0,1,3…...

Python学习阶段路线和内容
Python学习阶段路线和内容 这是我的看法和认识,供参考。 Python学习路线主要分为三个阶段:入门阶段、提高阶段和深入阶段。 入门阶段 入门阶段需要学习Python的基本语法,掌握变量和数据类型、条件语句和循环语句、函数和模块等内容。并通过…...

RocketMQ教程-安装和配置
Linux系统安装配置 64位操作系统,推荐 Linux/Unix/macOS 64位 JDK 1.8 Maven3.0 yum 安装jdk8 yum 安装maven 1.下载安装Apache RocketMQ RocketMQ 的安装包分为两种,二进制包和源码包。 点击这里 下载 Apache RocketMQ 5.1.3的源码包。你也可以从这…...

【LeetCode】55.跳跃游戏
题目 给定一个非负整数数组 nums ,你最初位于数组的 第一个下标 。 数组中的每个元素代表你在该位置可以跳跃的最大长度。 判断你是否能够到达最后一个下标。 示例 1: 输入:nums [2,3,1,1,4] 输出:true 解释:可以…...

Docker学习路线12:开发者体验
到目前为止,我们只讨论了使用Docker来部署应用程序。然而,Docker也是一个极好的用于开发应用程序的工具。可以采用一些不同的建议来改善开发体验。 在应用程序中使用docker-compose以方便开发。使用绑定挂载将本地代码挂载到容器文件系统中,…...

后端服务迁移方案及过程记录
阶段时序动作双写数据对比1新rdb集群上线双写数据对比2新服务上线,无流量双写数据对比2后端自己发起的流程比如job,新服务上线一份新的,独立运行双写数据对比2消费二方mq,新服务使用新的消费组消费原有消息双写数据对比3新旧服务比…...

StAX解析
StAX解析 StAX解析介绍 StAX解析与SAX解析类似,也是基于事件驱动的,不同之处在于StAX采用的是拉模式,应用程序通过调用解析器推进解析的进程,可以调用next()方法来获取下一个解析事件(开始文档,结束文档,开…...

[MCU]AUTOSAR COM STACK - CAN协议栈
各层PDU PDU:Protocal Data Unit,协议数据单元,由SDU和PCI组成; I-PDU:Interaction Layer PDU,数据交互层PDU;N-PDU:NetWork Layer PDU,网络层PDU,通常用的…...

React:从 npx开始
使用 npm 来创建第一个 recat 文件( react-demo 是文件名,可以自定义) npx create-react-app react-demo npx是 npm v5.2 版本新添加的命令,用来简化 npm 中工具包的使用 原始: 全局安装npm i -g create-react-app 2 …...

力扣热门100题之接雨水【困难】
题目描述 给定 n 个非负整数表示每个宽度为 1 的柱子的高度图,计算按此排列的柱子,下雨之后能接多少雨水。 示例 1: 输入:height [0,1,0,2,1,0,1,3,2,1,2,1] 输出:6 解释:上面是由数组 [0,1,0,2,1,0,1,3…...

Stable-Diffusion-Webui部署SDXL0.9报错参数shape不匹配解决
问题 已经在model/stable-diffusion文件夹下放进去了sdxl0.9的safetensor文件,但是在切换model的时候,会报错model的shape不一致。 解决方法 git pullupdate一些web-ui项目就可以,因为当前项目太老了,没有使用最新的版本。...

Springboot @Async 多线程获取返回值
Springboot Async 多线程获取返回值 需求背景 最近需要用到多线程, 自己维护线程池很麻烦, 正好看到Springboot集成线程池的例子, 这里自己做了个尝试和总结, 记录一下, 也分享给需要的朋友; 不考虑事务的情况下, 这个多线程实现比较简单, 主要有以下几点: 在启动类加上Enab…...

怎样接入chatGPT
官网链接: OpenAI platform...

Docker consul容器服务更新与发现
Docker consul容器服务更新与发现 一、什么事服务注册与发现二、什么是consul三、consul部署1、consul服务器2、registrator服务器3、consul-template 一、什么事服务注册与发现 服务注册与发现是微服务架构中不可或缺的重要组件。起初服务都是单节点的,不保障高可…...

[算法很美打卡] 多维数组篇 (打卡第一天)
文章目录 顺时针打印二维数组0所在的行列清零 顺时针打印二维数组 package 每日算法学习打卡.算法打卡.七月份.七月二十六号;public class test1 {public static void main(String[] args) {int[][] matrix {{1,2},{5,6},{9,10},{13,14},};print(matrix);}static void print(i…...