树莓派+ L298N 控制二相四线步进电机

2023-05-16

树莓派+ L298N 控制二相四线步进电机

1 步进电机

步进电机是一种将电脉冲信号转换成相应角位移或线位移的电动机。在非超载的情况下,电机的转速、停止的位置只取决于脉冲信号的频率和脉冲数,而不受负载变化的影响,即给电机加一个脉冲信号,电机则转过一个步距角。这一线性关系的存在,加上步进电机只有周期性的误差而无累积误差等特点。使得在速度、位置等控制领域用步进电机来控制变的非常的简单。

1.1 步进电机相关概念

相数:产生不同对极N、S磁场的激磁线圈对数,常用 m 表示。例如:二相四线电机,就有两对极N、S磁场的激磁线圈,四个线圈。上图可知,A+,A- 是连通的,B+ 和B- 是连通的,分别记为A组、B组。在不知道电机接线图的情况下可以用万用表测试,即相互连通的为一组。

拍数:完成一个磁场周期性变化所需脉冲数或导电状态用n表示,或指电机转过一个齿距角所需脉冲数,以四相电机为例,有四相四拍运行方式即AB-BC-CD-DA,四相八拍运行方式即 A-AB-B-BC-C-CD-D-DA。

步距角:对应一个脉冲信号,电机转子转过的角位移用θ表示。θ=360度(转子齿数J运行拍数),以常规二、四相,转子齿为50齿电机为例。四拍运行时步距角为θ=360度/( 50 × 4 50\times 4 50×4)=1.8度(俗称整步),八拍运行时步距角为θ=360度/( 50 × 8 50\times 8 50×8)=0.9度(俗称半步)。

定位转矩:电机在不通电状态下,电机转子自身的锁定力矩(由磁场齿形的谐波以及机械误差造成的)。

静转矩:电机在额定静态电作用下,电机不作旋转运动时,电机转轴的锁定力矩。此力矩是衡量电机体积(几何尺寸)的标准,与驱动电压及驱动电源等无关。

1.2 二相四线步进电机工作原理

首先电机有4个电极,一共有4个线圈,两两串联,A+与A-是一组线圈, B+与B-是一组线圈。

在这里插入图片描述

1、A+加正极,A-加负极,B+加负极,B-加负极,(电机状态,N极朝上,如图(a)所示)。

2、B+加正极,B-加负极,A+加负极,A-加负极,(电机状态,N极朝右,电机顺时针旋转90°,如图(b)所示)。

3、A-加正极,A+ 、B+ 、B- 皆加负极,(电机状态,N极朝下,电机顺时针再次旋转90°,如图©所示)。

4、B-加正极,A+ 、 A- 、B+ 皆加负极, (电机状态,N极朝下,电机顺时针再次旋转90°,如图(d)所示)。

只要依次给相应引脚相应的电平就可以使得电机转动,转动的最小角度为90度,正极顺时针旋转电机正转,正极逆时针旋转电机反转。

1.3 二相四线步进电机通电方式

单四拍控制通电方式

A+B+A-B-
1000
0100
0010
0001

双四拍控制通电方式

A+B+A-B-
1100
0110
0011
1001

单八拍控制通电方式

A+B+A-B-
1000
1100
0100
0110
0010
0011
0001
1001

2 驱动器

2.1 L298N电机驱动模块

L298N就是L298的立式封装,源自意法半导体集团旗下品牌产品,是一款可接受高电压、大电流双路全桥式电机驱动芯片,工作电压可达46V,输出电流最高可至4A,具有两个使能控制端,在不受输入信号影响的情况下通过板载跳帽插拔的方式,动态调整电路运作方式。有一个逻辑电源输入端,使内部逻辑电路部分在低电压下工作,也可以对外输出逻辑电压5V,为了避免稳压芯片损坏,当使用大于12V驱动电压时,务必使用外置的5V接口独立供电。

L298N通过控制主控芯片上的I/O输入端,直接通过电源来调节输出电压,即可实现电机的正转、反转、停止,由于电路简单,使用方便,通常情况下L298N可直接驱动继电器(四路)、螺线管、电磁阀、两台直流电机以及一台步进电机(两相或者四相)。

2.2 L298N 电机驱动版规格参数

