基于PS2手柄的Arduino遥控小车

Arduino与PS2手柄的无线控制实现 本文详细介绍了如何利用Arduino与PS2手柄实现无线控制。通过硬件连接、PS2X库文件安装和核心代码实战,手把手指导读者完成从基础测试到遥控小车项目的完整流程。该方案成本低、易于实现,为机器人、智能设备控制提供了稳定且低延迟的无线交互方案,是电子DIY爱好者的实用入门选择。 阅读详情
AI摘要

本文介绍了如何使用Arduino UNO、PS2手柄和L298N驱动模块制作一个可通过蓝牙控制的遥控小车。通过配置PS2手柄的红灯或绿灯模式,实现小车的前后左右移动。代码中详细解释了各部分的功能,包括按键检测和电机控制。

前言

本文利用PS2手柄和Arduino开发板制作了一个简易的遥控小车,利用蓝牙进行通信,可以实现前后左右的移动。(原理掌握之后可以自己拓展相关功能)

一、零件

1.Arduino UNO开发板:

ArduinoUNO是ArduinoUSB接口系列的最新版本,作为Arduino平台的参考标准模板。UNO的处理器核心是ATmega328,同时具有14路数字输入/输出口(其中6路可作为PWM输出),6路模拟输入,一个16MHz晶体振荡器,一个USB口,一个电源插座,一个ICSPheader和一个复位按钮。
在这里插入图片描述

2.PS2手柄与接收器:

PS2 手柄由手柄与接收器两部分组成,手柄主要负责发送按键信息;接收器与单片机相连,用于接收手柄发来的信息,并传递给单片机,单片机也可通过接收器,向手柄发送命令,配置手柄的发送模式。
在这里插入图片描述
接收器的引脚功能如下图所示:
在这里插入图片描述
特别需要提醒的是:按下遥控器的 MODE 键,手柄可配置成“红灯模式”或者“绿灯模式”,当遥控器侧面的 “MODE LED”亮为红灯模式,反之为绿灯模式,“红灯模式”和“绿灯模式”的主要区别是摇杆模拟值得输出。

3.L298N驱动模块:

L298N,是一款接受高电压的电机驱动器,直流电机和步进电机都可以驱动。一片驱动芯片可同时控制两个直流减速电机做不同动作,在6V到46V的电压范围内,提供2安培的电流,并且具有过热自断和反馈检测功能。L298N可对电机进行直接控制,通过主控芯片的I/O输入对其控制电平进行设定,就可为电机进行正转反转驱动,操作简单、稳定性好,可以满足直流电机的大电流驱动条件。

在这里插入图片描述

4.面包板

面包板是由于板子上有很多小插孔,专为电子电路的无焊接实验设计制造的。由于各种电子元器件可根据需要随意插入或拔出,免去了焊接,节省了电路的组装时间,而且元件可以重复使用,所以非常适合电子电路的组装、调试和训练。

在这里插入图片描述

5.小车

由亚克力板、直流电机、小轮胎、电池盒、电池等搭建的小车。
在这里插入图片描述

二、代码

#include <PS2X_lib.h>  //for v1.6

#define PS2_DAT        13  //14    
#define PS2_CMD        11  //15
#define PS2_SEL        10  //16
#define PS2_CLK        12  //17

int input1 = 5; //PIN 5(PWM)
int input2 = 6; //PIN 6(PWM)
int input3 = 9; //PIN 9(PWM)
int input4 = 3; //PIN 3(PWM)

#define pressures   true
#define rumble      true

PS2X ps2x; // create PS2 Controller Class

int error = 0;
byte type = 0;
byte vibrate = 0;

// Reset func 
void (* resetFunc) (void) = 0;

