小猪学arduino—PS2手柄控制

我们在做机器人调试时,只能通过串口发命令来控制,有时跟着出门了还得带着电脑,实在很不方便,今天来教大家如何使用PS2手柄来直接控制Arduino设备。

一、材料准备

ps2手柄   *1       // 2.4G无线通信,遥控距离20米

连接线      *若干

二、连线方法

注意电源接3.3V

三、开发环境

添加PS2X库:

# 下载
wget https://github.com/yanjingang/Arduino-PS2X/archive/refs/heads/master.zip
# 复制到arduino应用插件目录
cp -r ~/Arduino-PS2X/PS2X_lib /Applications/Arduino.app/Contents/Java/hardware/arduino/avr/libraries/

四、调试代码

#include "PS2X_lib.h"

PS2X ps2x;  // create PS2 Controller Class

int error = 0;
byte type = 0;
byte vibrate = 0;

void setup() {
    Serial.begin(57600);

    // 设置PS2控制引脚
    error = ps2x.config_gamepad(13, 11, 10, 12, true,true);  // setup pins and settings:  GamePad(clock, command, attention,  data, Pressures?, Rumble?) 
    if (error == 0) { // 成功
        Serial.println("Found Controller, configured successful");
        Serial.println("Try out all the buttons, X will vibrate the controller, faster as you press harder;");
        Serial.println("holding L1 or R1 will print out the analog stick values.");
        Serial.println("Go to [url]www.billporter.info[/url] for updates and to report bugs.");
    } else if (error == 1){ // 未找到控制器,请检查接线
        Serial.println("No controller found, check wiring, see readme.txt to enable debug. visit [url]www.billporter.info[/url] for troubleshooting tips");
    }else if (error == 2){  // 找到控制器但不接受命令
        Serial.println("Controller found but not accepting commands. see readme.txt to enable debug. Visit [url]www.billporter.info[/url] for troubleshooting tips");
    }else if (error == 3){  // 控制器拒绝进入压力模式,可能不支持
        Serial.println("Controller refusing to enter Pressures mode, may not support it. ");
    }
    // Serial.print(ps2x.Analog(1), HEX);

    // 读取PS2设备类型
    type = ps2x.readType();
    switch (type) {
        case 0:
            Serial.println("Unknown Controller type");
            break;
        case 1:
            Serial.println("DualShock Controller Found");
            break;
        case 2:
            Serial.println("GuitarHero Controller Found");
            break;
    }
}