驱动电机芯片:L298N双H桥直流电机驱动芯片
驱动供电范围:5V~35V ;如需板内取电,则供电范围7V~35V
驱动峰值电流:2A
逻辑部分端子供电范围:5V~7V(可板内取电5V)
逻辑部分工作电流范围: 0~36mA
控制信号输入电压范围:
低电平:-0.3V≤Vin≤1.5V
高电平: 2.3V≤Vin≤Vss
使能信号输入电压范围:
低电平:-0.3≤Vin≤1.5V(控制信号无效)
高电平:2.3V≤Vin≤Vss(控制信号有效)
最大功耗:20W(温度T=75℃时)、

ps:

VCC:C =circuit 表示电路的意思, 即接入电路的电压

VSS :S =series 表示公共连接的意思,通常指电路公共接地端电压

VDD:D=device 表示器件的意思, 即器件内部的工作电压

GND:Ground,电源的负极

VBAT:当使用电池或其他电源连接到VBAT脚上时,当VDD 断电时,可以保存备份寄存器的内容和维持RTC的功能。如果应用中没有使用外部电池,VBAT引脚应接到VDD引脚上

2.3 L298N 电机驱动板引脚

在这里插入图片描述

L298N驱动模块的引脚可以简单分为电源、控制输出等三大类。

电压类引脚
+12 V输入:L298N芯片的电源正极,模块儿上标定为 12 V,实际取电范围5 V~35 V ;如需板内取电,则供电范围7 V~35 V
GND: L298N芯片的电源地,使用的时候应该把树莓派的GND接到这里,即两者需要共地
+5V输出:L298N芯片输出的5V电源,可以给外部设备供电,使用的时候需要用跳线把5V输出使能端短接起来。

控制类引脚

ENA、ENB:A、B通道的使能端,高电平有效,可以用PWM来实现调速。使用时,可以接到树莓派的GPIO上,实现用程序进行控制。
IN1、IN2、IN3、IN4:IN1、IN2为A通道的控制输入,IN3、IN4为B通道的控制输入。

输出类引脚
OUT1、OUT2、OUT3、OUT4:OUT1、OUT2由A通道输出,OUT3、OUT4由B通道输出,可以用于连接直流电机、步进电机等设备。

3 树莓派(3B)

在这里插入图片描述

树莓派GPIO编号方式有三种,分别是:功能物理引脚(physical)、BCM以及wiring Pi.
功能物理引脚(Board):从左到右,从上到下。左边为奇数,右边为偶数。共计40个引脚,计数为1-40。

BCM:编号侧重于CPU寄存器,根据BCM2835的GPIO寄存器编号。具体编号参照上图中BCM一栏。

wiring Pi: 编号侧重实现逻辑,把扩展GPIO端口从0开始编号,这种编号方便编程。(本文没有提及)

编号方式不影响使用,操作时明确使用一种就行。

4 硬件连接部分

在这里插入图片描述

电机为FDK的二相四线步进电机,黄、橙、棕、黑四种颜色的线分别为A+, A-, B+ , B-, 分别连接在L298N驱动板的OUT1 , OUT3 , OUT2, OUT4(也可以改顺序,对应改代码就行)。外接电源给L298N提供稳定的5V电压,并使L298N与树莓派共地(两者的ground接通)。驱动板的IN1, IN2, IN3, IN4分别与树莓派的功能物理引脚编号38、40、15、16相连接,ENA, ENB 可以不操作(板载跳帽是默认连通的,即为高电平),本文ENA, ENB与物理引脚18、20连接,并定义为高电平。

5 代码部分

5.1 单四拍控制通电方式


# -*- coding: utf-8 -*-          #通过声明可以在程序中书写中文
import RPi.GPIO as GPIO          #引入RPi.GPIO库函数命名为GPIO
import time                      #引入计时time函数

GPIO.setmode(GPIO.BOARD)         #将GPIO编程方式设置为BOARD模式

#接口定义
IN1 = 22                         #将L298 IN1口连接到树莓派Pin22   
IN2 = 18                         #将L298 IN1口连接到树莓派Pin18
IN3 = 38                         #将L298 IN1口连接到树莓派Pin38
IN4 = 40                         #将L298 IN2口连接到树莓派Pin40
IN5 = 15                         #将L298 IN3口连接到树莓派Pin15
IN6 = 16                         #将L298 IN4口连接到树莓派Pin16

