久久久久久久999_99精品久久精品一区二区爱城_成人欧美一区二区三区在线播放_国产精品日本一区二区不卡视频_国产午夜视频_欧美精品在线观看免费

 找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

搜索
查看: 9759|回復: 6
打印 上一主題 下一主題
收起左側

arduino驅動PS2無線手柄庫文件與資料下載

[復制鏈接]
跳轉到指定樓層
樓主
PS2無線手柄快速上手教程
使用前準備
程序分析
使用前準備
將接收器連接到arduino上(共用到6個引腳,程序中使用的是8、
9、10、11號引腳,接收器跟arduino的連線可根據實際情況修改引腳。
如果沒有接收器轉接板,請查看接收器引腳說明)。
下載例程(使用的是arduino uno r3),打開串口監視器,按下遙控
按鍵查看效果(具體使用見下面程序分析)。

程序源碼與資料鏈接:
校內機器人比賽.rar (6.1 MB, 下載次數: 65)

游客,本帖隱藏的內容需要積分高于 10 才可瀏覽,您當前積分為 0

引腳需要與程序相對應
接收器轉接板
接收器引腳說明
程序分析
1. 首先將文件PS2X_lib.cpp,PS2X_lib.h拷貝到項目文件夾下。
2. 添加頭文件。
3. 遙控接收器引腳聲明(需要跟實際連線相對應)。
4. 實例化一個PS2對象
5. arduino初始化
ps2x.config_gamepad(PS2_CLK, PS2_CMD, PS2_CS, PS2_DAT, pressures, rumble);
PS2引腳初始化,返回值為0說明遙控連接成功。
6. 在循環中讀取遙控數據
ps2x.read_gamepad(false, 0);
You must Read Gamepad to get new values and set vibration values
ps2x.read_gamepad(small motor on/off, larger motor strenght from 0-255),if
you don't enable the rumble, use ps2x.read_gamepad(); with no values。You
should call this at least once a second。
PS2遙控內部是有兩個震動馬達的,這里我們不使用。
調用此函數讀取遙控器狀態,每個循環調用一次,但不要太頻繁。
按鍵狀態讀取有三個函數
ps2x.Button( x ) ,只要按鍵按下會一直觸發,按下時串口一直打印數據。
ps2x.ButtonPressed(x),按鍵按下時觸發一次,按下時串口只打印一次數據。
ps2x.ButtonReleased(x),按鍵釋放時觸發一次,松開時串口只打印一次數據。
x表示按鍵的宏定義,
具體效果請自行測試。
搖桿數據讀取
ps2x.Analog( x ) ,x表示搖桿的宏定義,具體如下圖:
遙控讀取數據的教程就到這里了,按鍵的具體功能就需要結合自己的機器人使用
了。

