这次的项目在软件上没多少调整,但本人希望分享一下硬件上的经验。
小车使用两轮差速底盘,驱动轮在小车中间,前后都要万向轮。这种形式可以实现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 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) + """
"""
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
"""
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