from machine import Pin,ADC
from time import sleep_us,sleep
import json
import utime
import machine
import time
def update_data():
# 将更新后的字典写回文件
with open("esp32_cnc.txt", "w",encoding='utf-8') as file:
json.dump(data, file)
def manul_control_port():
motion_ports = ['x', 'y', 'z']
current_port_index = motion_ports.index(data['manual_control_port'])
# 使用取模运算符循环列表
next_port_index = (current_port_index + 1) % len(motion_ports)
data['manual_control_port'] = motion_ports[next_port_index]
print(data['manual_control_port'])
update_data()
def Ramp_function(pin):
check_button.append(1)
def scan_callback(timer):
if len(check_button) == 0:
pass
else:
manul_control_port()
check_button.clear()
# 手动控制电机运行
# 输入电压范围对应方向 0-1.65v 对应负方向 1.65-3.3v 对应正方向
# 输入电压数值对应步进电机速度 0-1.65v
# 步进电机转速计算 周期f = 2000us,频率 1000000/2000/200 = 2.5r/s 最大8r/s 最小2r/s 0-1.65v对应时间500-1000us,1.65-3.3v对应时间1000-500us
# 手动操作添加步数更新
def manual_control(): # 摇杆调用控制运行命令
# 创建电压输入引脚
# 检测电压值
# 判断电压值范围
# 确定当前轴运动方向
# 确定当前轴的运动速度
# 驱动当前轴运动
# 确定轴运动停止条件
while Automatic_switching_control_pin.value() == 0:
voltage = round(voltage_detection_pin.read()/4095*3.3,1) # 读取电压值
# print("电压值:", voltage) # 打印电压值
while voltage < reference_voltage-0.3: # 判断电压值范围
direction = 0 # 确定当前轴运动方向为负方向
axis = globals()['{}_pin'.format(data['manual_control_port'])] # 动态轴变量
axis[1].value(direction) # 确定当前轴运动方向为负方向
delay_us = int(round(1000-(reference_voltage-voltage)/reference_voltage*500,0)) # 确定当前轴的运动速度
print(delay_us)
axis[0].value(1)
sleep_us(delay_us)
axis[0].value(0)
sleep_us(delay_us)
data['{}2'.format(data['manual_control_port'])] -= 1
update_data()
break
while voltage > reference_voltage+0.3: # 判断电压值范围
direction = 1 # 确定当前轴运动方向为正方向
axis = globals()['{}_pin'.format(data['manual_control_port'])] # 动态轴变量
axis[1].value(direction) # 确定当前轴运动方向为正方向
delay_us = int(round(1000-(voltage-reference_voltage)/(3.3-reference_voltage)*500,0)) # 确定当前轴的运动速度
print(delay_us)
axis[0].value(1)
sleep_us(delay_us)
axis[0].value(0)
sleep_us(delay_us)
data['{}2'.format(data['manual_control_port'])] += 1
update_data()
break
def manual_control_main():
print('手动运行》》》》》》》》')
while Automatic_switching_control_pin.value() == 0:
manul_control_pin.irq(trigger=Pin.IRQ_FALLING, handler=Ramp_function)
manual_control()
pass
# 输入值定义为距离还是步数:定义为距离mm
# 定义一个通用的步进函数2 m对应值x,y,z;delay_us = [500,1000],
def step_motor2(m, direction, distance, delay_us): # m = ["x","y","z"] 加工文件调用运行命令
steps = int(round(distance / 0.015,1))
step_pin,dir_pin = globals()['{}_pin'.format(m)]
dir_pin.value(direction)
#运行前检测x1的值处于运行范围内
#运行前判断下一步是否会超出限位
#运行一步,更新x1的值
#正向运行+1,反向运行-1步
axis0 = '{}0'.format(m)
axis1 = '{}1'.format(m)
axis2 = '{}2'.format(m)
print("{}轴运行".format(m))
if data[axis2] > data[axis0] and data[axis2] < data[axis1]: # 判断x2的值是否处于运行范围内
if direction == 1: # x轴正向运行
if data[axis2] + steps > data[axis1]: # 判断是否超出限位值
print("超出限位值,报警") # 超出限位值报警
return
else:
for i in range(steps):
step_pin.value(1)
sleep_us(delay_us)
step_pin.value(0)
sleep_us(delay_us)
data[axis2] += steps # 更新x2的值
update_data()
else: # x轴反向运行
if data[axis2] - steps < data[axis0]: # 判断是否超出限位值
print("超出限位值,报警") # 超出限位值报警
return
else:
for i in range(steps):
step_pin.value(1)
sleep_us(delay_us)
step_pin.value(0)
sleep_us(delay_us)
data[axis2] -= steps # 更新x2的值
update_data()
else:
print("步进值超出运行范围")
def step_motor3(m, direction): # m = ["x","y","z"] 回位调用运行命令
delay_us = 1500
step_pin,dir_pin = globals()['{}_pin'.format(m)]
dir_pin.value(direction)
step_pin.value(1)
sleep_us(delay_us)
step_pin.value(0)
sleep_us(delay_us)
# 机械回零
# Z轴回零,触发行程开关停止
# x轴回零,触发行程开关停止
# y轴回零,触发行程开关停止
# 更新x2、y2、z2坐标值为0
def Mechanical_reset(pin):
while z_limit_pin.value() == 1:
step_motor3('z', 0)
while x_limit_pin.value() == 1:
step_motor3('x', 1)
while y_limit_pin.value() == 1:
step_motor3('y', 1)
data['x2'] = 0
data['y2'] = 0
data['z2'] = 0
update_data()
print("机械回零完成")
return
def Zero_point_record(pin):
data['x3'] = data['x2'] # 记录工件零点
data['y3'] = data['y2'] # 记录工件零点
data['z3'] = data['z2'] # 记录工件零点
update_data() # 更新文件
print('工件零点已更新')
def Automatic_control_main():
# 自动控制
print('自动运行》》》》》》》》')
Mechanical_reset(2)
while Automatic_switching_control_pin.value() == 1:
pass
# 读取文件中的数据
if __name__ == '__main__':
# 从文件读取字典
with open("esp32_cnc.txt", "r",encoding='utf-8') as file:
data = json.load(file)
print(data)
# {"x0": 0, "y0": 0, "z0": 0, "x1": 25600, "y1": 20200, "z1": 8066, "x2": 0, "y2": 0, "z2": 0, "x3": 0, "y3": 0, "z3": 0,"manual_control_port": "x"}
# x0-z0:机械原点坐标;x1-z1:限位坐标;x2-z2:当前位置坐标;x3-z3:工件原点;manual_control_port:手动控制轴
# 初始化步进电机的引脚
x_pin = [Pin(13, Pin.OUT), Pin(14, Pin.OUT)] # x轴步进电机引脚,13step,14dir
y_pin = [Pin(26, Pin.OUT), Pin(25, Pin.OUT)] # y轴步进电机引脚,26step,25dir
z_pin = [Pin(33, Pin.OUT), Pin(32, Pin.OUT)] # z轴步进电机引脚,33step,32dir
manul_control_pin = Pin(27, Pin.IN,Pin.PULL_UP) # 上拉电阻,保持端口高电位,手动切换X,y,z轴运行
x_limit_pin = Pin(18, Pin.IN, Pin.PULL_UP) # x轴限位开关引脚,18
y_limit_pin = Pin(19, Pin.IN, Pin.PULL_UP) # y轴限位开关引脚,19
z_limit_pin = Pin(21, Pin.IN, Pin.PULL_UP) # z轴限位开关引脚,21
Mechanical_reset_pin = Pin(36, Pin.IN, Pin.PULL_UP) # ,34 触发机械回零
Automatic_switching_control_pin = Pin(34, Pin.IN) # 4 判断自动控制还是手动控制
Zero_point_pin = Pin(4, Pin.IN,Pin.PULL_UP) # 4 设置工件零点
check_button = []
# 设置方向
x_pin[1].value(1) # x轴方向设置为1
y_pin[1].value(1) # y轴方向设置为1
z_pin[1].value(1) # z轴方向设置为1
scan_timer = machine.Timer(-1)
scan_timer.init(period=10, mode=machine.Timer.PERIODIC, callback=scan_callback)
Mechanical_reset_pin.irq(trigger=Pin.IRQ_FALLING,handler = Mechanical_reset) # 机械回零触发中断
Zero_point_pin.irq(trigger=Pin.IRQ_FALLING,handler = Zero_point_record) # 记录工件零点触发中断
reference_voltage = 1.5
voltage_detection_pin = ADC(Pin(35))
voltage_detection_pin.atten(ADC.ATTN_11DB) # 设置电压输入范围 0-3.3v 0-4095
voltage_detection_pin.width(ADC.WIDTH_12BIT) # 设置电压输入精度 12位
while Automatic_switching_control_pin.value() == 0 or Automatic_switching_control_pin.value() == 1:
print(Automatic_switching_control_pin.value())
if Automatic_switching_control_pin.value() == 0:
manual_control_main()
elif Automatic_switching_control_pin.value() == 1:
Automatic_control_main()
# 运行说明
# 开机,运行ESP32_CNC.py
# 判断手动运行状态还是自动运行状态
# 手动运行:1、手动切换x,y,z;2、手动控制对应轴运动
# 自动运行:
# 1、自动机械回零;
# 2、工件零点 X3,y3,z3 手动记录工件零点
# 3、读取加工件;
# 4、运行加工