單片機源程序如下:
  1. #include "PS2X_lib.h"
  2. #include <math.h>
  3. #include <stdio.h>
  4. #include <stdint.h>
  5. #include <avr/io.h>
  6. #if ARDUINO > 22
  7. #include "Arduino.h"
  8. #else
  9. #include "WProgram.h"
  10. #include "pins_arduino.h"
  11. #endif



  12. static byte enter_config[]={0x01,0x43,0x00,0x01,0x00};
  13. static byte set_mode[]={0x01,0x44,0x00,0x01,0x03,0x00,0x00,0x00,0x00};
  14. static byte set_bytes_large[]={0x01,0x4F,0x00,0xFF,0xFF,0x03,0x00,0x00,0x00};
  15. static byte exit_config[]={0x01,0x43,0x00,0x00,0x5A,0x5A,0x5A,0x5A,0x5A};
  16. static byte enable_rumble[]={0x01,0x4D,0x00,0x00,0x01};
  17. static byte type_read[]={0x01,0x45,0x00,0x5A,0x5A,0x5A,0x5A,0x5A,0x5A};

  18. boolean PS2X::NewButtonState() {
  19.    return ((last_buttons ^ buttons) > 0);

  20. }

  21. boolean PS2X::NewButtonState(unsigned int button) {
  22.   return (((last_buttons ^ buttons) & button) > 0);
  23. }

  24. boolean PS2X::ButtonPressed(unsigned int button) {
  25.   return(NewButtonState(button) & Button(button));
  26. }

  27. boolean PS2X::ButtonReleased(unsigned int button) {
  28.   return((NewButtonState(button)) & ((~last_buttons & button) > 0));
  29. }
  30.   
  31. boolean PS2X::Button(uint16_t button) {
  32.    return ((~buttons & button) > 0);
  33. }

  34. unsigned int PS2X::ButtonDataByte() {
  35.    return (~buttons);
  36. }

  37. byte PS2X::Analog(byte button) {
  38.   return PS2data[button];
  39. }
  40. unsigned char PS2X::_gamepad_shiftinout (char byte) {
  41.   

  42.    unsigned char tmp = 0;
  43.    for(i=0;i<8;i++) {

  44.           if(CHK(byte,i)) CMD_SET();
  45.           else  CMD_CLR();
  46.           CLK_CLR();

  47.           delayMicroseconds(CTRL_CLK);

  48.           if(DAT_CHK()) SET(tmp,i);
  49.           CLK_SET();
  50. #if CTRL_CLK_HIGH
  51.           delayMicroseconds(CTRL_CLK_HIGH);
  52. #endif          
  53.    }
  54.    CMD_SET();
  55.    delayMicroseconds(CTRL_BYTE_DELAY);
  56.    return tmp;
  57. }

  58. void PS2X::read_gamepad() {
  59.     read_gamepad(false, 0x00);
  60. }


  61. boolean PS2X::read_gamepad(boolean motor1, byte motor2) {
  62.   double temp = millis() - last_read;
  63.   
  64.   if (temp > 1500) //waited to long
  65.     reconfig_gamepad();
  66.    
  67.   if(temp < read_delay)  //waited too short
  68.     delay(read_delay - temp);
  69.    
  70.    

  71.   if(motor2 != 0x00)
  72.     motor2 = map(motor2,0,255,0x40,0xFF); //noting below 40 will make it spin
  73.   
  74.   char dword[9] = {0x01,0x42,0,motor1,motor2,0,0,0,0};
  75.   byte dword2[12] = {0,0,0,0,0,0,0,0,0,0,0,0};

  76.   // Try a few times to get valid data...
  77.   for (byte RetryCnt = 0; RetryCnt < 5; RetryCnt++) {
  78.             CMD_SET();
  79.       CLK_SET();
  80.       ATT_CLR(); // low enable joystick
  81.           
  82.           delayMicroseconds(CTRL_BYTE_DELAY);
  83.           //Send the command to send button and joystick data;

  84.           for (int i = 0; i<9; i++) {
  85.                   PS2data[i] = _gamepad_shiftinout(dword[i]);
  86.           }


  87.           if((PS2data[1] == 0x79) || (PS2data[1] == 0x41)) {  //if controller is in full data return mode, get the rest of data
  88.                    for (int i = 0; i<12; i++) {
  89.                                 PS2data[i+9] = _gamepad_shiftinout(dword2[i]);
  90.                    }
  91.           }
  92.                
  93.             ATT_SET(); // HI disable joystick
  94.           // Check to see if we received valid data or not.  We should be in analog mode for our data
  95.           // to be valie
  96.           if ((PS2data[1] & 0xf0) == 0x70)
  97.                 break;
  98.        
  99.         // If we got to here, we are not in analog mode, try to recover...
  100.         reconfig_gamepad();        // try to get back into Analog mode.
  101.         delay(read_delay);
  102.   }
  103.   
  104.   // If we get here and still not in analog mode, try increasing the read_delay...
  105.   if ((PS2data[1] & 0xf0) != 0x70) {
  106.         if (read_delay < 10)
  107.                 read_delay++;        // see if this helps out...
  108.   }       

  109.        
  110.         #ifdef PS2X_COM_DEBUG
  111.     Serial.println("OUT:IN");
  112.                 for(int i=0; i<9; i++){
  113.                         Serial.print(dword[i], HEX);
  114.                         Serial.print(":");
  115.                         Serial.print(PS2data[i], HEX);
  116.                         Serial.print(" ");
  117.                 }
  118.                 for (int i = 0; i<12; i++) {
  119.                         Serial.print(dword2[i], HEX);
  120.                         Serial.print(":");
  121.                         Serial.print(PS2data[i+9], HEX);
  122.                         Serial.print(" ");
  123.                 }
  124.         Serial.println("");       
  125.         #endif
  126.        
  127.   last_buttons = buttons; //store the previous buttons states

  128. #if defined(__AVR__)
  129.    buttons = *(uint16_t*)(PS2data+3);   //store as one value for multiple functions
  130. #else
  131.    buttons =  (uint16_t)(PS2data[4] << 8) + PS2data[3];   //store as one value for multiple functions
  132. #endif
  133.    last_read = millis();
  134.    return ((PS2data[1] & 0xf0) == 0x70);
  135. }

  136. byte PS2X::config_gamepad(uint8_t clk, uint8_t cmd, uint8_t att, uint8_t dat) {
  137.         return config_gamepad(clk, cmd, att, dat, false, false);
  138. }


  139. byte PS2X::config_gamepad(uint8_t clk, uint8_t cmd, uint8_t att, uint8_t dat, bool pressures, bool rumble) {

  140.    byte temp[sizeof(type_read)];
  141.   
  142. #ifdef __AVR__
  143. _clk_mask = digitalPinToBitMask(clk);
  144. _clk_oreg = portOutputRegister(digitalPinToPort(clk));
  145. _cmd_mask = digitalPinToBitMask(cmd);
  146. _cmd_oreg = portOutputRegister(digitalPinToPort(cmd));
  147. _att_mask = digitalPinToBitMask(att);
  148. _att_oreg = portOutputRegister(digitalPinToPort(att));
  149. _dat_mask = digitalPinToBitMask(dat);
  150. _dat_ireg = portInputRegister(digitalPinToPort(dat));
  151. #else

  152.         uint32_t            lport;                   // Port number for this pin
  153.         _clk_mask = digitalPinToBitMask(clk);
  154.         lport = digitalPinToPort(clk);
  155.         _clk_lport_set = portOutputRegister(lport) + 2;
  156.         _clk_lport_clr = portOutputRegister(lport) + 1;

  157.         _cmd_mask = digitalPinToBitMask(cmd);
  158.         lport = digitalPinToPort(cmd);
  159.         _cmd_lport_set = portOutputRegister(lport) + 2;
  160.         _cmd_lport_clr = portOutputRegister(lport) + 1;

  161.         _att_mask = digitalPinToBitMask(att);
  162.         lport = digitalPinToPort(att);
  163.         _att_lport_set = portOutputRegister(lport) + 2;
  164.         _att_lport_clr = portOutputRegister(lport) + 1;
  165.   
  166.         _dat_mask = digitalPinToBitMask(dat);
  167.         _dat_lport = portInputRegister(digitalPinToPort(dat));

  168. #endif  

  169.   pinMode(clk, OUTPUT); //configure ports
  170.   pinMode(att, OUTPUT);
  171.   pinMode(cmd, OUTPUT);
  172.   pinMode(dat, INPUT);

  173. #if defined(__AVR__)
  174.   digitalWrite(dat, HIGH); //enable pull-up
  175. #endif
  176.    
  177.    CMD_SET(); // SET(*_cmd_oreg,_cmd_mask);
  178.    CLK_SET();
  179.    
  180.    //new error checking. First, read gamepad a few times to see if it's talking
  181.    read_gamepad();
  182.    read_gamepad();
  183.    
  184.    //see if it talked
  185.    if(PS2data[1] != 0x41 && PS2data[1] != 0x73 && PS2data[1] != 0x79){ //see if mode came back. If still anything but 41, 73 or 79, then it's not talking
  186.       #ifdef PS2X_DEBUG
  187.                 Serial.println("Controller mode not matched or no controller found");
  188.                 Serial.print("Expected 0x41 or 0x73, got ");
  189.                 Serial.println(PS2data[1], HEX);
  190.           #endif
  191.          
  192.          return 1; //return error code 1
  193.         }
  194.   
  195.   //try setting mode, increasing delays if need be.
  196.   read_delay = 1;
  197.   
  198.   for(int y = 0; y <= 10; y++)
  199.   {
  200.    sendCommandString(enter_config, sizeof(enter_config)); //start config run
  201.    
  202.    //read type
  203.            delayMicroseconds(CTRL_BYTE_DELAY);

  204.         CMD_SET();
  205.     CLK_SET();
  206.     ATT_CLR(); // low enable joystick
  207.        
  208.     delayMicroseconds(CTRL_BYTE_DELAY);

  209.     for (int i = 0; i<9; i++) {
  210.           temp[i] = _gamepad_shiftinout(type_read[i]);
  211.     }

  212.         ATT_SET(); // HI disable joystick
  213.        
  214.         controller_type = temp[3];
  215.    
  216.    sendCommandString(set_mode, sizeof(set_mode));
  217.    if(rumble){ sendCommandString(enable_rumble, sizeof(enable_rumble)); en_Rumble = true; }
  218.    if(pressures){ sendCommandString(set_bytes_large, sizeof(set_bytes_large)); en_Pressures = true; }
  219.    sendCommandString(exit_config, sizeof(exit_config));
  220.    
  221.    read_gamepad();
  222.    
  223.    if(pressures){
  224.         if((PS2data[1] == 0x79) || (PS2data[1] == 0x41))
  225.                 break;
  226.         if(PS2data[1] == 0x73)
  227.                 return 3;
  228.    }
  229.    
  230.     if(PS2data[1] == 0x73)
  231.       break;
  232.       
  233.     if(y == 10){
  234.                 #ifdef PS2X_DEBUG
  235.                 Serial.println("Controller not accepting commands");
  236.                 Serial.print("mode stil set at");
  237.                 Serial.println(PS2data[1], HEX);
  238.                 #endif
  239.       return 2; //exit function with error
  240.           }
  241.    
  242.     read_delay += 1; //add 1ms to read_delay
  243.   }
  244.    
  245. return 0; //no error if here
  246. }



  247. void PS2X::sendCommandString(byte string[], byte len) {
  248.   

  249.   #ifdef PS2X_COM_DEBUG
  250.   byte temp[len];
  251.   ATT_CLR(); // low enable joystick
  252.   delayMicroseconds(CTRL_BYTE_DELAY);
  253.        
  254.   for (int y=0; y < len; y++)
  255.     temp[y] = _gamepad_shiftinout(string[y]);
  256.    
  257.   ATT_SET(); //high disable joystick  
  258.    delay(read_delay);                  //wait a few
  259.   
  260.   Serial.println("OUT:IN Configure");
  261.   for(int i=0; i<len; i++){
  262.                         Serial.print(string[i], HEX);
  263.                         Serial.print(":");
  264.                         Serial.print(temp[i], HEX);
  265.                         Serial.print(" ");
  266.                 }
  267.    Serial.println("");
  268.   
  269.   #else
  270.   ATT_CLR(); // low enable joystick
  271.   for (int y=0; y < len; y++)
  272.     _gamepad_shiftinout(string[y]);
  273.    
  274.    ATT_SET(); //high disable joystick  
  275.    delay(read_delay);                  //wait a few
  276.    #endif
  277. }



  278. byte PS2X::readType() {
  279. /*
  280.         byte temp[sizeof(type_read)];
  281.        
  282.         sendCommandString(enter_config, sizeof(enter_config));
  283.        
  284.         delayMicroseconds(CTRL_BYTE_DELAY);

  285.         CMD_SET();
  286.     CLK_SET();
  287.     ATT_CLR(); // low enable joystick
  288.        
  289.     delayMicroseconds(CTRL_BYTE_DELAY);

  290.     for (int i = 0; i<9; i++) {
  291.           temp[i] = _gamepad_shiftinout(type_read[i]);
  292.     }
  293.        
  294.         sendCommandString(exit_config, sizeof(exit_config));
  295.          
  296.         if(temp[3] == 0x03)
  297.                 return 1;
  298.         else if(temp[3] == 0x01)
  299.                 return 2;
  300.        
  301.         return 0;
  302.         */
  303.        
  304.         if(controller_type == 0x03)
  305.                 return 1;
  306.         else if(controller_type == 0x01)
  307.                 return 2;
  308.        
  309.         //return 0;
  310.         return controller_type;
  311.        
  312. }

  313. byte PS2X::readMode() {
  314.         return PS2data[1];       
  315. }

  316. void PS2X::enableRumble() {
  317.   
  318.      sendCommandString(enter_config, sizeof(enter_config));
  319.      sendCommandString(enable_rumble, sizeof(enable_rumble));
  320.      sendCommandString(exit_config, sizeof(exit_config));
  321.      en_Rumble = true;
  322.   
  323. }

  324. bool PS2X::enablePressures() {
  325.   
  326.      sendCommandString(enter_config, sizeof(enter_config));
  327.      sendCommandString(set_bytes_large, sizeof(set_bytes_large));
  328.      sendCommandString(exit_config, sizeof(exit_config));
  329.          
  330.          read_gamepad();
  331.          read_gamepad();
  332.          
  333.           if((PS2data[1] != 0x79)  && (PS2data[1] != 0x41))
  334.                 return false;
  335.                
  336.      en_Pressures = true;
  337.          return true;
  338. }

  339. void PS2X::reconfig_gamepad(){
  340.   
  341.    sendCommandString(enter_config, sizeof(enter_config));
  342.    sendCommandString(set_mode, sizeof(set_mode));
  343.    if (en_Rumble)
  344.       sendCommandString(enable_rumble, sizeof(enable_rumble));
  345.    if (en_Pressures)
  346.       sendCommandString(set_bytes_large, sizeof(set_bytes_large));
  347.    sendCommandString(exit_config, sizeof(exit_config));
  348.    
  349. }


  350. #ifdef __AVR__
  351. inline void  PS2X::CLK_SET(void) {
  352.        
  353.    register uint8_t old_sreg = SREG;
  354.    cli();
  355.    *_clk_oreg |= _clk_mask;
  356.    SREG = old_sreg;
  357. }

  358. inline void  PS2X::CLK_CLR(void) {
  359.    register uint8_t old_sreg = SREG;
  360.    cli();
  361.    *_clk_oreg &= ~_clk_mask;
  362.    SREG = old_sreg;
  363. }

  364. inline void  PS2X::CMD_SET(void) {
  365.    register uint8_t old_sreg = SREG;
  366.    cli();
  367.    *_cmd_oreg |= _cmd_mask; // SET(*_cmd_oreg,_cmd_mask);
  368.    SREG = old_sreg;
  369. }

  370. inline void  PS2X::CMD_CLR(void) {
  371.    register uint8_t old_sreg = SREG;
  372.    cli();
  373.    *_cmd_oreg &= ~_cmd_mask; // SET(*_cmd_oreg,_cmd_mask);
  374.    SREG = old_sreg;
  375. }

  376. inline void  PS2X::ATT_SET(void) {
  377.    register uint8_t old_sreg = SREG;
  378.    cli();
  379.   *_att_oreg |= _att_mask ;        
  380.    SREG = old_sreg;
  381. }

  382. inline void PS2X::ATT_CLR(void) {
  383.    register uint8_t old_sreg = SREG;
  384.    cli();
  385.   *_att_oreg &= ~_att_mask;
  386.    SREG = old_sreg;
  387. }

  388. inline bool PS2X::DAT_CHK(void) {
  389.         return (*_dat_ireg & _dat_mask)? true : false;
  390. }

  391. #else
  392. // On pic32, use the set/clr registers to make them atomic...inline void  PS2X::CLK_SET(void) {
  393.         *_clk_lport_set |= _clk_mask;
  394. }

  395. inline void  PS2X::CLK_CLR(void) {
  396.         *_clk_lport_clr |= _clk_mask;
  397. }

  398. inline void  PS2X::CMD_SET(void) {
  399.         *_cmd_lport_set |= _cmd_mask;
  400. }

  401. inline void  PS2X::CMD_CLR(void) {
  402.         *_cmd_lport_clr |= _cmd_mask;
  403. }

  404. inline void  PS2X::ATT_SET(void) {
  405.         *_att_lport_set |= _att_mask;
  406. }

  407. inline void PS2X::ATT_CLR(void) {
  408.         *_att_lport_clr |= _att_mask;
  409. }

  410. inline bool PS2X::DAT_CHK(void) {
  411.         return (*_dat_lport & _dat_mask)? true : false;

  412. }


  413. byte PS2X::psxType() {
  414.         /*if(PS2data[1] == 0x41) {
  415.                 return 1;
  416.         } else if(PS2data[1] == 0x79) {
  417.                 return 2;
  418.         }*/
  419.        
  420.         return PS2data[1];
  421.         //return 0;
  422. }

  423. #endif
