MJKDZ PS2手柄控制OskarBot小车(一):Arduino串口发送数据

【目录】

- 1、无线通信模块设置

- 1.1 设置参数

- 1.2 调试步骤

- 2、按键与通信格式

- 2.1 PS2按键定义

- 2.2 发送数据格式

- 3、源代码

- 3.1 串口手动发送数据进行设置

- 3.2 程序自动发送数据设置

- 3.3 全部代码

【背景信息】

铭佳科电子(MJKDZ)的无线手柄,PS2手柄形式,基于Arduino,可编程下载代码。

MJKDZ手柄相对于传统的PS2手柄,优点:USB充电,自定义按键,数据格式等,通信距离更远(2.4GHz,号称100m)。

2.4GHz通信,BK2461模块相比NRF24L01模块的优点:模块设置好之后(相同的组网、信道、波特率等),直接用串口发送数据,另一边用串口接收数据。没有像模拟SPI那种多余的数据、应答、时钟信号等。

手柄采购自:

https://item.taobao.com/item.htm?spm=a1z10.5-c-s.w4002-1876613493.18.32d625d3yNaM5K&id=551994689358

【参考】2.4G无线串口模块_博通_BK2461

【源代码】https://www.lanzous.com/i2wd9cd

1、无线通信模块设置

1.1 设置参数

一个手柄控制几个设备,参数设置成一样;

几个手柄在同一场合使用,改变信道,改变组网ID;

1.2 调试步骤

调试注意事项:

Arduino IDE  串口监控对中文支持好,其它串口调试助手不支持中文。

推荐 串口调试助手:USR-TCP232-Test-V1.3。

1)手柄连接电脑,打开Arduino IDE下载源码

将源码“Test_Code_程序自动设置_UART-TX_更新按键号码_按键功能定义_改摇杆输出顺序_改PS2数据格式2.c”,修改名称,后缀为.ino后,下载到手柄中。

打开串口调试助手 USR-TCP232-Test-V1.3,打开手柄串口COM10,完成设置

按下ALT+SHIFT键,返回按键数值 16383,松开后的按键数值65535

(2)输入无线模块设置参数

串口发送设置参数AA5A00010001000000040064000000120080

返回参数 AA 5B AB 36 00 01 00 00 00 04 00 64 00 00 00 12 00 61

模块ID为 AB36

Q1、返回参数显示特别慢?

注意:再次按AT+Shift设置结束(否则串口被占用,没有释放,无线模块无法发送数据)

(3)无线模块设置参数

无线模块通过USB转串口模块连接电脑,SET端口连GND。

串口调试助手,选择COM11

串口发送设置参数  AA 5A 00 01 00 01 00 00 00 04 00 64 00 00 00 12 00 80

返回   AA 5B AA F8 00 01 00 00 00 04 00 64 00 00 00 12 00 22

模块ID为  AAF8

(4)手柄按键显示+发送信息,无线模块接收信息并显示

Arduino IDE 选择COM10

调试助手选择 COM11

2、按键与通信格式

2.1 PS2按键定义

MJKDZ PS2手柄按键定义如下

2.2 发送数据格式

原数据格式:AA+BB+按键+摇杆

//====================发送数据函数=========================
 void TX_data() { //发送数据函数
  unsigned int i = 0;//定义循环变量
  unsigned int crc_byte = 0;//定义CRC校验变量
  tx_data[0] = 0xAA;    //校验码1
  tx_data[1] = 0xBB;    //校验码2
  tx_data[2] = buttons;//按键数字
  tx_data[3] = (unsigned char)L1int; //左摇杆上下A0  
  tx_data[4] = (unsigned char)L2int;//左摇杆左右A1
  tx_data[5] = (unsigned char)R1int;//右摇杆上下A2
  tx_data[6] = (unsigned char)R2int;//右摇杆左右A3
  for(i = 0; i < 7; i++)
  crc_byte += tx_data[i];
  while(crc_byte > 255)
   crc_byte -= 255;
  tx_data[7] = crc_byte;    // CRC校验
  Serial1.write(tx_data, 8);

}

根据PS2手柄格式,修改后:73+按键+摇杆+5A(对应关系参考第二篇博文)

