Arduino Nano与模拟摇杆无操作持续输出U/L问题求助
解决Arduino摇杆未触碰却持续输出U/L的问题
问题描述
我用Arduino Nano搭配模拟摇杆开发了一款支持上下左右4方向移动的游戏,检查代码后觉得逻辑没问题,但通过串口监视器查看时,哪怕完全没触碰摇杆,设备也一直输出“U”和“L”,请问该怎么解决?
附上我的Arduino代码:
byte x_axis = A3; byte y_axis = A1; byte btn1 = 8; byte btn2 = 9; byte btn3 = 10; byte btn4 = 11; byte btn5 = 12; byte led = 13; void setup(){ pinMode(x_axis, INPUT); pinMode(y_axis, INPUT); pinMode(btn1, INPUT); pinMode(btn2, INPUT); pinMode(btn3, INPUT); pinMode(btn4, INPUT); pinMode(btn5, INPUT); digitalWrite(btn1, HIGH); digitalWrite(btn2, HIGH); digitalWrite(btn3, HIGH); digitalWrite(btn4, HIGH); digitalWrite(btn5, HIGH); pinMode(led, OUTPUT); digitalWrite(led, LOW); Serial.begin(9600); } void loop(){ Int read_x = analogRead(x_axis); // 注意这里的Int是大写I,属于语法小错误 int read_y = analogRead(y_axis); if(read_x > 600){ Serial.println("R"); digitalWrite(led, HIGH); } if(read_x < 400){ Serial.println("L"); digitalWrite(led, HIGH); } if(read_y > 600){ Serial.println("D"); digitalWrite(led, HIGH); } if(read_y < 400){ Serial.println("U"); digitalWrite(led, HIGH); } if(digitalRead(btn1) == LOW){ Serial.println("1"); digitalWrite(led, HIGH); } if(digitalRead(btn2) == LOW){ Serial.println("2"); digitalWrite(led, HIGH); } if(digitalRead(btn3) == LOW){ Serial.println("3"); digitalWrite(led, HIGH); } if(digitalRead(btn4) == LOW){ Serial.println("4"); digitalWrite(led, HIGH); } if(digitalRead(btn5) == LOW){ Serial.println("5"); digitalWrite(led, HIGH); } delay(10); digitalWrite(led, LOW); }
解决方案
这种情况几乎都是模拟摇杆的零点漂移导致的——每个摇杆的静止ADC值不一定正好是10位ADC的中间值512,会有个体差异,你用固定的400/600阈值就会误判。按以下步骤解决:
1. 先校准摇杆的静止零点
先运行这段简单的校准代码,读取摇杆完全静止时的X、Y轴数值:
byte x_axis = A3; byte y_axis = A1; void setup(){ Serial.begin(9600); } void loop(){ int read_x = analogRead(x_axis); int read_y = analogRead(y_axis); Serial.print("X静止值: "); Serial.print(read_x); Serial.print(" | Y静止值: "); Serial.println(read_y); delay(500); }
打开串口监视器,记录下稳定的X、Y数值(比如可能是X=475,Y=490)。
2. 修改原代码,加入死区判断
把固定阈值改成基于你校准得到的零点值,设置一个“死区”——在零点正负一定范围内的读数都判定为静止,不输出方向。同时修正原代码里的Int拼写错误:
byte x_axis = A3; byte y_axis = A1; byte btn1 = 8; byte btn2 = 9; byte btn3 = 10; byte btn4 = 11; byte btn5 = 12; byte led = 13; // 替换成你校准得到的静止零点值 const int X_ZERO = 475; const int Y_ZERO = 490; const int DEADZONE = 50; // 死区范围,可根据实际调整,比如40-60都试试 void setup(){ pinMode(x_axis, INPUT); pinMode(y_axis, INPUT); pinMode(btn1, INPUT); pinMode(btn2, INPUT); pinMode(btn3, INPUT); pinMode(btn4, INPUT); pinMode(btn5, INPUT); digitalWrite(btn1, HIGH); digitalWrite(btn2, HIGH); digitalWrite(btn3, HIGH); digitalWrite(btn4, HIGH); digitalWrite(btn5, HIGH); pinMode(led, OUTPUT); digitalWrite(led, LOW); Serial.begin(9600); } void loop(){ int read_x = analogRead(x_axis); int read_y = analogRead(y_axis); bool isActive = false; // 处理X轴方向 if(read_x > X_ZERO + DEADZONE){ Serial.println("R"); isActive = true; } else if(read_x < X_ZERO - DEADZONE){ Serial.println("L"); isActive = true; } // 处理Y轴方向 else if(read_y > Y_ZERO + DEADZONE){ Serial.println("D"); isActive = true; } else if(read_y < Y_ZERO - DEADZONE){ Serial.println("U"); isActive = true; } // 处理按钮 else if(digitalRead(btn1) == LOW){ Serial.println("1"); isActive = true; } else if(digitalRead(btn2) == LOW){ Serial.println("2"); isActive = true; } else if(digitalRead(btn3) == LOW){ Serial.println("3"); isActive = true; } else if(digitalRead(btn4) == LOW){ Serial.println("4"); isActive = true; } else if(digitalRead(btn5) == LOW){ Serial.println("5"); isActive = true; } // 根据状态控制LED digitalWrite(led, isActive ? HIGH : LOW); delay(10); }
3. 检查接线(额外排查)
如果校准后还是有问题,检查摇杆的接线是否牢固:
- 摇杆的VCC引脚必须接Arduino的5V
- GND引脚必须接Arduino的GND
- X、Y轴的输出引脚分别对应A3和A1,没有接反或松动
这样修改后,应该就能解决静止时误输出方向的问题了。
内容的提问来源于stack exchange,提问作者Emad mohseny
相关产品推荐
相关产品推荐