def setStep(w1, w2, w3, w4, w5, w6):
    GPIO.output(IN1, w1)
    GPIO.output(IN2, w2)
    GPIO.output(IN3, w3)
    GPIO.output(IN4, w4)
    GPIO.output(IN5, w5)
    GPIO.output(IN6, w6)
 
def stop():
    setStep(0, 0, 0, 0, 0, 0)
 
def forward(delay, steps):  
    for i in range(0, steps):
        setStep(1, 1, 1, 0, 0, 0)
        time.sleep(delay)
        setStep(1, 1, 0, 1, 0, 0)
        time.sleep(delay)
        setStep(1, 1, 0, 0, 1, 0)
        time.sleep(delay)
        setStep(1, 1, 0, 0, 0, 1)
        time.sleep(delay)
 
def backward(delay, steps):  
    for i in range(0, steps):
        setStep(1, 1, 0, 0, 0, 1)
        time.sleep(delay)
        setStep(1, 1, 0, 0, 1, 0)
        time.sleep(delay)
        setStep(1, 1, 0, 1, 0, 0)
        time.sleep(delay)
        setStep(1, 1, 1, 0, 0, 0)
        time.sleep(delay)
 
def setup():
    GPIO.setwarnings(False)
    GPIO.setmode(GPIO.BOARD)       # Numbers GPIOs by physical location
    GPIO.setup(IN1, GPIO.OUT)      # Set pin's mode is output
    GPIO.setup(IN2, GPIO.OUT)
    GPIO.setup(IN3, GPIO.OUT)
    GPIO.setup(IN4, GPIO.OUT)
    GPIO.setup(IN5, GPIO.OUT)
    GPIO.setup(IN6, GPIO.OUT)

def loop():
    while True:
        print ("backward...")
        backward(0.01, 200)   # 发射脉冲时间间隔0.01(单位秒)   脉冲个数200
        
        print ("stop...")
        stop()                 # stop
        time.sleep(2)          # sleep 2s
        
        print ("forward...")
        forward(0.01, 200)
        
        print ("stop...")
        stop()
        time.sleep(2)
 
def destroy():
    GPIO.cleanup()             # 释放数据
 
if __name__ == '__main__':     # Program start from here
    setup()
    try:
        loop()
    except KeyboardInterrupt:  # When 'Ctrl+C' is pressed, the child function destroy() will be  executed.
        destroy()


5.2 单八拍控制通电方式


# -*- coding: utf-8 -*-            #通过声明可以在程序中书写中文
import RPi.GPIO as GPIO            #引入RPi.GPIO库函数命名为GPIO
import time                        #引入计时time函数

# BOARD编号方式,基于插座引脚编号
GPIO.setmode(GPIO.BOARD)           #将GPIO编程方式设置为BOARD模式

#接口定义
IN1 = 22                           #将L298 IN1口连接到树莓派Pin22
IN4 = 18                           #将L298 IN2口连接到树莓派Pin18
IN3 = 38                           #将L298 IN1口连接到树莓派Pin38
IN4 = 40                           #将L298 IN2口连接到树莓派Pin40
IN5 = 15                           #将L298 IN3口连接到树莓派Pin15
IN6 = 16                           #将L298 IN4口连接到树莓派Pin16

def setStep(w1, w2, w3, w4, w5, w6):
    GPIO.output(IN1, w1)
    GPIO.output(IN2, w2)
    GPIO.output(IN3, w3)
    GPIO.output(IN4, w4)
    GPIO.output(IN5, w5)
    GPIO.output(IN6, w6)
 
def stop():
    setStep(0, 0, 0, 0, 0, 0)
 
def forward(delay, steps):  
    for i in range(0, steps):
        setStep(1, 1, 1, 0, 0, 0)
        time.sleep(delay)
        setStep(1, 1, 1, 1, 0, 0)
        time.sleep(delay)
        setStep(1, 1, 0, 1, 0, 0)
        time.sleep(delay)
        setStep(1, 1, 0, 1, 1, 0)
        time.sleep(delay)
        setStep(1, 1, 0, 0, 1, 0)
        time.sleep(delay)
        setStep(1, 1, 0, 0, 1, 1)
        time.sleep(delay)
        setStep(1, 1, 0, 0, 0, 1)
        time.sleep(delay)
        setStep(1, 1, 1, 0, 0, 1)
        time.sleep(delay)
 
