风筝
发表于: 2019-2-18 22:14:58 | 显示全部楼层

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


在之前的文章中,我们了解了Arduino中的I2C通信协议SPI通信协议。现在还有另一种称为RS-485的串行通信协议。该协议使用异步串行通信。 RS-485的主要优点是两个设备之间的长距离数据传输。它们最常用于电噪声工业环境。


在本篇文章中,我们将了解两个Arduino开发板之间的RS-485串行通信,然后通过RS-485模块发送ADC值,通过控制从Arduino主机连接到Arduino从机的LED的亮度来演示它。 10k电位器用于改变主机Arduino的ADC值。


让我们首先了解RS-485串行通信的工作原理。


RS-485串行通信协议

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


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

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


通过使用这种方法:

●    RS-485支持最高30Mbps的更高数据传输速率。

●    与RS-232协议相比,它还提供最大的数据传输距离。它最多可传输1200米的数据。

●    RS-485相对于RS-232的主要优点是具有单个主设备的多个从设备,而RS-232仅支持单个从设备。

●    它最多可以有32个设备连接到RS-485协议。

●    RS-485的另一个优点是它可以免受噪声影响,因为它们使用差分信号方法进行传输。

●    与I2C协议相比,RS-485更快。


Arduino中的RS-485

为了在Arduino中使用RS-485,需要一个基于Maxim MAX485 IC的称为5V MAX485 TTL到RS485的模块,因为它允许在1200米的长距离上进行串行通信并且是双向的。在半双工模式下,它的数据传输速率为2.5Mbps。


5V MAX485 TTL至RS485模块需要5V的电压并使用5V逻辑电平,以便可以与Arduino等微控制器的硬件串行端口连接。


它具有以下功能:

●    工作电压:5V

●    板载MAX485芯片

●    RS485通信功耗低

●    摆率受限的收发器

●    5.08mm间距2P端子

●    方便的RS-485通讯接线

●    芯片的所有引脚都已通过微控制器控制

●    板尺寸:44 x 14mm


引脚输出RS-485:

Pinout-of-RS-485.jpg


引脚名称
使用方法
VCC
5V
A
同相接收器输入

同相驱动器输出

B
反相接收器输入

反相驱动器输出

GND
GND(0V)
R0
接收器输出(RX引脚)
RE
接收器输出(低电平有效)
DE
驱动器输出(高电平启用)
DI
驱动器输入(TX引脚)

该RS-485模块可与Arduino轻松连接。我们使用Arduino 0(RX)和1(TX)的硬件串口(在UNO、NANO中)。编程也很简单,只需使用Serial.print()写入RS-485和Serial.Read()来读取RS-485即可。


稍后将详细介绍编程部分,但首先要检查所需的元件和电路图。


需要的组件

●    Arduino UNO或Arduino NANO

●    MAX485 TTL转RS485转换模块

●    10K电位器

●    1602 LCD显示屏

●    LED指示灯

●    面包板

●    连接导线


在本篇文章中,Arduino Uno用作Master,Arduino Nano用作Slave。这里使用两个Arduino板,因此需要两个RS-485模块。


电路原理图

Circuit-Diagram-for-RS485-Serial-Communication-between-Arduino-Uno-and-Arduino--Nano.png

第一个RS-485和Arduino UNO(主站)之间的电路连接:

RS-485 Arduino UNO
DI D1(TX)
DE D8
RE D8
R0 D0(RX)
VCC 5V
GND GND
A 连接至从机RS485的A
B 连接至从机RS485的B

对于从机RS-485

RS-485 Arduino Nano
DI D1(TX)
DE D8
RE D8
R0 D0(RX)
VCC 5V
GND GND
A 连接至主机RS485的A
B 连接至主机RS485的B

1602 LCD和Arduino Nano之间的电路连接:

1602 LCD Arduino Nano
VSS GND
VDD + 5V
V0
电位器中心引脚用于LCD的对比度控制
RS D2
RW GND
Ë D3
D4 D4
D5 D5
D6 D6
D7 D7
A + 5V
K GND

10K电位器连接到Arduino UNO的模拟引脚A0,用于提供模拟输入,LED连接到Arduino Nano的引脚D10。

跳转到指定楼层
风筝
发表于: 2019-2-19 21:22:03 | 显示全部楼层

编程Arduino UNO和Arduino Nano用于RS485串行通信

使用Arduino IDE开发环境编程这两个开发板,请确保您已从Tools-> Port选择了相应的端口,以及从Tools->Board选择相应的开发板。


在本篇文章的末尾处给出了完整代码。这里我们解释代码的重要部分。本教程中有两个程序,一个用于Arduino UNO(Master),另一个用于Arduino Nano(Slave)。


Master的代码说明:Arduino UNO

在主机Master侧,只需通过改变电位器在A0引脚上输入模拟输入,然后通过Arduino UNO的硬件串行端口(0,1)将这些值串行写入RS-485总线。

要在硬件串行引脚(0,1)上开始串行通信,请使用:

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

要读取Arduino UNO引脚A0的模拟值并将它们存储在potval变量中,请使用:

  1. int potval = analogRead(pushval);
