本网页已闲置超过3分钟,按键盘任意键或点击空白处,即可回到网页

带陀螺仪传感器的钻孔深度显示台钻

发布时间:2022-09-12
分享到:

带陀螺仪传感器的钻孔深度显示台钻

发布时间:2022-09-12
分享到:

如果您必须为项目钻孔一定深度,则需要带有深度显示的台钻。看看它在这个项目中是多么简单。

大多数台钻都有一个带箭头的尺子用于阅读。钻孔的成功取决于您读取所需位置的准确度。在这个项目中,我想出了一个替代方案:带有陀螺仪传感器的钻孔深度显示器和带有 Arduino 支持的 7 段显示器。

我在车间最常使用的机器不是锯或磨床。不过到目前为止,这是个台钻。无论项目如何,它实际上总是被使用。如果我需要一定的钻孔深度,我可以使用机器上的内置尺子,只需要记住我必须钻到的深度。

不过随着我们年龄的增长,对我来说,以毫米精度读取深度变得越来越困难。而如果光线不够亮,则几乎无法阅读。但是只是为此戴上眼镜?钻孔后,眼镜存放在哪里?我还没有想那么远,当然这只是我的一些顾虑。

测量可能性
我当然可以在刻度前放一个放大镜,使尺子更容易阅读。它会改善读数,但我必须记住每种情况下的测量值也无济于事。如果你在做手工艺品,那也应该很有趣。

这就是为什么电子解决方案要好得多的原因。最好在一个小空间里,以便所有东西都放在钻头的开/关开关旁边。对于这种情况,我喜欢使用 Arduino Nano。它有足够的引脚来控制几乎所有东西,并且相应地很小。

但是如何测量钻孔深度?长度测量有多种可能性。安装超声波测量?可以工作,但只需要一点机械装置,它与钻头一起移动作为反射表面。还是使用拉线编码器?如果您自己构建它是可能的,但非常复杂:带有转盘、叉形光栅和弹簧复位。最好马上带一个旋转编码器?这将意味着更少的组件 - 是的,但它太粗糙了,你必须安装齿轮才能翻译。

好吧,那就多想想吧。

我的钻头和大多数钻头一样,侧面有一个手轮来调节深度。它可以旋转大约 270°。所以甚至没有一个完整的回合。

不过这非常适合使用陀螺仪传感器进行角度测量。电缆连接不能扭曲,只需要一个便宜的组件。陀螺仪传感器也可以很容易地直接连接到手轮的旋转轴上。

概念
在指定钻孔深度时,我总是以相同的方式进行:用钻头刮擦表面,记下坐标,然后添加所需的钻孔深度,最后钻孔直到达到深度。

我想保留基本流程。为了不钻得太深,我想收到有关何时达到钻孔深度的信息。

一个按钮接管了这个功能。当您按下它时,Arduino 会将当前钻孔位置保存为停止值,并在以后到达时随时提醒我。

其余组件占用更多空间且重量明显更大。幸运的是,我的机器外壳是金属制成的。这就是为什么我使用钕磁铁来固定它。

问题仍然存在,传感器应该如何连接到机器上?

钻头的轴上有一个 SW17 六角螺母。所以我只需要一个可以接受传感器并且可以插入六角螺母的 3D 打印组件。

所需组件

  • Arduino纳米
  • 陀螺仪传感器 GY-521
  • 8位7段模块(带MAX7219 IC的SPI版本)
  • 按钮
  • 开/关
  • 电源:用于 AA 或 AAA 电池或移动电源的电池夹
  • 3D打印外壳
  • 钕磁铁

陀螺仪传感器的连接

陀螺仪传感器通过 I2C 连接。所以我们必须为 Nano 使用 A5 和 A4。

  • VCC -> 5V
  • 接地 -> 接地
  • SCL -> A5
  • SDA -> A4
  • XDA -> 未连接
  • XCL -> 未连接
  • ADO -> 未连接
  • INT -> 未连接

7段模块
连接 7 段模块时可以使用任何数字引脚。使用 Arduino 草图设置引脚。

  • VCC -> 3.3V
  • 接地 -> 接地
  • DIN -> D12
  • CS -> D10
  • 时钟-> D11

