sjiliang 发表于 2020-3-4 21:28:57

差速转向坦克车(PS2+SPI+LCD16202)

差速控制转向,可以用X/Y参数(这里用PS2手柄的一个摇杆)控制车辆前后、调速,转向;简化了操纵难度。
本人习惯用Promini328p,取其性价比高,体积小巧,功能够用;用74LS595实现SPI扩展并行接口;前四位驱动一个四相五线步进电机(炮塔),后四位通过754410驱动两个有刷电机。开机音乐尚没进步开发应用。
本机增加LCD1602作为人机对话,便于调试阶段检测遥控通讯。

/**
Version 2020.3.2
by SJL
**/
#include <PS2X_lib.h>            //PS2X
#include <LiquidCrystal.h>      //lcd
#include "pitches.h"               //tone

//LCD initial
const int rs = 5, en = 4, d4 = A0, d5 = A1, d6 = A2, d7 = A3;
//const int rs = A2, en = A1, d4 = A3, d5 = A4, d6 = A5, d7 = 5;数据脚皆可用模拟替代。
LiquidCrystal lcd(rs, en, d4, d5, d6, d7);

//74HC595 SPI initial
#define latchPin 12
#define clockPin 11
#define dataPin 10

//tone
const int Speaker=3;
int melody[] = {NOTE_C4, NOTE_G3, NOTE_G3, NOTE_A3, NOTE_G3, 0, NOTE_B3, NOTE_C4};    // notes in the melody:
int noteDurations[] = {4, 8, 8, 4, 4, 4, 4, 4};    // note durations: 4 = quarter note, 8 = eighth note, etc.:

//PS2 initial
#define PS2_DAT      8      // 2019.10.20旧版本 dat、cmd 不能用模拟管脚。
#define PS2_CMD      7   
#define PS2_SEL      A5      
#define PS2_CLK      A4      

#define motorL_En12   9               //754410 PinEnable,PWMpin
#define motorR_En34   6
int motorDr[]={B0101,B1010,B0000};    //(-+ -+,+-+-,----)/gofront,goback,stop motorCode
                                    //可调节管脚正负配置,{B1010,B0101,B0000}
int L_EnValue=0, R_EnValue=0;

PS2X ps2x;            // create PS2 Controller Class

int PS_LX;               //PS2手柄左摇杆X轴数据 左摇杆用于行走
int PS_LY;               
int PS_RX;               //PS2手柄右摇杆X轴数据 右摇杆用于炮塔 Turret
int PS_RY;               //暂空

int error = 0;         //ps2连接正确与否的判断标志
byte type = 0;         //ps2x.readType()转换判别标志   
byte vibrate = 0;

int carCoad=0;          //car move mode code
int F=0;                //car move value
int Turn=0;             //car turn value
int T=0;                //Turrent round value
int Degree=1100;          //most value of turrent round
int StepNumber = 0;   //stepmotor wont moveNumber
int old_Degree = 0;

int StepData=0;                              //步进电机的执行编码
int stepCode[] = {8, 12, 4, 6, 2, 3, 1, 9};//8步编码
int stepCodeIndex=0;                        //步编码-电机当前位于0~7的哪一步

void setup() {
lcd.begin(16, 2);               // set up the LCD's number of columns and rows:

lcd.print("Lx");      
lcd.setCursor(0,1);
lcd.print("Rx");
lcd.setCursor(8,0);
lcd.write("Ly");
lcd.setCursor(8,1);
lcd.write("Ry");

pinMode(dataPin,OUTPUT);pinMode(clockPin,OUTPUT);pinMode(latchPin,OUTPUT);//74HC595管脚配置
pinMode(motorL_En12,OUTPUT);pinMode(motorR_En34,OUTPUT);                      //电机使能管脚配置

//tone
   for (int thisNote = 0; thisNote < 8; thisNote++) {
      int noteDuration = 1000 / noteDurations;
      tone(Speaker, melody, noteDuration);
      int pauseBetweenNotes = noteDuration * 1.30;   // to distinguish the notes, set a minimum time between them.   
                                                   // the note's duration + 30% seems to work well:
      delay(pauseBetweenNotes);   
      noTone(3);                                  // stop the tone playing:
}

// initialize the serial communications
Serial.begin(9600);            
delay(50);
error = ps2x.config_gamepad(PS2_CLK, PS2_CMD, PS2_SEL, PS2_DAT);
}