def backward(delay, steps):  
    for i in range(0, steps):
        setStep(1, 1, 1, 0, 0, 1)
        time.sleep(delay)
        setStep(1, 1, 0, 0, 0, 1)
        time.sleep(delay)
        setStep(1, 1, 0, 0, 1, 1)
        time.sleep(delay)
        setStep(1, 1, 0, 0, 1, 0)
        time.sleep(delay)
        setStep(1, 1, 0, 1, 1, 0)
        time.sleep(delay)
        setStep(1, 1, 0, 1, 0, 0)
        time.sleep(delay)
        setStep(1, 1, 1, 1, 0, 0)
        time.sleep(delay)
        setStep(1, 1, 1, 0, 0, 0)
        time.sleep(delay)
 
def setup():
    GPIO.setwarnings(False)
    GPIO.setmode(GPIO.BOARD)       # Numbers GPIOs by physical location
    GPIO.setup(IN1, GPIO.OUT)      # Set pin's mode is output
    GPIO.setup(IN2, GPIO.OUT)
    GPIO.setup(IN3, GPIO.OUT)
    GPIO.setup(IN4, GPIO.OUT)
    GPIO.setup(IN5, GPIO.OUT)
    GPIO.setup(IN6, GPIO.OUT)

def loop():
    while True:
        print ("backward...")
        backward(0.01, 200)   # 发射脉冲时间间隔0.01(单位秒)   脉冲个数200
        
        print ("stop...")
        stop()                 # stop
        time.sleep(2)          # sleep 2s
        
        print ("forward...")
        forward(0.01, 200)
        
        print ("stop...")
        stop()
        time.sleep(2)
 
def destroy():
    GPIO.cleanup()             # 释放数据
 
if __name__ == '__main__':     # Program start from here
    setup()
    try:
        loop()
    except KeyboardInterrupt:  # When 'Ctrl+C' is pressed, the child function destroy() will be  executed.
        destroy()


参考文献

51单片机教程:二相四线步进电机驱动

零基础玩转树莓派(五)—控制直流电机

树莓派控制直流电机

L298N 电机驱动板 - 详细介绍.datazhen

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

树莓派+ L298N 控制二相四线步进电机 的相关文章