按钮
按钮的输入引脚也可以自由选择。我正在使用引脚 D9。

电源
对于电源,我使用 6 节 AA 电池。在开/关开关后,它们为整个系统供电。

套管
我使用 Autodesk Fusion 360 设计了外壳。我使用 Anycubic i3 Mega 创建了 3D 打印。

用于连接机器的钕磁铁被粘在里面。如果整个钻孔深度显示受到阻碍,所有东西都会很快被移除。

软件

我使用LedControl.h库来控制 7 段显示。如果您还没有安装这些,您必须首先使用库管理器安装它们。

陀螺仪传感器通过 I2C 总线连接。在为传感器寻找可能的库时,我决定不使用任何库。

7 段显示器的控制与LedControl配合得非常好。

用引脚初始化后,设置过程只需要一些准备工作即可唤醒显示器并调整亮度。

在循环部分,显示屏仅以数字显示当前钻孔深度和停止位置(如果已设置)。

显示器需要每个数字作为字符类型。我想使用小数位作为准确性。函数 dtostrf 将浮点数转换为字符数组。然后变成一个字符串以在显示屏上按字符显示。

dtostrf ( currentPos, 4,1, txt ) ;
s = '' + String ( txt ) ;
lc. setChar ( 0,4, see charAt ( see length () -1 ) , false ) ;
lc. setChar ( 0.5, see charAt ( see length () -3 ) , true ) ;
lc. setChar ( 0.6, see charAt ( see length () -4 ) , false ) ;
lc. setChar ( 0.7, see charAt ( see length () -5 ) , false ) ;

到达停止位置时,显示屏上会出现“StOP”。可以使用setRow过程和适当的位模式 B00001111 生成小“t”。

读取陀螺仪传感器通过线库的功能工作。我只使用加速度计来确定角位置。

使用 USB 连接到 Arduino IDE 时,一切正常。拔下并连接外部电源后,传感器没有提供任何数据。它仅在重置 Arduino 后再次起作用。

这让我在整个项目中最头疼。可以说是钻孔深度指示器可能救了我的眼睛,不过这也是我几乎拔掉所有头发的原因。

经过长时间的搜索,在唤醒传感器后设置等待时间是解决方案。这使得延迟(1000)成为整个源代码中最重要的命令。

//prepare GY-521 sensor
//we use only accelerator data
Wire.begin();
Wire.beginTransmission(MPU);
Wire.write(0x6B);
Wire.write(0x00); // wake up MPU
Wire.endTransmission(true);

//this delay was very necessary in my case!
delay(1000);

Wire.beginTransmission(MPU);
Wire.write(0x1C); //register ACCEL_CONFIG
Wire.write(0x10); //Set as 00010000 for +/- 8g full scale range
Wire.endTransmission(true);

偏移值必须在一开始就为传感器确定好,否则数值会出现波动。在设置部分,测量了 100 个值并对偏差进行平均。

从传感器数据计算角度并不容易。但是有很多关于如何进行计算的说明。

使用以下公式计算以度为单位的 X 角:

AccAngleX = (atan ((AccY) / sqrt (pow ((AccX), 2) + pow ((AccZ), 2))) * rad_to_deg);

但是,加速度传感器的数值波动很大。因此,当前计算的值与之前的值各取 50% 的平均值。

TotalAngleX = 0.5 * TotalAngleX + 0.5 * AccAngleX;

角度值由传感器从-90°到+90°输出。但我需要一个从 0° 到 360° 的角度来转换为钻孔深度。

我还没有找到一个简单的解决方案。然而,对于我的应用程序,查看传感器数据 Z 和 Y 是正数还是负数就足够了。并相应地转换角度。

delta=0;
if ((AccZ<0)) { 
  delta=180.0-TotalAngleX*2.0;
}
if ((AccZ>0)&&(AccY<0)) {
  delta=360.0;
}
DrillingMachineAngle=TotalAngleX+delta;

//if near 360°, display better 0°
if (DrillingMachineAngle>350) {DrillingMachineAngle=0;}