void loop() {
    int number=5 ;   
    ps2x.read_gamepad(false, vibrate);          //read controller and set large motor to spin at 'vibrate' speed
   
    /*if(ps2x.Button(PSB_START))                  //start选中
      Serial.println("Start is being held");   
    if(ps2x.Button(PSB_SELECT))                  //select选中
      Serial.println("Select is being held");*/

   PS_LX=ps2x.Analog(PSS_LX);         //把PS2手柄左摇杆X轴数据赋值PS_LX
   PS_RX=ps2x.Analog(PSS_RX);         //把PS2手柄右摇杆X轴数据赋值PS_RX
   PS_LY=ps2x.Analog(PSS_LY);         //把PS2手柄左摇杆Y轴数据赋值PS_LY
   PS_RY=ps2x.Analog(PSS_RY);         //把PS2手柄右摇杆Y轴数据赋值PS_RY

   lcd.setCursor(3,0);                  //LCD显示手柄参数
   lcd.print(PS_LX);
   lcd.setCursor(11,0);
   lcd.print(PS_LY);
   lcd.setCursor(3,1);
   lcd.print(PS_RX);
   lcd.setCursor(11,1);
   lcd.print(PS_RY);
   
/******************* 行走控制 ************************/         
    if(PS_LY<=125){                        //轮使能/电机运转旋向配置                  
      F = map(PS_LY,125,0,90,255);      //电机使能值确定
      carCoad = motorDr;               //各电机运行方向确定 goFront
      }
    else if(PS_LY>=130){
      F = map(PS_LY,130,255,90,255);   
      carCoad = motorDr;               //goBack
      }
   else {F=0;    carCoad=motorDr;}   //Stop
   //转向影响旋转使能的百分比            
   if(PS_LX<=125){               //左转                     
      Turn = map(PS_LX,125,0,90,40);
      L_EnValue = F * Turn/100;         //转向侧电机使能值 按照百分比减弱
      if(L_EnValue<30)L_EnValue=0;    //若使能值小于某值,直接定义为0;以免烧电机。
      R_EnValue = F;   
      }
   else if(PS_LX>=130){             //右转
      Turn = map(PS_LX,130,255,90,40);
      L_EnValue = F;
      R_EnValue = F * Turn/100;         //转向侧电机使能值 按照百分比减弱
         if(R_EnValue<30)R_EnValue=0;   //若使能值小于某值,直接定义为0;以免烧电机。
      }
    else {                           //Turn=0;
      L_EnValue = F;
      R_EnValue = F;
      }
                     
carMove(carCoad,L_EnValue,R_EnValue,StepData); //用所得参数 调用行走子程序。

   /***************** 炮塔控制 *************************/
   {      }   
}
            /********************************************
            走行子程序(行走模式,en_L, en_R, Turrent_StepData)
               *******************************************/
void carMove(int carCoad,int L_EnValue,int R_EnValue,int StepData)
{                     
      byte DataByte;
         digitalWrite(motorL_En12,LOW);                //first turnOff every enPin
         digitalWrite(motorR_En34,LOW);
         
      DataByte = (StepData<< 4) | carCoad;             //字节组合
      //Serial.print(" StepData ");Serial.print(StepData);Serial.print(" carCoad ");Serial.println(carCoad);
      
      digitalWrite(latchPin, LOW);                     //数据串行输出,关断latchPin。         
      shiftOut(dataPin, clockPin, MSBFIRST, DataByte); //逐个字节发送
      //delay(5);   
      digitalWrite(latchPin, HIGH);                  //打开latchPin,数据并行输出
      
      analogWrite(motorL_En12, L_EnValue);   
      analogWrite(motorR_En34, R_EnValue);      
}

太行摄狼 发表于 2020-3-8 16:55:58

把接线和图片都发出来吧

allen727hk 发表于 2020-3-12 10:18:13

本帖最后由 allen727hk 于 2020-3-12 10:33 编辑

有影片看嗎?

cjs1748 发表于 2020-3-12 12:24:52

記起來! 記起來!!    空閒再來研究一下~

lbyc106 发表于 2020-3-24 17:56:52

有接线图吗?

ljblj001 发表于 2020-4-2 10:02:47

有接线图吗?   
页: [1]
查看完整版本: 差速转向坦克车(PS2+SPI+LCD16202)