void setup(){
 
  Serial.begin(9600);
  
  delay(500);  //added delay to give wireless ps2 module some time to startup, before configuring it
   
  error = ps2x.config_gamepad(PS2_CLK, PS2_CMD, PS2_SEL, PS2_DAT, pressures, rumble);
  
  if(error == 0){
    Serial.print("Found Controller, configured successful ");
    Serial.print("pressures = ");
	if (pressures)
	  Serial.println("true ");
	else
	  Serial.println("false");
	Serial.print("rumble = ");
	if (rumble)
	  Serial.println("true)");
	else
	  Serial.println("false");
    Serial.println("Try out all the buttons, X will vibrate the controller, faster as you press harder;");
    Serial.println("holding L1 or R1 will print out the analog stick values.");
    Serial.println("Note: Go to www.billporter.info for updates and to report bugs.");
  }  
  else if(error == 1)
    Serial.println("No controller found, check wiring, see readme.txt to enable debug. visit www.billporter.info for troubleshooting tips");
   
  else if(error == 2)
    Serial.println("Controller found but not accepting commands. see readme.txt to enable debug. Visit www.billporter.info for troubleshooting tips");

  else if(error == 3)
    Serial.println("Controller refusing to enter Pressures mode, may not support it. ");
  
  type = ps2x.readType(); 
  switch(type) {
    case 0:
      Serial.println("Unknown Controller type found ");
      break;
    case 1:
      Serial.println("DualShock Controller found ");
      break;
    case 2:
      Serial.println("GuitarHero Controller found ");
      break;
	case 3:
      Serial.println("Wireless Sony DualShock Controller found ");
      break;
   }
pinMode(input1,OUTPUT);
pinMode(input2,OUTPUT);                                                    
pinMode(input3,OUTPUT); 
pinMode(input4,OUTPUT);
}


void STOP(){
 digitalWrite(input1,LOW);
 digitalWrite(input2,LOW);  
 digitalWrite(input3,LOW);
 digitalWrite(input4,LOW);  
}//停止函数

void RUN(){
  digitalWrite(input1,HIGH); 
  digitalWrite(input2,LOW); 
  digitalWrite(input3,LOW);
  digitalWrite(input4,HIGH); 
 analogWrite(input1,250);
 analogWrite(input4,250);
}//可调速的前进函数

void LEFT(){
  digitalWrite(input1,HIGH); 
  digitalWrite(input2,LOW);  
  digitalWrite(input3,HIGH); 
  digitalWrite(input4,LOW); 
 analogWrite(input1,200);
 analogWrite(input3,200);
}//可调速的左转函数

void RIGHT(){
  digitalWrite(input1,LOW);
  digitalWrite(input2,HIGH);  
  digitalWrite(input3,LOW);
  digitalWrite(input4,HIGH); 
 analogWrite(input2,200);
 analogWrite(input4,200);
}//可调速的右转函数

