• 博客园logo
  • 会员
  • 众包
  • 新闻
  • 博问
  • 闪存
  • 赞助商
  • HarmonyOS
  • Chat2DB
    • 搜索
      所有博客
    • 搜索
      当前博客
  • 写随笔 我的博客 短消息 简洁模式
    用户头像
    我的博客 我的园子 账号设置 会员中心 简洁模式 ... 退出登录
    注册 登录
MKT-porter
博客园    首页    新随笔    联系   管理    订阅  订阅
stm32步进电机激光测距

 

 

 

3D打印机配件单轴混合式42步进电机2相4线17HS8401s/17HS8401

 https://item.taobao.com/item.htm?id=561097731505&pisk=gzIt2rGIoWVg2LF8_Gznmr2-kLwhMyXa91WSmIAil6Cdh1OMiE9sOk9WBKi6ct9XD610QCXb_sIvOt7gQEVZHwCNFFfA3RJXGs1viN43qOWw0nNkMuqlQk_KO3f9hF6QhKp6GJYsuAKBtnNuZo3ndFPMc10eVRZIRLRBCK9X1JdBEL-XCFibpB9vUIi1Gs6QpKpkGq9XGetBnLKj5KT1dk9WUc96CniQpKRBhV1XcJKIh-NvOAOmDagzYcau0qnoqMp9WInD9mC5x0YwNRRIDmdHcF3GCBnjcMQnAEHe1zkHghANDdC44c-6kaWDH1EtfsBPY6pCNonk19WlrFS_o0YJjCLVfsFxkdQl6sR1Cfg6ehd9PGTEF-t9lwIpjGNqz9Xp1UKh-yPMohCOzQ8_8W5ApCffXeGTtIblKGTdNWmdgEQPnKCTXc154tIl2mlKZQpm5JeKuq86L8mvwm4tn9qDpQ2TDqu28JomWgqKuq8sbpduBRuqueSR.&spm=a1z10.3-c-s.w4002-24032463620.22.5bca5bdfVqJOHz&skuId=4324632572616

 

 

https://item.taobao.com/item.htm?_u=f1qf7bf50694&id=613911068384&pisk=gSTU_1GHO23eApO2CEbzb-J8iCbdWakjEU65ZQAlO9Xn26guzQRcNXH-9h5kFdh-9wOlULJ1Bz1SvYUyQpODAM9WATflIdAQRTgd4LRXHLaSJH1uzdORqLTywz5kZLhdFXn69BQRrxMfzqOp9cilFYTFZN2M6_PhZcs3YVRI1xMjl4o3sakEhp1TLYiGgsbltgfujf5Pgu2kEg4MsOCRZJfu-flNwOfht_XHs5flwJfHE_bGI61PtTfurOVGMOXlrM4n_CXOaxe6tQ4NGMczELR65DgEutRhQz4k-4Ll3AXA668aaMB2tFGETbCFYtAhQxC8uIIMwg88wzWHtnpRip2nhMdkbd5FzVZhoC-k31LnlJ59ACAfIIP8yB_e0E7HYAEORp8GSex4ZzAN89IlspyEQtYpsEQGfqc2sFpB9FR7Z4f6hOAp-aumMw7hKN59PAUhUhxkRMQ8KxspZhJNTZjrU8Cg7OYJY8qPx1CNhflwIy0uxDRZ8iE82GbA_tGCOuqueSfNhf8U2uIG_1WjOzf..&spm=a1z09.2.0.0.3f1f2e8dWmrgGf

 

 

 

 

控制代码1

int PUL = 7; //定义脉冲引脚
int DIR = 6; //定义方向销
int ENA = 5; //定义启用引脚  低电平有效
 
 
int wait_time=2000;  
/**
* TB6600驱动器 . 42两相四线步进电机
*/
void setup() {
  pinMode (PUL, OUTPUT);
  pinMode (DIR, OUTPUT);
  pinMode (ENA, OUTPUT);
 
  Serial.begin(9600);
  // 初始化复位 - 转3圈
  for (int i = 0; i < 1600; i++) //前进4800步 SW1=OFF,SW2=ON,SW3=OFF(每圈1600脉冲)
  {
    digitalWrite(DIR, LOW); // 定义正转
    digitalWrite(ENA, 0);// 启动
    digitalWrite(PUL, HIGH);// 输出脉冲
    delayMicroseconds(wait_time);
    digitalWrite(PUL, LOW);
     
    delayMicroseconds(wait_time);
  }
  delay(2000);
  Serial.println("开始");
}
    
