如何搭建ROS小车底盘1--硬件准备篇

发布时间:2016年09月27日 22:19:10    浏览数:5906次    来自:EAIBOT
教大家如何使用简单的硬件搭建一台支持ROS的低成本小车-硬件准备篇

一、搭建前准备

硬件清单:

树梅派2或3代

带编码器测速JGA25-371减速电机一对

小车轮子一对

万向轮一个

小车亚克力板底板一套

Arduino MEGA2560 R3开发板一块:用于控制电机驱动,接收上位机指令并把传感器

L298N电机驱动板模块

12V充电电池块

电池分压模块

软件清单:

Unbuntu 14.04

indigo版本ROS系统

indigo版本ros_arduino_bridge

搭建步骤: 

首先,我们把JGA25-371减速电机和轮子连接,然后和万向轮一起固定到小车亚克力板底板上。这一步比较简单,我们就不再详细介绍。 

然后,我们重点要考虑JGA25-371减速电机、L298N电机驱动板模块、Arduino MEGA2560 R3、树梅派和电池之间如何连接。

主要部件的介绍:

JGA25-371减速电机:JGA25-371带编码器测速码盘的电机由直流减速电机和双通道霍尔效应编码器两部分组成。

如下图所示:

1.png

直流减速电机的工作电压:6-24VDC。根据在额定电压12V时每分钟空载转速不同, 

JGA25-371系列电机分为如下几个型号:977rpm 463rpm 201rpm 126rpm 95rpm 55rpm 41rpm 25rpm 19rpm 11rpm 8.6rpm。

如下图所示。 

2.png

转速越快,做出来来小车的速度就会越快,但转速快的小车扭矩就小,小车的载重就随之变小,并且小车在上坡或越过障碍物时就显得动力不足。我们建议购买型号为126rpm转速的电机。 
测速的编码器是双通道霍尔效应编码器,它包含一个磁栅和磁敏检测电路,输出两个通道正交相位角为90度的方波。如下图所示。 

3.png

该编码器单路每圈脉冲13CPR(Counts Per Revolution,每转脉冲的个数)。

一方面由于每圈又可以分一个上升沿和一个下降沿,

另一方面该编码器拥有A B双路输出

所以每转一圈,该编码器的双路上下沿总共可以输出52CPR。

那么小车轮子转一圈,最多只能产生52个脉冲信号吗?

不对,还要考虑减速比,以转速为126rpm 的型号电机为例,它的减速比为1:34,也就是说,编码器侧转34圈,小车的轮子才转一圈。所以,小车轮子转一圈,可以产生52*34=1768个脉冲信号。 

另外,还可以根据A B双路输出的信号,确定轮子是正转还是反转。 

JGA25-371电机和编码器的接线如下图所示:

QQ截图20160516113546.jpg

接线按上图片从右到左分是M+、M-、Hgnd、Hvcc、HoutA、 HoutB

M+(红线) 电机电源+

M-(黑线) 电机电源-

Hgnd(绿线) 编码器地线

Hvcc(蓝线) 编码器电源(接5V电压)

HoutA(黄线) 信号A输出

HoutB(白线) 信号B输出

arduino编码器测试代码:

#define BAUDRATE     115200
#define LEFT            0
#define RIGHT           1
#define FORWARDS true
#define BACKWARDS false

volatile long encoderLeft = 0L;
volatile long encoderRight = 0L;

void initEncoders(){
  pinMode(2, INPUT);
  pinMode(3, INPUT);

  attachInterrupt(0, encoderLeftISR, CHANGE);  
  attachInterrupt(1, encoderRightISR, CHANGE);
}

void encoderLeftISR(){
    encoderLeft++;
}

void encoderRightISR(){
    encoderRight++;
}

long readEncoder(int i) {
  long encVal = 0L;
  if (i == LEFT)  {
     noInterrupts();
    //detachInterrupt(0);
    encVal = encoderLeft;
    interrupts();
    //attachInterrupt(0, Code_left, FALLING);
  }
  else {
    noInterrupts();
    //detachInterrupt(1);
    encVal = encoderRight;
    interrupts();
    //attachInterrupt(1, Code_right, FALLING);
  }
  return encVal;
}

/* Wrap the encoder reset function */
void resetEncoder(int i) {
  if (i == LEFT){
    noInterrupts();
    encoderLeft = 0L;
    interrupts();
  }else {
    noInterrupts();
    encoderRight = 0L;
     interrupts();
  }
}
/* Wrap the encoder reset function */
void resetEncoders() {
  resetEncoder(LEFT);
  resetEncoder(RIGHT);
}

 void setup() {
  Serial.begin(BAUDRATE);
  initEncoders();
  resetEncoders();
}

