Eric Leung
Published © GPL3+

OpenBot V1

By using some common products that can be purchased in the market and create a low cost but effective humanoid that everyone can afford.

IntermediateShowcase (no instructions)1,545
OpenBot V1

Things used in this project

Hardware components

QSC 24E NANO
You can replace it with any different servo control board
×1

Story

Read more

Schematics

QSC 24E NANO

Arduino Nano board with servo output control

Code

ps2 controller code(By QDS Controller Board)

Arduino
decode ps2 controller signal and control the humanoid (By using the QDS board)
/*
--------------------------------------------------------------------------------
    Standard Digital Pad

    BYTE    CMND    DATA

     01     0x01    idle
     02     0x42    0x41
     03     idle    0x5A    Bit0 Bit1 Bit2 Bit3 Bit4 Bit5 Bit6 Bit7
     04     idle    data    SLCT           STRT UP   RGHT DOWN LEFT
     05     idle    data    L2   R2    L1  R1   /\   O    X    |_|

    All Buttons active low.

--------------------------------------------------------------------------------
    Analogue Controller in Red Mode

    BYTE    CMND    DATA

     01     0x01    idle
     02     0x42    0x73
     03     idle    0x5A    Bit0 Bit1 Bit2 Bit3 Bit4 Bit5 Bit6 Bit7
     04     idle    data    SLCT JOYR JOYL STRT UP   RGHT DOWN LEFT
     05     idle    data    L2   R2   L1   R1   /\   O    X    |_|
     06     idle    data    Right Joy 0x00 = Left  0xFF = Right
     07     idle    data    Right Joy 0x00 = Up    0xFF = Down
     08     idle    data    Left Joy  0x00 = Left  0xFF = Right
     09     idle    data    Left Joy  0x00 = Up    0xFF = Down
--------------------------------------------------------------------------------
// Button Hex Representations:
//hat 
#define psxLeft		0x0080  
#define psxDown		0x0040 
#define psxRight	0x0020 
#define psxUp		0x0010 
#define psxStrt		0x0008 
#define psxSlct		0x0001 

//buttons
#define psxSqu		0x8000 
#define psxX		0x4000 
#define psxO		0x2000 
#define psxTri		0x1000 
#define psxR1		0x0800 
#define psxL1		0x0400 
#define psxL2		0x0100 
#define psxR2		0x0200 
#define psxJoyL		0x0002
#define psxJoyR		0x0004
//other defines
#define psxAnalog	0x0073
#define psxDigital	0x00FF
*/
/////////////////*****************不可修改***************************
#include "PSX.h"                                          // 导入 Psx 库文件
Psx Psx;                                                  // Initializes the library
#define dataPin  6        
#define cmndPin   5        
#define attPin    4          
#define clockPin   3   
//#define center  0x7F    /////////定义摇杆中间值
////////*********************不可修改**************************

/////所有按键初始化//////////不可修改
int START=0;	
int SELECT=0;
int UP=0;          //上
int DOWN=0;        //下
int LEFT=0;        //左
int RIGHT=0;       //右
int SQUARE=0;	   //方框	
int CROSS=0;       //叉叉 
int CIRCLE=0;	   //圈圈
int TRIANGLE=0;    //三角
int L1=0;
int R1=0;
int R2=0;
int L2=0;

int JoyL=0;        //摇杆左
int JoyR=0;        // 摇杆右
///定义摇杆模拟量
  int X1;
  int Y1;
  int X2;
  int Y2;
////////////////////////////所有按键初始化//////////不可修改

int m=100;//定义动作组指定速度比 -200到+200
int t=500; //定义舵机T值作为舵机控制的速度 初始化为500
int p=20;//定义P值的变量值  初始化为500
int s_1=1500;//定义舵机的速率 初始化 为500
int s=0;//动作组 SQ初始化
//int a=0;
int b=0;//模拟模式取反
int b1=0;
int b2=0;
int b3=0;
int c1=0;
int c1_1;//C1取反   STICK LEFT
int c2=0;
int c2_1;//C2取反   STICK RIGHT	
int dy=30;//摇杆的速度
int se=0;//SELCET按键状态 按下为1 松开为0
int str=0;

