#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 } }
|