搭建小车底盘分两步:
首先,我们把JGA25-371减速电机和轮子连接,然后和万向轮一起固定到小车亚克力板底板上。这一步比较简单,我们就不再详细介绍。
然后,我们重点要考虑JGA25-371减速电机、L298N电机驱动板模块、Arduino MEGA2560 R3、树梅派和电池之间如何连接。
JGA25-371带编码器测速码盘的电机由两部分组成:直流减速电机和双通道霍尔效应编码器。如下图所示:
直流减速电机的工作电压:6-24VDC。根据在额定电压12V时每分钟空载转速不同, JGA25-371系列电机分为如下几个型号:977rpm 463rpm 201rpm 126rpm 95rpm 55rpm 41rpm 25rpm 19rpm 11rpm 8.6rpm。如下图所示。
转速越快,做出来来小车的速度就会越快,但转速快的小车扭矩就小,小车的载重就随之变小,并且小车在上坡或越过障碍物时就显得动力不足。我们建议购买型号为126rpm转速的电机。
测速的编码器是双通道霍尔效应编码器,它包含一个磁栅和磁敏检测电路,输出两个通道正交相位角为90度的方波。如下图所示。
该编码器单路每圈脉冲13CPR(Counts Per Revolution,每转脉冲的个数)。一方面由于每圈又可以分一个上升沿和一个下降沿,另一方面该编码器拥有A B双路输出,所以每转一圈,该编码器的双路上下沿总共可以输出52CPR。那么小车轮子转一圈,最多只能产生52个脉冲信号吗?不对,还要考虑减速比,以转速为126rpm 的型号电机为例,它的减速比为1:34,也就是说,编码器侧转34圈,小车的轮子才转一圈。所以,小车轮子转一圈,可以产生52*34=1768个脉冲信号。
另外,还可以根据A B双路输出的信号,确定轮子是正转还是反转。
JGA25-371电机和编码器的接线如下图所示。
接线按上图片从右到左分是M+、M-、Hgnd、Hvcc、HoutA、 HoutB。
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);
}
由于JGA25-371电机需要L298N模块来驱动,所以再讲JGA25-371电机连线之前,先来介绍下L298N模块。
L298N电机驱动模块如下图所示。
驱动电压5v~35v, 逻辑电压5v. 内置的78M05通过驱动电源部分取电工作, 当使用大于12V驱动电压的时候,为了避免稳压芯片损坏, 请使用外置的5V逻辑供电。
ENA:OUT1和OUT2的使能端,默认情况下,跳线帽接上时,高电平有效,低电平禁止;如果需要PWM调速,就需要拔掉跳线帽.
由于本模块是2路的H桥驱动,所以可以同时驱动两个电机
使能ENA ENB之后,
可以分别从IN1 IN2输入PWM信号驱动电机1的转速和方向
可以分别从IN3 IN4输入PWM信号驱动电机2的转速和方向
信号如图所示
由于本模块是2路的H桥驱动,所以可以同时驱动两个电机,
使能ENA ENB之后,
可以分别从IN1 IN2输入PWM信号驱动电机1的转速和方向
可以分别从IN3 IN4输入PWM信号驱动电机2的转速和方向
如果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);
}