void BACK(){
  digitalWrite(input1,LOW); 
  digitalWrite(input2,HIGH); 
  digitalWrite(input3,HIGH);
  digitalWrite(input4,LOW); 
 analogWrite(input2,250);
 analogWrite(input3,250);
}//可调速的后退函数
void loop() {
  
  if(error == 1){ //skip loop if no controller found
    resetFunc();
  }
  
  if(type == 2){ //Guitar Hero Controller
    ps2x.read_gamepad();          //read controller 
   
    if(ps2x.ButtonPressed(GREEN_FRET))
      Serial.println("Green Fret Pressed");
    if(ps2x.ButtonPressed(RED_FRET))
      Serial.println("Red Fret Pressed");
    if(ps2x.ButtonPressed(YELLOW_FRET))
      Serial.println("Yellow Fret Pressed");
    if(ps2x.ButtonPressed(BLUE_FRET))
      Serial.println("Blue Fret Pressed");
    if(ps2x.ButtonPressed(ORANGE_FRET))
      Serial.println("Orange Fret Pressed"); 

    if(ps2x.ButtonPressed(STAR_POWER))
      Serial.println("Star Power Command");
    
    if(ps2x.Button(UP_STRUM))          //will be TRUE as long as button is pressed
      Serial.println("Up Strum");
    if(ps2x.Button(DOWN_STRUM))
      Serial.println("DOWN Strum");
 
    if(ps2x.Button(PSB_START))         //will be TRUE as long as button is pressed
      Serial.println("Start is being held");
    if(ps2x.Button(PSB_SELECT))
      Serial.println("Select is being held");
    
    if(ps2x.Button(ORANGE_FRET)) {     // print stick value IF TRUE
      Serial.print("Wammy Bar Position:");
      Serial.println(ps2x.Analog(WHAMMY_BAR), DEC); 
    } 
  }
  else { //DualShock Controller
    ps2x.read_gamepad(false, vibrate); //read controller and set large motor to spin at 'vibrate' speed
    
    if(ps2x.Button(PSB_START))         //will be TRUE as long as button is pressed
      Serial.println("Start is being held");
    if(ps2x.Button(PSB_SELECT))
      Serial.println("Select is being held");      

    if(ps2x.Button(PSB_PAD_UP)) {      //will be TRUE as long as button is pressed
      Serial.print("Up held this hard: ");
      RUN();
      Serial.println(ps2x.Analog(PSAB_PAD_UP), DEC);
    }
    if(ps2x.Button(PSB_PAD_RIGHT)){
      Serial.print("Right held this hard: ");
      LEFT();
      Serial.println(ps2x.Analog(PSAB_PAD_RIGHT), DEC);
    }
    if(ps2x.Button(PSB_PAD_LEFT)){
      Serial.print("LEFT held this hard: ");
      RIGHT();
      Serial.println(ps2x.Analog(PSAB_PAD_LEFT), DEC);
    }
    if(ps2x.Button(PSB_PAD_DOWN)){
      Serial.print("DOWN held this hard: ");
      BACK();
      Serial.println(ps2x.Analog(PSAB_PAD_DOWN), DEC);
    }   

    vibrate = ps2x.Analog(PSAB_CROSS);  //this will set the large motor vibrate speed based on how hard you press the blue (X) button
    if (ps2x.NewButtonState()) {        //will be TRUE if any button changes state (on to off, or off to on)
      if(ps2x.Button(PSB_L3))
        Serial.println("L3 pressed");
      if(ps2x.Button(PSB_R3))
        Serial.println("R3 pressed");
      if(ps2x.Button(PSB_L2))
        Serial.println("L2 pressed");
      if(ps2x.Button(PSB_R2))
        Serial.println("R2 pressed");
      if(ps2x.Button(PSB_TRIANGLE))
        Serial.println("Triangle pressed");   
        STOP();      
    }

    if(ps2x.ButtonPressed(PSB_CIRCLE))               //will be TRUE if button was JUST pressed
      Serial.println("Circle just pressed");
    if(ps2x.NewButtonState(PSB_CROSS))               //will be TRUE if button was JUST pressed OR released
      Serial.println("X just changed");
    if(ps2x.ButtonReleased(PSB_SQUARE))              //will be TRUE if button was JUST released
      Serial.println("Square just released");     

    if(ps2x.Button(PSB_L1) || ps2x.Button(PSB_R1)) { //print stick values if either is TRUE
      Serial.print("Stick Values:");
      Serial.print(ps2x.Analog(PSS_LY), DEC); //Left stick, Y axis. Other options: LX, RY, RX  
      Serial.print(",");
      Serial.print(ps2x.Analog(PSS_LX), DEC); 
      Serial.print(",");
      Serial.print(ps2x.Analog(PSS_RY), DEC); 
      Serial.print(",");
      Serial.println(ps2x.Analog(PSS_RX), DEC); 
    }     
  }
  delay(50);  
}

参考文献

  1. https://www.arduino.cc/
基于Arduino的手柄遥控智能车 使用PS2远程遥控手柄的方向按钮控制小车运动,包含源码和原理讲解 阅读详情