仍然缺少的是手轮能够实现的最大可能旋转角度。最简单的方法是通过 Serial.print 输出确定的角度并记下最大值。

对我来说是316°。最大钻孔深度为 50 mm 时,当前位置计算如下:

currentPos=50.0/316.0*DrillingMachineAngle;

如果按下按钮,Arduino 会保存当前钻孔位置。显示屏上显示 8888,等待 1 秒。

如果设置了停止位置,则直到停止的剩余钻孔深度显示在右侧显示屏上。

组装和测试
陀螺传感器最好用一点热胶固定。引导连接电缆穿过盖板。这就是这部分。

在第一次测试中,陀螺传感器必须首先对齐。我是水平安装的。由于支架设计为可旋转,因此可以轻松调整,直到显示屏上显示 0.0。

然后可以开始第一个测试。

总的来说,我对解决方案非常满意。传感器反应非常迅速,计算值与钻孔深度完全匹配。

得益于大型 LED 显示屏,我不必担心 85 岁以下的眼睛需要戴上眼镜才可以读取准确的钻孔深度。

drilling-depth.ino:

/* program: drilling-depth.ino
 * author:  Thomas Angielsky
 * version: 2021-03-20
 * 
 * https://techpluscode.de/
 * https://techpluscode.de/bohrtiefenanzeige-mit-gyro-sensor/
 * 
 * this sketch measures the drilling depth of a table drilling
 * machine by using data of GY-521 gyro sensor
 * depth is viewed by 7 segment display
 * 
 * idea of calc error compensation from electronoobs.com - thanks!
 * 
 */


#include <Wire.h>
#include <math.h>
#include "LedControl.h"

#define MPU 0x68

char txt[8];
String s;
float currentPos,stopPos;
float rad_to_deg;
float AccX, AccY, AccZ;  
float AccAngleX, AccAngleY;         
float AccAngleErrorX, AccAngleErrorY; 
float TotalAngleX, TotalAngleY;
float DrillingMachineAngle, delta;

//init LED's: pin D12, pin D11, pin D10, 1 module
LedControl lc=LedControl(12,11,10,1);


void setup() {
  //prepare serial connection
  //Serial.begin(9600);

  
  //start values
  stopPos=0.0;
  currentPos=0.0;  
  rad_to_deg = 180/PI;

  //prepare GY-521 sensor
  //we use only accelerator data
  Wire.begin(); 
  Wire.beginTransmission(MPU);         
  Wire.write(0x6B);
  Wire.write(0x00); // wake up MPU
  Wire.endTransmission(true); 

  //this delay was very necessary in my case!
  delay(1000);
  Wire.beginTransmission(MPU);
  Wire.write(0x1C); //register ACCEL_CONFIG 
  Wire.write(0x10); //Set as 00010000 for +/- 8g full scale range
  Wire.endTransmission(true); 


  //calculate the accellerator data error
  //do 100 measurments
  for(int a=0; a<100; a++) {
      Wire.beginTransmission(MPU);
      Wire.write(0x3B);
      Wire.endTransmission(false);
      Wire.requestFrom(MPU,6,true); 
      
      AccX=(Wire.read()<<8|Wire.read())/4096.0 ; 
      AccY=(Wire.read()<<8|Wire.read())/4096.0 ;
      AccZ=(Wire.read()<<8|Wire.read())/4096.0 ;
      
      AccAngleErrorX=AccAngleErrorX+((atan((AccY)/sqrt(pow((AccX),2)+pow((AccZ),2)))*rad_to_deg));
      //AccAngleErrorY=AccAngleErrorY+((atan(-1*(AccX)/sqrt(pow((AccY),2)+pow((AccZ),2)))*rad_to_deg)); 
    }
      
  AccAngleErrorX=AccAngleErrorX/100;
  //AccAngleErrorY=AccAngleErrorY/100;
  
  //prepare button: pin D9
  pinMode(9,INPUT_PULLUP);

  //prepare 7 segment display
  lc.shutdown(0,false);
  lc.setIntensity(0,8);
  lc.clearDisplay(0);
}


