差速转向坦克车(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);
}
把接线和图片都发出来吧 本帖最后由 allen727hk 于 2020-3-12 10:33 编辑
有影片看嗎? 記起來! 記起來!! 空閒再來研究一下~ 有接线图吗? 有接线图吗?
页:
[1]