//////////传感器
/*
int xpin=0;  //�加速度 X�轴� 接模拟IO A0
int ypin=1; //��加速度 Y 轴�接模拟IO A1
int zpin=2; // 加速度 Z�轴�接模拟IO A2
int a_pin=3;  //陀螺仪A   接模拟IO A3
int b_pin=4;  //陀螺仪B    接模拟IO A4
int X=0;
int Y=0;
int Z=0;
int A=0;
int B=0;
*/
int c=0;

////////////////////////////
void setup()
{
  Psx.setupPins(dataPin, cmndPin, attPin, clockPin);   // 设置接收器对应ARDUINO 端口   
  delay(100); ///等待手柄连线
   //Psx.initcontroller(psxAnalog);    ///模拟模式     只能选择其中一个或者都不选
  // Psx.initcontroller(psxDigital);    ///数字模式      只能选择其中一个或者都不选
  delay(100); ///等待手柄刷新数据
  
  Serial.begin(115200); ///设置波特率
 
}
// #<ch>  舵机号ch   0-31
// P<pw>  脉冲宽度pw  500-2500  即舵机的位置
// S<spd> 舵机移动速率spd   S只对单个舵机有效
// T<time> 移动到指定位置所需要的时间  T对所有舵机有效
//PL <p> 指定动作场景p,       0 必须指定 
//SQ <s> 指定动作组编号 s,        0 - 127
//SM <m> 指定速度比m,          –200- 200 不指定为100
//IX <i> 指定启动动作组开始步编号i ,          0 - 255。 不指定为0
//PA <a> 设定步之间的暂停时间a,              0 -65535 毫秒。 不指定为0 毫秒
//ONCE 指定执行动作一次。               不指定为循环运行

//L2减速 R2加速  按一次 加/减一档速度


/////////PRESSED////////按下按键 发送一次
/////////RELEASED////////松开按键  发送一次
/////////DOWN////////按住按键不放   一直发送
//程序里面 DOWN ////比如 :if (Psx.digital_buttons & psxStrt)   可屏蔽掉
//但是 PRESSD  RELEASED///// 比如:if (Psx.digital_buttons == psxStrt && START==0 )    if (Psx.digital_buttons != psxStrt && START==1)   不可屏蔽
   