void loop() {
  Wire.beginTransmission(MPU);
  Wire.write(0x3B);
  Wire.endTransmission(false);
  Wire.requestFrom(MPU,6,true);
  
  AccX=(Wire.read()<<8|Wire.read())/4096.0; 
  AccY=(Wire.read()<<8|Wire.read())/4096.0;
  AccZ=(Wire.read()<<8|Wire.read())/4096.0; 

  AccAngleX=(atan((AccY)/sqrt(pow((AccX),2)+pow((AccZ),2)))*rad_to_deg)-AccAngleErrorX;
  //AccAngleY=(atan(-1*(AccX)/sqrt(pow((AccY),2)+pow((AccZ),2)))*rad_to_deg)-AccAngleErrorY;    

  //smooth values
  TotalAngleX=0.5*(TotalAngleX)+0.5*AccAngleX;
  //TotalAngleY=0.5*(TotalAngleY)+0.5*AccAngleY;

  //calculate x angle to 360 by using +/- of X,Y,Z
  delta=0;
  
  if ((AccZ<0)) { 
    delta=180.0-TotalAngleX*2.0;
  }

 if ((AccZ>0)&&(AccY<0)) {
    delta=360.0;
  }

  DrillingMachineAngle=TotalAngleX+delta;
  //if near 360, display better 0
  if (DrillingMachineAngle>350) {DrillingMachineAngle=0;}

  //calculate drilling depth
  //max drilling depth: 50 mm (measured on machine)
  //max angle of hand wheel: 316 (measured with Serial.print data)
  currentPos=50.0/316.0*DrillingMachineAngle;


  /*
  Serial.print("X / X / Y / Z / E : BOHRTIEFE");
  Serial.print(TotalAngleX);
  Serial.print(" ");
  Serial.print(AccX);
  Serial.print(" ");
  Serial.print(AccY);
  Serial.print(" ");
  Serial.print(AccZ);  
  Serial.print(" >> ");
  Serial.print(DrillingMachineAngle);
  Serial.print(" >> ");
  Serial.print(currentPos);
  Serial.println(" ");
*/
  
  //button pressed?
  if (digitalRead(9)==LOW) {
    //store stop position
    stopPos=currentPos;        
    lc.setChar(0,3,'8',false);
    lc.setChar(0,2,'8',false);
    lc.setChar(0,1,'8',false);
    lc.setChar(0,0,'8',false); 
    //Serial.println("Button pressed");
    delay(1000);
  }

  if (stopPos>0) {
    //stop position reached?
    if (currentPos>=stopPos) {
      //yes: display STOP (5t0P) on right side
      lc.setChar(0,3,'5',false);
      lc.setRow(0,2,B00001111);
      lc.setChar(0,1,'0',false);
      lc.setChar(0,0,'P',false);
    } else {
      //no: display distance to stop position
      dtostrf(stopPos-currentPos,4,1,txt);
      s=' '+String(txt);
      lc.setChar(0,0,s.charAt(s.length()-1),false); 
      lc.setChar(0,1,s.charAt(s.length()-3),true); 
      lc.setChar(0,2,s.charAt(s.length()-4),false); 
      lc.setChar(0,3,s.charAt(s.length()-5),false); 
    }
  } else {
      //display nothing
      lc.setChar(0,3,' ',false);
      lc.setChar(0,2,' ',false);
      lc.setChar(0,1,' ',false);
      lc.setChar(0,0,' ',false);        
  }

  //display current drilling depth on left side
  //format as string
  dtostrf(currentPos,4,1,txt);
  s=' '+String(txt);
 
  lc.setChar(0,4,s.charAt(s.length()-1),false); 
  lc.setChar(0,5,s.charAt(s.length()-3),true); 
  lc.setChar(0,6,s.charAt(s.length()-4),false); 
  lc.setChar(0,7,s.charAt(s.length()-5),false); 

  delay(200);
}

如果您对此项目有任何想法、意见或问题,请在下方留言。

以上内容翻译自网络,原作者:Thomas Angielsky,如涉及侵权,可联系删除。

加入微信技术交流群

技术交流,职业进阶

关注与非网服务号

获取电子工程师福利

加入电路城 QQ 交流群

与技术大牛交朋友

讨论