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