风筝
发表于: 2019-4-21 19:46:55 | 显示全部楼层

选择用于微控制器和外围设备之间通信的通信协议是嵌入式系统的重要部分。这很重要,因为任何嵌入式应用的整体性能都取决于通信手段,因为它与降低成本、更快的数据传输、长距离覆盖等有关。


到目前为止,我们已经写过Arduino Uno和Arduino Nano之间如何进行RS485串行通信,今天我们将主要介绍Arduino UNO开发板和树莓派之间的RS-485通信。


RS485串行通信协议

RS-485是一种异步串行通信协议,不需要时钟信号。它使用一种称为差分信号的技术将二进制数据从一个设备传输到另一个设备。


那么什么是差分信号传输方法呢?

差分信号方法通过使用正负5V产生差分电压来工作。当使用两根电线时,它提供半双工通信,而全双工需要4条电线。


在本篇文章中,伺服电机与Arduino UNO开发板连接,树莓派通过RS-485串行通信向Arduino UNO发送角度值来控制电机的角度。Raspberry Pi用作主机(Master),Arduino UNO和伺服电机作为从站。Arduino开发板还连接一个LCD 1602显示屏,显示从Raspberry Pi收到的角度值。


需要的组件

●    Raspberry Pi 3 B +(安装了Raspbian OS)

●    Arduino UNO开发板

●    MAX485 TTL转RS485转换模块(2)

●    SG-90伺服电机

●    1602 LCD

●    10K电位器

●    面包板

●    连接线


MAX-485 TTL至RS-485转换器模块的引脚和特性

Pinout-of-RS-485.jpg

引脚名称
引脚说明
VCC
5V
A
非反相接收器输入,非反相驱动器输出
B
反相接收器输入,反相驱动器输出
GND
GND(0V)
R0
接收器输出(RX引脚)
RE
接收器输出(低电平有效)
DE
驱动器输出(高电平使能)
DI
驱动器输入(TX引脚)

MAX-485 TTL转RS-485转换模块具有以下特点:

●    工作电压:5V

●    板载MAX485芯片

●    RS485通信功耗低

●    5.08mm间距2P端子

●    方便的RS-485通讯接线

●    板尺寸:44 x 14mm

●    它允许长距离1200米的串行通信


将RS-485模块与Raspberry Pi 3 B +连接

要将MAX485 TTL和RS-485转换模块连接到Raspberry Pi,需要使用Pi的以下UART引脚(GPIO14、GPIO15)。

Raspberry-Pi-UART-Pins.png


将RS-485模块与Arduino UNO连接

要将MAX485 TTL和RS-485转换器模块连接到Arduino UNO,请使用UNO的以下UART引脚(0、1)。

Circuit-Diagram-for-Connecting-RS-485-Module-with-Arduino-UNO.png


RS-485模块和Raspberry Pi 3 B +(主站)之间的电路连接:

RS-485
Raspberry Pi 3 B +
DI
GPIO14(TX)
DE
GPIO4
RE
R0
GPIO15(RX)
VCC
5V
GND
GND
A
RS485从机模块的A
B
RS485从机模块的B

RS-485和Arduino UNO开发板(从站)之间的电路连接:

RS-485
Arduino UNO
DI
1(TX)
DE
2
RE
R0
0(RX)
VCC
5V
GND
GND
A
RS485主机模块的A
B
RS485主机模块的B

这样就完成了所有组件之间所有必要的电路连接。现在开始编写Raspberry Pi和Arduino UNO的Master和Slave代码。


使用Python将Raspberry Pi编程为Master

在主机Raspberry Pi中,(0、10、45、90、135、180、135、90、45、10、0)角度值通过Pi的串行端口发送到RS-485模块,然后将值发送给Arduino UNO并根据角度值控制伺服电机。因此,要在Raspberry Pi中使用串行端口,必须启用UART串行端口。


在Raspberry Pi中启用UART(串行端口)引脚:

在Raspberry Pi中使用UART引脚之前,需要启用它。按照以下步骤在Raspberry Pi中启用UART(串行)引脚。


1.打开终端并输入sudo raspi-config

2.选择“接口选项(Interfacing Options)”

Enabling-UART -pins-in-Raspberry-Pi.png

3.然后选择串口Serial

Select-Serial-Communication-in-Raspberry-Pi.png

4.然后单击“No”(这用于禁用Linux UART控制台)

Disable-Linux-UART-Console-in-Raspberry-Pi.png

5.之后退出raspi-config

6.重新启动Pi


现在可以使用串口了。


重要提示:在将值写入RS-485模块之前,必须将引脚DE和RE置为高电平。


那么,现在让我们详细了解主端的Python编码。

最初,所有库都是为使用的外围设备导入的。这里重要的库是时间、串行(用于串行通信),用于访问GPIO和休眠的GPIO。

  1. import time
  2. import serial
  3. import RPi.GPIO as GPIO
  4. from time import sleep
复制代码

下面,GPIO.BOARD选项指定您通过电路板中的引脚数指引脚。

  1. GPIO.setmode(GPIO.BOARD)
复制代码

Raspberry Pi上的GPIO引脚编号7变为高电平,因为Pi的引脚7连接到RS-485的DE&RE。由于它使RPi向RS-485发送值,因此它变为高电平。

  1. GPIO.setup(7, GPIO.OUT, initial=GPIO.HIGH)
复制代码