void loop()
{
  Psx.poll();    delay(50);           // 刷新PSX数据           
      
    //////////////////////Start 
  if (Psx.digital_buttons == psxStrt && START==0 )        ///按下START                               
  {  
       START=1; 
       // Serial.println(Psx.digital_buttons, HEX);     
       Serial.println("pressed_START");    //  发送一次 pressed_START

  }

    if (Psx.digital_buttons != psxStrt && START==1)    //////////松开START
    {
      START=0;
    Serial.println("released_START"); //发送一次 released_START
    }

  /*
    if (Psx.digital_buttons & psxStrt)                                       
  {  

      
      Serial.println("DOWN_START");    //  按一次 START   
    
  }
  */
    //////////////////////Select 
  if (Psx.digital_buttons == psxSlct && SELECT==0)   /////按下SELECT                           
  {  
   SELECT=1;
   Serial.println("pressed_Select");    //    发送 按下 SELECT
      

  }
      if (Psx.digital_buttons == 0 && SELECT==1)     ////松开SELECT
    {
      SELECT=0;
     Serial.println("released_Select"); //发送 松开 SELECT
    }
  
  /*
    if (Psx.digital_buttons == psxSlct)        //一直按住 SELECT                              
  {  
       
      Serial.println("DOWN_Select");    //  发送一直按住 SELECT    
    
  }
  */
  
    //////////////////////UP 
  if (Psx.digital_buttons == psxUp && UP==0)   // 按一下"上 "                       
  {  
      UP=1;
      Serial.println("pressed_UP");    //按下UP   
    Serial.println("#5 P1600 T500");//5号舵机用500MS的时间运行到P1600的位置
    delay(500);// 延时500MS,以保证该舵机运行到指定位置
   Serial.println("#5 P2500 T500");//5号舵机用500MS的时间运行到P2500的位置
   delay(500);// 延时500MS,以保证该舵机运行到指定位置
    //////////////////////////////5号舵机来回转动/////
  }
      if (Psx.digital_buttons != psxUp && UP==1)
    {
      UP=0;
    Serial.println("released_Up"); //松开 UP

    }
       if (Psx.digital_buttons == psxUp)                                      
  {  
     Serial.println("down_Up"); //一直按住
    }
    
   //////////////////////DOWN
  if (Psx.digital_buttons == psxDown && DOWN==0)                               
  {  
      DOWN=1;
      Serial.println("pressed_DOWN");    ///按下DOWN
    Serial.println("#5P1000 #10P1200 #20P1500 T500")//5号、10号、20号舵机转到P1000\P1200\P1500位置
  delay(500);//延时500MS,以保证该动作运行完成
  Serial.println("#5P1500 #10P2000 #20P2500 T500")//5号、10号、20号舵机转到P1500\P2000\P2500位置
  delay(500);//延时500MS,以保证该动作运行完成
   /////////////////////////////////5.10.20号舵机来回转动/////

  }
        if (Psx.digital_buttons != psxDown && DOWN==1)
    {
      DOWN=0;
    Serial.println("released_Down"); //松开 Down
    
    }
      if (Psx.digital_buttons == psxDown )      ///////////一直按住DOWN                         
  {  
    
   
    }
  /////////////////////LEFT
  if (Psx.digital_buttons == psxLeft && LEFT==0)     //按一次LEFT                                  
  {  

   LEFT=1;
      Serial.println("pressed_Left");    //按一次LEFT 
      Serial.println("PL0 ");//先停止以前的所有动作组
   Serial.println("PL0 SQ2 SM100 ONCE");//然后再以100%速度运行动作组2一次
    delay(500);//延时500MS,以保证该动作组运行完成
  ////////////运行2号动作组一次
  }
     if (Psx.digital_buttons != psxLeft && LEFT==1)  ///松开LEFT
    {
      LEFT=0;
    Serial.println("released_Left"); //松开 LEFT
    }
    
      if (Psx.digital_buttons == psxLeft )       //////一直按住LEFT                               
  { 
    Serial.println("down_Left"); //按住 LEFT
    
    }
  /////////////////////RIGHT
  if (Psx.digital_buttons == psxRight && RIGHT==0)                                      
  {  

     RIGHT=1;
      Serial.println("pressed_RIGHT");    //按一次RIGHT 
 
  }
    if (Psx.digital_buttons != psxRight && RIGHT==1)
    {
      RIGHT=0;
    Serial.println("released_Right"); //松开 RIGHT
    }
      if (Psx.digital_buttons == psxRight)                                      
  {  
    
   
     
   }
   
 /////当SELECT=0的时候 按下其他键////****************************************************
 
 if (se==0)
 {
    /////////////////////TRIANGLE   三角
  if (Psx.digital_buttons == psxTri && TRIANGLE==0)                                      
  {  

     TRIANGLE=1;
      Serial.println("pressed_TRIANGLE");    //按下三角 


  }
      if (Psx.digital_buttons != psxTri && TRIANGLE==1)
    {
      TRIANGLE=0;
    Serial.println("released_Trlangle"); //松开 三角
    }
    
    if (Psx.digital_buttons == psxTri)                                      
  {  
   
      Serial.println("Down_TRIANGLE");   //一直按住三角 
    
  }
    /////////////////////CROSS   叉叉
  if (Psx.digital_buttons == psxX && CROSS==0)                                      
  {  
       CROSS=1; 
      Serial.println("pressed_CROSS");    //按一次叉叉 

     }
 

      if (Psx.digital_buttons != psxX && CROSS==1)
    {
      CROSS=0;
    Serial.println("released_CROSS"); //松开 叉叉
    }
    if (Psx.digital_buttons == psxX )                                      
  {  

      Serial.println("Down_CROSS");   //一直按住叉叉
     
  }
  /////////////////////SQUARE   方框
  if (Psx.digital_buttons == psxSqu && SQUARE==0)      //按下方框                              
  {  
    SQUARE=1;
      Serial.println("pressed_SQUARE");    //发送按下方框 
    

  }
   if (Psx.digital_buttons != psxSqu  && SQUARE==1)   ///松开方框
    {
      SQUARE=0;
    Serial.println("released_SQUARE"); //发送 松开方框
    }
    
    
    if (Psx.digital_buttons == psxSqu )     ////按住方框                                
  {  

      Serial.println("Down_SQUARE");   //发送按住方框
  
  }
  /////////////////////CIRCLE   圈圈
   if (Psx.digital_buttons == psxO  && CIRCLE==0)        ///按一次圈圈                              
  {  
     CIRCLE=1;
      Serial.println("pressed_CIRCLE");    //发送按下圈圈 
       
    
  }
  if (Psx.digital_buttons != psxO && CIRCLE==1)   ///松开圈圈
    {
      CIRCLE=0;
    Serial.println("released_CIRCLE"); //发送 松开圈圈
    }
  
  
   if (Psx.digital_buttons == psxO)        ///一直按住圈圈                              
  {  

      Serial.println("Down_CIRCLE");   //发送一直按住圈圈
    
  } 
  
  ////////////////L1
  if (Psx.digital_buttons == psxL1 && L1==0)    /////按下L1                                                                                                                                       
  {  
     L1=1;//取反
      Serial.println("pressed_L1");    
     
  }
  
  if (Psx.digital_buttons != psxL1 && L1==1)   ///松开L1
    {
      L1=0;//取反
    Serial.println("released_L1"); //发送 松开L1
    }
    if (Psx.digital_buttons == psxL1)   ////////一直按住L1                                                                                                                                        
  {  
   
      Serial.println("Down_L1");
     
  }
  
  
  ////////////////////R1
  if (Psx.digital_buttons == psxR1  && R1==0)    //按下R1                                                                                                                                       
  {  
      R1=1;//取反
      Serial.println("pressed_R1");    
     
  }
  
  if (Psx.digital_buttons != psxR1 && R1==1)   ///松开L1
    {
      R1=0;//取反
    Serial.println("released_R1"); //发送 松开L1
    }
  
    if (Psx.digital_buttons == psxR1)                                                                                                                                           
  {  

      Serial.println("Down_R1");
     
  }
 }  
 /////////////////////////////////////////////////////////////
 
   /////当SELECT=1的时候按下其他键//////*********************************************
  if(se==1)
 {
    /////////////////////TRIANGLE   三角
  if (Psx.digital_buttons == psxTri && TRIANGLE==0)                                      
  {  

 TRIANGLE=1;
      Serial.println("Select + pressed_TRIANGLE");    //按下三角 

  }
      if (Psx.digital_buttons != psxTri && TRIANGLE==1)
    {
      TRIANGLE=0;
    Serial.println("Select + released_Trlangle"); //松开 三角
    }
    
    if (Psx.digital_buttons == psxTri)                                      
  {  
   
      Serial.println("Select + Down_TRIANGLE");   //一直按住三角 
    
  }
    /////////////////////CROSS   叉叉
  if (Psx.digital_buttons == psxX && CROSS==0)                                      
  {  
       CROSS=1; 
      Serial.println("Select + pressed_CROSS");    //按一次叉叉 
 
  }
      if (Psx.digital_buttons != psxX && CROSS==1)
    {
      CROSS=0;
    Serial.println("Select + released_CROSS"); //松开 叉叉
    }
    if (Psx.digital_buttons == psxX )                                      
  {  

      Serial.println("Select + Down_CROSS");   //一直按住叉叉
     
  }
  /////////////////////SQUARE   方框
  if (Psx.digital_buttons == psxSqu && SQUARE==0)      //按下方框                              
  {  
    SQUARE=1;
      Serial.println("Select + pressed_SQUARE");    //发送按下方框 

  }
   if (Psx.digital_buttons != psxSqu && SQUARE==1)   ///松开方框
    {
      SQUARE=0;
    Serial.println("Select + released_SQUARE"); //发送 松开方框
    }
    
    
    if (Psx.digital_buttons == psxSqu)     ////按住方框                                
  {  

      Serial.println("Select + Down_SQUARE");   //发送按住方框
  
  }
  /////////////////////CIRCLE   圈圈
   if (Psx.digital_buttons == psxO && CIRCLE==0)        ///一直按住圈圈                              
  {  
     CIRCLE=1;
      Serial.println("Select + pressed_CIRCLE");    //发送按下圈圈 
    
  }
  if (Psx.digital_buttons != psxO && CIRCLE==1)   ///松开圈圈
    {
      CIRCLE=0;
    Serial.println("Select + released_CIRCLE"); //发送 松开圈圈
    }
  
  
   if (Psx.digital_buttons == psxO)        ///一直按住圈圈                              
  {  

      Serial.println("Select + Down_CIRCLE");   //发送一直按住圈圈
    
  } 
  
  ////////////////L1
  if (Psx.digital_buttons == psxL1 && L1==0)    /////按下L1                                                                                                                                       
  {  
     L1=1;//取反
      Serial.println("Select + pressed_L1");    
     
  }
  
  if (Psx.digital_buttons != psxL1 && L1==1)   ///松开L1
    {
      L1=0;//取反
    Serial.println("Select + released_L1"); //发送 松开L1
    }
    if (Psx.digital_buttons == psxL1)   ////////一直按住L1                                                                                                                                        
  {  
   
      Serial.println("Select + Down_L1");
     
  }
  
  
  ////////////////////R1
  if (Psx.digital_buttons == psxR1  && R1==0)    //按下R1                                                                                                                                       
  {  
      R1=1;//取反
      Serial.println("Select + pressed_R1");    
     
  }
  
  if (Psx.digital_buttons != psxR1 && R1==1)   ///松开L1
    {
      R1=0;//取反
    Serial.println("Select + released_R1"); //发送 松开L1
    }
  
    if (Psx.digital_buttons == psxR1)                                                                                                                                           
  {  

      Serial.println("Select + Down_R1");
     
  }
   
 }
  //////////////////*************************************************////////////////////
  
  
  ////////////////L2
  if (Psx.digital_buttons & psxL2   && L2==0)                                                                                                                                           
  {  
    L2=1;
      Serial.println("pressed_L2");   
    t=t+100;
  if (t>=2000)
{
  t=2000;
}
Serial.print("T=");Serial.println(t);
  p=p-5;
  if(p<=5)
  {
    p=5;
  }
  Serial.print("P=");Serial.println(p);
   
      
  }
  if (Psx.digital_buttons==0 && L2==1)   ///松开L1
    {
      L2=0;//取反
    Serial.println("released_L2"); //发送 松开L1
    }
  
    if (Psx.digital_buttons & psxL2)                                                                                                                                           
  {  

      Serial.println("Down_L2");   
  }
  
  
  ///////////////////////R2  
  if (Psx.digital_buttons & psxR2 && R2==0)    //按下R2                                   
  {  
      R2=1;
      Serial.println("pressed_R2");    // 
t=t-100;
if (t<100)
{
  t=100;
}

Serial.print("T=");Serial.println(t);
  p=p+5;
  if(p>=50)
  {
    p=50;
  }
  Serial.print("P=");Serial.println(p);
    
  }
   if (Psx.digital_buttons==0 && R2==1)   ///松开L1
    {
      R2=0;//取反
    Serial.println("released_R2"); //发送 松开L1
    }
    if (Psx.digital_buttons & psxR2)                                       
  {  

      Serial.println("Down_R2");
    
  }
  
  
  ////////////////JoyL    左摇杆按键
  if (Psx.digital_buttons & psxJoyL && JoyL==0)     ///按下左摇杆                                                                                                                                    
  {  
     JoyL=1;
      Serial.println("pressed_JoyL");     //发送按下左摇杆
      c1=c1++;
     c1_1=c1%2;  //求余数 的奇偶性
     if(c1_1==0)
    {   
   // 左摇杆x1  y1使能
    }
       if(c1_1==1)
    {

        Serial.print("#10P"); Serial.print(X1);Serial.print("S");Serial.println(s_1);delay(dy);//左右   头部舵机
        Serial.print("#11P"); Serial.print(Y1);Serial.print("S");Serial.println(s_1);delay(dy);//前后   左手指舵机
         //左摇杆 x1  y1  不使能
    }
     
  }
    if (Psx.digital_buttons==0 && JoyL==1)   ///松开L1
    {
      JoyL=0;//取反
    Serial.println("released_JoyL"); //发送 松开L1
    }
  
  ///////////////////////JoyR    右摇杆按键
  if (Psx.digital_buttons & psxJoyR && JoyR==0)      ///按下 右摇杆                                 
  {  
    JoyR=1;
      Serial.println("pressed_JoyR");    // //发送按下右摇杆
       c2=c2++;
    c2_1=c2%2;  //求余数 的奇偶性
     if(c2_1==0)
    { 
  
   // 右摇杆x2  y2使能
    }
       if(c2_1==1)
    {

        Serial.print("#4P"); Serial.print(X2);Serial.print("S");Serial.println(s_1);delay(dy);//左右
        Serial.print("#13P"); Serial.print(Y2);Serial.print("S");Serial.println(s_1);delay(dy);//前后   右手指舵机
         //右摇杆 x2  y2  不使能
    }
    
  }
      if (Psx.digital_buttons==0 && JoyR==1)   ///松开右摇杆
    {
      JoyR=0;//取反
    Serial.println("released_JoyR"); //发送 松开右摇杆
    }
  
  
      ///////////////////摇杆////////////************************************///////////
      
    if (Psx.Controller_mode==0x0073) /////如果是模拟模式 才开启摇杆
      
  {   
  int x1 = Psx.Left_x;          // x= 0-128-255
  int y1 = Psx.Left_y;           //y= 0-127-255
  int x2 = Psx.Right_x;  
  int y2 = Psx.Right_y;

   int x=128;int y=127;//XY的中间数值,新手柄适用
  //将模式数值0-255 转换成P值 500-2500
  ///x1
  if (x1<=x)
  {
   X1=500+x1*7.8125;
  }
   if (x1>x)
  {
     X1=500+(x1+1)*7.8125;
  }
  ///y1 
   if (y1<y)
  {
   Y1=500+(y1)*7.8125;
  }
   if (y1>=y)
  {
   Y1=500+(y1+1)*7.8125;
  }
  
  
  ///X2
   if (x2<=x)
  {
   X2=500+x2*7.8125;
  }
    if (x2>x)
  {
   X2=500+(x2+1)*7.8125;
  }
  ///y2
 if (y2<y)
  {
   Y2=500+y2*7.8125;
  }
 if (y2>=y)
  {
   Y2=500+(y2+1)*7.8125;
  }
  
  
   if(c1_1==0)
 {
   ///////////////LEFT_X
  if (x1<118||x1>138)
  {
  Serial.print("analog left x= "); Serial.println( x1);  
    Serial.print("#10P"); Serial.print(X1);Serial.print("S");Serial.println(s_1);delay(dy); 
   b=1;  
  } 
 
   if (x1>118 && x1<138&&  b==1)
  {
  Serial.print("analog left x= "); Serial.println( x1); 
     Serial.print("#10P"); Serial.print(X1);Serial.print("S");Serial.println(s_1);delay(dy);
   b=0;  
  } 
  ///////////// LEFT_Y
    if (y1<117||y1>137)
  {
  Serial.print("analog left y= "); Serial.println( y1);  
 Serial.print("#11P"); Serial.print(Y1);Serial.print("S");Serial.println(s_1);delay(dy);  
   b1=1;  
  } 
 
   if (y1>117 && y1<137&&  b1==1)
  {
  Serial.print("analog left y= "); Serial.println( y1); 
  Serial.print("#11P"); Serial.print(Y1);Serial.print("S");Serial.println(s_1);delay(dy); 
   b1=0;  
  } 
 }
 
  if(c2_1==0)
 {
      ///////////////RIGHT_X
  if (x2<118||x2>138)
  {
  Serial.print("analog right x= "); Serial.println( x2);   
   Serial.print("#4P"); Serial.print(X2);Serial.print("S");Serial.println(s_1);delay(dy);  
   b2=1;  
  } 
 
   if (x2>118 && x2<138&&  b2==1)
  {
  Serial.print("analog right x= "); Serial.println( x2); 
   Serial.print("#4P"); Serial.print(X2);Serial.print("S");Serial.println(s_1);delay(dy);  
   b2=0;  
  } 
  ///////////// RIGHT_Y
    if (y2<117||y2>137)
  {
  Serial.print("analog right y= "); Serial.println( y2);   
   Serial.print("#13P"); Serial.print(Y2);Serial.print("S");Serial.println(s_1);delay(dy);  
   b3=1;  
  } 
 
   if (y2>117 && y2<137&&  b3==1)
  {
  Serial.print("analog right y= "); Serial.println( y2); 
   Serial.print("#13P"); Serial.print(Y2);Serial.print("S");Serial.println(s_1);delay(dy);  
   b3=0;  
  }
 }
  
  } 
 

}

Credits

Eric Leung

Eric Leung

9 projects • 8 followers
Robot Lover

Comments