相关推荐

用PS2手柄和Arduino UNO,我给孩子做了个遥控小车(附完整代码和接线图)

本文详细介绍了如何利用PS2手柄和Arduino UNO制作亲子互动遥控小车的完整过程,包括硬件接线、代码编写和调试技巧。通过这个项目,不仅能让孩子学习基础的电子和编程知识,还能增强亲子互动,培养STEM兴趣。附完整代码和接线图,适合家庭DIY。

weixin_28718793的博客 150

老游戏手柄的新玩法:拆解PS2无线协议,教你用Arduino或ESP32自制遥控器

本文详细解析了PS2手柄的无线通讯协议,并指导如何用Arduino或ESP32自制遥控器。通过硬件连接方案和核心代码实现,帮助创客将闲置PS2手柄改造为高性价比控制器,适用于机器人、智能家居等多种DIY项目。

weixin_30587927的博客 510

用PS2手柄和Arduino UNO做个遥控小车,手把手教你从接线到代码调试(附完整代码)

本文详细介绍了如何使用PS2手柄和Arduino UNO制作智能遥控小车,从硬件搭建到代码调试的全过程。通过清晰的接线图和完整的代码示例,帮助读者快速掌握Arduino编程和电机控制技术,实现无线遥控功能。项目适合初学者,兼具趣味性和实用性。

weixin_42631411的博客 135

arduino uno开发板搭配SP2手柄控制舵机

这是摇杆的定义,我们知道PS2手柄的两个摇杆分别有X轴和Y轴两个轴,我们通过PS2手柄的模拟值进行判断,使其能够达到相应的效果,LX,LY就是左边摇杆的两个轴,RX,RY就是右边摇杆的两个轴。而在代码中模拟值小于10就是左边摇杆向上推,这个模拟值的定义是与我们的库函数有关的,你说为什么小于10就是向上推,这就是库函数中定义好的,你也可以修改。我们大多数时候使用PS2手柄只需要简略的了解他的原理,PS2手柄原理的文章很多,更多的是要去看封装的函数,或者是我们导入的函数库,去学习我们应该如何调参。

Xushao_qing的博客 3411

Arduino PS2手柄智能小车:从库配置到遥控驾驶全解析

本文详细解析了如何使用Arduino和PS2手柄实现智能小车的遥控驾驶,从库配置、硬件接线到核心代码编写全流程指导。通过优化PWM调速和按键防抖等技巧,提升控制精度,适合硬件爱好者快速上手。文章还提供了常见问题排查方法和进阶功能扩展建议。

weixin_29185493的博客 361

用PS2手柄和Arduino UNO做个遥控小车,代码和接线保姆级教程(附避坑点)

本文详细介绍了如何使用PS2手柄和Arduino UNO制作遥控小车的完整教程,包括硬件连接、代码编写和常见问题解决方案。通过L298N电机驱动模块实现精准控制,提供避坑点和进阶玩法,适合DIY爱好者和创客实践。

weixin_26897585的博客 230

PS2手柄遥控控制灯开关(arduino)

PS2手柄遥控控制灯开关(arduino) 使用的材料 arduino板子: ps2遥控手柄; 一个5V供电的LDE; 连线 首先按照遥控手柄底座上的英文,你会发现一共有六根线,分别是GND,VCC,DAT,CMD,CS,CL。GND连接arduino板子上的gnd,vcc连接5V或者3.3v,其他四根线可以按照代码中的引脚设置连接,也可以自己更改。 代码部分 #include <PS...

weixin_42673396的博客 2946

PS2手柄+Arduino智能小车遥控实战:接线、协议与避坑指南

