You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.28 10:17:53