void loop() {
    /* You must Read Gamepad to get new values
    Read GamePad 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
    */
    if (error == 1)  // skip loop if no controller found
        return;

    // 读取手柄的控制信号
    if (type == 2) {  // Guitar Hero Controller
        ps2x.read_gamepad();  // read controller

        if (ps2x.ButtonPressed(GREEN_FRET))
            Serial.println("Green Fret Pressed");
        if (ps2x.ButtonPressed(RED_FRET))
            Serial.println("Red Fret Pressed");
        if (ps2x.ButtonPressed(YELLOW_FRET))
            Serial.println("Yellow Fret Pressed");
        if (ps2x.ButtonPressed(BLUE_FRET))
            Serial.println("Blue Fret Pressed");
        if (ps2x.ButtonPressed(ORANGE_FRET))
            Serial.println("Orange Fret Pressed");

        if (ps2x.ButtonPressed(STAR_POWER))
            Serial.println("Star Power Command");

        if (ps2x.Button(UP_STRUM))  // will be TRUE as long as button is pressed
            Serial.println("Up Strum");
        if (ps2x.Button(DOWN_STRUM))
            Serial.println("DOWN Strum");

        if (ps2x.Button(PSB_START))  // will be TRUE as long as button is pressed
            Serial.println("Start is being held");
        if (ps2x.Button(PSB_SELECT))
            Serial.println("Select is being held");

        if (ps2x.Button(ORANGE_FRET))  // print stick value IF TRUE
        {
            Serial.print("Wammy Bar Position:");
            Serial.println(ps2x.Analog(WHAMMY_BAR), DEC);
        }
    }else {  // DualShock Controller
        ps2x.read_gamepad(false, vibrate);  // read controller and set large motor to spin at 'vibrate' speed

        if (ps2x.Button(PSB_START))  // will be TRUE as long as button is pressed
            Serial.println("Start is being held");
        if (ps2x.Button(PSB_SELECT))
            Serial.println("Select is being held");

        if (ps2x.Button(    PSB_PAD_UP)) {  // will be TRUE as long as button is pressed
            Serial.print("Up held this hard: ");
            Serial.println(ps2x.Analog(PSAB_PAD_UP), DEC);
        }
        if (ps2x.Button(PSB_PAD_RIGHT)) {
            Serial.print("Right held this hard: ");
            Serial.println(ps2x.Analog(PSAB_PAD_RIGHT), DEC);
        }
        if (ps2x.Button(PSB_PAD_LEFT)) {
            Serial.print("LEFT held this hard: ");
            Serial.println(ps2x.Analog(PSAB_PAD_LEFT), DEC);
        }
        if (ps2x.Button(PSB_PAD_DOWN)) {
            Serial.print("DOWN held this hard: ");
            Serial.println(ps2x.Analog(PSAB_PAD_DOWN), DEC);
        }

        vibrate = ps2x.Analog(PSAB_BLUE);  // this will set the large motor vibrate speed based on how hard you press the blue (X) button

        if (ps2x.NewButtonState())  // will be TRUE if any button changes state  (on to off, or off to on)
        {
            if (ps2x.Button(PSB_L3))
                Serial.println("L3 pressed");
            if (ps2x.Button(PSB_R3))
                Serial.println("R3 pressed");
            if (ps2x.Button(PSB_L2))
                Serial.println("L2 pressed");
            if (ps2x.Button(PSB_R2))
                Serial.println("R2 pressed");
            if (ps2x.Button(PSB_GREEN))
                Serial.println("Triangle pressed");
        }

        if (ps2x.ButtonPressed(    PSB_RED))  // will be TRUE if button was JUST pressed
            Serial.println("Circle just pressed");

        if (ps2x.ButtonReleased(    PSB_PINK))  // will be TRUE if button was JUST released
            Serial.println("Square just released");

        if (ps2x.NewButtonState(PSB_BLUE))  // will be TRUE if button was JUST pressed OR released
            Serial.println("X just changed");

        if (ps2x.Button(PSB_L1) || ps2x.Button(PSB_R1))  // print stick values if either is TRUE
        {
            Serial.print("Stick Values:");
            Serial.print(ps2x.Analog(PSS_LY), DEC);  // Left stick, Y axis. Other options: LX, RY, RX
            Serial.print(",");
            Serial.print(ps2x.Analog(PSS_LX), DEC);
            Serial.print(",");
            Serial.print(ps2x.Analog(PSS_RY), DEC);
            Serial.print(",");
            Serial.println(ps2x.Analog(PSS_RX), DEC);
        }
    }
    delay(50);
}

将示例代码上传到UNO板中,打开PS2无线手柄的开关(ON、START、MODE,确保两个灯都亮起),观察无线接收器的绿灯与手柄的上的灯都停止闪烁说明连接成功了。

打开串口监视器,可以看到连接成功,控制手柄查看信号接收是否正常(需要注意demo里两个摇柄的当前值是在按L1和R1时打印Stick Values输出的)。

按钮定义:

好了,单片机能准确的收到相应按钮信号之后,剩下的对应控制逻辑就不在此赘述了,自己实现即可。

 

yan 22.1.8

 

参考:

Arduino Robot With PS2 Controller

Arduino控制PS2无线手柄

欢迎关注下方“非著名资深码农“公众号进行交流~

发表评论

邮箱地址不会被公开。