在机器人控制和创客项目中,无线遥控方案的选型往往直接影响开发效率与操控体验。相比手机APP的蓝牙串口透传和航模遥控器的高成本,PS2手柄以其成熟稳定的同步串行通讯、细腻的比例摇杆控制以及极低的上手门槛,成为众多开发者遥控智能小车、机械臂和云台的首选。其底层通讯协议类似SPI主机模式,主控通过CLK、CMD、DAT、SEL四线时序即可完成手柄数据的实时读取,配合PWM调速可实现差速转向、弧线行驶等细腻操作。本文从硬件接线与电平匹配出发,深入解析PS2X库的协议核心,给出Arduino驱动双电机的完整示例代码,

weixin_30983965的博客 93

PS2手柄遥控Arduino小车

使用手柄遥控小车是经常要用到的,看到PS2手柄很6,就拿来尝试一下。 PS2手柄是索尼的PlayStation2游戏机的遥控手柄,因为这款手柄性价比较高,按键丰富,方便扩展到其它应用中,后来有人将其通讯协议破解,使得手柄可以用在遥控其他电器上,比如遥控控制机器人小车。最主要的是这款手柄,拿来就可以用,有人已经将其通讯协议破解了。 具体可以参考极客工坊。 其PS2X_lib库,可以参见Github

ゃ﹏淸凨ゞ 3万+

用废旧PS2手柄改造智能小车控制器:Arduino无线遥控方案详解

本文详细介绍了如何利用废旧PS2手柄和Arduino改造智能小车无线遥控器的完整方案。通过解析PS2手柄的SPI通信协议,结合L298N电机驱动模块,实现对小车的精确控制。文章提供了从硬件连接到软件编程的详细步骤,包括信号解析、电机驱动逻辑以及利用模拟摇杆实现PWM速度控制等进阶优化技巧,为硬件爱好者和创客提供了一个低成本、高可玩性的环保实践项目。

w7x8y9z的博客 520

【雕爷学编程】Arduino动手做(118)---PS2接口模块

雕爷学编程,Arduino动手做,开源硬件,创客传感器,PS2接口模块

雕爷学编程 1007

从PS2手柄到Arduino:打造可编程遥控小车的实战指南

本文详细介绍了如何利用PS2手柄和Arduino打造可编程遥控小车的实战指南。从硬件搭建到软件配置,再到调试优化,全面解析了PS2手柄的双模拟摇杆控制、Arduino的PWM调速与差速转向技术,帮助创客低成本实现专业级遥控小车功能。

weixin_30443075的博客 379

Arduino智能小车PS2手柄遥控实战:PS2X-lib接线与避坑指南

在嵌入式开发中,外设通信与遥控交互是机器人项目的常见技术点。Arduino作为广泛使用的开源平台,常与各类手柄、无线模块配合实现小车或机械臂的控制。PS2手柄因其摇杆精度和按键丰富性,成为遥控方案的优选。其底层协议通过时钟、数据、命令等信号线实现双向通信,而PS2X-lib库封装了复杂的时序逻辑,使开发者能高效读取摇杆模拟量和按键状态。该方案适用于智能小车差速转向、机械臂舵机控制等场景,同时需注意初始化时序、电气干扰及掉线保护等工程问题。本文围绕PS2X-lib的接线方法、初始化流程、数据映射及常见避坑实践

weixin_30036289的博客 271

arduino(17):特别好玩的玩具,使用ESP32接入PS2无线手柄,然后控制小车,使用遥控杆控制前后左右,解决启动空转,和连接不上手柄一直空转问题,有接线图和源代码,给小盆友玩。

目录前言1,关于arduino 控制PS2手柄2,接线配置3,总结 前言 相关arduino 全部分类: https://blog.youkuaiyun.com/freewebsys/category_8799254.html 本文的原文连接是: https://blog.youkuaiyun.com/freewebsys/article/details/104855458 未经博主允许不得转载。 博主地址是:htt...

freewebsys的专栏 7299

Arduino+PS2+接线图+源码

Arduino+PS2+接线图+源码。包括支撑的库文件,亲测有效