void loop() {
  Serial.println("前进");
  for (int i = 0; i < 1600; i++) //正转1圈
  {
    digitalWrite(DIR, LOW);
    digitalWrite(ENA, 0);
    digitalWrite(PUL, HIGH);
    delayMicroseconds(wait_time);
    digitalWrite(PUL, LOW);
    delayMicroseconds(wait_time);
  }
  delay(3000); // 暂停10秒
  Serial.println("后退");
  for (int i = 0; i < 1600; i++) //倒转1圈
  {
    digitalWrite(DIR, HIGH);
    digitalWrite(ENA, 0);
    digitalWrite(PUL, HIGH);
    delayMicroseconds(wait_time);
    digitalWrite(PUL, LOW);
    delayMicroseconds(wait_time);
  }
   delay(3000); // 暂停10秒
}

  

 

控制代码2

输入0-1米  自动根据转化到角度

int PUL = PB7; // 定义脉冲引脚
int DIR = PB6; // 定义方向引脚
int ENA = PB5; // 定义启用引脚,低电平有效
int wait_time = 2000;

const int stepsPerRevolution = 1600; // 每圈1600步
const float maxDistance = 1.0; // 8米最大距离

int current_step=0;


void setup() {
  pinMode(PUL, OUTPUT);
  pinMode(DIR, OUTPUT);
  pinMode(ENA, OUTPUT);

  digitalWrite(PUL, HIGH);//   低电平
  digitalWrite(DIR, HIGH);//   默认反方向
  digitalWrite(ENA, HIGH);//   关闭电机

   
  Serial.begin(9600);
  Serial.println("输入距离 (0-8米):");
}

void loop() {
  if (Serial.available() > 0) {
    float distance = Serial.parseFloat(); // 读取串口输入的距离
    if (distance >= 0 && distance <= maxDistance) {
      int stepsToMove = map(distance*1000 , 0, maxDistance*1000 , 0, stepsPerRevolution); // 映射到步数
      int move_step=stepsToMove-current_step;
      
      

      
      Serial.print("移动步数: ");
      Serial.println(move_step);
      moveStepper(move_step);
      current_step=stepsToMove;
    } else {
      Serial.println("无效输入,请输入0-1米之间的数值。");
    }
  }
}

void moveStepper(int steps) {

  

  
  bool direction = steps >= 0;
  digitalWrite(DIR, direction ? LOW : HIGH); // 设定方向
  digitalWrite(ENA, LOW); // 使能电机

  for (int i = 0; i < abs(steps); i++) {
    digitalWrite(PUL, HIGH);
    delayMicroseconds(wait_time);
    digitalWrite(PUL, LOW);
    delayMicroseconds(wait_time);
  }

  digitalWrite(ENA, HIGH);//   关闭电机
  delayMicroseconds(2000);
  
}

  

例子3 通过激光测距 动态调整步进电机的步数

int PUL = PB7; // 定义脉冲引脚
int DIR = PB6; // 定义方向引脚
int ENA = PB5; // 定义启用引脚,低电平有效
int wait_time = 2000;

const int stepsPerRevolution = 1600; // 每圈1600步
const float maxDistance = 1000; // 8米最大距离 

int current_step=0;


#define START_BYTE  0xAA  // 帧头字节
#define FRAME_SIZE  195   // 总数据长度

uint8_t frameBuffer[FRAME_SIZE]; // 用于存储一帧数据
bool capturing = false;          // 是否在捕获数据
uint8_t index_ = 0;               // 数据索引


uint16_t f_distance=0; // 测量的距离



void moveStepper(int steps) {
  if (abs(steps)<6){
    digitalWrite(ENA, HIGH);//关闭电机
    Serial.println("移动步数: 0");
    return;
    }
  

  
  bool direction = steps >= 0;
  if(direction){
     Serial.print("移动步数: 往前");Serial.println(steps);
   }
   else{
     Serial.print("移动步数: 往后");Serial.println(steps);
    }
                    
  digitalWrite(DIR, direction ? LOW : HIGH); // 设定方向
  digitalWrite(ENA, LOW); // 使能电机

  for (int i = 0; i < abs(steps); i++) {
    digitalWrite(PUL, HIGH);
    delayMicroseconds(wait_time);
    digitalWrite(PUL, LOW);
    delayMicroseconds(wait_time);
  }

  digitalWrite(ENA, HIGH);//   关闭电机
  delayMicroseconds(2000);
  
}