復制代碼





分享到:  QQ好友和群QQ好友和群 QQ空間QQ空間 騰訊微博騰訊微博 騰訊朋友騰訊朋友
收藏收藏2 分享淘帖 頂 踩
回復

使用道具 舉報

沙發
ID:32574 發表于 2018-10-17 14:06 | 只看該作者
謝謝樓主分享,學習了
回復

使用道具 舉報

板凳
ID:349169 發表于 2018-10-20 22:14 | 只看該作者
謝謝樓主
回復

使用道具 舉報

地板
ID:417151 發表于 2018-10-29 11:24 | 只看該作者
謝謝樓主
回復

使用道具 舉報

5#
ID:422153 發表于 2018-12-3 11:52 | 只看該作者
謝謝分享
回復

使用道具 舉報

6#
ID:708902 發表于 2020-3-15 16:32 | 只看該作者
謝謝樓主
回復

使用道具 舉報

7#
ID:757507 發表于 2020-5-21 16:18 | 只看該作者

謝謝樓主
回復

使用道具 舉報

您需要登錄后才可以回帖 登錄 | 立即注冊

本版積分規則

手機版|小黑屋|51黑電子論壇 |51黑電子論壇6群 QQ 管理員QQ:125739409;技術交流QQ群281945664

Powered by 單片機教程網