在引脚GPIO14和GPIO 15(串行0端口)上启动串行类,其中包含各种信息,如串行端口、波特率、奇偶校验和停止位。

  1. send = serial.Serial(
  2.     port='/dev/serial0',
  3.     baudrate = 9600,
  4.     parity=serial.PARITY_NONE,
  5.     stopbits=serial.STOPBITS_ONE,
  6.     bytesize=serial.EIGHTBITS,
  7.     timeout=1
  8. )
复制代码

定义了具有角度值数组的变量“i”,这些值将通过串行通信发送。

  1. i = [0,10,45,90,135,180,135,90,45,10,0]
复制代码

函数send.write(str(x))在连续执行时,在while循环内逐个写入串口到RS-485的值。值以1.5秒的延迟发送。

  1. while True:
  2. for x in i:
  3.      send.write(str(x))
  4.      print(x)
  5.      time.sleep(1.5)
复制代码

以上完成了Raspberry Pi的代码,它在基于RS485的串行通信中充当主设备。


编程Arduino UNO(从机)

从机一侧是Arduino UNO,从主机收到角度值。连接到Arduino的伺服电机根据接收的值旋转,并且该值显示在LCD显示屏上。所以,在Arduino编程中使用LCD显示库和伺服电机库


使用Arduino IDE开发环境编程Arduino UNO。

就像主机一样,我们有几个外围设备并包含必要的库,类似地,从机侧有外围设备,如伺服电机和1602 LCD显示器,所以首先要包括这些外围设备的库。

  1. #include <LiquidCrystal.h>            
  2. #include <Servo.h>  
复制代码

接下来定义了与Arduino UNO一起使用的1602 LCD显示引脚,然后还创建了Servo对象。

  1. LiquidCrystal lcd(8,9,10,11,12,13);     // Define LCD display pins RS,E,D4,D5,D6,D7
  2. Servo servo;
复制代码

最初显示一条显示消息,可以根据项目进行更改,然后将其清除以显示下一条消息。

  1.   lcd.begin(16,2);
  2.   lcd.print("CIRCUIT DIGEST");
  3.   lcd.setCursor(0,1);
  4.   lcd.print("RS_485");
  5.   delay(3000);
  6.   lcd.clear();
复制代码

串行通信以波特率9600启动。

  1. Serial.begin(9600);     
复制代码

由于Arduino RS-485从主机接收值,因此(EnablePin)的引脚2变为低电平使其处于输入模式,并使RS-485的引脚DE和RE为低电平从主机Raspberry Pi读取值。

  1. digitalWrite(enablePin, LOW);      
复制代码

伺服电机PWM引脚连接到Arduino PWM引脚3。

  1. servo.attach(3);            
复制代码

当连接RS485模块的串行端口有值时,执行while循环。


Serial.paseInt()函数用于从Raspberry Pi发送的串口接收整数值(Angle)

  1. int angle = Serial.parseInt();
复制代码

将接收到的角度值写入伺服电机,使伺服电机轴从(0到180)旋转。

  1. servo.write(angle);
复制代码

最后,使用相应的LCD函数在LCD显示屏上显示角度值。

  1.   lcd.setCursor(0,0);
  2.         lcd.print("Angle From RPi ");
  3.         lcd.setCursor(0,1);
  4.         lcd.print(angle);
复制代码

以上完成了从机侧的编程。此外,通过在Raspberry Pi和Arduino UNO中上传代码,两个控制器都可以进行工作演示。


使用Raspberry Pi和Arduino UNO测试RS485串行通信

当电路连接完成,并将代码上传到Arduino UNO时,请使用终端在Raspberry Pi中运行python代码。角度值从Raspberry Pi发送到Arduino Uno,通过RS-485串行通信控制伺服电机角度。

1.角度:0

Pi-to-Arduino-to Control-Servo-angle-to-0-via-RS-485-Serial-Communication.jpg

2.角度:90

Pi-to-Arduino-to-Control-Servo-angle-to-90-via-RS-485-Serial-Communication.jpg

3.角度:135

Pi-to-Arduino-to-Control-Servo-angle-to-135-via-RS-485-Serial-Communication.jpg

4.角度:180

Pi-to-Arduino-to-Control-Servo-angle-to-180-via-RS-485-Serial-Communication.jpg


以上就是使用Raspberry Pi进行RS485串行通信的完整教程。如果您有任何疑问或建议,请在本帖下面进行回复。


代码

本文使用的完整代码如下: main.zip (1003 Bytes, 下载次数: 49)

跳转到指定楼层
w1998
发表于: 2020-2-13 16:17:48 | 显示全部楼层

没有电位器还可以用吗
回复

使用道具 举报

风筝
发表于: 2020-2-15 19:27:43 | 显示全部楼层

w1998 发表于 2020-2-13 16:17
没有电位器还可以用吗

可以的
回复

使用道具 举报

Amber977
发表于: 2020-4-5 17:41:04 | 显示全部楼层

请问,是现在arduino中上传从机代码,再在树莓派上运行主机代码吗?arduino连接到电脑上?为什么我这边舵机没反应呢
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

主题 705 | 回复: 1492



手机版|

GMT+8, 2024-11-8 09:06 , Processed in 0.043437 second(s), 6 queries , Gzip On, MemCache On. Powered by Discuz! X3.5

YiBoard一板网 © 2015-2022 地址:河北省石家庄市长安区高营大街 ( 冀ICP备18020117号 )

快速回复 返回顶部 返回列表