复制代码

在将potval值写入串口之前,RS-485的引脚DE和RE应为HIGH,连接到Arduino UNO的引脚8,以使引脚8为高电平:

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

接下来将这些值放入与RS-485模块连接的串行端口中,使用以下语句

  1. Serial.println(potval);
复制代码

Slave的代码说明:Arduino NANO

在从机Slave侧,从主RS-485接收一个整数值,该值可在Arduino Nano的硬件串口(Pins -0,1)上获得。只需读取这些值并存储在变量中即可。值的形式为(0-1023)。因此,它被转换为(0-255),因为PWM技术用于控制LED亮度。

然后AnalogWrite将那些转换后的值转换为LED引脚D10(它是一个PWM引脚)。因此,根据PWM值,LED的亮度会发生变化,并在1602 LCD显示屏中显示这些值。


为了让Slave Arduino的RS-485接收来自Master的值,只需将RS-485的引脚DE和RE置为低电平即可。因此,Arduino NANO的引脚D8(enablePin)变为低电平。

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

然后读取串行端口可用的整数数据,将它们存储在变量使用中

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

接下来将值从(0-1023转换为0-255)并将它们存储在变量中:

  1. int convert = map(pwmval,0,1023,0,255);
复制代码

接下来将模拟值(PWM)写入连接LED阳极的引脚D10:

  1. analogWrite(ledpin,convert);   
复制代码

要在1602 LCD显示屏上打印那些PWM值,使用

  1. lcd.setCursor(0,0);
  2. lcd.print("PWM FROM MASTER");
  3. lcd.setCursor(0,1);
  4. lcd.print(convert);
复制代码

通过串行通信RS485控制LED亮度

使用电位器将PWM值设置为0时,LED将熄灭。

RS485-Serial-Communication-between-Arduino-Uno-and-Arduino--Nano.jpg

当使用电位器将PWM值设置为251时:LED以全亮度打开,如下图所示:

Testing-RS485-Serial-Communication-between-Arduino-Uno-and-Arduino--Nano.jpg

以上就是在Arduino中RS485如何用于串行通信。


代码

  1. Master (Arduino UNO):

  2. //Master code (Arduino UNO)
  3. //Serial Communication Between Arduino using RS-485

  4. int enablePin = 8;  
  5. int pushval = A0;
  6. int potval =0 ;

  7. void setup()
  8. {
  9.   Serial.begin(9600);            // initialize serial at baudrate 9600:
  10.   pinMode(enablePin, OUTPUT);
  11.   pinMode(pushval,INPUT);
  12.   delay(10);
  13.   digitalWrite(enablePin, HIGH);  //  (always high as Master Writes data to Slave)
  14. }
  15. void loop()
  16. {
  17.     int potval = analogRead(pushval);
  18.     Serial.println(potval);          //Serial Write POTval to RS-485 Bus
  19.     delay(100);
  20. }

  21. SLAVE CODE: (Arduino NANO):

  22. //Slave code (Arduino NANO)
  23. //Serial Communication Between Two Arduinos using RS-485
  24. //Circuit Digest

  25. #include <LiquidCrystal.h>          //Include LCD library for using LCD display functions

  26. int enablePin = 8;
  27. int ledpin = 10;

  28. LiquidCrystal lcd(2,3,4,5,6,7);       // Define LCD display pins RS,E,D4,D5,D6,D7

  29. void setup()
  30. {
  31.   lcd.begin(16,2);
  32.   lcd.print("CIRCUIT DIGEST");
  33.   lcd.setCursor(0,1);
  34.   lcd.print("RS485 ARDUINO");
  35.   delay(3000);
  36.   lcd.clear();
  37.   Serial.begin(9600);                   // initialize serial at baudrate 9600:
  38.   pinMode(ledpin,OUTPUT);
  39.   pinMode(enablePin, OUTPUT);
  40.   delay(10);
  41.   digitalWrite(enablePin, LOW);        //  (Pin 8 always LOW to receive value from Master)
  42.   
  43. }

  44. void loop()

  45. {                                                  
  46.   while (Serial.available())                   //While have data at Serial port this loop executes
  47.      {
  48.         lcd.clear();            
  49.         int pwmval = Serial.parseInt();            //Receive INTEGER value from Master throught RS-485
  50.         int convert = map(pwmval,0,1023,0,255);    //Map those value from (0-1023) to (0-255)
  51.         analogWrite(ledpin,convert);               //PWM write to LED
  52.         lcd.setCursor(0,0);
  53.         lcd.print("PWM FROM MASTER");
  54.         lcd.setCursor(0,1);
  55.         lcd.print(convert);                        //Displays the PWM value
  56.         delay(100);
  57.     }
  58. }
复制代码

回复

使用道具 举报

相信未来
发表于: 2019-2-19 22:27:03 | 显示全部楼层

风筝 发表于 2019-2-19 21:22
编程Arduino UNO和Arduino Nano用于RS485串行通信使用Arduino IDE开发环境编程这两个开发板,请确保您已从T ...

赞一个
回复

使用道具 举报

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

本版积分规则

主题 705 | 回复: 1492



手机版|

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

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

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