快速回復 返回頂部 返回列表
主站蜘蛛池模板: 婷婷久久综合 | 瑟瑟激情 | 久久中文字幕在线 | 久久久久久久一区 | 日韩欧美一级精品久久 | av香蕉 | 亚洲国产一区视频 | 亚洲欧洲成人在线 | aaaa日韩| 精品久久国产 | 国产专区在线 | 国产美女福利在线观看 | 在线观看日本高清二区 | 91精品国产99 | av电影一区二区 | 国产三级精品三级在线观看四季网 | 剑来高清在线观看 | 欧美精品久久久久久 | 国产精品高潮呻吟久久 | 亚洲字幕在线观看 | 久久亚洲国产 | 狠狠干av | 亚洲精品美女 | 91精品国产91久久久久久 | 天天想天天干 | 亚洲欧美日韩国产综合 | 国产精品久久久久久久久久 | 国产精品国产 | 午夜免费视频 | 成人水多啪啪片 | 看亚洲a级一级毛片 | 羞羞网站免费 | 狠狠干天天干 | 亚洲国产aⅴ成人精品无吗 欧美激情欧美激情在线五月 | 欧美全黄 | 日本精品久久久久久久 | www国产成人免费观看视频,深夜成人网 | 在线成人免费视频 | 欧美日韩综合一区 | 韩日一区 | www日韩高清 |