void loop() {
  long lval=readEncoder(0);
   long rval=readEncoder(1);
   Serial.print("left: ");
   Serial.print(lval);
   Serial.print("; right: ");
   Serial.println(rval);
  delay(30);
}

测试结果如下: 

1.jpg

由于JGA25-371电机需要L298N模块来驱动,所以再讲JGA25-371电机连线之前,先来介绍下L298N模块。

L298N电机驱动模块如下图所示。

1.jpg

驱动电压5v~35v, 逻辑电压5v. 内置的78M05通过驱动电源部分取电工作, 当使用大于12V驱动电压的时候,为了避免稳压芯片损坏, 请使用外置的5V逻辑供电。 

ENA:OUT1和OUT2的使能端,默认情况下,跳线帽接上时,高电平有效,低电平禁止;如果需要PWM调速,就需要拔掉跳线帽.

驱动直流电机:

由于本模块是2路的H桥驱动,所以可以同时驱动两个电机

使能ENA ENB之后, 

可以分别从IN1 IN2输入PWM信号驱动电机1的转速和方向 

可以分别从IN3 IN4输入PWM信号驱动电机2的转速和方向 

信号如图所示 

2.jpg

驱动步进电机:

由于本模块是2路的H桥驱动,所以可以同时驱动两个电机, 

使能ENA ENB之后, 

可以分别从IN1 IN2输入PWM信号驱动电机1的转速和方向 

可以分别从IN3 IN4输入PWM信号驱动电机2的转速和方向

2.jpg

接线如上上上图所示,这个很简单就不说了

如果L298N和arduino使用不同的电源供电的话,那么需要将arduino的GND和模块上的GND连接在一起,共地,只有这样单片机上过来的逻辑信号才有个参考0点。此点非常重要,请大家注意。

两种接线方式。 

方式一:通过IN1和IN2控制电机转动方向(正转或反转), 通过ENA控制电机的转速。 

arduino的代码:

int enA = 5;
int in1 = 7;
int in2 = 8;
// motor two
int enB = 6;
int in3 = 9;
int in4 = 10;
void setup()
{
  // set all the motor control pins to outputs
  pinMode(enA, OUTPUT);
  pinMode(enB, OUTPUT);
  pinMode(in1, OUTPUT);
  pinMode(in2, OUTPUT);
  pinMode(in3, OUTPUT);
  pinMode(in4, OUTPUT);
}
void demoOne()
{
  // this function will run the motors in both directions at a fixed speed
  // turn on motor A
  digitalWrite(in1, HIGH);
  digitalWrite(in2, LOW);
  // set speed to 200 out of possible range 0~255
  analogWrite(enA, 200);
  // turn on motor B
  digitalWrite(in4, HIGH);
  digitalWrite(in3, LOW);
  // set speed to 200 out of possible range 0~255
  analogWrite(enB, 200);
  delay(2000);
  // now change motor directions
  digitalWrite(in1, LOW);
  digitalWrite(in2, HIGH);  
  digitalWrite(in4, LOW);
  digitalWrite(in3, HIGH); 
  delay(2000);
  // now turn off motors
  digitalWrite(in1, LOW);
  digitalWrite(in2, LOW);  
  digitalWrite(in3, LOW);
  digitalWrite(in4, LOW);
}
void demoTwo()
{
  // this function will run the motors across the range of possible speeds
  // note that maximum speed is determined by the motor itself and the operating voltage
  // the PWM values sent by analogWrite() are fractions of the maximum speed possible 
  // by your hardware
  // turn on motors
  digitalWrite(in1, LOW);
  digitalWrite(in2, HIGH);  
  digitalWrite(in3, LOW);
  digitalWrite(in4, HIGH); 
  // accelerate from zero to maximum speed
  for (int i = 0; i < 256; i++)
  {
    analogWrite(enA, i);
    analogWrite(enB, i);
    delay(20);
  } 
  // decelerate from maximum speed to zero
  for (int i = 255; i >= 0; --i)
  {
    analogWrite(enA, i);
    analogWrite(enB, i);
    delay(20);
  } 
  // now turn off motors
  digitalWrite(in1, LOW);
  digitalWrite(in2, LOW);  
  digitalWrite(in3, LOW);
  digitalWrite(in4, LOW);  
}
void loop()
{
  demoOne();
  delay(1000);
  demoTwo();
  delay(1000);
}

方式二:ENA插帽不用拔掉,通过IN1和IN2输入PWM控制电机转动的方向和转速。 

1.jpg


标签: EAIBOT 小车

评论共0条评论

登录后再评论!

全部评论

目前没有评论