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