MATLAB控制信号发生器(USB-GPIB-HS)GPIB仪器控制教程(含matlab代码)

自动化测试时需要自动产生信号,通过matlab控制信号发生器的频率与功率,以实现自动化信号生成输出

qq_43686057的博客 1606

基于Arduino的PS2机械臂遥控小车(L298N)傻瓜教程

基于Arduino的PS2机械臂遥控小车(L298N)傻瓜教程 1、材料 L298N、Arduino板、数据线、舵机、机械臂、亚克力板、电机、PS2、杜邦线、电池(7.4V)、螺丝。 2、软件 Arduino IDE。 3、代码 一、硬件安装: 安装车底盘: 线路连接: PS2//CLK接13号接口;CMD接11号接口;GND接GND接口;VCC接3.3V接口;CS接10号接口;DAT接12号接口...

Milleroh的博客 8302

IATF16949核心职位全解析

TM / Top MgmtMR / QMRProcess OwnerQMQAQCSQECQEPQEPETEMEIEPM / PJMFMEA ModeratorMSA CoordinatorSPC CoordinatorCM / CCB内审员CP / CPK

weixin_49938552的博客 972

小车主板哪家强?PS2手柄4路电机输出..火魔童主板了解一下?

微信关注“DLGG创客DIY”设为“星标”,重磅干货,第一时间送达。最近收到了芯吧客邮寄的火魔童V1.0主板,今天简单给大家介绍一下别的废话就不多说了,直接看干货重点资料板子介绍(功能概...

tiandiren111的专栏 832

保姆级教程:用GPU-Burn给你的NVIDIA Tesla服务器做个“压力体检”(附温度功耗监控脚本)

本文提供了一份详细的GPU服务器压力测试指南,重点介绍如何使用GPU-Burn工具对NVIDIA Tesla服务器进行全面的性能测试和温度功耗监控。从环境部署、多GPU测试策略到专业级监控指标解析,帮助运维人员构建标准化的GPU健康评估体系,确保AI训练和科学计算等关键业务的稳定性。

weixin_30619101的博客 395

用户画像标签维度_搭建电商平台用户画像标签体系

01 整体思路电商平台连接了卖家和买家两端,最终目的都是促进交易,从而追求更高的销售额。提高人货匹配度是促进交易的关键,而提高人货匹配度的关键就是“让买家找到想要的货物”。本文结合“人、货、场”理论模型,尝试建立电商平台的用户画像标签体系。02 三类标签用户在平台购物的整体流程可以概括为:进入平台、选择商品、下单付款。可以将该过程抽象为“人、货、场”。即用户通过什么途径进入什么商品的页面...

weixin_31668621的博客 1642

用PS2手柄和Arduino UNO R3,从零搭建你的第一台遥控小车(附完整代码与L298N接线图)

本文详细介绍了如何使用PS2手柄和Arduino UNO R3从零搭建遥控小车,包括硬件选购、接线图、代码解析与调试技巧。通过完整的教程和常见问题解决方案,帮助创客爱好者快速实现遥控小车的制作,提升硬件组装和编程能力。

weixin_42531163的博客 375

使用Python,OpenCV查找图像中的最亮点

这篇博客展示了,为什么在图像中找到最亮的点之前应用高斯模糊是至关重要的。 通过应用高斯模糊,可以将每个给定半径内的像素平均在一起。取平均值可以去除高频噪声,否则会影响cv2.minMaxLoc函数的结果。 一定要研究高斯模糊半径的恰当值。如果取值太小,将会减轻平均值的影响,而忽略了更大、更亮的区域。但是如果半径太大,将无法探测到小的明亮区域。

qq_40985985的博客 3809
下一篇: STM32+L298N+PWM可调速小车(四驱)
晓shuo
晓shuo 优质创作者: 人工智能技术领域 优质创作者: 人工智能技术领域
博客等级 码龄6年 4万+粉丝 113原创
评论 19
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

晓shuo

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值