//====================发送数据函数=========================
   void TX_DATA() { //发送数据函数
    unsigned int i = 0;//定义循环变量
    unsigned int crc_byte = 0;//定义CRC校验变量
    tx_data[0] = 0x73;    //红灯模式

if(buttons>=8 && buttons<=15)//发送第二组数据:左、下、右、上、START、R3、L3、SELECT
    {
            tx_data[1] = buttons_PS2;//按键数字
    }
    else{
            tx_data[1] = 0xFF;
    }

if(buttons>=0 && buttons<=7)//发送第二组数据:方形/叉/圆圈/三角/R1/L1/R2/L2
    {
            tx_data[2] = buttons_PS2;//按键数字
    }
    else{
            tx_data[2] = 0xFF;
    }

tx_data[3] = (unsigned char)R2int;//右摇杆R3左右A3 
    tx_data[4] = (unsigned char)R1int;//右摇杆上下A2
    tx_data[5] = (unsigned char)L2int;//左摇杆L3左右A1
    tx_data[6] = (unsigned char)L1int; //左摇杆上下A0

tx_data[7] = 0x5A;    //数据发送Ready

3、源代码

关键点:(1)无线模块参数设置正确;

(2)串口调试时,模拟串口(Serial)通过USB连接电脑,串口1(Serial1)连接无线模块;相互转发消息,用于串口调试,确保发送数据正确。

(3)发送的按键值,先判断条件,再赋值。

3.1 串口手动发送数据进行设置

//======SELECT+START按键:手动配置无线串口模块AT设置===============
  if(keyint==16383){
    //Serial.println("无线串口模块:开始手动设置,请输入参数");
    setwi=!setwi;//组合键第一次按下,设置标志位,开启串口设置
    digitalWrite(RULED,setwi);//功能指示灯开启用于显示无线模块开始设置
    delay(600);//为了防止按键重复开启关闭设置端口必须延时

if(setwi==1){//如果是组合键按下,第一次按下为1,则启动设置无线模块参数
      digitalWrite(SET, LOW);//设置无线模块管脚开启
      setWX=true;//串口转发标志true,代表开启串口转发,为了软件设置串口
      //Serial.println("无线串口模块(手动设置):参数读取完毕,请再次按ELECT+START键");
   
     
    }

else{//如果是组合键按下,第二次按下为0,则关闭设置无线模块
       delay(600);//为了防止按键重复开启关闭设置端口必须延时
       digitalWrite(SET, HIGH);//关闭无线模块的设置管脚
       digitalWrite(RULED, LOW);//功能指示关闭无线模块设置结束
       //Serial.println("无线串口模块:手动设置OK");
       setWX=false;//串口转发标志false,代表关闭串口,转发为了软件设置串口
    }
  }

/*//======串口转发:手动设置无线模块,并显示返回值=============
  输入参数较慢,需要在主循环中不停遍历和判断
  //(1)、电脑通过USB模拟串口,发送无线模块设置参数给Ardunino;
  //(2)、Arduino的模拟串口,收到设置参数,转发给串口1,传给无线串口模块,完成参数设置;
  //(3)、无线串口模块返回参数(包含模块ID),给串口1;
  //(4)、串口1转发给模拟串口,通过USB在电脑上显示返回参数
  //  ===================================================//*/

//======接收数据在主函数中,因为不知道什么时候串口发数据,要一直轮询========
  if(setWX == true){   //接收串口设置参数 18位数组
    if(Serial.available()){//串口转发,模拟串口发给串口1
        for(char i=0;i<18;i++)//一次只能读取一位数据,轮训18次
        {
          Serial1.write(Serial.read()); //模拟串口读取数据,发给串口1。
        }    
        bibi();//蜂鸣器函数
    }

if(Serial1.available()){//串口转发,串口1返回参数,发给模拟串口
        for(char i=0;i<18;i++)//一次只能读取一位数据,轮训18次
        {
          Serial.write(Serial1.read()); //串口1读取数据,发给模拟串口。
        }    
        bibi();

}

}

3.2 程序自动发送数据设置

//======SELECT+START按键:自动设置无线串口模块参数===============
  if(keyint==16383){ //判断SELECT+START按键是否同时按下
    setwi=!setwi;//组合键第一次按下,设置标志位,开启串口设置

if(setwi==1){//如果是组合键按下则启动设置无线模块参数
      digitalWrite(RULED, HIGH);//功能指示灯开启用于显示无线模块开始设置
      digitalWrite(SET, LOW);//设置无线模块管脚开启
      setWX=true;//串口转发标志true,代表开启串口转发,为了软件设置串口
     
      delay(600);//延时600ms
      Serial1.write(SETWX,18);//给串口(无线模块)发送18组16进制数,设置参数指令的18位字符数组
      delay(600);//延时600ms
      
      if(Serial1.available())//串口转发,串口1返回参数,发给模拟串口
      {
        for(char i=0;i<18;i++)//一次只能读取一位数据,轮训18次
        {
          Serial.write(Serial1.read()); //串口1读取数据,发给模拟串口。
        }
        Serial.print("\n");
       
        bibi();//蜂鸣器函数
      }

digitalWrite(RULED, LOW);//功能指示,关闭无线模块设置结束
      //Serial.println("无线串口模块设置OK,可以发送数据");

3.3 全部代码

#include <Mkeyin2.h>//按键函数库调用
Mkeyin2<2> Mkey; //按键控制芯片设置

/*=============================
程序说明:
1、模拟串口通过USB连接电脑,串口1连接无线模块;
2、AT+Shift,启动串口无线设置:程序自动设置无线模块参数,串口1发送参数到无限模块,并将返回参数通过模拟串口显示。
无法在Arduino IDE的串口监视器中显示,需要使用串口调试助手 USR-TCP232-Test-V1.3
3、按键有更新,模拟串口显示按键数据+发送数据+按键功能(Arduino IDE查看),串口1无线模块发送8位数据(串口调试助手查看)。
4、摇杆数值有变更,不发送串口数据(后期再追加 )Volts: 4.24LX: 129LY: 128RX: 125RY: 125;
5、更新按键号码,保持与按键函数一致;
6、改摇杆输出顺序:右摇杆R3左右(X轴)->右摇杆R3上下(Y轴)->左摇杆L3左右(X轴)->左摇杆L3上下(Y轴);
7、增加变量 buttons_PS2,用于保持与PS2手柄按键格式一致;去掉校验位与CRC和校验
无线模块发送数据,格式为8为字符:校验位/红灯模式/0x73+按键值+摇杆数值+校验位0x5A;
/*======================

/*==========================
 *   串口无线模块设置指令
 ===========================*/
//AA 5A 00 01 00 01 00 00 00 04 00 64 00 00 00 12 00 80
unsigned char SETWX[18] ={0xAA,0x5A,0x00,0x01,0x00,0x01,0x00,0x00,0x00,0x04,0x00,0x64,0x00,0x00,0x00,0x12,0x00,0x80};//18个16进制

//========所有IO功能口定义===========
const int LMotor=10;//左震动电机
const int RMotor=6;//右震动电机
const int buzzer=9;//蜂鸣器接口
const int SET=4;//串口无线模块AT调试使能接口
const int CS=13;//无线模块使能睡眠管脚(2.4G无线模块有效)
const int OFF_POW=23;//关机端口(默认必须低电平否则会自动关机)

//====================================
const int Bat=A4;//电池电压读取
const int Lxvr=A2;//左摇杆上下
const int Lyvr=A3;//左摇杆左右
const int Rxvr=A0;//右摇杆上下
const int Ryvr=A1;//右摇杆上下
const int RULED=17;//运行状态指示灯

//==============变量定义==================
long keyint=0;//测试电压摇杆标记变量
byte setwi;//无线模块设置状态变量

float Var;//计算公式得到的数值存储变量
float voltage;//实际电压存储变量
unsigned char buttons = 99;    //按键值变量,初始值为99,对应65535
unsigned int buttons_PS2 = 99;//PS2手柄按键值,初始值为99,对应65535

byte Lset;  //左摇杆数据发送状态变量
byte Rset;  //左摇杆数据发送状态变量

//**======小车加速、减速控制============**//
int L1int=0;  //左摇杆上下数据存储变量,

int L2int=0;  //左摇杆左右数据存储变量
int R1int=0;  //右摇杆上下数据存储变量
int R2int=0;  //右摇杆左右数据存储变量

byte tx_data[8];//发送8个数据

//=====小车运动方向控制========
#define FORWARD 3//MOTO COMMAND
#define BACKWARD 1
#define TURNLEFT 0
#define TURNRIGHT 2
#define CARSTOP 99

//==========超声波舵机方向控制======
#define SONICINCREASE 10  //角度增大,向右转0->30->60
#define SONICDECREASE 12  //角度减小,向左转0<-30<-60

//==========摄像头舵机方向控制======
#define CAMERAINCREASE 13  //角度增大,向右转0->30->60
#define CAMERADECREASE 11  //角度减小,向左转0<-30<-60

//=========== 标志=========================
boolean setWX= false;//false!true 切换串口转发功能标志,主要用于软件设置无线模块。

//=================设置函数==================
void setup() {
   pinMode(OFF_POW, OUTPUT);//设定关机端口为输出
   digitalWrite(OFF_POW, LOW);//关机端口默认设置为关闭状态否则会自动关机

Var=1023.0/(3.3/(10.0/(10.0+10.0)));//电池电压计算公式,并将计算好的数值送给变量

pinMode(CS, OUTPUT);//设置为输出
   pinMode(SET, OUTPUT);//设置为输出
   pinMode(RULED, OUTPUT);//设置为输出

Serial1.begin(9600);//串口1,连接无线模块2.4GHz
   Serial.begin(9600);//默认虚拟串口,USB连接电脑

Mkey.begin();//按键函数库初始化
   digitalWrite(CS, LOW);//设置无线模块开启(2.4G无线模块可用)
   digitalWrite(SET, HIGH);//设置无线模块管脚关闭
}

//=============主函数
void loop() {

if(setWX==false){//判断串口转发标志是否开启false代表没有开启
   if (Serial1.available()) {//判断无线模块是否接收到了数据
    if (Serial1.read()=='A'){//串口接收到了数据就调用蜂鸣器函数
      bibi();//蜂鸣器函数 哔哔响
      }
    }
  }

voltage = (float)analogRead(Bat)/Var;//读取电压并除以计算公式所得到的数值,然后将得到的实际电压送给实际电压存储变量
 
  L1int = analogRead(Lxvr);//读取左摇杆上下数据
  L2int = analogRead(Lyvr);//读取左摇杆左右数据
  R1int = analogRead(Rxvr);//读取右摇杆上下数据
  R2int = analogRead(Ryvr);//读取右摇杆左右数据

L1int= map(L1int, 0, 1023, 0, 255);//将左摇杆上下数据1023转换成255,并送给发送数据串里
  L2int= map(L2int, 0, 1023, 0, 255);//将左摇杆左右数据1023转换成255,并送给发送数据串里
  R1int= map(R1int, 0, 1023, 0, 255);//将右摇杆上下数据1023转换成255,并送给发送数据串里
  R2int= map(R2int, 0, 1023, 0, 255);//将右摇杆左右数据1023转换成255,并送给发送数据串里

//========调用函数,更新按键值为按键号码==========
  Bkey_Long();//调用按键函数,支持长按键(前:L1/2,R1/2)
  Bkey_Short(); //调用按键按下和释放功能函数,短按键(左+右)
  Bkey_Function();//功能按键函数(前:L1/2,R1/2)
 
  if (Mkey.update()) {
    for (int i = 0; i < Mkey.getDataWidth(); i++);//循环读取按键数值
    keyint=Mkey.getCurrent();//将读取按键数值送给按键变量
  
    if(buttons<14){// 除SELECT,START,SELECT+START按键
      Serial.println(buttons);//模拟串口,让USB口发送按键值,除外:SELECT+START按键没有被按下(buttons=16)

if(setWX==false){//判断串口转发标志是否开启,false代表没有开启,串口转发。
        //======按键号码更新,调用发送数据函数
   
        TX_DATA();//按键有更新,发送数据,模拟串口发送按键功能命令
        //Serial1.println(keyint);//串口1,让无线模块发送按键值
      }
    }
  }

//======SELECT+START按键:自动设置无线串口模块参数===============
  if(keyint==16383){ //判断SELECT+START按键是否同时按下
    setwi=!setwi;//组合键第一次按下,设置标志位,开启串口设置

if(setwi==1){//如果是组合键按下则启动设置无线模块参数
      digitalWrite(RULED, HIGH);//功能指示灯开启用于显示无线模块开始设置
      digitalWrite(SET, LOW);//设置无线模块管脚开启
      setWX=true;//串口转发标志true,代表开启串口转发,为了软件设置串口
     
      delay(600);//延时600ms
      Serial1.write(SETWX,18);//给串口(无线模块)发送18组16进制数,设置参数指令的18位字符数组
      delay(600);//延时600ms
      
      if(Serial1.available())//串口转发,串口1返回参数,发给模拟串口
      {
        for(char i=0;i<18;i++)//一次只能读取一位数据,轮训18次
        {
          Serial.write(Serial1.read()); //串口1读取数据,发给模拟串口。
        }
        Serial.print("\n");
       
        bibi();//蜂鸣器函数
      }

digitalWrite(RULED, LOW);//功能指示,关闭无线模块设置结束
      //Serial.println("无线串口模块设置OK,可以发送数据");
      digitalWrite(SET, HIGH);//关闭无线模块的设置管脚
      setWX=false;//串口转发标志false,代表关闭串口,转发为了软件设置串口   
      setwi=0;//清除设置标志位
    }    
  }

}

//====================发送数据函数=========================
   void TX_DATA() { //发送数据函数
    unsigned int i = 0;//定义循环变量
    unsigned int crc_byte = 0;//定义CRC校验变量
    tx_data[0] = 0x73;    //红灯模式

if(buttons>=8 && buttons<=15)//发送第二组数据:左、下、右、上、START、R3、L3、SELECT
    {
            tx_data[1] = buttons_PS2;//按键数字
    }
    else{
            tx_data[1] = 0xFF;
    }

if(buttons>=0 && buttons<=7)//发送第二组数据:方形/叉/圆圈/三角/R1/L1/R2/L2
    {
            tx_data[2] = buttons_PS2;//按键数字
    }
    else{
            tx_data[2] = 0xFF;
    }

tx_data[3] = (unsigned char)R2int;//右摇杆R3左右A3 
    tx_data[4] = (unsigned char)R1int;//右摇杆上下A2
    tx_data[5] = (unsigned char)L2int;//左摇杆L3左右A1
    tx_data[6] = (unsigned char)L1int; //左摇杆上下A0

tx_data[7] = 0x5A;    //数据发送Ready

/*  参考PS2格式,去掉CRC校验位
    for(i = 0; i < 7; i++)
    crc_byte += tx_data[i];
    while(crc_byte > 255)
     crc_byte -= 255;
    tx_data[7] = crc_byte;    // CRC校验
*/

Serial1.write(tx_data, 8); // 发送数据

//=====打印发送的数据
     Serial.print("Send Data=");
     Serial.print(tx_data[0],HEX);
     Serial.print("-");
     Serial.print(tx_data[1],HEX);
     Serial.print("-");
     Serial.print(tx_data[2],HEX);
     Serial.print("-");
     Serial.print(tx_data[3]);
     Serial.print("-");
     Serial.print(tx_data[4]);
     Serial.print("-");
     Serial.print(tx_data[5]);
     Serial.print("-");
     Serial.print(tx_data[6]);
     Serial.print("-");
     Serial.println(tx_data[7],HEX);

switch(tx_data[2])
    {
       case FORWARD:
      Serial.println("前进");
       //tone(buzzer, 1000); // 发送给蜂鸣器1KHz声音信号
       break;
       case BACKWARD:
      Serial.println("后退");
        // tone(buzzer, 100); // 发送给蜂鸣器1KHz声音信号
       break;
       case TURNLEFT:
       Serial.println("左转");
      // tone(buzzer, 400); // 发送给蜂鸣器1KHz声音信号
       break;
       case TURNRIGHT:
       Serial.println("右转");
      // tone(buzzer, 500); // 发送给蜂鸣器1KHz声音信号
       break;
       case CARSTOP:
       Serial.println("停止");
     //  noTone(buzzer);     //停止发送
       break;

case SONICINCREASE:
       Serial.println("超声波右转(角度增大)");
       break;
       case SONICDECREASE:
       Serial.println("超声波左转(角度减小)");
       break;
       case CAMERAINCREASE:
       Serial.println("摄像头右转(角度增大)");
       break;
       case CAMERADECREASE:
       Serial.println("摄像头左转(角度减小)");
       break;
    }
  }

//**===========按键数值转换为按键号码:支持长按===========
  void Bkey_Long(){//按键函数
    switch(keyint){
    case 65023://判断如果是L1按键按下
    //buttons=9;//给按键变量赋值9
    buttons=7;//给按键变量赋值7,根据PS2按键定义,与R1,R2在同一组
    buttons_PS2=0xFB;        //PS2按键赋值
    break;
    case 65279://判断如果是L2按键按下
    //buttons=8;//给按键变量赋值8
    buttons=6;//给按键变量赋值6,根据PS2按键定义,与R1,R2在同一组
    buttons_PS2=0xFE;        //PS2按键赋值
    break;
    case 65519://判断如果是R1按键按下
    buttons=4;//给按键变量赋值4
    buttons_PS2=0xF7;        //PS2按键赋值
    break;
    case 65503://判断如果是R2按键按下
    buttons=5;//给按键变量赋值5
    buttons_PS2=0xFD;        //PS2按键赋值
    break;
    case 16383://判断如果是Shift+Start按键同时按下
    buttons=16;//给按键变量赋值16
    break;
    }
  }
//**===========按键数值转换为按键号码:仅支持短按===========
void Bkey_Short(){
//===========三角按键=======================
   if(Mkey.released(3)){//判断按键是否按下
    buttons=3;                        //给按键变量赋值3,前进,FORWARD
    buttons_PS2=0xEF;        //PS2按键赋值
    }
   if(Mkey.pressed(3)){ //按键是否松开
   buttons=99;                        //给按键变量赋值99
   buttons_PS2=0xFF;        //给变量赋值FF
    }
 //===========X按键=======================
   if(Mkey.released(1)){//判断按键是否按下
    buttons=1;                        //给按键变量赋值1,后退,BACKWARD
    buttons_PS2=0xBF;        //PS2按键赋值
    }
   if(Mkey.pressed(1)){ //按键是否松开
    buttons=99;                        //给按键变量赋值99
   buttons_PS2=0xFF;        //给变量赋值FF
    }
 //===========正方形按键=======================
   if(Mkey.released(0)){//判断按键是否按下
    buttons=0;//给按键变量赋值0,左转,LEFT
    buttons_PS2=0x7F;        //PS2按键赋值
    }
   if(Mkey.pressed(0)){ //按键是否松开
   buttons=99;//给按键变量赋值99
   buttons_PS2=0xFF;        //给变量赋值FF
    }
 //===========圆圈按键=======================
   if(Mkey.released(2)){//判断按键是否按下
    buttons=2;给按键变量赋值2,右转,RIGHT
    buttons_PS2=0xDF;        //PS2按键赋值
    }
   if(Mkey.pressed(2)){ //按键是否松开
    buttons=99;//给按键变量赋值99
    buttons_PS2=0xFF;        //给变量赋值FF
    }

//===========上按键=======================
   if(Mkey.released(10)){//判断按键是否按下
    buttons=10;//给按键变量赋值3,前进,FORWARD
    buttons_PS2=0xEF;        //PS2按键赋值
    }
   if(Mkey.pressed(10)){ //按键是否松开
   buttons=99;//给按键变量赋值99
   buttons_PS2=0xFF;        //给变量赋值FF
    }
 //===========下按键=======================
   if(Mkey.released(12)){//判断按键是否按下
    buttons=12;//给按键变量赋值1,后退,BACKWARD
    buttons_PS2=0xBF;        //PS2按键赋值
    }
   if(Mkey.pressed(12)){ //按键是否松开
    buttons=99;//给按键变量赋值99
    buttons_PS2=0xFF;        //给变量赋值FF
    }
 //===========左按键=======================
   if(Mkey.released(11)){//判断按键是否按下
    buttons=11;//给按键变量赋值0,左转,LEFT
    buttons_PS2=0x7F;        //PS2按键赋值
    }
   if(Mkey.pressed(11)){ //按键是否松开
   buttons=99;//给按键变量赋值99
   buttons_PS2=0xFF;        //给变量赋值FF
    }
 //===========右按键=======================
   if(Mkey.released(13)){//判断按键是否按下
    buttons=13;给按键变量赋值2,右转,RIGHT
    buttons_PS2=0xDF;        //PS2按键赋值
    }
   if(Mkey.pressed(13)){ //按键是否松开
    buttons=99;//给按键变量赋值99
    buttons_PS2=0xFF;        //给变量赋值FF
    }

//===========SELECT按键=======================
   if(Mkey.released(14)){//判断按键是否按下
    buttons=14;//给按键变量赋值14
    buttons_PS2=0xFE;        //PS2按键赋值
    }
   if(Mkey.pressed(14)){ //按键是否松开
    buttons=99;//给按键变量赋值99
    buttons_PS2=0xFF;        //给变量赋值FF
    }
 //===========START按键=======================
   if(Mkey.released(15)){//判断按键是否按下
    buttons=15;//给按键变量赋值15
    buttons_PS2=0xF7;        //PS2按键赋值
    }
   if(Mkey.pressed(15)){ //按键是否松开
    buttons=99;//给按键变量赋值99
    buttons_PS2=0xFF;        //给变量赋值FF
    }
  //===============摇杆按键========================
    if(Mkey.released(7)){//L3左摇杆按键判断是否按下
    //buttons=7;//给按键变量赋值7
    buttons=9;//给按键变量赋值9,根据PS2按键定义,与SELCT,START在同一组
    buttons_PS2=0xFD;        //PS2按键赋值
    }
    if(Mkey.pressed(7)){ //按键是否松开
    buttons=99;//给按键变量赋值99
    buttons_PS2=0xFF;        //给变量赋值FF
    }
    if(Mkey.released(6)){//R3右摇杆按键判断是否按下
    //buttons=6;//给按键变量赋值6
    buttons=8;//给按键变量赋值8,根据PS2按键定义,与SELCT,START在同一组
    buttons_PS2=0xFB;        //PS2按键赋值
    }
    if(Mkey.pressed(6)){ //按键是否松开
    buttons=99;//给按键变量赋值99
    buttons_PS2=0xFF;        //给变量赋值FF
  }

//===============功能按键:R1========================
    if(Mkey.released(4)){//R1键判断是否按下
    buttons=4;//给按键变量赋值4
    buttons_PS2=0xF7;        //PS2按键赋值
    }
    delay(100);//延时判断按键松开

if(buttons==4 && Mkey.pressed(4)){ //按键一次,并松开
      Serial.print("Volts: ");//串口输出“Volts: ”字符串
      Serial.print(voltage);//串口输出电池电压数值
      Serial.print("LX: ");//串口输出“LX: ”字符串
      Serial.print(L1int);//串口输出左摇杆X轴数据
      Serial.print("LY: ");//串口输出“LY: ”字符串
      Serial.print(L2int);//串口输出左摇杆Y轴数据
      Serial.print("RX: ");//串口输出“RX: ”字符串
      Serial.print(R1int);串口输出右摇杆X轴数据
      Serial.print("RY: ");//串口输出“RY: ”字符串
      Serial.println(R2int);串口输出右摇杆Y轴数据,并换行
      buttons=99;//给按键变量赋值99
    }
}

MJKDZ PS2手柄控制OskarBot小车(一):Arduino串口发送数据相关推荐

  1. MJKDZ PS2手柄控制OskarBot小车(三):STM32接收无线串口模块的数据并处理

    MJKDZ PS2手柄控制OskarBot小车(三):无线串口模块接收数据并处理 [目录] 1.硬件与软件设计思路 - 1.1 硬件资源 - 1.2 STM32串口接收数据的方法 2.源代码详解 - ...

  2. Arduino 串口发送数据代码

    一.代码如下 void setup() {Serial.begin(230400); } void loop() { float gps_time = 1660538360.228776;float ...

  3. python树莓派串口通信实例_树莓派通过串口发送数据

    可以通过串口登陆树莓派,也可以通过串口向其他主机发送数据.树莓派的串口接受数据科技爱好者博客已经写过,可以参考这篇文章:树莓派与arduino串口通信实践.这篇文章教大家如果通过树莓派的串口发送数据. ...

  4. java串口发送16进制_串口发送数据——字符串发送与十六进制发送的区别

    在计算机中,数据是以二进制的形式存储的,例如十进制 1(10)在计算机中用 0000 0001(2)来表示.我们在用串口发送数据的时候首先将待数据转换为对应的ASCII码,然后再将这些ASCII码按照 ...

  5. 向STM32串口发送数据的标准函数

    向STM32串口发送数据的标准函数 例子:1 void UART_Send_Message(u8 *Data,u8 lenth) {while(lenth--){USART_SendData(USAR ...

  6. 安捷伦万用表--Agilent34401A数字万用表串口发送数据只上位机使用说明

    Agilent34401A数字万用表串口发送数据使用说明 安捷伦34410A万用表可以通过背后的RS232接口与电脑连接,进行串口通信. 仪表的串口有两种工作方式,一种是交互模式–既能接收命令,又能发 ...

  7. 【嵌入式】——串口实验——实现芯片串口收发数据,按键中断串口发送数据,串口接收数据中断来控制LED亮/灭

    实验目的: 实现芯片串口收发数据,按键中断串口发送数据:按下按键,向串口发送数据,并通过虚拟终端显示出来: 串口接收数据中断来控制LED亮/灭:通过串口助手向MCU发送数据,"A" ...

  8. C#串口通信—向串口发送数据,同步接收返回数据

    最近写C#串口通信程序,系统是B/S架构.SerialPort类有一个DataReceived事件,用来接收串口返回的数据,但这种方式在C/S架构下很好用,但B/S就不好处理了.所以写了一个同步模式接 ...

  9. STM32F0 HAL库软件模拟串口发送数据

    试验STM32F0官方提供的例程的时候,希望看到程序中某些变量的值,但是程序中往往没有串口发送部分,自己加又非常麻烦. 而点亮LED的程序基本上每个例程都有.所以用点亮LED引脚模拟串口发送数据就很方 ...

最新文章

  1. 从数据中心三大趋势看如何做布线规划
  2. MyBitis(iBitis)系列随笔之六:mybitis与spring集成
  3. 安装Mediamanager 后Messenger后无法登录
  4. python设置excel格式_Python使用xlwt写excel并设置写入格式
  5. 华为手机android怎么解锁,华为手机解锁密码忘了怎么办?华为手机找回锁屏密码方法...
  6. 机械键盘无冲测试软件,全键无冲/六键无冲可切换 键盘测试_狼派 X09暗影机械键盘_键鼠评测-中关村在线...
  7. Python:计算任意n阶矩阵行列式
  8. 智慧医疗管理系统解决方案:医药电商系统实现智能化改造
  9. Cobbler自动化安装系统2
  10. kindle上查看微信读书的书籍
  11. Garbage First (G1) GC垃圾回收器:区域化分代式【图文】
  12. html5文本框里插图片文字,word应用教程:在文本框内插入图片
  13. 电脑桌面计算机文件打不开怎么办,电脑开机桌面文件都点不开的解决方法
  14. 最左前缀 mysql优化器_mysql查询优化之索引类型、最左前缀
  15. linux进程挂掉 自动启动,配置systemd以在Linux崩溃后自动启动服务
  16. 搞笑决战水源之巅收藏六 师傅
  17. 必应壁纸php,PHP 自动保存Bing 每日壁纸
  18. 中标麒麟学习笔记0:安装极点五笔输入法
  19. 计算机网络知识全面讲解:域名解析的过程
  20. c语言中的fock方法输出hello,(1.1.20)C程序之Fock()函数

热门文章

  1. Linux基本文件操作练习(附答案分析)
  2. git push时rejected,解决non-fast-forward errors的办法
  3. uniapp app 端截屏且保存到本地
  4. comon lisp标准_common-lisp – Common Lisp的最新标准
  5. GoLand ide编辑器设置方法注释模板(例如author,date)
  6. iPhone备忘录清除缓存
  7. 在线免费体验的文字识别接口
  8. Html5游戏开发攻略(API篇)
  9. 如何去高效的学习?怎样克服?
  10. 结合实例,直观理解正态分布、卡方分布、t分布、F分布和对应的Z检验、卡方检验、t检验、F检验