/** *************************************************************************************** * @file buffer.cpp * @author lijihu * @version V1.0.0 * @date 2025/05/10 * @brief 实现缓冲器功能 *缓冲器说明 光感:遮挡1,不遮挡0; 耗材开关:有耗材0,无耗材1; 按键:按下0,松开1; 引脚: HALL1 --> PB2 (光感3) HALL2 --> PB3 (光感2) HALL3 --> PB4 (光感1) ENDSTOP_3 --> PB7(耗材开关) KEY1 --> PB13(后退) KEY2 --> PB12(前进) * * @note *************************************************************************************** * 版权声明 COPYRIGHT 2025 xxx@126.com *************************************************************************************** **/ #include "buffer.h" TMC2209Stepper driver(UART, UART, R_SENSE, DRIVER_ADDRESS); Buffer buffer={0};//存储个传感器状态 Motor_State motor_state=Stop; bool is_front=false;//前进标志位 uint32_t front_time=0;//前进时间 const int EEPROM_ADDR_TIMEOUT = 0; const uint32_t DEFAULT_TIMEOUT = 30000; uint32_t timeout=30000;//超时时间,单位:ms; bool is_error=false;//错误标志位,如果连续30s推送耗材没停过,则认为错误 String serial_buf; static HardwareTimer timer(TIM6);//超时出错 void buffer_init(){ buffer_sensor_init(); buffer_motor_init(); delay(1000); EEPROM.get(EEPROM_ADDR_TIMEOUT, timeout); // 判断读取的值是否有效(例如首次写入前是 0xFFFFFFFF 或 0) if (timeout == 0xFFFFFFFF || timeout == 0) { timeout = DEFAULT_TIMEOUT; EEPROM.put(EEPROM_ADDR_TIMEOUT, timeout); Serial.println("EEPROM is empty"); } else { Serial.print("read timeout: "); Serial.println(timeout); } timer.pause(); timer.setPrescaleFactor(48);//48分频 48000000/48=1000000 timer.setOverflow(1000);//1ms timer.attachInterrupt(&timer_it_callback); timer.resume(); } void buffer_loop(){ uint32_t lastToggleTime = millis(); // 记录上次切换的时间 while(1) { if(millis() - lastToggleTime >= 500) // 每隔 500ms { lastToggleTime = millis(); // 记录当前时间 digitalToggle(ERR_LED); } //1、读取各传感器的值 read_sensor_state(); #if DEBUG buffer_debug(); while(Serial.available()>0){ char c=Serial.read(); serial_buf+=c; int pos_enter = -1; pos_enter = serial_buf.indexOf("\n"); if(pos_enter != -1){ String str=serial_buf.substring(0,pos_enter); serial_buf=serial_buf.substring(pos_enter+1); if(strstr(str.c_str(),"gconf")!=NULL){ TMC2208_n::CHOPCONF_t gconf{0}; // 提取 "gconf" 后面的十六进制字符串 int pos = str.indexOf("gconf"); if (pos != -1) { String hexPart = str.substring(pos + 5); // 跳过 "gconf" hexPart.trim(); // 去除前后空白符 // 将字符串转换为 32 位无符号整数 uint32_t hexValue = strtoul(hexPart.c_str(), NULL, 16); // 赋值给结构体(按你的结构定义赋值) gconf.sr = hexValue; // 假设 sr 是结构体中的原始寄存器值字段 } driver.GCONF(gconf.sr); Serial.print("write GCONF:0x"); Serial.println(gconf.sr,HEX); Serial.print("read GCONF: 0x"); Serial.println(driver.GCONF(),HEX); } } } #else motor_control(); while(Serial.available()>0){ char c=Serial.read(); serial_buf+=c; } if(serial_buf.length()>0){ if(serial_buf=="rt"){ Serial.print("read timeout="); Serial.println(timeout); serial_buf=""; } else if(serial_buf.startsWith("set")){ serial_buf.remove(0,3); int64_t num=serial_buf.toInt(); if(num<0||num>0xffffffff){ serial_buf=""; Serial.println("Error: Invalid timeout value."); continue; } timeout=num; EEPROM.put(EEPROM_ADDR_TIMEOUT, timeout); serial_buf=""; Serial.print("set succeed! timeout="); Serial.println(timeout); } else{ Serial.println(serial_buf.c_str()); Serial.println("command error!"); serial_buf=""; } } #endif } } void buffer_sensor_init(){ //传感器初始化 pinMode(HALL1,INPUT); pinMode(HALL2,INPUT); pinMode(HALL3,INPUT); pinMode(ENDSTOP_3,INPUT); pinMode(KEY1,INPUT); pinMode(KEY2,INPUT); //耗材指示灯初始化 pinMode(DUANLIAO,OUTPUT); pinMode(ERR_LED,OUTPUT); pinMode(START_LED,OUTPUT); } void buffer_motor_init(){ //电机驱动引脚初始化 pinMode(EN_PIN, OUTPUT); pinMode(STEP_PIN, OUTPUT); pinMode(DIR_PIN, OUTPUT); digitalWrite(EN_PIN, LOW); // Enable driver in hardware //电机驱动初始化 driver.begin(); // UART: Init SW UART (if selected) with default 115200 baudrate driver.beginSerial(9600); driver.I_scale_analog(false); driver.toff(5); // Enables driver in software driver.rms_current(I_CURRENT); // Set motor RMS current driver.microsteps(Move_Divide_NUM); // Set microsteps to 1/16th driver.VACTUAL(STOP); // Set velocity driver.en_spreadCycle(true); driver.pwm_autoscale(true); } /** * @brief 读取各传感器状态 * @param NULL * @retval NULL **/ void read_sensor_state(void) { buffer.buffer1_pos1_sensor_state= digitalRead(HALL3); buffer.buffer1_pos2_sensor_state= digitalRead(HALL2); buffer.buffer1_pos3_sensor_state= digitalRead(HALL1); buffer.buffer1_material_swtich_state=digitalRead(ENDSTOP_3); buffer.key1=digitalRead(KEY1); buffer.key2=digitalRead(KEY2); } /** * @brief 电机控制 * @param NULL * @retval NULL **/ void motor_control(void) { static Motor_State last_motor_state=Stop; //按键控制电机 //按键1按下 if(!digitalRead(KEY1)) { WRITE_EN_PIN(0);//使能 driver.VACTUAL(STOP); //停止 driver.shaft(BACK); driver.VACTUAL(VACTRUAL_VALUE); while(!digitalRead(KEY1));//等待松手 driver.VACTUAL(STOP); //停止 motor_state=Stop; is_front=false; front_time=0; is_error=false; WRITE_EN_PIN(1);//失能 } else if(!digitalRead(KEY2))//按键2按下 { WRITE_EN_PIN(0); driver.VACTUAL(STOP); //停止 driver.shaft(FORWARD); driver.VACTUAL(VACTRUAL_VALUE); while(!digitalRead(KEY2)); driver.VACTUAL(STOP); //停止 motor_state=Stop; is_front=false; front_time=0; is_error=false; WRITE_EN_PIN(1); } //判断耗材 if(digitalRead(ENDSTOP_3)) { //无耗材,停止电机 driver.VACTUAL(STOP); //停止 motor_state=Stop; //断料引脚输出低电平 digitalWrite(DUANLIAO,0); //关闭指示灯 digitalWrite(START_LED,0); is_front=false; front_time=0; is_error=false; WRITE_EN_PIN(1); return;//无耗材,结束 } //有耗材,断料引脚输出高电平 digitalWrite(DUANLIAO,1); //开启指示灯 digitalWrite(START_LED,1); //判断是否有错误 if(is_error){ //停止电机 driver.VACTUAL(STOP); //停止 motor_state=Stop; WRITE_EN_PIN(1); return ; } //缓冲器位置记录 if(buffer.buffer1_pos1_sensor_state) //缓冲器位置为1,耗材往前推 { last_motor_state=motor_state; //记录上一次状态 motor_state=Forward; is_front=true; } else if(buffer.buffer1_pos2_sensor_state) //缓冲器位置为2,电机停止转动 { last_motor_state=motor_state; //记录上一次状态 motor_state=Stop; is_front=false; front_time=0; } else if(buffer.buffer1_pos3_sensor_state) //缓冲器位置为3,回退耗材 { last_motor_state=motor_state; //记录上一次状态 motor_state=Back; is_front=false; front_time=0; } if(motor_state==last_motor_state)//如果上次状态跟这次状态一致,则不需要再次发送控制命令,结束此次函数 return; //电机控制 switch(motor_state) { case Forward://向前 { WRITE_EN_PIN(0); if(last_motor_state==Back) driver.VACTUAL(STOP);//上次是后退,先停下再前进 driver.shaft(FORWARD); driver.VACTUAL(VACTRUAL_VALUE); }break; case Stop://停止 { WRITE_EN_PIN(1); driver.VACTUAL(STOP); }break; case Back://向后 { WRITE_EN_PIN(0); if(last_motor_state==Forward) driver.VACTUAL(STOP);;//上次是前进,先停下再后退 driver.shaft(BACK); driver.VACTUAL(VACTRUAL_VALUE); }break; } } void timer_it_callback(){ if(is_front){//如果往前推 front_time++; if(front_time>timeout){//如果超时 is_error=true; } } } void buffer_debug(void){ // Serial.print("buffer1_pos1_sensor_state:");Serial.println(buffer.buffer1_pos1_sensor_state); // Serial.print("buffer1_pos2_sensor_state:");Serial.println(buffer.buffer1_pos2_sensor_state); // Serial.print("buffer1_pos3_sensor_state:");Serial.println(buffer.buffer1_pos3_sensor_state); // Serial.print("buffer1_material_swtich_state:");Serial.println(buffer.buffer1_material_swtich_state); // Serial.print("key1:");Serial.println(buffer.key1); // Serial.print("key2:");Serial.println(buffer.key2); static int i=0; if(i<0x1ff){ Serial.print("i:"); Serial.println(i); driver.GCONF(i); driver.PWMCONF(i); i++; } uint32_t gconf = driver.GCONF(); uint32_t chopconf=driver.CHOPCONF(); uint32_t pwmconf = driver.PWMCONF(); if(driver.CRCerror){ Serial.println("CRCerror"); } else{ Serial.print("GCONF():0x"); Serial.println(gconf,HEX); Serial.print("CHOPCONF():0x"); char buf[11]; // "0x" + 8 digits + null terminator sprintf(buf, "%08lX", chopconf); // %08lX -> 8位大写十六进制(long unsigned) Serial.println(buf); Serial.print("PWMCONF():0x"); sprintf(buf, "%08lX", pwmconf); // %08lX -> 8位大写十六进制(long unsigned) Serial.println(buf); Serial.println(""); } delay(1000); }