基于Arduino ESP32 的 CAD Controller Design for Siemens NX 11 (上篇)
背景介绍
对于长期从事CAD建模的同学来说,为了从不同角度观察3D模型,“旋转”,“缩放” 是使用率最高的操作。而对于常用的滚轮鼠标而言因其“滚轮中键”向下按压时操作面太小,长时间点击容易患上“鼠标手”,笔者在之前从事产品设计过程中深受其扰。
近期在自学Arduino后,萌生了自己做一个用于CAD 建模的控制器。Prototype 的构思源于摇杆及旋转编码器的示例程序。感兴趣的同学可以将此拓展到CATIA 上应用。
项目期间参考了,Li-Yongjun 的《ESP32 EC11 制作电脑音量调节旋钮》,
[https://blog.csdn.net/lyndon_li/article/details/124564530?utm_medium=distribute.pc_relevant.none-task-blog-2defaultbaidujs_baidulandingword~default-5-124564530-blog-137572167.235v43
稚晖君的 “【瀚文】HelloWord-Keyboard”
[https://oshwhub.com/pengzhihui/b11afae464c54a3e8d0f77e1f92dc7b7]:
感谢大佬们的开源贡献!
项目分为上、下两篇,本部分为上篇。
1. 硬件选型及设计
1.1 PS2 摇杆模块
PS2 摇杆模块,共有3路输出:VRx, VRy,SW。
其中VRx, VRy为模拟量,其实质为电位器输出端的电压值,需接AD口;
其中SW为数字量,接数字口。VRx, VRy经ESP32 AD 转换后输出数值,数据类型为int。
[摇杆模块]
[摇杆模块原理图及Proteus仿真,该模块的全值电阻为4.5K]
1.2 EC11 旋转编码器模块
旋转编码器的是一种位置传感器,用于确定旋转轴的角位置。它根据旋转运动生成模拟或数字信号,旋转编码器有许多不同类型,它们根据输出信号或传感技术进行分类。本方案采用的是一种低成本的触点电刷增量式旋转编码器,它是测量旋转最简单的传感器。
本项目中,旋转编码器是用于替代鼠标的滚轮,用于3D建模“缩小”,“放大”操作。
1.2.1 工作原理
详见B站,【旋转编码器如何工作以及如何与Arduino一起使用[How To Mechatronics]】https://www.bilibili.com/video/BV1JJ411s7p3?p=2&vd_source=37fd58933b54ae0d29f796611848ad70
其工作原理,如下所示:
EC11 Encoder-原理
1.2.2 引脚定义
CLK: CLK(Clock):这是编码器的主要输出脉冲信号,用于确定旋转的数量。每当旋钮向任一方向转动一个触点,CLK输出会经历一次从高电平到低电平的周期变化。
DT: DT(Data or Direction):这是类似于CLK输出的信号,但它比CLK信号滞后90°的相位。这个输出用于确定旋转的方向。当编码器逆时针旋转时,DT输出逻辑低电平;当编码器顺时针旋转时,DT输出逻辑高电平。
SW: 按键输出端口
+: 电源+
GND: 电源-
CLK和DT信号通常通过相位差来确定旋转的方向。例如,如果CLK信号在下降沿时(电平由高变低),而DT信号是高电平,则表示顺时针旋转;如果DT信号是低电平,则表示逆时针旋转。
1.2.3 电路原理图
1.3 按键
按键的工作原理简单,不再赘述。本项目中按键用于替代“鼠标中键的向下按键”,实现在3D建模的过程中旋转模型的部分操作。
为了规避按键的抖动,采用上拉电阻接入,按键不触发时,保持高电平,电路原理图如下:
2.程序设计
源代码如下:
// CAD Controller Design for Siemens NX 11
// Auth:Hope.Zhu Sep/10/2024
// REV :00
// 预编译第三方库文件
#include <BleCombo.h>
#include "EC11.hpp"
#include "OneButton.h"
EC11 encoder;
// Polling allows to use the encoder with any digital input pin.
const int encoderPinA = 17; //EC11 引脚A
const int encoderPinB = 16; //EC11 引脚B
//const int EC11_SW_Pin = 4; //EC11 引脚SW 停用,不好操作
// 摇杆
const int X_Pin = A4; // X向的输入,其实质是电位器经AD转换后的电压信号
const int Y_Pin = A5; // Y向的输入, 同上
// 独立按键
const int SW_Pin = 14; //
// LED 状态指示灯,用于调试过程中观察状态的变化
const int LEDPin1 = 13; // CW 旋转指示
const int LEDPin2 = 27; // C.C.W 旋转指示
const int LEDPin3 = 2; // 蓝牙连接状态指示灯
const int LEDPin4 = 26; // 摇杆指示灯,X+
const int LEDPin5 = 15; // 摇杆指示灯,X-
const int LEDPin6 = 25; // 摇杆指示灯,Y+
const int LEDPin7 = 12; // 摇杆指示灯,Y-
OneButton button(SW_Pin, true); // 独立按键,
void setup() {
Serial.begin(115200);
Serial.println("Starting CAD Controller work!");
Keyboard.begin();
Mouse.begin();
// 编码器,C PIN 为公共端
pinMode(encoderPinA, INPUT_PULLUP);
pinMode(encoderPinB, INPUT_PULLUP);
analogSetWidth(10); // 设置采样分辨率
pinMode(X_Pin, INPUT);
pinMode(Y_Pin, INPUT);
pinMode(SW_Pin, INPUT_PULLUP);
digitalWrite(SW_Pin, HIGH);
pinMode(LEDPin1, OUTPUT);
digitalWrite(LEDPin1, HIGH); // LEDPin1共阳极,初始化置高电平熄灭
pinMode(LEDPin2, OUTPUT);
digitalWrite(LEDPin2, HIGH); // LEDPin2共阳极,初始化置高电平熄灭
pinMode(LEDPin3, OUTPUT);
pinMode(LEDPin4, OUTPUT);
pinMode(LEDPin5, OUTPUT);
pinMode(LEDPin6, OUTPUT);
pinMode(LEDPin7, OUTPUT);
// link functions to be called on events.
button.attachLongPressStart(LongPressStart, &button);
button.attachDuringLongPress(DuringLongPress, &button);
button.attachLongPressStop(LongPressStop, &button);
button.setLongPressIntervalMs(500);
}
void loop() {
if (Keyboard.isConnected()) {
button.tick();
Rocker_Switch();
// 旋转编码器代码不够优雅,可以后续封装成函数
EC11Event e;
if (encoder.read(&e)) {
blinkLED(LEDPin3);
// OK, got an event waiting to be handled.
if (e.type == EC11Event::StepCW) { // 顺时针
Serial.println("Scroll Down");
Mouse.move(0, 0, -5); //(X向,Y向,滚轮),此处只控制滚轮
Serial.println("- - -");
blinkLED2(LEDPin1);
} else { // 逆时针
Serial.println("Scroll Up");
Mouse.move(0, 0, 5);
Serial.println("+ + +");
blinkLED2(LEDPin2);
}
} else {
//Serial.println("not connected");
}
}
// With polling-style pin checking we can still read infrequently, but we need to poll the pins often enough.
for (int i = 0; i < 10; i++) {
encoder.checkPins(digitalRead(encoderPinA), digitalRead(encoderPinB));
delay(1);
}
}
// 共阴极LED模块闪烁
void blinkLED(int ledPin) {
digitalWrite(ledPin, HIGH);
delay(10);
digitalWrite(ledPin, LOW);
}
// 共阳极LED模块闪烁
void blinkLED2(int ledPin) {
digitalWrite(ledPin, LOW);
delay(10);
digitalWrite(ledPin, HIGH);
}
// 摇杆模块
void Rocker_Switch() {
int X_Val = analogRead(X_Pin)/4; // AD 转换后的X_Val 模拟值, /4 防溢出
//Serial.print("X_Val:"); // 调试时用于观察输出量
//Serial.println(X_Val);
int Y_Val = analogRead(Y_Pin)/4; // AD 转换后的Y_Val 模拟值,/4 防溢出
//Serial.print("Y_Val:"); // 调试时用于观察输出量
//Serial.println(Y_Val);
// int C_Val= 2900; // 摇杆的中值 (需根据实际输出量调整)
// int P_Val=200; // 摇杆的偏移量 (需根据实际输出量调整)
int H_Val = 850; //C_Val + P_Val ; // 摇杆的 上阈值
int L_Val = 650; //C_Val + P_Val ; // 摇杆的 下阈值
if (X_Val > H_Val) { // 水平移动
//Keyboard.write(KEY_RIGHT_ARROW); //用于后续开发模式2,控制键盘按键
Mouse.move(25, 0, 0); // 移动量根据个人使用习惯调整
delay(20);
blinkLED(LEDPin4);
Serial.println("--->");
} else if (X_Val < L_Val) {
//Keyboard.write(KEY_LEFT_ARROW); //用于后续开发模式2,控制键盘按键
Mouse.move(-25, 0, 0);
delay(20);
blinkLED(LEDPin5);
Serial.println("<---");
}
if (Y_Val > H_Val) {
//Keyboard.write(KEY_UP_ARROW); //用于后续开发模式2,控制键盘按键
Mouse.move(0, 25, 0);
//Mouse.release(MOUSE_MIDDLE);
delay(20);
blinkLED(LEDPin6);
Serial.println("^^^");
} else if (Y_Val < L_Val) {
//Keyboard.write(KEY_DOWN_ARROW); //用于后续开发模式2,控制键盘按键
Mouse.move(0, -25, 0);
delay(20);
blinkLED(LEDPin7);
Serial.println("$$$");
}
}
// this function will be called when the button started long pressed.
void LongPressStart(void *oneButton)
{
Serial.print(((OneButton *)oneButton)->getPressedMs());
Serial.println("\t - LongPressStart()");
}
// this function will be called when the button is released.
void LongPressStop(void *oneButton)
{
Serial.print(((OneButton *)oneButton)->getPressedMs());
Serial.println("\t - LongPressStop()\n");
Mouse.release(MOUSE_MIDDLE);
}
// this function will be called when the button is held down.
void DuringLongPress(void *oneButton)
{
Serial.print(((OneButton *)oneButton)->getPressedMs());
Serial.println("\t - DuringLongPress()");
Mouse.press(MOUSE_MIDDLE);
}
// End
3.演示动画
3.1 EC11 控制PDF 文档/网页,翻页
3.2 摇杆及按键控制 Siemens NX 11 3D 模型旋转 (需先设置好旋转点)
3.3 EC11 控制 Siemens NX 11 3D 模型缩放
4 结构设计(待下篇更新)
待人体工学DEMO验证完后更新…