随机推荐

  • 嵌入式FreeRTOS学习五,FreeRTOS任务调度器

    四 调度器 FreeRTOS 操作系统支持三种调度方式 xff1a 抢占式调度 xff0c 时间片调度和合作式调度 实际应用主要是抢占式调度和时间片调度 xff0c 合作式调度用到的很少 启动调度器的API函数vTaskStartSched
  • 嵌入式FreeRTOS学习九,任务链表的构成,TICK时间中断和任务状态切换调度

    一 tskTaskControlBlock 函数结构体 在tskTaskControlBlock 任务控制块结构体中 xff0c 其中有任务状态链表和事件链表两个链表成员 xff0c 首先介绍任务状态链表这个结构 xff0c 这个链表通常用
  • 嵌入式FreeRTOS学习十,任务调度和任务就绪链表任务调度过程

    一 main函数里面的栈是哪里分配的 main函数里面用到的栈 xff0c 假设为msp 是汇编代码里面设定的 xff0c 对于STM32F103 在汇编代码里的向量表设置了一个栈 initial sp 那这个栈是给谁用的呢 xff1f 可
  • ovn 通过网关虚拟路由器连接外部网络

    本文实验如何通过ovn的网关逻辑路由器将ovn网络连接到外部网络 前面讲过ovn的逻辑路由器是分布式的 xff0c 这意味着它没有绑定到某个节点上 xff0c 而是存在于所有节点上的 xff0c 同时它是通过每个节点的openflow流表来
  • 嵌入式FreeRTOS学习十一,深入理解任务调度机制

    一 任务调度机制 可抢占 xff1a 高优先级的任务先运行时间片轮转 xff1a 同优先级的任务轮流执行空闲任务礼让 xff1a 如果有同是优先级为0的其他就绪任务 xff0c 空闲任务主动放弃一次运行机会函数调用vTaskDelay xD
  • SOAP传输协议

    一 HTTP传输协议 超文本传输协议 xff08 HyperText Transfer Protocol xff0c 缩写 xff1a HTTP xff09 xff0c 它是基于请求 响应的模式协议 xff0c 客户端发出请求 xff0c
  • ONVIF简介

    一 什么是ONVIF ONVIF规范描述了网络视频的模型 接口 数据类型以及数据交互的模式 并复用了一些现有的标准 xff0c 如WS系列标准等 ONVIF规范的目标是实现一个网络视频框架协议 xff0c 使不同厂商所生产的网络视频产品 x
  • gsoap工具生成onvif设备搜索(remotediscovery)代码框架

    什么是gsoap工具 xff1f gSOAP 提供了两个工具来方便开发人员使用 C C 43 43 语言快速开发Web 服务应用 xff0c 通过 gSOAP 提供的这两个工具 xff0c 开发人员可以快速生成服务端与客户端代码框架 xff
  • 001_初识_飞航科技光标飞控

    这两天老潘给我一块飞控 xff0c 让我练手 xff0c 为电赛做准备 xff0c 拿到控挺开心的 xff0c 毕竟省了一笔RMB 本来想着买块正点原子的飞控 资料 xff1a 说起资料简单看了一下发现还蛮全的 xff0c 但是这个资料我居
  • 写出C语言的第一个程序“Hello World”

    这里写自定义目录标题 写出C语言的第一个程序 Hello World 写出C语言的第一个程序 Hello World 下面展示一些 内联代码片 span class token comment A code block span span
  • Eigen库的安装攻略

    Eigen库的安装攻略 转载 xff1a Eigen库安装 xff08 两种方式 xff09 转载 xff1a Eigen库安装 xff08 两种方式 xff09 链接 link
  • 【ROS2基础学习】

    入门篇 前言一 创建一个功能包二 编译三 source总结 前言 提示 xff1a 这里是记录的大概内容 xff1a 随着机器人技术的不断发展 xff0c ROS也越来越重要 xff0c 很多人都开启了学习ROS xff0c 本文就介绍了R
  • Arduino 外部中断重置内部定时器

    Arduino 外部中断重置内部定时器 文章目录 Arduino 外部中断重置内部定时器前言一 准备工作二 代码三 实验效果1 设置1Hz的方波 xff08 外部中断触发 xff09 xff1a 2 观察示波器各个波形 xff1a 3 延迟
  • ALUBI LPMS-IG1 RS232 IMU ROS2驱动安装

    文章目录 前言一 下载官方系列文档二 windows上的上位机程序安装2 Ubuntu上的ROS2驱动安装Offset Mode 2 总结 前言 IMU在自动驾驶领域广泛应用 xff0c 本文主要记录了在ROS2中使用ALUBI LPMS
  • ovn-northd 源码分析

    ovn northd是ovn中的核心后台进程 xff0c 主要负责将ovn的高层配置转换成供ovn controller后台进程使用的逻辑配置 xff0c 更详细的说就是它将ovn northbound数据库中传统意义上的逻辑网络配置转换成
  • 镭神CH128x1系列激光雷达使用记录

    镭神CH128x1系列激光雷达使用记录 文章目录 镭神CH128x1系列激光雷达使用记录前言一 操作步骤1 PC连接雷达 二 实验1 雷达控制器上的接口 xff1a 2 接口定义3 Rviz中显示效果 总结致谢 前言 本条博客的需求来源于自
  • c语言中char数组的结束位

    因为是半路出家学习cpp的 xff0c 所以经常会对c语言里面的字符数组感到困惑 xff0c 这次一次性做个总结 首先 xff0c 结束位 0 只针对字符数组 xff0c 不针对整型或者其他数组 其次 xff0c 字符数组的大小只针对里面的
  • SUMO 使用netconvert报错解决办法

    SUMO 使用netconvert报错 问题描述正确解决方法不适用的解决方法 问题描述 刚开始学习使用sumo xff0c 版本是sumo1 8 0 第一次使用netconvert转换地图时出现报错 xff0c 提示没有PROJ Libra
  • IoTDB基础 初识IoTDB 安装及基本使用(个人学习记录)

    官方文档 http iotdb incubator apache org zh UserGuide V0 13 x API Programming Java Native API html 参考博客 时序数据库IoTDB安装及基本使用htt
  • 树莓派+ L298N 控制二相四线步进电机

    树莓派 43 L298N 控制二相四线步进电机 1 步进电机 步进电机是一种将电脉冲信号转换成相应角位移或线位移的电动机 在非超载的情况下 xff0c 电机的转速 停止的位置只取决于脉冲信号的频率和脉冲数 xff0c 而不受负载变化的影响