void printFrame() {
//    Serial.println("完整数据帧:");

    // 发送数据到 Python 格式解析
//    Serial.print("Data: ");
//    for (int i = 0; i < FRAME_SIZE; i++) {
//        Serial.print(frameBuffer[i], HEX);
//        Serial.print(" ");
//    }
//    Serial.println();

    // 解析数据
    //Serial.println("解析后的测量数据:");
    for (int i = 10; i < FRAME_SIZE; i += 15) {
        if (i + 15 < FRAME_SIZE) { // 确保不会越界
            // 解析距离 distance
            uint16_t distance = (frameBuffer[i + 1] << 8) | frameBuffer[i];

            f_distance=distance;

            // 解析环境噪声 noise
            uint16_t noise = (frameBuffer[i + 3] << 8) | frameBuffer[i + 2];

            // 解析接收强度 peak
            uint32_t peak = (frameBuffer[i + 7] << 24) | (frameBuffer[i + 6] << 16) |
                            (frameBuffer[i + 5] << 8) | frameBuffer[i + 4];

            // 解析置信度 confidence
            uint8_t confidence = frameBuffer[i + 8];

            // 解析积分次数 intg
            uint32_t intg = (frameBuffer[i + 12] << 24) | (frameBuffer[i + 11] << 16) |
                            (frameBuffer[i + 10] << 8) | frameBuffer[i + 9];

            // 解析温度表征值 reftof
            uint16_t reftof = (frameBuffer[i + 14] << 8) | frameBuffer[i + 13];

            // 打印解析后的数据
              //Serial.print("距离: "); Serial.println(distance);
//            Serial.print(" | 噪声: "); Serial.print(noise);
//            Serial.print(" | 强度: "); Serial.print(peak);
//            Serial.print(" | 置信度: "); Serial.print(confidence);
//            Serial.print(" | 积分次数: "); Serial.print(intg);
//            Serial.print(" | 温度: "); Serial.println(reftof);
        }
    }

    //Serial.println("\n--- End of Frame ---");
}

void Read_distance(uint8_t byteReceived){
  
  
         if (!capturing) {
            // 进入帧头检测
            static uint8_t headerBuffer[4] = {0};
            headerBuffer[0] = headerBuffer[1];
            headerBuffer[1] = headerBuffer[2];
            headerBuffer[2] = headerBuffer[3];
            headerBuffer[3] = byteReceived;

            if (headerBuffer[0] == START_BYTE && headerBuffer[1] == START_BYTE &&
                headerBuffer[2] == START_BYTE && headerBuffer[3] == START_BYTE) {
                // 发现帧头,开始接收数据
                capturing = true;
                index_ = 4;
                memcpy(frameBuffer, headerBuffer, 4);
            }
        } else {
            // 继续存储数据
            frameBuffer[index_++] = byteReceived;

            // 收到完整一帧数据
            if (index_ >= FRAME_SIZE) {
                capturing = false;
                printFrame(); // 打印数据帧

                if(f_distance>8000){
                   // 数据无效
                  }
                else{
                  Serial.print("距离: "); Serial.println(f_distance);
                  // 在这里去做后续的事情
                

                  // 完整解析数据后在做动作
              
                  float distance = f_distance; // 读取串口输入的距离

                
                  if (distance >= 0 && distance <= maxDistance) {
                  
                  } else {
                    distance=maxDistance;
                  }

                    int stepsToMove = map(distance , 0, maxDistance , 0, stepsPerRevolution); // 映射到步数
                    int move_step=stepsToMove-current_step;
            

                    
                    moveStepper(move_step);
                    current_step=stepsToMove;

                }                  
                
            }
        }
  
  }

void setup() {
  pinMode(PUL, OUTPUT);
  pinMode(DIR, OUTPUT);
  pinMode(ENA, OUTPUT);

  digitalWrite(PUL, HIGH);//   低电平
  digitalWrite(DIR, HIGH);//   默认反方向
  digitalWrite(ENA, HIGH);//   关闭电机

   
  Serial.begin(9600);
  Serial.println("输入距离 (0-8米):");

   Serial2.begin(230400);     // 设备串口
}

void loop() {


    while (Serial2.available()) {
        uint8_t byteReceived = Serial2.read();
        Read_distance(byteReceived);
    }

    // 不要做其他动作干扰数据解析
  



}

  

posted on 2025-03-16 01:17  MKT-porter  阅读(34)  评论(0)    收藏  举报
刷新页面返回顶部
博客园  ©  2004-2025
浙公网安备 33010602011771号 浙ICP备2021040463号-3